Kubernetes核心概念及核心組件使用與理解

什麼是Kubernetes?


工作流程
在這裏插入圖片描述


Kubernetes是一個可移植性,可擴展的開源平臺,用於管理容器化工作負載和服務,有助於聲明性配置和自動化管理。它擁有龐大,快速發展的生態系統。
谷歌在2014年開源了Kubernetes項目。Kubernetes以谷歌在大規模運行生產工作負載方面的15年經驗爲基礎,結合社區的最佳想法和實踐。

	1.kubernetes是什麼意思?
	2.我們爲什麼需要kubernetes以及它可以爲我們做些什麼?
	3.kubernetes是一個怎樣的平臺?
	4.kubernetes不是什麼?
	5.爲什麼使用容器?
kubernetes是什麼意思?

Kubernetes也稱爲k8s,kubernetes這個名字來源於希臘語,意爲舵手和飛行員,而k8s則是將“ubernete”8個字母替換爲“8”而得到的縮寫。

我們爲什麼需要kubernetes以及它可以爲我們做些什麼?

kubernetes擁有許多的功能,可以認爲它是:

1: 一個容器平臺
2: 一個微服務平臺
3: 便攜式雲平臺,等等。

Kubernetes提供了以容器化爲中心的管理環境,它代表用戶工作負載協調計算,網絡和存儲基礎架構。這提供了平帶即服務(PaaS)的簡單性,具有基礎架構即服務(LaaS)的靈活性,並支持跨基礎架構提供商的可移植性。

kubernetes是一個怎樣的平臺?

儘管kubernetes提供了很多的功能,但總會有新的方案從新功能中受益。可以簡化特定程序的工作流程,以加快開發人員的速度,最初可接受的特殊編排通常需要大規模的健壯自動化。這就是爲什麼kubernetes被設計成一個平臺,用於構建一個有組件和工具組成的生態系統,使其更容易部署,擴展和管理應用。
此外,kubernetes控制平面基於開發人員和用戶可用的相同API構建,用戶可以使用自己的API編寫控制器,(列如調度程序),這些API可以通過命令行工具進行定位。
這種設計使得許多其他系統能夠在Kubernetes上面構建。

kubernetes不是什麼?

Kubernetes不是一個傳統的,包羅萬象的PaaS(平臺即服務),由於Kubernetes在容器級而非硬件級運行,因此它提供了PasS產品常用的一些通用功能,例如:部署,擴展,負載均衡,日誌記錄和監控。然而,Kubernetes並不是完全統一的,而且這些默認解決方案是可選的和可插入的。Kubernetes爲構建開發平臺提供了構建快,但在重要的地方保留了用戶的選擇和靈活性。

Kubernetes:

1:不限制所支持的應用程序類型,Kubernetes的目標是支持多樣化的工作負載,有狀態和數據處理工作負載,如果有應用程序可以在容器中運行,那麼它就可以更好地在Kubernetes上面運行。
2:不部署源代碼,也不構建應用程序,持續集成,交付和部署(CI/CD)工作流程由偏好及技術要求決定。
3:不提供應用程序級服務,例如 消息總線 (例如:中間件),數據處理框架,數據庫,高速緩存,也不提供集羣存儲系統(列如:Ceph)。在服務中,這些組件可以在Kubernetes中運行,可以通過便攜式機制(列如:Open Service Broker) 在Kubernetes上運行的應用程序訪問。
4:不指示記錄,監控或警報解決方案。提供了一些集成作爲概念證明,以收集和導出標準的機制。
5:不提供或者授權配置語言或者系統(例如:jsonnet)。它提供了一個聲明性的API,可以通過任意形式的聲明性規範來實現。
6:不提供或採用任何全面的機器配置,維護,管理或者自我修復。

此外,Kubernetes不僅僅是一個編排系統。實際上,它消除了編排的需要。業務流程的技術定義:首先執行A,然後運行B,然後運行C,相反,Kubernetes由一組獨立的,可組合的控制流程組成,這些流程將當前狀態持續推向所提供的所需狀態,從何從A到C無關緊要,也不需要集中控制。這使得系統更易於使用,且功能更加強大,更具有伸縮性和可擴展性。

爲什麼使用容器?

部署應用程序的舊方法就是使用操作系統軟件包管理器在主機上安裝應用,這樣做的缺點是將應用程序的可執行文件,配置,生命期彼此糾纏在一起,並與主機的操作系統糾纏在一起,可以構建不可變的虛擬機鏡像以實現可預測的部署和回滾,但虛擬機是重量級且不可移植的。

而容器則是基於操作系統虛擬化,而不是硬件虛擬化部署的容器,這些容器彼此隔離並與主機隔離,無法看到彼此之間的進程,具有自己的文件系統,並且它們的計算機資源使用受到限制。比虛擬機更容易構建,與底層基礎架構和主機文件系統分離,所有它們可以跨雲和操作系統進行移植。

由於容器小而快,因此它們每個容器鏡像中打包一個應用程序,這種一對一的應用程序到鏡像關係解鎖了容器的全部優勢。使用容器,可以在構建/發佈時而不是部署時創建不可變得容器鏡像,因爲每個應用程序不需要與應用程序的堆棧的其餘部署組合。也不需要與生產基礎結構環境結合。在構建/發佈時容器鏡像可以實現從開發到生產環境統一。同樣,容器比VM更加透明,有利於監控和管理。容器的流程生命週期由基礎架構管理而不是容器內的流程管理。最後,對於每個容器只有一個應用程序,管理容器就相當於管理容器的部署!




Kubernetes核心組件

kubernetes主要由以下幾個組件組成:

  • etcd 保存了整個集羣的狀態.
  • kubectl 是 Kubernetes 客戶端命令行工具(CLI).
  • apiserver 操作資源的唯一入口,並且提供了,認證,授權,驗證,註冊和發現機制.
  • kubelet 負責維護容器的生命週期,同時也負責,Volume(卷)和CNI(網絡)的管理.
  • controller manager 負責維護集羣的狀態,比如故障檢測,自動擴展,滾動升級等.
  • kube-proxy 負責爲 server 提供 cluster 內部的服務發現和負載均衡
  • kube-scheduler 負責分配調度已經創建好的 pod 到集羣內的節點上,並且監聽 apiserver 查詢還未分配 pod 的 node,然後根據調度策略爲這些 pod 分配節點.

詳情如下

kubeadm

所有的機器都需要初始化執行引擎和 kubelet,這是因爲 kubeadm 依賴 kubelet 來啓動 master 組件,像 kube-apiserver,kube-proxy等等,kubeadm 的提供讓我們可以一鍵部署集羣,是目前 Kubernetes 主推的部署方式.我們只需要執行
kubeadm init --config kubeadm-config.yaml
//或者不指定配置文件
kubeadm init --kubernetes-version=v1.12.0
這兩個命令都會執行:
  • 系統檢查,
  • 生成token,
  • 生成自簽名 CA 證書 和 client 端證書,
  • 生成 kubeconfig 用於 kubelet 鏈接 apiserver,
  • 爲 Master 組件生成 Static Pod manifests 並放到 /etc/kubernetes/manifests 目錄中
  • 配置 RBAC 權限,設置污點
  • 創建其他服務,比如:kube-proxy,kube-dns
刪除集羣也同樣非常簡單:
kubeadm reset		

kubectl

kubectl配置:使用 kubectl 的第一步就是配置 kubernetes 集羣以及認證方式包括, cluster信息:kubernetes server 地址, 用戶信息:用戶名密碼, Context:cluster,用戶信息以及 Namespaces 的組合.
kubernetes 提供了 kubectl 來管理集羣,同時 kubelet 本身提供了大量的命令比如這裏說一下怎麼查看幫助命令:

kubectl options //查看全局選型
kubectl [command] --help //查看子命令幫助
kubectl explain [RESOURCE] //查看資源的定義
kubectl [command] [PARAMS] -o= //設置輸出格式(如 json、yaml、jsonpath 等)
kubectl一些常用命令:

//創建(提供兩種方式)
kubectl create -f xxx.yaml	
kubectl run xxx --image=xxx
//刪除(提供兩種方式)
kubectl delete -f xxx.yaml
kubectl delete <resource> xxx
//更新(提供兩種方式)
kubectl set 
kubectl patch
//查詢
kubectl get xxx
//容器內執行命令
kubectl exec -it <pod-name> sh
//日誌查看
kubectl logs [-f] <pod-name>

apiserver

apiserver 提供了 kubernetes 各類資源的對象(pod,RC)增刪改查以及 watch 等 http Rest接口,是系統的數據總線和數據中心, apiserver 主要提供的功能包括:
  • 集羣之間管理的 REST API 接口,(包括認證授權,數據校驗,以及集羣狀態變更)
  • 提供了其他模塊之間的數據交互和通訊的樞紐,(其他模塊只能通過 apiserver 查詢或者修改數據,只有 apiserver 可以直接操作 etcd)
  • 是資源資源配額控制的入口
  • 擁有完善的集羣安全機制

REST API
kube-apiserver 支持同時提供 http(6443端口)和 http API(127.0.0.1的8080端口),其中 http API 是非安全的是不建議生產環境使用的.
集羣內部與 API Server 的交互
例:與 kube-scheduler,當 scheduler通過 API Server的 Watch接口監聽到新建 pod副本的信息後,它就會檢索所有符合該 pod要求的 node,開始執行 pod調度邏輯,調度成功之後將 pod綁定到 node上。
與 kubelet進行交互,每個 node上面的 kubelet會每隔一個時間週期,就會調用一次 API Server的 REST接口報告自身狀態,API Server則是接收到這些狀態,將這些狀態保存到 etcd中,此外,kubelet也通過 API Server的 watch接口監聽 pod信息,假如監聽到新的 pod副本被分配到本節點上,則執行 pod對應的容器創建和啓動邏輯,刪除以及也是一樣。


kubelet

kubelet會運行在每個節點上面,默認監聽的是 10250端口,接收並執行 user發送的信息,管理 pod以及 pod中的容器,每個 kubelet 都會向 apiserver註冊自身,監控節點和容器資源,並且定期向 apiserver彙報節點資源信息.

節點管理主要包括:

  • 啓動參數 --register-node確認是否向 apiserver註冊自己
  • 如果 kubelet沒有選擇自注冊模式,則需要用戶自己配置 node資源信息,同時需要告知 kubelet集羣在 apiserver的位置.
  • kubelet在啓動時通過 apiserver註冊節點信息,並且定時向 apiserver發送節點信息, apiserver在得到消息後,向信息寫入 etcd.

pod管理主要包括:

kubelet通過 PodSpec的方式工作,PodSpec是描述一個 Pod的 yaml或者 json對象,kubelet採用一組通過各種機制提供的 PodSpecs(apiserver),並確保這些 PodSpecs描述的 Pod正常運行.

  • 文件:啓動參數 --config指定的配置目錄下的文件,默認在 /etc/kubernetes/manifests下,每20秒檢索一次
  • HTTP endpoint(URL):起訂參數 --manifest-url設置,每20秒檢索一次這個端點
  • API Server:通過 API Server監聽 etcd,同步更新 pod清單
  • ATTP Server:kubelet監聽 HTTP 請求,並相應簡單的 API以提交新的 pod清單

通過 apiserver獲取 pod清單並且創建修改 pod過程:
kubelet通過 apiserver client使用 Watch+List 的方式監聽 “/registyr/node/$ 當前節點名”和 “/registry/pods”目錄是獲取的信息獲取到同步緩存中,kubelet監聽 etcd所有針對 pod的操作都會被 kubelet堅挺到,如果發現有新綁定到本節點的 pod,則按照 pod的清單進行創建.
發現本地的 pod被修改,kubelet會做出更新動作,如:刪除 pod中的某個容器,則通過 Docker Client刪除該容器,發現刪除本節點的 pod,則刪除相應的 pod,並且通過 Docker Client刪除該 pod中的容器.

  • 爲該 pod創建一個數據目錄
  • 從 apiserver讀取該 pod清單
  • 爲該 pod掛載外部卷
  • 檢查已經在節點上運行的 pod,如果該 pod沒有容器或者 pause 容器,沒有啓動,則先停止 pod裏所有的容器進程,如果 pod裏有需要刪除的容器,則刪除這些容器
  • 用 “kubernetes/pause” 鏡像爲每個 Pod 創建一個容器,pause容器用於接管 pod中所有其他容器的網絡,每創建一個新的 pod,kubelet都會先創建一個 pause容器,然後創建其他容器.
  • 爲 pod中的每個容器做出下面處理:
    1:爲容器計算出一個 hash值,然後用容器的名字去 Docker查詢對應容器的 hash值,若查到容器,且兩者的 hash值並不相同,則停止 docker中運行的容器,並停止相關聯的 pause容器,若兩者完全相同,則不做任何處理.

Pod的啓動流程
在這裏插入圖片描述

這張圖出自:	https://kubernetes.feisky.xyz/he-xin-yuan-li/index-1/kubelet

Static Pod

所有以非 apiserver方式創建的 pod都叫做 static pod ,kubelet將 static pod的狀態彙報給 apiserver,apiserver爲該 static pod創建一個 Mirror pod和其相匹配,Mirror pod的狀態信息真是反映 static pod的狀態,當 static pod被刪除時,與之對應的 Mirror Pod也會被刪除.

容器運行時

容器運行時(Container Runtime)是 kubernetes最總要的組件之一,真正負責管理鏡像和容器的生命週期,kubelet通過 Container Runtime Interface與容器運行時交互,以管理容器和鏡像.
Container Runtime Interface它將 kubelet與容器運行時解耦,將原來完全面向 pod級別的內部接口拆分面向 Sandbox和 Container的 gRPC接口,並將鏡像管理和容器管理分離到不同的服務.
在這裏插入圖片描述
CRI最早從1.4版本就開始設計討論和研發,在 v1.5中發佈了第一個測試版,在v1.6中已經有了很多外部容器運行時,在 v1.7中又新增了 cri-containerd支持.

kubelet是kubernetes最爲核心的部分,這裏只寫出了一部分,就不一一贅述了,大家可以參考下面網站內容
//https://github.com/kubernetes/kubernetes/tree/master/pkg/kubelet
//https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/
//https://kubernetes.feisky.xyz/he-xin-yuan-li/index-1/kubelet

kube-controller-manager

controller-manager則是很多很多控制器的集合,它的作用就好像人類的大腦一樣通過 apiserver控制着整個集羣並且確保集羣處於預期的工作狀態,其中就包括:
  • Replication Controller
  • Node Controller
  • CronJob Controller
  • Daemon Controller
  • Deployment Controller
  • Endpoint Controller
  • Garbage Collector
  • Namespace Controller
  • Job Controller
  • Pod AutoScaler
  • RelicaSet
  • Service Controller
  • ServiceAccount Controller
  • StatefulSet Controller
  • Volume Controller
  • Resource quota Controller

這裏另外提一個叫做 cloud-controller-manager的控制器,它也是 kube-controller-manager的一部分,稍有不同的是隻有用戶啓動 cloud-Provider的時候纔會需要,用來提供雲服務供應商的控制,它裏面的控制器就比較少了:

  • Node Controller
  • Route Controller
  • Service Controller

高可用
在啓動時設置 --leader-elect=true後,controller manager會使用多節點選主的方式選擇主節點,只有主節點纔會調用 StartControllers()啓動所有控制器,而其他從節點則僅執行選主算法.
多節點選主的實現方法在 leaderelection.go文件它實現了兩種資源鎖( Endpoint或 ConfigMap,kube-controller-manager和 cloud-controller-manager都使用 Endpoint鎖),通過更新資源的 Annotation,來確定主從關係.

高性能
從 Kubernetes1.7開始,所有需要監控資源變化情況的調用均推薦使
Informer,Informer提供了基於事件通知的只讀緩存機制,可以註冊資源變化的回調函數,並可以極大減少 API 的調用.


kube-proxy

kube-proxy在每臺機器上面運行,用來監聽 apiserver 和 server的變化,並且通過 iptables爲服務配置負載均衡,目前僅支持TCP和UDP.
支持以下幾種實現方式
  • usernamespace,最早實現負載均衡的方案,它是在用戶的命名空間監聽一個端口,所有訪問通過 iptables轉發到該端口,然後再內部負載均衡到實際的 pod,該方法效率較低,所以性能比較差.
  • iptables,比較主流的方法,該方法完全以 iptables的方式實現到 server之間的負載均衡,該方法的問題是在服務多是會產生大量的 iptables規則,會出現延時,大規模集羣的情況下有着明顯的性能問題.
  • ipvs:爲解決 iptables 模式的性能問題,v1.11新增了 ipvs模式(v1.8 開始支持測試版,並在 v1.11 GA),採用增量式更新,並可以保證 service更新期間連接保持不斷開.

iptables示例
在這裏插入圖片描述

圖片出自:https://github.com/cilium/k8s-iptables-diagram

啓動 kube-proxy

kube-proxy --kubeconfig=/var/lib/kubelet/kubeconfig --cluster-cidr=10.240.0.0/12 --feature-gates=ExperimentalCriticalPodAnnotation=true --proxy-mode=iptables

kube-proxy工作原理
在這裏插入圖片描述

該圖出自:https://kubernetes.feisky.xyz/he-xin-yuan-li/index-1/kube-proxy

etcd


etcd在這裏就沒有那麼多的事情了,etcd是基於 CoreOS基於 Raft開發的 key-value分佈式存儲,用於服務發現,共享配置,以及一些分佈式鎖,選主等.

etcd的主要功能

  • 基本的 key-value 存儲
  • 監聽機制
  • key 的過期及續約機制,用於監控和服務發現
  • 原子 CAS 和 CAD,用於分佈式鎖和 leader 選舉

Etcd 基於 RAFT 的一致性

選舉方法

  1. 初始啓動時,節點處於 follower 狀態並被設定一個 election timeout,如果在這一時間週期內沒有收到來自 leader 的 heartbeat,節點將發起選舉:將自己切換爲 candidate 之後,向集羣中其它 follower 節點發送請求,詢問其是否選舉自己成爲 leader。

  2. 當收到來自集羣中過半數節點的接受投票後,節點即成爲 leader,開始接收保存 client 的數據並向其它的 follower 節點同步日誌。如果沒有達成一致,則 candidate 隨機選擇一個等待間隔(150ms ~ 300ms)再次發起投票,得到集羣中半數以上 follower 接受的 candidate 將成爲 leader

  3. leader 節點依靠定時向 follower 發送 heartbeat 來保持其地位。

  4. 任何時候如果其它 follower 在 election timeout 期間都沒有收到來自 leader 的 heartbeat,同樣會將自己的狀態切換爲 candidate 併發起選舉。每成功選舉一次,新 leader 的任期(Term)都會比之前 leader 的任期大 1。

日誌複製

當前 Leader 收到客戶端的日誌(事務請求)後先把該日誌追加到本地的 Log 中,然後通過 heartbeat 把該 Entry 同步給其他 Follower,Follower 接收到日誌後記錄日誌然後向 Leader 發送 ACK,當 Leader 收到大多數(n/2+1)Follower 的 ACK 信息後將該日誌設置爲已提交併追加到本地磁盤中,通知客戶端並在下個 heartbeat 中 Leader 將通知所有的 Follower 將該日誌存儲在自己的本地磁盤中。

安全性

安全性是用於保證每個節點都執行相同序列的安全機制,如當某個 Follower 在當前 Leader commit Log 時變得不可用了,稍後可能該 Follower 又會被選舉爲 Leader,這時新 Leader 可能會用新的 Log 覆蓋先前已 committed 的 Log,這就是導致節點執行不同序列;Safety 就是用於保證選舉出來的 Leader 一定包含先前 committed Log 的機制;

選舉安全性(Election Safety):每個任期(Term)只能選舉出一個 Leader

Leader 完整性(Leader Completeness):指 Leader 日誌的完整性,當 Log 在任期 Term1 被 Commit 後,那麼以後任期 Term2、Term3… 等的 Leader 必須包含該 Log;Raft 在選舉階段就使用 Term 的判斷用於保證完整性:當請求投票的該 Candidate 的 Term 較大或 Term 相同 Index 更大則投票,否則拒絕該請求。

失效處理

  1. Leader 失效:其他沒有收到 heartbeat 的節點會發起新的選舉,而當 Leader 恢復後由於步進數小會自動成爲 follower(日誌也會被新 leader 的日誌覆蓋)

2)follower 節點不可用:follower 節點不可用的情況相對容易解決。因爲集羣中的日誌內容始終是從 leader 節點同步的,只要這一節點再次加入集羣時重新從 leader 節點處複製日誌即可。

3)多個 candidate:衝突後 candidate 將隨機選擇一個等待間隔(150ms ~ 300ms)再次發起投票,得到集羣中半數以上 follower 接受的 candidate 將成爲 leader

ps:個人認爲etcd並不是很難理解,所以沒有細寫,這裏寫的etcd出自:https://kubernetes.feisky.xyz/he-xin-yuan-li/index-1/etcd


參考網站:kubernetes.io
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章