StatefulSet在Kubernetes中的應用

概述

Kubernetes中有很多的控制器,比如常用的ReplicaSet,Deployment,DaemonSet,StatefulSet等。以這四種爲例,我們可以將它們分爲兩種,一種爲有狀態控制器,一種爲無狀態控制器,StatefulSet則爲有狀態控制器,通常用於管理有狀態的服務,如:MySQL,Redis,MongoDB等。

有狀態控制器通常有以下幾個特點:

  • 穩定的,唯一的網絡標識

  • 穩定的,持久的存儲

  • 有序的,優雅的部署和伸縮

  • 有序的,優雅的刪除和停止

  • 有序的,自動的滾更新

也就是說如果我們的應用如有以上的任何一個特點我們就可以使用statefulset控制器來完成應用的部署。


網絡標識:

Pod名稱:唯一且不會發生變化,由 $(statefulset name)-(0-N)組成,N爲一個無限大的正整數,從0開始。

容器內計算機名:與Pod名稱一至且不會發生變化。

DNS A記錄:每一個副本都擁有唯一且不變的一條A記錄指定自己,格式組成:$(pod name).$(service name).$(namespace name).svc。

唯一的Pod標籤,通過StatefulSet創建的每個副本都擁有一個唯一的標籤,格式爲:statefulset.kubernetes.io/pod-name=$(pod name),通常可以將新的service單獨關聯到此標籤,來解決某個Pod的問題等。

以上的標識只要配置不發生改變,發生重啓,升級,刪除後再創建這些標識都不會發生變化。

備註:Pod的IP地址會發生變化,但我們也可以使用另外的方案來結合StatefulSet實現固定IP的方案,通常不推薦這麼做。


持久存儲:

每個Pod都對應一個PVC,PVC的名稱組成:$(volumeClaimTemplates name)-$(pod name)-(0-N),N爲一個無限大的正整數,從0開始。

當Pod被刪除的時候不會自動刪除對應的PVC,需要手動刪除。

每次Pod升級,重啓,刪除重新創建後都呆以保證使用的是首次使用的PVC,保證數據的唯一性與持久化。


有序:

當部署有N個副本的StatefulSet時候,嚴格按照從0到N的順序創建,並且下一個Pod創建的前提是上一個Pod已經Running狀態。

當刪除有N個副本的StatefulSet時候,嚴格按照從N到0的順序刪除,並且下一個Pod刪除的前提是上一個Pod已經完全Delete。

當擴容StatefulSet副本的時候,每增加一個pod前提是上一個Pod已經Running狀態。

當減少StatefulSet副本的時候,每刪除一個pod前提是上一個Pod已經完全Delete。

當升級StatefulSet的時候,嚴格按照從N到1的順序升級,並且下一個Pod升級的前提是上一個Pod已經Running狀態。


無頭服務(headless service)

無頭服務是Kubernetes中service類型的一種,爲什麼需要無頭服務?通常我們在使用Deployment部署Pod的時候名稱是隨機的字符串,Pod也是無序的。但 StatefulSet是有序且名稱唯一,每一個Pod不可以被取代,所以這時候就需要使用無頭服務來實現。

無頭服務特點:當使用Kubernetes內DNS解析去訪問Service的時候,會將解析的IP指向Service後端的Pod。當無頭服務與StatefulSet控制器使用的時候,因爲每個Pod的數據可能是不一樣的,所以在Service名前面再加了一個Pod名,這樣我們的每個StatefulSet控制器的Pod就擁有了唯一的網絡標識(A記錄)。

無頭服務案例:

apiVersion: v1
kind: Service
metadata:
  namespace: test
  name: mysql-test
spec:
  selector:
    app: mysql-test
  clusterIP: None
  ports:
  - port: 3306
    targetPort: 3306

ClusterIP:當此項的值爲“None”的時候,此服務就爲無頭服務,Kubernetes不會給此服務分配IP地址。當使用type爲NodePort的時候不可以使用無頭服務。


volumeClaimTemplates:

此爲Kubernetes中的一個對象,對象的路徑爲“statefulset.spec.volumeClaimTemplates”,用於給StatefulSet的Pod申請PVC,稱爲卷申請模板,它會爲每個Pod生成不同的PVC,關綁定到PV,從而實現Pod的專有存儲。

通常我們在使用Deployment中使用“deployment.spec.template.spec.volumes”與PVC建立關聯的時候,所有的副本使用的是相同的PV與PVC,他們的數據是相同的。而StatefulSet爲實現各Pod的專有存儲,所以纔有了“statefulset.spec.volumeClaimTemplates”此方法。


實際應用場景



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