Kubernetes

彬彬zhidao發表於2024-11-11

基本概念

用 Docker 進行容器化管理之後方便了很多,容器少的話,可以使用 Shell 指令碼來管理。但隨著容器越來越多,容器也越來越難以管理,專案架構也越來越複雜,如何管理和維護這些容器,就是Kubernetes 要解決的問題。

Kubernetes 元件

透過架構逐漸升級和演進的過程,一步步引入 K8s 中的各種資源物件,不但要理解他們是為了解決什麼而存在的,還要理解他們之間是如何協同工作的。
目標是根據需求選擇使用哪些資源物件和如何使用這些資源物件來解決問題。

Node

Node:節點,一個物理機或者一臺虛擬機器。

Pod

Pod 是 Kubernetes 的最小排程單元,可以理解為容器的抽象。一個 Pod 就是一個或者多個應用容器的組合。它建立了一個容器的執行環境,在這個環境中容器可以共享一些資源,比如網路、儲存和執行時的一些配置等等。

假設我們系統包括一個應用程式和一個資料庫,就可以將應用程式和資料庫分別放到兩個不同的 Pod 中,一般情況下一個 Pod 中只執行一個容器,這樣可以更好地實現應用程式的解耦和擴充套件。
![[Pasted image 20241027152854.png]]

Sidecar 邊車模式

一個 Pod 中也是可以執行多個容器的,一般僅限於這些容器是高度耦合的情況,它們之間為了共享一些配置或者資源,不得不將它們放到一個容器中。

應用程式要訪問資料庫的話,只需要知道資料庫的 IP 地址,這裡的 IP 地址是 Pod 在建立的時候自動建立的,是一個叢集內部的 IP 地址(也就是無法從叢集外部訪問),Pod 之間透過這些 IP 地址進行通訊。

IP 地址不穩定的問題

Pod 並不是穩定的實體,它們非常容易被建立或者銷燬,比如發生故障的時候,Kubernetes會自動將發生故障的 Pod 銷燬掉然後建立一個新的 Pod 替代它,這時候 IP 也會重新分配,如果應用程式還用原來的 IP 來訪問的話就找不到。

Service

為了解決這個問題,Kubernetes 提供了一個名為 Service 的資源物件,它可以將一組 Pod 封裝成一個服務,這個服務透過一個統一的入口來訪問。

就比如上面的場景,我們分別將應用程式和資料庫兩組 Pod 封裝成兩個 Service,這樣應用程式就可以透過 Service 的 IP 地址訪問資料庫,即使 Pod 的 IP 地址發生了變化,Service 的 IP 地址也不會發生變化,Service 會自動將請求轉發到其它健康的 Pod 上。(像反向代理)

服務也分為內部服務和外部服務。
內部服務例如資料庫,快取,訊息佇列等只需要在叢集內部訪問就可以了。
外部服務例如後端服務的 api 介面或者一些給使用者使用的前端介面等需要暴露給外部的服務。

外部服務有幾種常見的型別。其中一種就是 Node:Port:他會在一個節點上開放一個埠,然後將這個埠對映到 Service 的 IP 地址和埠上。這樣就可以透過節點的 IP 地址來訪問 Service 了。

在測試和開發階段透過這種 ip:port方式訪問是沒問題的,但是在生產環境通常是透過域名來訪問服務的。

Ingress

Ingress 是用來管理從叢集外部來訪問叢集內部服務的入口和方式的。可以透過 Ingress 來配置不同的轉發規則。從而根據不同的規則來訪問叢集內部不同的 Service 以及 Service 後面對應的後端pod。還可以透過 Ingress 來配置域名,將使用 IP: port 的方式轉換成使用域名來訪問 Service。
還可以配置一些其他功能,比如負載均衡,SSL 證書等。

![[Pasted image 20241031110727.png]]

現在應用程式和資料庫已經可以在 Kubernetes 中執行,並且對外提供服務。

ConfigMap

應用程式和資料庫之間的耦合問題沒有考慮到。比如,應用程式需要訪問資料庫的話,通常吧資料庫的地址和埠等連線資訊寫入配置檔案或者環境變數中,然後在應用程式中讀取這些配置資訊,這樣的話配置資訊就和應用程式耦合在了一起,一旦資料庫的地址和埠發生變化,我們就需要重新編譯應用程式。然後重新部署到叢集中,這樣不但比較麻煩,而且還會造成應用程式的停機時間。

ConfigMap 元件就是來解決這種問題。他可以將一些配置資訊封裝起來,然後就可以在應用程式中讀取和使用。有了 ConfigMap,我們就可以把配置資訊和應用程式的映象內容分離開來。這樣就可以保持容器化應用程式的可移植性。

當資料庫的地址和埠發生變化的時候,我們只需要修改 ConfigMap 中的配置資訊,然後重新載入 Pod 就可以了,不需要重新編譯和部署應用程式。實現了應用程式和資料庫的解耦。

注意:ConfigMap 中的配置資訊都是明文的,如果配置資訊中包含一些敏感資訊,這些敏感資訊不建議儲存在 ConfigMap 中,這樣會帶來一些安全風險和問題。

Secret

為了解決這個安全風險和問題,Kubernetes 提供了 Secret 元件,和 ConfigMap 類似,可以將一些敏感資訊封裝起來,然後就可以在應用程式中讀取和使用了。

這些敏感資訊雖然不是以明文的形式來儲存的,但是也只是做了一層 Bqase 64 編碼而已,所以僅僅只靠 Secret 並不能完全保證敏感資訊的安全。還需要靠一些其他的手段來提高安全性,比如 Kubernetes 提供的一些其他的安全機制,包括網路安全、訪問控制、身份認證等等。

Volumes

當容器被銷燬或者重啟的時候,容器中的資料也會跟著消失,這對於一些需要持久化儲存的應用程式,比如資料庫來說顯然是不行的。因此為了解決這個問題,Kubernetes 提供了一個叫做 Volume 的元件,他可以將一些持久化儲存的資源掛載到叢集中的本地磁碟上,或者掛載到叢集外部的遠端儲存上。這樣,即使容器被銷燬或者重啟,這些資料也不會消失,也就實現了容器中資料的持久化儲存。

Deployment

還沒有考慮到應用程式的高可用性。比如,應用程式所在的節點發生了故障,需要對節點進行升級和更新維護的時候,應用程式會停止服務,這樣就會造成一些不必要的麻煩和損失。解決方案就是一個節點不行就多加幾個節點。簡單來說就是把所有的東西都複製一份。讓後放到另外一個節點上,這樣當一個節點發生故障的時候,Service 會自動將請求轉發到另外一個節點上來繼續提供服務。

Deployment 元件就是來解決這個問題的,他可以定義和管理應用程式的副本數量以及應用程式的更新策略。可以簡化應用程式的部署和更新操作。

![[Pasted image 20241031115619.png]]

Deploy 可以看做一組 Pod 的抽象。(複製備份的 Pod)

Service 也是一組 Pod 的抽象(一個功能所需要的多個 Pod)

並且還有副本控制,滾動控制,自動擴縮容等高階特性和功能。

副本控制是指可以定義和管理應用程式的副本數量,例如可以定義一個應用程式的副本數量為 3 個。如果有副本發生故障的時候,他會自動建立一個新的副本來替代它。始終保持有三個副本在叢集中執行。
滾動更新是指可以定義和管理應用程式的更新策略,可以輕鬆升級應用程式的版本,逐漸使用新的版本替換掉舊的版本,確保應用程式的平滑升級。

StatefulSet 的元件來管理

除了應用程式,資料庫也會發生類似的故障,例如資料庫的節點發生了故障,或者需要進行更新維護的時候,也會停止服務,影響使用者的正常使用,所以資料庫也是需要採取類似多副本的方式來保證他的高可用性。但是和應用程式不同的是,我們一般不使用 Deployment 來實現資料庫的多副本,因為資料庫的多副本之間是有狀態的,每個副本都有自己的狀態,也就是資料。這些資料都是需要持久化儲存的,而且也需要保證多個副本之間的資料是一致的。這就需要一些額外的機制,比如把資料寫入一個共享的儲存中,或者把資料同步到其他的副本中。

對於這一類有狀態的應用程式,使用 StatefulSet 元件來管理。他和 Deployment 非常類似也提供了定義和管理應用程式副本數量,動態擴縮容等功能。此外他還保證每個副本都有自己穩定的網路識別符號和持久化儲存。因此像資料庫、快取、訊息佇列等有狀態類的應用,以及一些保留了會話狀態的應用程式,一般都會用 StatefulSet 而不是 Deployment 來部署。

Kubernetes架構

Kubernetes是典型的Master-Worker架構, Master Node負責管理整個叢集,Worker Node負責執行應用程式和服務。

Kubernetes透過將容器放入在節點上執行的Pod中來執行工作負載。

Worker Node

image-20241111105519642

為了對外提供服務,每個Node都會包含三個元件,kubelet、kube-proxy和container-runtime.

container-runtime

翻譯為執行環境,可以理解為一個容器執行的例項,負責拉取容器映象,建立容器,啟動或者停止容器等等,所有的容器都需要透過container-runtime來執行,所以每個節點上都要安裝container-runtime。

kebelet

負責管理和維護每個節點上的Pod並確保他們按照預期執行,他也會定期從apiservice元件接收新的或者修改後的Pod規範,同時監控工作節點的執行情況,然後將資訊彙報給apiservice。

kube-proxy

負責為Pod物件提供網路代理和負載均衡服務。

一般 Kubernetes 叢集包含多個節點,節點之間透過 Service 通訊,這就需要一個負載均衡器來接收請求,然後再將請求傳送到不同節點上。kube-proxy 就是負責這個功能的元件,它在每個 Node 上啟動一個網路代理,使發往 Service 的流量路由到正確的後端 Pod,比如 Node A 的應用程式要訪問資料庫,應用程式對資料庫的訪問請求並不會被隨機路由到別的節點的資料庫中,kube-proxy 會把請求路由到與應用程式同一個節點(也就是 Node A)的資料庫 Pod 中。

Master Node

image-20241111110930269

kube-apiserver

負責提供Kubernetes叢集的api介面服務,所有的元件透過apiserver通訊,使用者在叢集中部署應用的時候也需要使用客戶端與 apiserver 進行互動。apiserver 就像一個叢集的閘道器,是整個系統的入口,所有的請求都會先經過它,再由它分發給不同的元件進行處理。

除了提供 API 介面之外,apiserver 還負責對所有物件的增刪改查等操作進行認證、授權和訪問控制。apiserver 接收到請求時會先驗證請求的合法性,驗證透過之後才會將請求轉發給 Scheduler 處理。

Scheduler排程器

負責監控叢集中所有節點的資源使用情況,然後根據排程策略將 Pod 排程到合適的節點上執行。

排程策略:比如新增一個新 Pod 時,將 Pod 排程到空閒資源最多的節點上。

control manager控制器管理器

負責管理叢集中各種資源物件(比如 Node、Pod、Service)的狀態,然後根據狀態做出相應的響應。比如叢集中有一個節點發生故障時,得有一個機制來監控和檢測這個故障然後處理故障,比如重啟 Pod 或者使用新 Pod 替代,這就是 Controller Manager 要做的事。

etcd

高可用鍵-值儲存系統,類似 Redis,用於儲存叢集中所有資源物件的狀態資訊,每新增或者崩掉一個 Pod,這些資訊都會被記錄到 etcd 中,使用命令列查詢叢集狀態時就是透過 etcd 來獲取的。

etcd 一般只儲存叢集中應用程式的狀態資訊,不儲存應用程式的資料

Cloud Controller Manager

一個雲平臺相關的控制器,負責與雲平臺(例如 Google GKE、Microsoft AKS、Amazon EKS)的 API 進行互動,並且對不同平臺都提供一致的管理介面。

minikube環境搭建

minikube 是一個輕量級的 Kubernetes 發行版可以在本地執行單節點的 Kubernetes 叢集。

kubectl 是一個命令列工具,可以透過在命令列輸入各種命令與 Master Node 的 apiserver 互動,從而與 Kubernetes 叢集進行互動。

安裝docker

  • 下載地址:https://docs.docker.com/desktop/install/windows-install/
  • 知道下載後的 Docker for Windows Installer 安裝檔案,完成安裝。
  • 安裝好之後會重啟

安裝minikube

minikube 下載地址 https://minikube.sigs.k8s.io/docs/start/

1、 在命令列中輸入 choco install minikube直接安裝。然後就直接安裝成功了。

我這裡一開始choco無法使用,也無法下載,經過檢查報錯和瀏覽器搜尋,透過將本地中的chocolatey資料夾刪除後,保證網路環境的條件下,以管理員身份重新安裝配置成功過後就可以了。

點選這裡下載安裝程式minikube-installer.exe,安裝即可minikube version檢視版本資訊驗證是否安裝成功

啟動minikube minikube start --kubernetes-version=v1.23.3

安裝kubectl

kubectl 是一個與 Kubernetes、minikube 彼此獨立的專案,可以單獨進行安裝,所以不包含在 minikube 裡,但 minikube 提供了安裝它的簡化方式,只需執行下面的這條命令:

minikube kubectl

使用Multipass和k3sh搭建kubernetes叢集環境

Multipass

安裝直接

常用命令

# 檢視幫助
multipass help
multipass help <command>
# 建立⼀個名字叫做k3s的虛擬機器
multipass launch --name k3s
# 在虛擬機器中執⾏命令
multipass exec k3s -- ls -l
# 進⼊虛擬機器並執⾏shell
multipass shell k3s
# 檢視虛擬機器的資訊
multipass info k3s
# 停⽌虛擬機器
multipass stop k3s
# 啟動虛擬機器
multipass start k3s
# 刪除虛擬機器
multipass delete k3s
# 清理虛擬機器
multipass purge
# 檢視虛擬機器列表
multipass list
# 建立一臺虛擬機器
multipass launch --name k3s --cpus 2 --memory 4G --disk 10G

相關文章