Kubernetes無狀態服務特徵:
1)是指該服務運行的實例不會在本地存儲須要持久化的數據,而且多個實例對於同一請求響應的結果是徹底一致的;
2)多個實例能夠共享相同的持久化數據。例如:nginx實例、tomcat實例等;
3)相關的Kubernetes資源有:ReplicaSet、ReplicationController、Deployment等,因爲是無狀態服務,因此這些控制器建立的Pod名稱都是隨機性的。而且在縮容時並不會明確縮容某一個Pod,而是隨機的,由於全部實例獲得的返回值都是同樣的,因此縮容任何一個Pod均可以;html
Kubernetes有狀態服務特徵:
1)有狀態服務能夠說是須要數據存儲功能的服務、或者指多線程類型的服務、隊列等。(好比:mysql數據庫、kafka、zookeeper等);
2)每一個實例都須要本身獨立的持久化存儲,而且在Kubernetes中經過聲明模板的方式來進行定義。持久卷聲明模板在建立pod以前建立,綁定到pod中,模板能夠定義多個;
3)相關的Kubernetes資源有:StatefulSet。因爲是有狀態的服務,因此每一個Pod都有特定的名稱和網絡標識。好比Pod名稱是由StatefulSet名+有序的數字組成(0、一、2……);
4)在進行縮容操做時,能夠明確知道會縮容那一個Pod,從數字最大的開始。而且StatefulSet在已有實例不健康的狀況下是不容許作縮容操做的;node
主要表如今如下方面:
1)實例數量:無狀態服務能夠有一個或多個實例,所以支持兩種服務容量調節模式;有狀態服務職能有一個實例,不容許建立多個實例,所以也不支持服務容量的調節;
2)存儲卷:無狀態服務能夠有存儲卷,也能夠沒有,即便有也沒法備份存儲卷中的數據;有狀態服務必需要有存儲卷,而且在建立服務時,必須指定該存儲卷分配的磁盤空間大小;
3)數據存儲: 無狀態服務運行過程當中的全部數據(除日誌和監控數據)都存在容器實例裏的文件系統中,若是實例中止或者刪除,則這些數據都將丟失,沒法找回;而對於有狀態服務,凡是已經掛載了存儲卷的目錄下的文件內容均可以隨時進行備份,備份的數據能夠下載,也能夠用於恢復新的服務。但對於沒有掛載卷的目錄下的數據,仍然是沒法備份和保存的,若是實例中止或者刪除,這些非掛載卷裏的文件內容一樣會丟失。mysql
StatefulSet是Kubernetes提供的管理有狀態應用的負載管理控制器API。在Pods管理的基礎上,保證Pods的順序和一致性。與Deployment同樣,StatefulSet也是使用容器的Spec來建立Pod,與之不一樣StatefulSet建立的Pods在生命週期中會保持持久的標記(例如Pod Name)。nginx
1)穩定的持久化存儲,即Pod從新調度後仍是能訪問到相同的持久化數據,基於PVC來實現;
2)穩定的網絡標誌,即Pod從新調度後其PodName和HostName不變,基於Headless Service(即沒有Cluster IP的Service)來實現;
3)有序部署,有序擴展,即Pod是有順序的,在部署或者擴展的時候要依據定義的順序依次依次進行(即從0到N-1,在下一個Pod運行以前全部以前的Pod必須都是Running和Ready狀態),基於init containers來實現;
4)有序收縮,有序刪除(即從N-1到0);web
爲了方便,就直接在master節點上部署NFS存儲了!sql
[root@master ~]# yum -y install nfs-utils rpcbind [root@master ~]# vim /etc/exports /nfsdata *(rw,sync,no_root_squash) [root@master ~]# mkdir /nfsdata [root@master ~]# systemctl start nfs-server [root@master ~]# systemctl start rpcbind [root@master ~]# showmount -e Export list for master: /nfsdata *
[root@master ~]# vim rbac-rolebind.yaml apiVersion: v1 #建立一個用於認證的服務帳號 kind: ServiceAccount metadata: name: nfs-provisioner --- apiVersion: rbac.authorization.k8s.io/v1 #建立羣集規則 kind: ClusterRole metadata: name: nfs-provisioner-runner rules: - apiGroups: [""] resources: ["persistentvolumes"] verbs: ["get", "list", "watch", "create", "delete"] - apiGroups: [""] resources: ["persistentvolumeclaims"] verbs: ["get", "list", "watch", "update"] - apiGroups: ["storage.k8s.io"] resources: ["storageclasses"] verbs: ["get", "list", "watch"] - apiGroups: [""] resources: ["events"] verbs: ["watch", "create", "update", "patch"] - apiGroups: [""] resources: ["services", "endpoints"] verbs: ["get","create","list", "watch","update"] - apiGroups: ["extensions"] resources: ["podsecuritypolicies"] resourceNames: ["nfs-provisioner"] verbs: ["use"] --- kind: ClusterRoleBinding #將服務認證用戶與羣集規則進行綁定 apiVersion: rbac.authorization.k8s.io/v1 metadata: name: run-nfs-provisioner subjects: - kind: ServiceAccount name: nfs-provisioner namespace: default #必寫字段,不然會提示錯誤 roleRef: kind: ClusterRole name: nfs-provisioner-runner apiGroup: rbac.authorization.k8s.io [root@master ~]# kubectl apply -f rbac-rolebind.yaml
[root@master ~]# vim nfs-deployment.yaml apiVersion: extensions/v1beta1 kind: Deployment metadata: name: nfs-client-provisioner spec: replicas: 1 #指定副本數量爲1 strategy: type: Recreate #指定策略類型爲重置 template: metadata: labels: app: nfs-client-provisioner spec: serviceAccount: nfs-provisioner #指定rbac yanl文件中建立的認證用戶帳號 containers: - name: nfs-client-provisioner image: registry.cn-hangzhou.aliyuncs.com/open-ali/nfs-client-provisioner #使用的鏡像 volumeMounts: - name: nfs-client-root mountPath: /persistentvolumes #指定容器內掛載的目錄 env: - name: PROVISIONER_NAME #容器內的變量用於指定提供存儲的名稱 value: lzj - name: NFS_SERVER #容器內的變量用於指定nfs服務的IP地址 value: 192.168.1.1 - name: NFS_PATH #容器內的變量指定nfs服務器對應的目錄 value: /nfsdata volumes: #指定掛載到容器內的nfs的路徑及IP - name: nfs-client-root nfs: server: 192.168.1.1 path: /nfsdata [root@master ~]# kubectl apply -f nfs-deployment.yaml [root@master ~]# kubectl get pod NAME READY STATUS RESTARTS AGE nfs-client-provisioner-66df958f9c-mbvhv 1/1 Running 0 2m34s
[root@master ~]# vim sc.yaml apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: stateful-nfs namespace: xiaojiang-test provisioner: lzj #這個要和nfs-client-provisioner的env環境變量中的PROVISIONER_NAME的value值對應。 reclaimPolicy: Retain #指定回收策略爲Retain(手動釋放) [root@master ~]# kubectl apply -f sc.yaml [root@master ~]# kubectl get StorageClass NAME PROVISIONER AGE stateful-nfs lzj 17s
[root@master ~]# vim statefulset.yaml apiVersion: v1 kind: Service metadata: name: headless-svc #從名稱就能夠是無頭服務 labels: app: headless-svc spec: ports: - port: 80 name: myweb selector: app: headless-pod clusterIP: None #不分配羣集的IP地址,因此不具有負載均衡的能力 --- apiVersion: apps/v1 kind: StatefulSet #定義pod中運行的應用 metadata: name: statefulset-test spec: serviceName: headless-svc replicas: 3 selector: matchLabels: app: headless-pod template: metadata: labels: app: headless-pod spec: containers: - image: httpd name: myhttpd ports: - containerPort: 80 name: httpd volumeMounts: - mountPath: /usr/local/apache2/htdocs name: test volumeClaimTemplates: #定義建立PVC使用的模板 - metadata: name: test annotations: #這是指定storageclass volume.beta.kubernetes.io/storage-class: stateful-nfs spec: accessModes: - ReadWriteOnce resources: requests: storage: 100Mi [root@master ~]# kubectl apply -f statefulset.yaml [root@master ~]# kubectl get pod NAME READY STATUS RESTARTS AGE nfs-client-provisioner-66df958f9c-mbvhv 1/1 Running 0 10m statefulset-test-0 1/1 Running 0 29s statefulset-test-1 1/1 Running 0 18s statefulset-test-2 1/1 Running 0 11s [root@master ~]# kubectl get pv [root@master ~]# kubectl get pvc #PV與PVC已經生成 [root@master ~]# ls /nfsdata/ default-test-statefulset-test-0-pvc-54d0b06c-698e-4f1a-8327-255b10978cbe default-test-statefulset-test-1-pvc-1b499d49-a787-4f2b-b238-404b05f75fd7 default-test-statefulset-test-2-pvc-7766f8da-6f3b-4c1f-9eb8-dfadda1e656f [root@master ~]# echo "hello world" > /nfsdata/default-test-statefulset-test-0-pvc-54d0b06c-698e-4f1a-8327-255b10978cbe/index.html [root@master ~]# kubectl get pod -o wide | grep test-0 statefulset-test-0 1/1 Running 0 4m53s 10.244.2.4 node02 <none> <none> [root@master ~]# curl 10.244.2.4 hello world [root@master ~]# curl -I 10.244.2.4 HTTP/1.1 200 OK Date: Wed, 12 Feb 2020 09:52:04 GMT Server: Apache/2.4.41 (Unix) Last-Modified: Wed, 12 Feb 2020 09:45:37 GMT ETag: "c-59e5dd5ac0a63" Accept-Ranges: bytes Content-Length: 12 Content-Type: text/html #能夠看出如今提供web頁面的服務是Apache
[root@master ~]# vim statefulset.yaml apiVersion: v1 kind: Service metadata: name: headless-svc labels: app: headless-svc spec: ports: - port: 80 name: myweb selector: app: headless-pod clusterIP: None --- apiVersion: apps/v1 kind: StatefulSet metadata: name: statefulset-test spec: updateStrategy: rollingUpdate: partition: 2 #指定並行升級的個數 serviceName: headless-svc replicas: 10 selector: matchLabels: app: headless-pod template: metadata: labels: app: headless-pod spec: containers: - image: nginx #更換擴容時使用的鏡像 name: myhttpd ports: - containerPort: 80 name: httpd volumeMounts: - mountPath: /usr/share/nginx/html/ #更換容器中的主目錄 name: test volumeClaimTemplates: - metadata: name: test annotations: #這是指定storageclass volume.beta.kubernetes.io/storage-class: stateful-nfs spec: accessModes: - ReadWriteOnce resources: requests: storage: 100Mi [root@master ~]# kubectl apply -f statefulset.yaml [root@master ~]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nfs-client-provisioner-66df958f9c-mbvhv 1/1 Running 0 35m 10.244.2.2 node02 <none> <none> statefulset-test-0 1/1 Running 0 21m 10.244.2.4 node02 <none> <none> statefulset-test-1 1/1 Running 0 20m 10.244.1.4 node01 <none> <none> statefulset-test-2 1/1 Running 0 3m52s 10.244.1.9 node01 <none> <none> statefulset-test-3 1/1 Running 0 4m54s 10.244.2.5 node02 <none> <none> statefulset-test-4 1/1 Running 0 4m43s 10.244.1.6 node01 <none> <none> statefulset-test-5 1/1 Running 0 4m31s 10.244.2.6 node02 <none> <none> statefulset-test-6 1/1 Running 0 4m25s 10.244.1.7 node01 <none> <none> statefulset-test-7 1/1 Running 0 4m19s 10.244.2.7 node02 <none> <none> statefulset-test-8 1/1 Running 0 4m12s 10.244.1.8 node01 <none> <none> statefulset-test-9 1/1 Running 0 4m3s 10.244.2.8 node02 <none> <none> [root@master ~]# ls /nfsdata/ | wc -l 10 [root@master ~]# curl -I 10.244.2.4 HTTP/1.1 200 OK Date: Wed, 12 Feb 2020 10:05:34 GMT Server: Apache/2.4.41 (Unix) Last-Modified: Wed, 12 Feb 2020 09:45:37 GMT ETag: "c-59e5dd5ac0a63" Accept-Ranges: bytes Content-Length: 12 Content-Type: text/html [root@master ~]# curl -I 10.244.2.8 HTTP/1.1 403 Forbidden Server: nginx/1.17.8 Date: Wed, 12 Feb 2020 10:05:41 GMT Content-Type: text/html Content-Length: 153 Connection: keep-alive
由此能夠看出在執行擴容操做時,並不會更改pod,這就是StatefulSet的特色!數據庫
————————————本文到此結束,感謝閱讀————————————apache