一、StatefulSet概述
應用程序存在有狀態和無狀態兩種類別,因為無狀態類應用的pod資源可按需增加、減少或重構,而不會對由其提供的服務產生除了並發相應能力之外的其他嚴重影響。pod資源的常用控制器中,deployment、replicaset和daemonset等常用於管理無狀態應用。但實際情況是,應用本身就是分布式的集群,各應用實例彼此之間存在着關聯關系,甚至是次序、角色方面的相關性,其中的每個實例都有其自身的獨特性而無法輕易由其他實例所取代。
1、stateful應用和stateless應用
應用程序與用戶、設備、其他應用程序或外部組件進行通信時,根據其是否需要記錄前一次或多次通信中的相關信息以作為下一次通信的分類標准,可以將那些需要記錄信息的應用程序稱為有狀態(stateful)應用,而無須記錄的則稱為無狀態(stateless)應用。
狀態是進程的時間屬性。無狀態意味着一個進程不必跟蹤過去的交互操作,本質上可以說它是一個純粹的功能性行為。相應地,有狀態則意味着進程存儲了以前交互過程的記錄,並且可以基於它對新的請求進行響應。至於狀態信息被保存在內存中。
存儲是表述持久保存數據的方法,現今通常是指機械硬盤或ssd設備。若進程僅需操作內存中的數據,則表示其無須進行磁盤I/O操作;如果產生了I/O操作,則通常意味着數據的只讀訪問或讀寫訪問行為。
2、statefulset的特性
statefulset簡稱sts,是pod資源控制器的一種實現,用於部署和擴展有狀態應用的pod資源,確保他們的運行順序及每個pod資源的唯一性。其與ReplicaSet控制器不同的是,雖然所有pod對象都基於同一個spec配置所創建,但statefulset需要為每個pod維持一個唯一且固定的標識符,必要時還要為其創建專用的存儲卷。StatefulSet主要適用於那些依賴於下列類型資源的應用程序:
穩定且唯一的網絡標識符
穩定且持久的存儲
有序、優雅地部署和擴展
有序、優雅地刪除和終止
有序而自動地滾動更新。
一般來說,一個典型、完整可用的StatefulSet通常由三個組件構成:Headless Service、StatefulSet和volumeClaimTemplate。其中,Headless Service用於為pod資源標識符生成可解析的DNS資源記錄,StatefulSet用於管控pod資源,volumeClaimTemplate則基於靜態或動態的PV供給方式為pod資源提供專有且固定的存儲。
二、StatefulSet基礎應用
1、創建statefulset對象
一個完整得分statefulset控制器需要由一個headless service、一個statefulset和一個volumeClaimTemplate組成。其中,Headless Service用於為pod資源標識符生成可解析的DNS資源記錄,statefulset用於管控pod資源,volumeClaimTemplate則基於靜態或動態的pv供給方式為pod資源提供專有且固定的存儲:
apiVersion: v1 kind: Service metadata: name: demo-svc labels: app: myapp-svc spec: ports: - port: 80 name: web clusterIP: None selector: app: myapp-pod --- apiVersion: apps/v1 kind: StatefulSet metadata: name: myapp spec: serviceName: myapp-svc replicas: 2 selector: matchLabels: app: myapp-pod template: metadata: labels: app: myapp-pod spec: containers: - name: myapp image: ikubernetes/myapp:v5 ports: - containerPort: 80 name: web volumeMounts: - name: myappdata mountPath: /usr/share/nginx/html volumeClaimTemplates: - metadata: name: myappdata spec: accessModes: ["ReadWriteOnce"] storageClassName: "managed-nfs-storage" resources: requests: storage: 2Gi
2、pod資源標識符及存儲卷
由StatefulSet控制器創建的pod資源擁有固定、唯一的標識符和專用存儲卷,即便重新調度或終止后重建,其名稱也依然保持不變,且此前的存儲卷及其數據不會丟失。
pod資源的固定標識符:
[root@master stateful]# kubectl get pods --show-labels NAME READY STATUS RESTARTS AGE LABELS myapp-0 1/1 Running 1 22h app=myapp-pod,controller-revision-hash=myapp-6c6b4f98d5,statefulset.kubernetes.io/pod-name=myapp-0 myapp-1 1/1 Running 1 22h app=myapp-pod,controller-revision-hash=myapp-6c6b4f98d5,statefulset.kubernetes.io/pod-name=myapp-1
pod資源的主機名同其資源名稱相同,這些名稱標識會由StatefulSet資源相關的Headless Service資源創建為dns資源記錄,其域名格式為$(service_name).$(namespace).svc.cluster.local。
Headless Service資源借助於SRV記錄來引用真正提供服務的后端pod資源的主機名稱,進行指向包含pod IP地址的記錄條目。此外,由statefulset控制器管控的pod資源終止后會有控制器自動進行重建,雖然其IP地址存在變化的可能性,但它的名稱標識在重建后會保持不變。因此,當客戶端嘗試向statefulset資源的pod成員發出訪問請求時,應該針對Headless Service資源的CNAME記錄進行,它指向的SRV記錄包含了當前處於就緒狀態的pod資源,考慮到名稱標識固定不變,也可以讓客戶端直接向SRV資源記錄發出請求。