1.0 環境版本控制
序號 | 名稱 | 版本 | 備註 |
---|---|---|---|
01 | Kubernetes | 1.25 | |
01 | kubeasz | 3.4.1 | |
02 | Docker | 19.0.0 | |
03 | Java | 1.17 | |
04 | Harbor | 2.0.2 | |
05 | Prometheus | 2.40.3 | |
06 | Istio | 1.16.0 |
注意:
在新版本Kubernetes環境(1.24以及以上版本)下官方不在支持docker作爲容器運行時
2.0 什麼是Kubernetes
2.1 命名、logo等設計概念
Kubernetes單詞起源於古希臘,是舵手的意思。logo既像一張漁網,又像一個羅盤、船舵
另一層意思,Google想表達的是,docker的logo是一條滿載貨物在大海中遨遊的鯨魚,Kubernetes捕獲和引導docker的運行。
2.2 技術概念
Kubernetes,也稱爲K8s,是一個用於自動化部署、擴展和管理集裝箱應用程序的開源系統。它將組成應用程序的容器分組爲邏輯單元,以便於管理和發現。
一個不太合適的理解:k8s 相當於 docker 容器的管理平臺。
3.0 Kubernetes特徵
- 一切以服務爲中心(在什麼地方運行,都是無差別的)
- 自動化(k8s中的服務可以自動擴容、升級、更新、部署等)
4.0 Kubernetes和Docker的關係
Kubernetes,可以看成Docker的上層架構。
以Docker標準的架構爲基礎,打造的一個分佈式架構系統。
但Kubernetes不一定要依賴於Docker,Docker只是一個產品,但Docker技術是一系列的標準。
5.0 Kubernetes的核心概念
假設一個普通的docker容器,Container。
容器中放置各種鏡像。
5.1 pod概念
pod:第一個介紹的就是k8s中新的概念,k8s 的最小調度單元,相當於邏輯主機的概念。
pod特徵:
pod裏面可以多個容器。
裏面的所有容器都運行在一臺機器上。
容器都有自己唯一的id
每個pod內都會有一個容器——Pause,會有一個自己固定的鏡像,作用:根容器,目的主要是將其他容器關聯到根容器上,附帶共享資源(共享存儲、網絡、運行信息等)。
5.2 ReplicaSet(Rs)概念
pod的上一層,叫ReplicaSet(Rs)(副本集),副本集會管理多個pod。
ReplicaSet的作用就是當一個pod出現問題,就會調度起另一個pod運行,保障服務穩定。
5.3 Deployment概念
ReplicaSet(Rs)(副本集)的上一層,叫Deployment(部署)。
比如,一箇舊的應用,運行了2個實例(pod),當想要更新這個應用。此時就相當於更新Deployment容器。
Deployment會自動創建一個新的ReplicaSet(Rs)(副本集)。
滾動先啓動一個新的pod。新的pod和 舊的一模一樣,當然,id會更新。
通過健康檢查後,此時會有3個實例。
然後會刪掉舊版本,這時候運行一個新版本和一箇舊版本實例。
舊版本刪除一個以後,新的ReplicaSet(Rs)(副本集)會創建另一個pod,並管理起來。
然後刪掉舊的ReplicaSet(Rs)(副本集)
此時,
服務更新
的過程就完成了。
以上Deployment操作纔是人爲層面參與進行的,Deployment下的ReplicaSet(Rs)(副本集)和pod的操作由k8s自動完成。
5.4 Service概念
Service概念涉及到label(標籤)概念。
k8s中很多概念都可以打標籤,比如Deployment(部署)可以打標籤,pod也可以打標籤。
比如,我們運用了一個單點登錄的服務,可以打標籤app:login
。
此時我們創建一個Service,Service可以配置Selector,表明這個Service負責管理的標籤爲app=login
的對象。
Service對外,會有一個ClusterIP。
Client(客戶端)可以通過ClusterIP訪問到Service,進行一些操作。
6.0 Kubernetes的架構設計
6.1 節點(Node)概念
k8s肯定會需要很多的服務器(節點)。
服務器分爲2種角色。
一種叫做master節點(Node)(主節點),一種叫做work節點(Node)。
master負責去管理各種work節點。
6.2 組件——EDCD
k8s當然也有自己的數據存儲持久化(比如文件存儲、數據庫存儲、中間件存儲等),這寫信息就需要放在一個地方,k8s選擇的組件叫EDCD
(EDCD集羣)。
比如:
- master節點上,有一個組件
ApiServer
,是操作k8s的唯一入口。ApiServer
接到客戶端請求後,通過k8s的另一個組件Scheduler(調度器)
獲取信息。Scheduler
會收集每一個work節點
的詳細信息(比如資源、內存、CPU、節點上運行了什麼樣的服務等)。Scheduler
通過策略、算法(主要是預選策略、優選策略),最終選擇一個最優的work節點
,將work節點
和pod
建立起關係。Scheduler
告訴ApiServer
,這個pod
可以運行在某個work節點
上。ApiServer
把這個信息存到EDCD
中,實現數據存儲持久化。
6.3 Controller Manager
pod和work節點綁定之後,需要將pod真正啓動起來。這時候需要另一個組件ControllerManager
,ControllerManager
,集羣內部控制中心,負責維護各種k8s對象。
Controller Manager 由 kube-controller-manager 和 cloud-controller-manager 組成,是 Kubernetes 的大腦,它通過 apiserver 監控整個集羣的狀態,並確保集羣處於預期的工作狀態。
Controller Manager通過 apiserver ,獲取EDCD
存儲的節點信息的變化,使pod運行起來。
kube-controller-manager 由一系列的控制器組成
序號 | 名稱 | 說明 |
---|---|---|
1 | Certificate Controller | |
2 | ClusterRoleAggregation Controller | |
3 | Node Controller | |
4 | CronJob Controller | |
5 | Daemon Controller | |
6 | StatefulSet Controller | |
7 | Endpoint Controller | |
8 | Endpointslice Controller | |
9 | Garbage Collector | |
10 | Namespace Controller | |
11 | Job Controller | |
12 | Pod AutoScaler | |
13 | PodGC Controller | |
14 | ReplicaSet Controller | |
15 | Service Controller | |
16 | ServiceAccount Controller | |
17 | Volume Controller | |
18 | Resource quota Controller | |
19 | Disruption Controller |
cloud-controller-manager 在 Kubernetes 啓用 Cloud Provider 的時候才需要,用來配合雲服務提供商的控制,也包括一系列的控制器,如
序號 | 名稱 | 說明 |
---|---|---|
1 | Node Controller | |
2 | Node Lifecycle Controller | |
3 | Route Controller | |
4 | Service Controller |
6.4 pod怎麼在work節點上運行起來
每一個work節點需要裝好一個服務——Kubelet
。
Kubelet:主要負責維護pod的生命週期,容器的mem、網絡等,最終Kubelet會調用本地的docker,運行起容器、和各種pod。
7.0 Kubernetes的認證密碼學原理
我們已經知道k8s中,所有的資源,都是通過組件ApiServer來實現。
k8s集羣關鍵在於,ApiServer如何去實現客戶端的身份,通過身份(認證)去訪問權限的授權授權()。
密碼學的2個概念。
- 對稱加密:加密解密同一個祕鑰
- 非對稱加密:加密解密2個祕鑰且不相同。
這2個祕鑰稱爲密鑰對,加密的就叫公鑰,解密的叫私鑰。
非對稱加密的缺點就是算法複雜,加密和解密消耗非常大。
密碼學解決方案:
ServiceX(服務X)將對稱加密的祕鑰A,
通過非對稱加密的公鑰B加密後,
發送給另一臺服務ServiceY(服務Y),
ServiceY(服務Y)非對稱加密的私鑰C進行解密,
獲得對稱加密的祕鑰A。
接下來2個服務通過對稱加密進行通訊即可。
這種解決方案,就是鼎鼎大名的SSL/TLS
協議。(https就是通過這2個協議進行加密實現的)
這樣協議還是有風險的。
截獲ServiceY(服務Y)發送到ServiceX(服務X)的公鑰。
ServiceX(服務X)拿到公鑰後加密自己的私鑰
ServiceX(服務X)傳輸時,被截取數據,拿截取的公鑰當成私鑰解密,得到對稱加密的私鑰。
此時,數據就已經不安全了。
當然,以上的技術實現難度很高。
新的解決方案就是通過CA(證書認證)實現。
使用 CA ,證書認證機構,所有合法的網站的證書,都保存在 CA。
ServiceX(服務X)拿到公鑰後,向CA認證證書請求,判斷公鑰是否合法。合法後再去通訊,保證公鑰是一個正常的公鑰。
這個就是 https 的實現機制,所有的 https 網站相當於ServiceB, 公開聲明一個公鑰,而且這個公鑰要註冊到證書認證機構。
8.0 Kubernetes的認證和授權
8.1 認證
k8s用到的CA證書是自己頒發給自己的自定義CA。
k8s提供的認證方式有:
- 集羣外部訪問APiServer
- 客戶端證書認證(TLS雙向認證)
- BearerToken:相當於一個複雜的密碼,定義在ApiServer中,客戶端每次請求帶上這個密碼,就可以進行通訊。
- k8s內部進行通訊,比如pod和ApiServer進行通訊
- ServiceAccount(namespace、token、ca)
8.2 授權
k8s中有一系列鑑權的機制。
比如:
ABAC
WebHook
RBAC(k8s 1.6 引入)(全稱:Role Based Access Control,基於角色的訪問控制)
RBAC是最新的一種授權策略,相對於其他兩種,目前RBAC也是一種更好地選擇。
因此只需要瞭解掌握RBAC即可。
8.3 RBAC
RBAC權限系統遵循這樣一種三層結構。
user(用戶) Role (角色) Authority(權限)
User
User層面上分爲2種用戶。
User:普通用戶
ServiceAccount:集羣內部訪問ApiServer的用戶
Role
name:名字
resourse:哪些權限
Verbs(動作 ):擁有哪些操作
Authority
權限也分爲2種
Resource:資源維度
Verbs:可以理解爲增刪改查(CURD)維度。
k8s沒有數據庫,通過RolBinding
資源實現一種類似於數據庫關係綁定的建立。
k8s中有個非常重要的概念——namespace,namespace作用主要是對k8s中的資源起到隔離的作用。
如果一個角色,只能訪問某個或者某幾個命名空間下的資源,當下權限就不兼容了,因爲不包含命名空間體系參與。
因此,k8s將角色放入一個namespace下,如果擁有某個角色,則只能擁有當前這個命名空間下的角色。
如果用戶需要整個集羣得到角色,則需要用到如下的定義:
ClusterRole:集羣的角色。
ClusterRoleBinding:集羣的角色綁定。
8.4 API 對象
Role
、
ClusterRole
、
RoleBinding
、
ClusterRoleBinding
。
- Role 總是用來在某個名字空間內設置訪問權限; 在你創建 Role 時,你必須指定該 Role 所屬的名字空間。
- Role 和 ClusterRole只能選其中一個。
如果希望在名字空間內定義角色,應該使用 Role;
如果希望定義集羣範圍的角色,應該使用 ClusterRole。
- ClusterRole爲以下資源授予訪問權限:
- 集羣範圍資源(比如節點(Node))
- 非資源端點(比如
/healthz
)- 跨名字空間訪問的名字空間作用域的資源(如 Pod)
RoleBinding 和 ClusterRoleBinding的區別:
https://kubernetes.io/zh-cn/docs/reference/access-authn-authz/rbac/#rolebinding-and-clusterrolebinding
AdmisionControl
AdmisionControl:准入控制
准入控制可以理解爲一個個的小插件,各種小插件獨立存在,沒有任何關係,依次執行各種准入策略,如果通了,那就表示准入成功。
常見的幾種AdmisionControl:
AlwaysAdmit:總是允許所有的請求
此插件已被棄用,因其行爲與沒有準入控制器一樣。AlwaysDeny:總是拒絕所有的請求(一般用於測試)
由於它沒有實際意義,已被棄用。ServiceAccount:總是允許所有的請求,和上面說的ServiceAccount完全不是同一個概念。
作用是給ServiceAccount提供自動化,輔助ServiceAccount去做一些事情。
比如某些pod,沒有ServiceAccount,它會自動去添加當前命名空間默認的一個ServiceAccount。
確保ServiceAccount在每個pod都存在。
PS:強烈推薦爲 Kubernetes 項目啓用此准入控制器。 如果你打算使用 Kubernetes 的 ServiceAccount 對象,你應啓用這個准入控制器。DenyEscolatingExec:用於拒絕所有的Exec和tech到我們的具有一些特權的POD上,用於限制登錄到我們的容器裏執行命令的一個安全層面的插件
9.0 集羣搭建方案對比
9.1 社區方案
- 雜亂
非常的雜,非常的多,五花八門的,一些是個人做的方案,一些是一些小團隊出的方案,有點方案是單機部署的,有的方案是部署集羣的,還有一些是高可用的方案,還有一些是非高可用的方案。
- 不可靠
一方面體現在雖然大部分的解決方案都號稱簡化,但其實它們並不簡單,如果安裝過程中出現任何的問題都是出於字面很難定位原因,非常的難以解決,如果對方案涉及到的技術(如Linux Shell)不是很懂 ,出現問題基本上是搞不定。
- 升級難
比如使用了一個方案,半年前是1.0版本,現在想升級到1.3,你可定還是用之前使用的那個方案,因爲你比較熟悉了。但是很有可能你發現之前那個方案就停留在了1.0,不支持更高級版本的安裝,所以你只能用另外的方式做了。
綜上,社區方案不推薦。
9.2 kubeadm(官方推薦)
優點:
- 優雅
使用kubeadm去安裝幾乎所有的組件都是運行在容器中的,並且都是運行k8s的pod裏面,這個是它非常優雅的一個地方
- 簡單
安裝的過程非常的簡單,配上一個配置文件,運行一個命令kubeadm-init,它幾乎會幫你做所有的事情,過程還是非常簡單的。
- 支持高可用
不但支持非高可用的集羣安裝,也支持高可用的集羣安裝
- 升級方便
升級可以說是隨時隨地,只要拿到了kubeadm的命令,肯定是可以部署最新的k8s的集羣,官方出的,肯定會跟k8s同步更新。
缺點:
- 不易維護
對容器不太熟悉,或者是說對k8s機制不太熟悉的運維人員,維護可能非常的困難的。傳統的運維去運維Kubernetes的POD,很難上手
- 文檔不夠細緻
如果直接按照官方的文檔去做,很多時候會卡主,或者是出現什麼問題,很有可能不知道說的這一步是什麼意思,一些變量不知道該如何去替換,有的時候文檔裏面會有一些錯誤。曾經1.1的文檔中kubectl中的yum配置文件在的內容是有缺失的,就導致很多用戶花費很長時間去解決這個問題。
9.3 Binary
優點:
- 易於維護
所有都是通過進程直接運行的,並需要一點一點去配置,手動去運行起來,這樣會非常清楚每個組件怎麼運行,有什麼樣的調用關係,非常易於去理解。
- 靈活
不管搭建單機,還是高可用,需要一個模塊一個模塊的去運行起來的,你想怎麼配置就怎麼配置,控制你來非常的靈活
- 升級方便
這個跟Kubeadm一樣,可以一點點去升級,不會對真個集羣造成太大影響。
缺點
- 沒有文檔
在官方文檔裏,都沒有發現關於二進制的安裝和配置的一些文檔。
- 安裝複雜
一方面原因跟沒有文檔有一定的關係,還有個重要的原因是每一個組件都需要手動去進行配置,包括數字證書、認證授權CA都需要一步步的生成。
9.4 方案的選擇
官方的方案有兩種:kubeadm、Binary(二進制),都有各自有各自的優缺點,可以根據自身情況做選擇。
目前生產環境中,大部分的公司使用Binary(二進制)的方式比較多。