k8s 到底是什麼,架構是怎麼樣的?

你是一個程序員,你用代碼寫了一個博客應用服務,並將它部署在了雲平臺上。
但應用服務太過受歡迎,訪問量太大,經常會掛。

所以你用了一些工具自動重啓掛掉的應用服務,並且將應用服務部署在了好幾個服務器上,總算抗住了。

後來你又上線了商城應用服務和語音應用服務,隨着應用服務變多,需求也千奇百怪。有的應用服務不希望被外網訪問到,有的部署的時候要求內存得大於 xxGB 才能正常跑。
你每次都需要登錄到各個服務器上,執行手動操作更新。不僅容易出錯,還賊浪費時間

原本就沒時間找女朋友的你,現在哭得更大聲了。

那麼問題就來了,有沒有一個辦法,可以解決上面的問題?當然有,沒有什麼是加一箇中間層不能解決的,如果有,那就再加一層
這次我們要加的中間層,叫 Kubernetes

Kubernetes 的位置

Kubernetes 是什麼?

Kubernetes,它是 G 家開源的神器,因爲單詞太長,所以我們習慣省略中間 8 個字母,簡稱它爲 k8s

k8s 名稱的由來

它介於應用服務服務器之間,能夠通過策略,協調和管理多個應用服務,只需要一個 yaml 文件配置,定義應用的部署順序等信息,就能自動部署應用到各個服務器上,還能讓它們掛了自動重啓,自動擴縮容。

聽起來有些厲害,它是怎麼實現這些功能的呢?

Kubernetes 架構原理

爲了實現上面的功能,Kubernetes 會將我們的服務器劃爲兩部分,一部分叫控制平面(control plane,以前叫 master),另一部分叫工作節點,也就是 Node。簡單來說它們的關係就是老闆和打工人, 用現在流行的說法就是訓練師和帕魯。控制平面負責控制和管理各個 Node,而 Node 則負責實際運行各個應用服務。

k8s 控制平面和 Node 的關係

我們依次看下這兩者的內部架構。

控制平面內部組件

以上就是控制平面內部的組件。

k8s 控制平面組件

我們接下來再看看 Node 裏有哪些組件。

Node 內部組件

Node 是實際的工作節點,它既可以是裸機服務器,也可以是虛擬機。它會負責實際運行各個應用服務。多個應用服務共享一臺 Node 上的內存和 CPU 等計算資源。

Node 可以是裸機服務器或虛擬機

在文章開頭,我們聊到了部署多個應用服務的場景。以前我們需要上傳代碼到服務器,而用了 k8s 之後,我們只需要將服務代碼打包成 Container Image(容器鏡像),就能一行命令將它部署。

如果你不瞭解容器鏡像的含義,你可以簡單理解爲它其實就是將應用代碼和依賴的系統環境打了個壓縮包,在任意一臺機器上解壓這個壓縮包,就能正常運行服務。爲了下載和部署鏡像,Node 中會有一個 Container runtime 組件。

將容器鏡像粗略理解爲壓縮包

每個應用服務都可以認爲是一個 Container(容器), 並且大多數時候,我們還會爲應用服務搭配一個日誌收集器 Container 或監控收集器 Container,多個 Container 共同組成一個一個 Pod,它運行在 Node 上。

一個 pod 內有多個容器

k8s 可以將 pod 從某個 Node 調度到另一個 Node,還能以 pod 爲單位去做重啓和動態擴縮容的操作。
所以說 Pod 是 k8s 中最小的調度單位

Node 調度 Pod

另外,前面提到控制平面會用 Controller Manager (通過 API Server)控制 Node 創建和關閉服務,那 Node 也得有個組件能接收到這個命令才能去做這些動作,這個組件叫 kubelet,它主要負責管理和監控 Pod。最後,Node 中還有個 Kube Proxy ,它負責 Node 的網絡通信功能,有了它,外部請求就能被轉發到 Pod 內。

控制平面和 Node 的組件

Cluster

控制平面和 Node 共同構成了一個 Cluster,也就是集羣。在公司裏,我們一般會構建多個集羣, 比如測試環境用一個集羣,生產環境用另外一個集羣。同時,爲了將集羣內部的服務暴露給外部用戶使用,我們一般還會部署一個入口控制器,比如 Ingress 控制器(比如 Nginx),它可以提供一個入口讓外部用戶訪問集羣內部服務。

生產和測試環境

kubectl 是什麼

上面提到說我們可以使用 k8s 提供的 API 去創建服務,但問題就來了,這是需要我們自己寫代碼去調用這些 API 嗎?答案是不需要,k8s 爲我們準備了一個命令行工具 kubectl,我們只需要執行命令,它內部就會調用 k8s 的 API。

kubectl 調用 k8s 的 API

接下來我們以部署服務爲例子,看下 k8s 是怎麼工作的。

怎麼部署服務?

首先我們需要編寫 YAML 文件,在裏面定義 Pod 裏用到了哪些鏡像,佔用多少內存和 CPU 等信息。然後使用 kubectl 命令行工具執行 kubectl apply -f xx.yaml ,此時 kubectl 會讀取和解析 YAML 文件,將解析後的對象通過 API 請求發送給 Kubernetes 控制平面內 的 API Server。API Server 會根據要求,驅使 Scheduler 通過 etcd 提供的數據尋找合適的 Node, Controller Manager 會通過 API Server 控制 Node 創建服務,Node 內部的 kubelet 在收到命令後會開始基於 Container runtime 組件去拉取鏡像創建容器,最終完成 Pod 的創建。

至此服務完成創建。

部署應用服務

整個過程下來,我們只需要寫一遍 yaml 文件,和執行一次 kubectl 命令,比以前省心太多了!部署完服務後,我們來看下服務是怎麼被調用的。

怎麼調用服務?

以前外部用戶小明,直接在瀏覽器上發送 http 請求,就能打到我們服務器上的 Nginx,然後轉發到部署的服務內。用了 k8s 之後,外部請求會先到達 Kubernetes 集羣的 Ingress 控制器,然後請求會被轉發到 Kubernetes 內部的某個 Node 的 Kube Proxy 上,再找到對應的 pod,然後纔是轉發到內部容器服務中,處理結果原路返回,到這就完成了一次服務調用。

用戶調用 k8s 內應用服務的流程

到這裏我們就大概瞭解了 k8s 的工作原理啦,它本質上就是應用服務和服務器之間的中間層,通過暴露一系列 API 能力讓我們簡化服務的部署運維流程。

並且,不少中大廠基於這些 API 能力搭了自己的服務管理平臺,程序員不再需要敲 kubectl 命令,直接在界面上點點幾下,就能完成服務的部署和擴容等操作,是真的嘎嘎好用。

總結

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