通俗易懂 k8s (2):認識 k8s 核心組件原理


第二篇來了


1. 核心組件原理 —— pod 核心原理

1.1 pod 是什麼

  • pod 也可以理解是一個容器,裝的是 docker 創建的容器,也就是用來封裝容器的一個容器;
  • pod 是一個虛擬化分組, 有自己的 IP 地址和主機名 hostname,利用 namespace 進行資源隔離,相當於一臺獨立沙箱環境;
  • pod 相當於一臺獨立主機,內部可以封裝一個或多個容器(通常是一組相關的容器),內部容器之間訪問採用 localhost。

1.2 pod 用來幹什麼

通常情況下,在服務部署的時候,使用 pod 來管理一組相關的服務(一個 pod 中要麼部署一個服務,要麼部署一組有關係的服務)。如下圖是部署了一組有關係的服務的結構圖,其中 C 表示容器(container),下面的 pod 裏就有很多個容器。
在這裏插入圖片描述
如何理解一組相關的服務
如下圖:有一個請求是訪問 Nginx,然後部署了 Nginx 的容器就把請求轉發給部署了 web 服務的容器,web 再訪問數據庫,然後請求會依次返回來數據,最後再返回給用戶。
因此在 鏈式調用的調用鏈路上的服務 叫做一組相關的服務
在這裏插入圖片描述

1.3 實現 web 服務集羣

只需要複製多個 pod 的副本即可,這也是 k8s 管理的先進之處。k8s 如果要進行擴容或縮容,只需要控制 pod 的數量即可。比如上面那個部署模式,服務集羣就是複製多個這樣的 pod。
在這裏插入圖片描述

1.4 pod 底層網絡和數據存儲是如何進行的

前面說過 pod 內部的容器也是一個獨立的沙箱環境,因此也有自己的 ip 和 端口。如果內部容器還是通過 ip:port 來通信,相當於還是遠程訪問,這樣的話性能會受到一定的影響。如何提高內部容器之間訪問的性能呢?

在這裏插入圖片描述
pod 底層

  • pod 內部容器創建之前,必須先創建 pause 容器。pause 有兩個作用:共享網絡和共享存儲
  • 每個服務容器共享 pause 存儲,不需要自己存儲數據,都交給 pause維護。
  • pause 也相當於這三個容器的網卡,因此他們之間的訪問可以通過 localhost 方式訪問,相當於訪問本地服務一樣,性能非常高(就像本地幾臺虛擬機之間可以 ping 通)。

2. ReplicaSet 副本控制器

2.1 副本控制器基本理解

作用:管理控制 pod 副本(服務集羣)的數量,以使其永遠與預期設定的數量保持一致。
例如:replicas = 3 (創建 3 個副本,這是提前設置好的)
在這裏插入圖片描述
當副本設置爲 3 時,副本控制器將會永遠保證副本數量爲 3。因此當有 pod 服務宕機時(如上面第 3 個 pod),那副本控制器會立馬重新創建一個新的 pod,就能夠保證副本數量一直爲預先設定好的 3 個。

2.2 ReplicaSet 和 ReplicationController 的區別

ReplicaSet 和 ReplicationController 都是副本控制器,其中:

  • 相同點:都有前面 2.1 節所描述的功能

  • 不同點:標籤選擇器的功能不同
    ReplicaSet 可以使用標籤選擇器進行 單選 和 複合選擇;而 ReplicationController 只支持 單選操作

    什麼意思呢?
    假設下面有下面兩個不同機器上的 Node 結點,如何知道它們的 pod 其實都是相同的呢?答案是通過標籤。

    給每個 pod 打上標籤 ( key=value 格式,如下圖中的 app=web, release=stable,這有兩個選項,相同的pod副本的標籤是一樣的),於是副本控制器可以通過標籤選擇器 seletor 去選擇一組相關的服務。

    一旦 selector 和 pod 的標籤匹配上了,就表明這個 pod 是當前這個副本控制器控制的,表明了副本控制器和 pod 的所屬關係。如下圖中 seletor 指定了 app = web 和 release=stable複合選擇,要用 ReplicaSet 才能實現若用 ReplicationController 的話只能選擇一個,如只選擇匹配app=web標籤。這樣下面的 3 個 pod 就歸這個副本控制器管。

在這裏插入圖片描述
可見 ReplicaSet 功能更齊全,所以在新版的 k8s 中,建議使用 ReplicaSet 作爲副本控制器,不再使用 ReplicationController。


3. Deployment 部署對象

3.1 滾動更新

ReplicaSet 副本控制器可以永久保持 pod 副本的數量。但是項目的需求在不斷的迭代、更新,項目在不斷髮版。那如何做到服務更新?難道把服務停掉再把新版本部署上去嗎?當然不是,答案是用滾動更新。就是重新創建一個 pod (v2版本) 來代替 之前的 pod (v1版本)。

在這裏插入圖片描述
那是如何滾動更新的呢?涉及到下面要講到的部署模型。

3.2 部署模型

單獨的 ReplicaSet 是不支持滾動更新的,Deployment 對象支持滾動更新,通常和 ReplicaSet 一起使用。
需要滾動更新時的步驟:

  1. Deployment 建立新的 Replicaset
  2. Replicaset 重新建立新的 pod

所以它們之間是有層次關係的,Deployment 管 Replicaset,Replicaset 維護 pod。在更新時刪除的是舊的 pod,老版本的 ReplicaSet 是不會刪除的,所以在需要時還可以回退以前的狀態。

在這裏插入圖片描述

4. StatefulSet 部署有狀態服務

4.1 引入定義

思考:如果 MySQL(有狀態服務) 使用容器化部署,會存在什麼問題?

  1. 容器都是有生命週期的,一旦宕機數據就很可能丟失
  2. pod 也有生命週期的,用 pod 部署時把 pod 集羣副本重啓以後也可能會出現數據丟失

因此對 k8s 來說,不能使用 Deployment 部署有狀態的服務。通常情況下,Deployment 被用來部署無狀態服務
然後 StatefulSet 就是爲了解決有狀態服務使用容器化部署的一個問題。

4.2 如何理解狀態服務

  • 有狀態服務
    • 有實時的數據需要存儲
    • 在有狀態服務集羣中,如果把某一個服務抽離出來,一段時間後再加入回集羣網絡,此後集羣網絡會無法使用
  • 無狀態服務
    • 沒有實時的數據需要存儲
    • 在無狀態服務集羣中,如果把某一個服務抽離出去,一段時間後再加入回集羣網絡,對集羣服務無任何影響,因爲它們不需要做交互,不需要數據同步等等。

4.3 部署模型

StatefulSet 的部署模型和 Deployment 的很相似。
比如下圖,藉助 PVC(與存儲有關) 文件系統來存儲的實時數據,因此下圖就是一個有狀態服務的部署。
在 pod 宕機之後重新建立 pod 時,StatefulSet 通過保證 hostname 不發生變化來保證數據不丟失。因此 pod 就可以通過 hostname 來關聯(找到) 之前存儲的數據。
在這裏插入圖片描述

之前的第一篇:通俗易懂 k8s (1):kubernetes 架構及應用場景




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