1. Kubernetes 是什么?
Kubernetes 是一個自動化的容器編排平台,它負責應用的部署、應用的彈性伸縮以及應用的管理。
2. Kubernetes 架構
Kubernetes 架構是一個比較典型的二層架構和 Server-Client 架構。Master 作為中央的管控節點,會去與 Node 進行一個連接。客戶端(比如UI/CLI等)只會和 Master 進行連接,把希望的狀態或者想執行的命令下發給 Master,Master 會把這些命令或者狀態下發給相應的節點,進行最終的執行。
2.1 Master
Kubernetes 的 Master 包含四個主要的組件:kube-apiserver、kube-controller、kube-scheduler 以及 etcd,如下圖所示。我們一般也稱Master節點為控制面(Control Plane),控制面的這4個組件對集群做出全局決策(比如把Pod調度到某個合適的節點上),以及檢測和響應集群事件。
各組件的作用簡要概括如下:
-
kube-apiserver:顧名思義是用來處理 API 操作的,Kubernetes 中所有的組件都會和 API Server 進行連接,組件與組件之間一般不進行獨立的連接,都依賴於 API Server 進行消息的傳送;
-
kube-controller-manager:是控制器管理器,它用來完成對集群狀態的管理。其中具體包括這幾個控制器,如下所示:
- Node controller: Responsible for noticing and responding when nodes go down.
- Replication controller: Responsible for maintaining the correct number of pods for every replication controller object in the system.
- Endpoints controller: Populates the Endpoints object (that is, joins Services & Pods).
- Service Account & Token controllers: Create default accounts and API access tokens for new namespaces
-
kube-scheduler:是調度器,“調度器”顧名思義就是完成調度的操作,該組件監視那些新創建的 Pod,並選擇符合調節的節點讓 Pod 在上面運行。調度決策考慮的因素包括單個 Pod 和 Pod 集合的資源需求、硬件/軟件/策略約束、親和性和反親和性規范、數據位置、工作負載間的干擾等。
-
etcd:是一個分布式的一個存儲系統,API Server 中所需要的這些原信息都被放置在 etcd 中,etcd 本身是一個高可用系統,通過 etcd 保證整個 Kubernetes 的 Master 組件的高可用性。
2.2 Node
Kubernetes 的 Node 是真正運行業務負載的,每個業務負載會以 Pod 的形式運行。一個 Pod 中運行一個或者多個容器,真正去運行這些 Pod 的組件的是叫做 kubelet,也就是 Node 上最為關鍵的組件,它通過 API Server 接收到所需要 Pod 運行的狀態,然后提交到我們下面畫的這個 Container Runtime 組件(簡單的理解也就是平時我們所說的容器)中。
各組件的作用概括如下:
- kubelet:這是運行在每個工作節點上最重要的組件,kubelet 接收一組通過各類機制提供給它的 PodSpecs(也就是Pod的期望狀態),確保這些 PodSpecs 中描述的容器處於運行狀態且健康。
- kube-proxy:kube-proxy 維護節點上的網絡規則。這些網絡規則允許從集群內部或外部的網絡與 Pod 進行網絡通信。它是實現Kubernetes Service概念的重要組件。
- Container Runtime:容器運行時,指的是負責運行容器的軟件,Kubernetes 支持多種容器運行時: Docker、 containerd、cri-o、 rktlet 以及任何實現 Kubernetes CRI 的容器。(初學者暫時可以把container runtime等同於Docker,或者平時所說的“容器”即可)
另外,上圖中還有 Storage Plugin 和 Network Plugin,這些是 Kubernetes 的插件(addons),而不是 Kubernetes 本身就實現的,這些插件使用 Kubernetes 資源 (DaemonSet, Deployment等) 的形式實現集群功能。因為插件提供的功能是集群級別的,所以插件的命名空間資源屬於 kube-system
命名空間,看起來就像 Kubeenetes 本身提供的原生功能一樣。比如網絡插件比較出名的就有 Calico 和 Flannel。
需要強調的是,Kubernetes 的 Node 並不會直接和用戶進行交互,它的交互只會通過 Master,用戶通過 Master 向節點下發信息。Kubernetes 每個 Node 上,都會運行剛才提到的這幾個組件。
總結:
【拓展】
為了深入理解各個組件的交互過程,對「拉起一個Pod的具體過程」需要有非常細致的了解。
3. Kubernetes 核心概念
3.1 Pod
Pod 是 Kubernetes 的一個最小調度以及資源單元。用戶可以通過 Kubernetes 的 Pod API 生產一個 Pod,讓 Kubernetes 對這個 Pod 進行調度,也就是把它放在某一個 Kubernetes 管理的節點上運行起來。一個 Pod 簡單來說是對一組容器的抽象,它里面會包含一個或多個容器。
比如像下面的這幅圖里面,它包含了兩個容器,每個容器可以指定它所需要資源大小。比如說,一個1 C, 1G,或者說 0.5 C, 0.5 G。
當然在這個 Pod 中也可以包含一些其他所需要的資源:比如說我們所看到的 Volume 卷這個存儲資源;比如說我們需要 100 個 GB 的存儲或者 20GB 的另外一個存儲。
在 Pod 里面,我們也可以去定義容器所需要運行的方式。比如說運行容器的 Command,以及運行容器的環境變量等等。Pod 這個抽象給容器提供了一個共享的運行環境,它們會共享同一個網絡環境,這些容器可以用 localhost 來進行直接的連接。而 Pod 與 Pod 之間,則是互相隔離的。
3.2 Volume
Volume 就是卷的概念,它是用來管理 Kubernetes 存儲的,是用來聲明在 Pod 中的容器可以訪問文件目錄的,一個卷可以被掛載在 Pod 中一個或者多個容器的指定路徑下面。
而 Volume 本身是一個抽象的概念,一個 Volume 可以去支持多種的后端的存儲。比如說 Kubernetes 的 Volume 就支持了很多存儲插件,它可以支持本地的存儲,可以支持分布式的存儲,比如說像 ceph,GlusterFS ;它也可以支持雲存儲,比如說阿里雲上的雲盤、AWS 上的雲盤、Google 上的雲盤等等。
3.3 Deployment
Deployment 是在 Pod 這個抽象上更為上層的一個抽象,它可以定義一組 Pod 的副本數目、以及這個 Pod 的版本。一般用 Deployment 來做應用的真正的管理,而 Pod 是組成 Deployment 最小的單元。
Kubernetes 是通過 kube-controller去維護 Deployment 中 Pod 的數目,它也會去幫助 Deployment 自動恢復失敗的 Pod。
比如說我可以定義一個 Deployment,這個 Deployment 里面需要兩個 Pod,當一個 Pod 失敗的時候,控制器就會監測到,它重新把 Deployment 中的 Pod 數目從一個恢復到兩個,通過再去新生成一個 Pod。通過控制器,我們也會幫助完成發布的策略。比如說進行滾動升級,進行重新生成的升級,或者進行版本的回滾。
3.4 Service
Service 提供了一個或者多個 Pod 實例的穩定訪問地址。
比如在上面的例子中,我們看到:一個 Deployment 可能有兩個甚至更多個完全相同的 Pod。對於一個外部的用戶來講,訪問哪個 Pod 其實都是一樣的,所以它希望做一次負載均衡,在做負載均衡的同時,我只想訪問某一個固定的 VIP,也就是 Virtual IP 地址,而不希望得知每一個具體的 Pod 的 IP 地址。
我們剛才提到,如果一個 Pod 失敗了,可能會換成另外一個新的。對一個外部用戶來講,提供了多個具體的 Pod 地址,這個用戶要不停地去更新 Pod 地址,當這個 Pod 再失敗重啟之后,我們希望有一個抽象,把所有 Pod 的訪問能力抽象成一個第三方的一個 IP 地址,實現這個的 Kubernetes 的抽象就叫 Service。
實現 Service 有多種方式,Kubernetes 支持 Cluster IP,上面我們講過的 kuber-proxy 的組網,它也支持 nodePort、 LoadBalancer 等其他的一些訪問的能力。
3.5 Namespace
Namespace 是用來做一個集群內部的邏輯隔離的,它包括鑒權、資源管理等。Kubernetes 的每個資源,比如剛才講的 Pod、Deployment、Service 都屬於一個 Namespace,同一個 Namespace 中的資源需要命名的唯一性,不同的 Namespace 中的資源可以重名。
比如運行 kubernetes 本身需要的一些基礎組件,也就上面提到的kube-apiserver,kube-proxy等,他們的 Namespace 就是 kube-system
。
➜ ~ kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-66bff467f8-tzbcz 1/1 Running 1 21h
coredns-66bff467f8-x6jml 1/1 Running 1 21h
etcd-minikube 1/1 Running 0 20h
kube-apiserver-minikube 1/1 Running 0 20h
kube-controller-manager-minikube 1/1 Running 1 21h
kube-proxy-77nj4 1/1 Running 1 21h
kube-scheduler-minikube 1/1 Running 1 21h
storage-provisioner 1/1 Running 3 21h
參考: