Kubernetes 架構原理詳解

Kubernetes 是什麼,爲什麼上手這麼難?

Kubernetes 是一個基於容器技術的分佈式集羣管理系統。它是谷歌在大規模應用容器技術方面數十年經驗的實際成果。因此,支持大規模的集羣管理承載着非常多的組件,分佈式本身的複雜度非常高。

Kubernetes 到底有什麼?

接下來我們一步步來看看 Kubernetes 到底有什麼?

首先,既然是分佈式系統,那麼肯定有多個 Node 節點(物理主機或者虛擬機),它們共同構成了一個分佈式集羣,而這些節點之間會有一個 Master 節點,統一管理 Node 節點。如圖所示:

問題 1:Master 節點和 Worker 節點如何通信?

首先,當 Master 節點啓動時,會運行一個 Kube-apiserver 進程,它提供了集羣管理的 API 接口,是集羣中各個功能模塊之間進行數據交互和通信的中心樞紐,同時也提供了一個完善的集羣安全機制。

在 Node 節點上,利用 Kubernetes 中的 kubelet 組件,每個 Node 節點上都會運行一個 kubelet 進程,負責向 Master 彙報本節點的運行狀態,如 Node 節點註冊、終止、定期健康報告等等,並接收來自 Master 的命令並創建相應的 Pod。

在 Kubernetes 中,Pod 是最基本的運行單元。它與 Docker 容器略有不同,因爲 Pod 中可能包含一個或多個容器(可以是 Docker 容器),這些容器內部共享網絡資源,即可以通過 localhost 相互訪問。

關於如何在 Pod 中實現網絡共享,每個 Pod 啓動,內部都會啓動一個 pause 容器(谷歌的 image)。它使用默認的網絡模式,其他容器的網絡設置爲它,完成網絡共享問題。

如圖所示:

問題 2:Master 如何將 Pod 調度到指定的 Node 上?

這項工作由 Kube-scheduler 完成。整個調度過程通過執行一系列複雜的算法,最終爲每個 Pod 計算出一個最優的目標 Node,這是由 Kube-scheduler 進程自動完成的。

最常見的是循環調度(RR)。當然也有可能我們需要將 Pod 調度到指定的 Node 上。我們可以通過將節點的標籤(Label)與 Pod 的節點選擇器屬性進行匹配來達到指定的效果。

如圖所示:

問題 3:各個節點和 Pod 的信息統一在哪裏維護,誰來維護?

從上面的 Pod 調度來看,我們必須有一個存儲中心來存儲每個節點的每個 Pod 的資源使用情況、健康狀態和基本信息,這樣 Pod 調度才能正常進行。

在 Kubernetes 中,etcd 組件被用作高可用和一致的存儲庫。該組件可以內置在 Kubernetes 中,也可以外部構建供 Kubernetes 使用。

集羣上的所有配置信息都存儲在 etcd 中。考慮到各個組件的相對獨立性和整體的可維護性,這些存儲的數據的增刪改查都是統一由 Kube-apiserver 來調用的,並且 apiserver 還提供了 REST 支持,不僅爲各個內部組件提供服務但也向集羣外的用戶公開服務。

外部用戶可以通過 REST 接口或 kubectl 命令行工具管理集羣,該工具內部與 apiserver 通信。

如圖所示:

問題 4:外部用戶如何訪問集羣中運行的 Pod?

前面我們講了外部用戶如何管理 Kubernetes,但我們更關心的是內部運行的 Pod 如何對外訪問。

用過 Docker 的同學應該都知道,如果使用 bridge 模式,在創建容器的時候會分配一個虛擬 IP,外部無法訪問該 IP。我們需要做一層端口映射,將容器中的端口映射到宿主機的端口 Map 並綁定,這樣外部就可以通過訪問宿主機的指定端口來訪問容器內部的端口。

那麼,Kubernetes 的外部訪問也是這樣實現的嗎?答案是否定的,Kubernetes 中的情況更加複雜。因爲上面說的 Docker 是單機模式,一個容器對外暴露一個服務。在分佈式集羣中,服務往往由多個應用提供,以分擔訪問壓力,而這些應用可能分佈在多個節點上,這就涉及到跨主機通信。

這裏 Kubernetes 引入了 Service 的概念,將多個相同的 Pod 包裝成一個完整的服務,對外提供服務。至於獲取這些相同的 Pod,每個 Pod 在啓動時都會設置 labels 爲 attribute。

在服務中,我們傳遞選擇器 Selector,選擇與整體服務具有相同 Name 標籤屬性的 Pod,將服務信息通過 Apiserver 存儲到 etcd 中,由 Service Controller 完成。同時在每個節點上啓動一個 kube-proxy 進程,負責從服務地址到 Pod 地址的代理和負載均衡。

如圖所示:

問題 5:Pod 如何動態擴容和伸縮?

既然我們知道服務是由 Pod 組成的,那麼服務的擴展也意味着 Pod 的擴展。通俗地說,就是在需要的時候將 Pod 做多個副本,在不需要的時候將 Pod 縮減到指定的副本數。

在 Kubernetes 中,使用 Replication Controller 進行管理,爲每個 Pod 設置一個預期的副本數。當實際副本數量不符合預期時,動態調整數量以達到預期值。所需值可以由我們手動更新,也可以由自動縮放代理更新。如圖所示:

問題 6:各個組件如何協同工作?

最後說一下 Kube-controller-manager 進程的作用。我們知道 ectd 是作爲集羣數據的存儲中心,而 apiserver 是用來管理數據中心,充當其他進程與數據中心通信的橋樑。

Service Controller 和 Replication Controller 由 Kube-controller-manager 管理。作爲一個守護進程,每個 Controller 都是一個控制迴路,通過 apiserver 監控集羣的共享狀態,並嘗試將實際狀態中不符合預期的變化。關於 Controller,管理器還包括 Node Controller、ResourceQuota Controller、Namespace Controller 等。

如圖所示:

總結

本文通過問答的方式不涉及任何深入的實現細節。從整體的角度,從概念上介紹了 Kubernetes 涉及的基本概念。相關用途包括:

與運行過程相關的是:

作者:banq

來源:https://www.jdon.com/64368.html

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/sZd6rpNOEUvzEngbGvOcdQ