
pod 也可以了解是一個容器,裝的是 docker 建立的容器,也就是用來封裝容器的一個容器;
pod 是一個虛拟化分組, 有自己的 IP 位址和主機名 hostname,利用 namespace 進行資源隔離,相當于一台獨立沙箱環境;
pod 相當于一台獨立主機,内部可以封裝一個或多個容器(通常是一組相關的容器),内部容器之間通路采用 localhost。
通常情況下,在服務部署的時候,使用 pod 來管理一組相關的服務(一個 pod 中要麼部署一個服務,要麼部署一組有關系的服務)。如下圖是部署了一組有關系的服務的結構圖,其中 C 表示容器(container),下面的 pod 裡就有很多個容器。
如何了解一組相關的服務?
如下圖:有一個請求是通路 Nginx,然後部署了 Nginx 的容器就把請求轉發給部署了 web 服務的容器,web 再通路資料庫,然後請求會依次傳回來資料,最後再傳回給使用者。
是以在 鍊式調用的調用鍊路上的服務 叫做一組相關的服務。
隻需要複制多個 pod 的副本即可,這也是 k8s 管理的先進之處。k8s 如果要進行擴容或縮容,隻需要控制 pod 的數量即可。比如上面那個部署模式,服務叢集就是複制多個這樣的 pod。
前面說過 pod 内部的容器也是一個獨立的沙箱環境,是以也有自己的 ip 和 端口。如果内部容器還是通過 ip:port 來通信,相當于還是遠端通路,這樣的話性能會受到一定的影響。如何提高内部容器之間通路的性能呢?
pod 底層
pod 内部容器建立之前,必須先建立 pause 容器。pause 有兩個作用:共享網絡和共享存儲。
每個服務容器共享 pause 存儲,不需要自己存儲資料,都交給 pause維護。
pause 也相當于這三個容器的網卡,是以他們之間的通路可以通過 localhost 方式通路,相當于通路本地服務一樣,性能非常高(就像本地幾台虛拟機之間可以 ping 通)。
作用:管理控制 pod 副本(服務叢集)的數量,以使其永遠與預期設定的數量保持一緻。
例如:replicas = 3 (建立 3 個副本,這是提前設定好的)
當副本設定為 3 時,副本控制器将會永遠保證副本數量為 3。是以當有 pod 服務當機時(如上面第 3 個 pod),那副本控制器會立馬重新建立一個新的 pod,就能夠保證副本數量一直為預先設定好的 3 個。
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。
ReplicaSet 副本控制器可以永久保持 pod 副本的數量。但是項目的需求在不斷的疊代、更新,項目在不斷發版。那如何做到服務更新?難道把服務停掉再把新版本部署上去嗎?當然不是,答案是用滾動更新。就是重新建立一個 pod (v2版本) 來代替 之前的 pod (v1版本)。
那是如何滾動更新的呢?涉及到下面要講到的部署模型。
單獨的 ReplicaSet 是不支援滾動更新的,Deployment 對象支援滾動更新,通常和 ReplicaSet 一起使用。
需要滾動更新時的步驟:
Deployment 建立新的 Replicaset
Replicaset 重建立立新的 pod
是以它們之間是有層次關系的,Deployment 管 Replicaset,Replicaset 維護 pod。在更新時删除的是舊的 pod,老版本的 ReplicaSet 是不會删除的,是以在需要時還可以回退以前的狀态。
思考:如果 MySQL(有狀态服務) 使用容器化部署,會存在什麼問題?
容器都是有生命周期的,一旦當機資料就很可能丢失
pod 也有生命周期的,用 pod 部署時把 pod 叢集副本重新開機以後也可能會出現資料丢失
是以對 k8s 來說,不能使用 Deployment 部署有狀态的服務。通常情況下,Deployment 被用來部署無狀态服務。
然後 StatefulSet 就是為了解決有狀态服務使用容器化部署的一個問題。
有狀态服務
有實時的資料需要存儲
在有狀态服務叢集中,如果把某一個服務抽離出來,一段時間後再加入回叢集網絡,此後叢集網絡會無法使用
無狀态服務
沒有實時的資料需要存儲
在無狀态服務叢集中,如果把某一個服務抽離出去,一段時間後再加入回叢集網絡,對叢集服務無任何影響,因為它們不需要做互動,不需要資料同步等等。
StatefulSet 的部署模型和 Deployment 的很相似。
比如下圖,借助 PVC(與存儲有關) 檔案系統來存儲的實時資料,是以下圖就是一個有狀态服務的部署。
在 pod 當機之後重建立立 pod 時,StatefulSet 通過保證 hostname 不發生變化來保證資料不丢失。是以 pod 就可以通過 hostname 來關聯(找到) 之前存儲的資料。
_原文連結:https://blog.csdn.net/qq_43280818/article/details/106910187_