Kubernetes的資源控制器StatefulSet詳解與示例html
服務器名稱(hostname) | 系統版本 | 配置 | 內網IP | 外網IP(模擬) |
---|---|---|---|---|
k8s-master | CentOS7.7 | 2C/4G/20G | 172.16.1.110 | 10.0.0.110 |
k8s-node01 | CentOS7.7 | 2C/4G/20G | 172.16.1.111 | 10.0.0.111 |
k8s-node02 | CentOS7.7 | 2C/4G/20G | 172.16.1.112 | 10.0.0.112 |
kubernetes中內建了不少controller(控制器),這些至關於一個狀態機,用來控制pod的具體狀態和行爲。node
StatefulSet 是用來管理有狀態應用的工做負載 API 對象。nginx
StatefulSet 中的 Pod 擁有一個具備黏性的、獨一無二的身份標識。這個標識基於 StatefulSet 控制器分配給每一個 Pod 的惟一順序索引。Pod 的名稱的形式爲<statefulset name>-<ordinal index> 。例如:web的StatefulSet 擁有兩個副本,因此它建立了兩個 Pod:web-0和web-1。web
和 Deployment 相同的是,StatefulSet 管理了基於相同容器定義的一組 Pod。但和 Deployment 不一樣的是,StatefulSet 爲它們的每一個 Pod 維護了一個固定的 ID。這些 Pod 是基於相同的聲明來建立的,可是不能相互替換:不管怎麼調度,每一個 Pod 都有一個永久不變的 ID。api
【使用場景】StatefulSets 對於須要知足如下一個或多個需求的應用程序頗有價值:安全
如上面,穩定意味着 Pod 調度或重調度的整個過程是有持久性的。服務器
若是應用程序不須要任何穩定的標識符或有序的部署、刪除或伸縮,則應該使用由一組無狀態的副本控制器提供的工做負載來部署應用程序,好比使用 Deployment 或者 ReplicaSet 可能更適用於無狀態應用部署須要。網絡
對於具備 N 個副本的 StatefulSet,StatefulSet 中的每一個 Pod 將被分配一個整數序號,從 0 到 N-1,該序號在 StatefulSet 上是惟一的。app
StatefulSet 中的每一個 Pod 根據 StatefulSet 中的名稱和 Pod 的序號來派生出它的主機名。組合主機名的格式爲$(StatefulSet 名稱)-$(序號)。less
StatefulSet 不該將 pod.Spec.TerminationGracePeriodSeconds 設置爲 0。這種作法是不安全的,要強烈阻止。
在下面的 nginx 示例被建立後,會按照 web-0、web-一、web-2 的順序部署三個 Pod。在 web-0 進入 Running 和 Ready 狀態前不會部署 web-1。在 web-1 進入 Running 和 Ready 狀態前不會部署 web-2。
若是 web-1 已經處於 Running 和 Ready 狀態,而 web-2 還沒有部署,在此期間發生了 web-0 運行失敗,那麼 web-2 將不會被部署,要等到 web-0 部署完成並進入 Running 和 Ready 狀態後,纔會部署 web-2。
若是想將示例中的 StatefulSet 收縮爲 replicas=1,首先被終止的是 web-2。在 web-2 沒有被徹底中止和刪除前,web-1 不會被終止。當 web-2 已被終止和刪除;但web-1 還沒有被終止,若是在此期間發生 web-0 運行失敗,那麼就不會終止 web-1,必須等到 web-0 進入 Running 和 Ready 狀態後纔會終止 web-1。
說明:本次示例不涉及存儲,StatefulSet的存儲示例會在「Kubernetes K8S之存儲PV-PVC詳解」文章中演示。
yaml文件
1 [root@k8s-master controller]# pwd 2 /root/k8s_practice/controller 3 [root@k8s-master controller]# cat statefulset.yaml 4 apiVersion: v1 5 kind: Service 6 metadata: 7 name: nginx 8 labels: 9 app: nginx 10 spec: 11 ports: 12 - port: 80 13 name: http 14 clusterIP: None 15 selector: 16 app: nginx 17 --- 18 apiVersion: apps/v1 19 kind: StatefulSet 20 metadata: 21 name: web 22 spec: 23 selector: 24 matchLabels: 25 app: nginx # has to match .spec.template.metadata.labels 26 serviceName: "nginx" 27 replicas: 3 # by default is 1 28 template: 29 metadata: 30 labels: 31 app: nginx # has to match .spec.selector.matchLabels 32 spec: 33 terminationGracePeriodSeconds: 10 # 默認30秒 34 containers: 35 - name: nginx 36 image: registry.cn-beijing.aliyuncs.com/google_registry/nginx:1.17 37 ports: 38 - containerPort: 80 39 name: http
啓動StatefulSet和Service,並查看狀態
1 [root@k8s-master controller]# kubectl apply -f statefulset.yaml 2 service/nginx created 3 statefulset.apps/web created 4 [root@k8s-master controller]# kubectl get service -o wide 5 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR 6 kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 17d <none> 7 nginx ClusterIP None <none> 80/TCP 87s app=nginx 8 [root@k8s-master controller]# 9 [root@k8s-master controller]# kubectl get statefulset -o wide 10 NAME READY AGE CONTAINERS IMAGES 11 web 3/3 15m nginx registry.cn-beijing.aliyuncs.com/google_registry/nginx:1.17 12 [root@k8s-master controller]# 13 [root@k8s-master controller]# kubectl get pod -o wide 14 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES 15 web-0 1/1 Running 0 16m 10.244.2.95 k8s-node02 <none> <none> 16 web-1 1/1 Running 0 16m 10.244.3.103 k8s-node01 <none> <none> 17 web-2 1/1 Running 0 16m 10.244.3.104 k8s-node01 <none> <none>
由上可見,StatefulSet 中的pod是有序的。有N個副本,那麼序列號爲0~(N-1)。
啓動一個pod
1 [root@k8s-master test]# pwd 2 /root/k8s_practice/test 3 [root@k8s-master test]# cat myapp_demo.yaml 4 apiVersion: v1 5 kind: Pod 6 metadata: 7 name: myapp-demo 8 namespace: default 9 labels: 10 k8s-app: myapp 11 spec: 12 containers: 13 - name: myapp 14 image: registry.cn-beijing.aliyuncs.com/google_registry/myapp:v1 15 imagePullPolicy: IfNotPresent 16 ports: 17 - name: httpd 18 containerPort: 80 19 protocol: TCP 20 [root@k8s-master test]# 21 [root@k8s-master test]# kubectl apply -f myapp_demo.yaml 22 pod/myapp-demo created 23 [root@k8s-master test]# 24 [root@k8s-master test]# kubectl get pod -o wide | grep 'myapp' 25 myapp-demo 1/1 Running 0 3m24s 10.244.2.101 k8s-node02 <none> <none>
進入pod並查看StatefulSet域名信息
1 # 進入一個k8s管理的myapp鏡像容器。 2 [root@k8s-master test]# kubectl exec -it myapp-demo sh 3 / # nslookup 10.244.2.95 4 nslookup: can't resolve '(null)': Name does not resolve 5 6 Name: 10.244.2.95 7 Address 1: 10.244.2.95 web-0.nginx.default.svc.cluster.local 8 / # 9 / # 10 / # nslookup 10.244.3.103 11 nslookup: can't resolve '(null)': Name does not resolve 12 13 Name: 10.244.3.103 14 Address 1: 10.244.3.103 web-1.nginx.default.svc.cluster.local 15 / # 16 / # 17 / # nslookup 10.244.3.104 18 nslookup: can't resolve '(null)': Name does not resolve 19 20 Name: 10.244.3.104 21 Address 1: 10.244.3.104 web-2.nginx.default.svc.cluster.local 22 / # 23 / # 24 ##### nginx.default.svc.cluster.local 爲service的域名信息 25 / # nslookup nginx.default.svc.cluster.local 26 nslookup: can't resolve '(null)': Name does not resolve 27 28 Name: nginx.default.svc.cluster.local 29 Address 1: 10.244.3.104 web-2.nginx.default.svc.cluster.local 30 Address 2: 10.244.3.103 web-1.nginx.default.svc.cluster.local 31 Address 3: 10.244.2.95 web-0.nginx.default.svc.cluster.local
有上文可得以下信息:
一、匹配StatefulSet的Pod name(網絡標識)的模式爲:$(statefulset名稱)-$(序號),好比StatefulSet名稱爲web,副本數爲3。則爲:web-0、web-一、web-2
二、StatefulSet爲每一個Pod副本建立了一個DNS域名,這個域名的格式爲:$(podname).(headless service name),也就意味着服務之間是經過Pod域名來通訊而非Pod IP。當Pod所在Node發生故障時,Pod會被漂移到其餘Node上,Pod IP會發生改變,但Pod域名不會變化
三、StatefulSet使用Headless服務來控制Pod的域名,這個Headless服務域名的爲:$(service name).$(namespace).svc.cluster.local,其中 cluster.local 指定的集羣的域名
四、根據volumeClaimTemplates,爲每一個Pod建立一個PVC,PVC的命令規則爲:$(volumeClaimTemplates name)-$(pod name),好比volumeClaimTemplates爲www,pod name爲web-0、web-一、web-2;那麼建立出來的PVC爲:www-web-0、www-web-一、www-web-2
五、刪除Pod不會刪除對應的PVC,手動刪除PVC將自動釋放PV。
一、Kubernetes K8S之資源控制器RC、RS、Deployment詳解
完畢!
———END———
若是以爲不錯就關注下唄 (-^O^-) !