溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Kubernetes針對有狀態(tài)服務數(shù)據(jù)持久化之Statefu

發(fā)布時間:2020-02-14 11:07:52 來源:網(wǎng)絡(luò) 閱讀:848 作者:筱振 欄目:云計算

一、Kubernetes無狀態(tài)服務VS有狀態(tài)服務

1)Kubernetes無狀態(tài)服務

Kubernetes無狀態(tài)服務特征:
1)是指該服務運行的實例不會在本地存儲需要持久化的數(shù)據(jù),并且多個實例對于同一請求響應的結(jié)果是完全一致的;
2)多個實例可以共享相同的持久化數(shù)據(jù)。例如:nginx實例、tomcat實例等;
3)相關(guān)的Kubernetes資源有:ReplicaSet、ReplicationController、Deployment等,由于是無狀態(tài)服務,所以這些控制器創(chuàng)建的Pod名稱都是隨機性的。并且在縮容時并不會明確縮容某一個Pod,而是隨機的,因為所有實例得到的返回值都是一樣的,所以縮容任何一個Pod都可以;

2)Kubernetes有狀態(tài)服務

Kubernetes有狀態(tài)服務特征:
1)有狀態(tài)服務可以說是需要數(shù)據(jù)存儲功能的服務、或者指多線程類型的服務、隊列等。(比如:mysql數(shù)據(jù)庫、kafka、zookeeper等);
2)每個實例都需要自己獨立的持久化存儲,并且在Kubernetes中通過聲明模板的方式來進行定義。持久卷聲明模板在創(chuàng)建pod之前創(chuàng)建,綁定到pod中,模板可以定義多個;
3)相關(guān)的Kubernetes資源有:StatefulSet。由于是有狀態(tài)的服務,所以每個Pod都有特定的名稱和網(wǎng)絡(luò)標識。比如Pod名稱是由StatefulSet名+有序的數(shù)字組成(0、1、2……);
4)在進行縮容操作時,可以明確知道會縮容那一個Pod,從數(shù)字最大的開始。并且StatefulSet在已有實例不健康的情況下是不允許做縮容操作的;

3)無狀態(tài)服務和有狀態(tài)服務的區(qū)別

主要表現(xiàn)在以下方面:
1)實例數(shù)量:無狀態(tài)服務可以有一個或多個實例,因此支持兩種服務容量調(diào)節(jié)模式;有狀態(tài)服務職能有一個實例,不允許創(chuàng)建多個實例,因此也不支持服務容量的調(diào)節(jié);
2)存儲卷:無狀態(tài)服務可以有存儲卷,也可以沒有,即使有也無法備份存儲卷中的數(shù)據(jù);有狀態(tài)服務必須要有存儲卷,并且在創(chuàng)建服務時,必須指定該存儲卷分配的磁盤空間大?。?br/>3)數(shù)據(jù)存儲: 無狀態(tài)服務運行過程中的所有數(shù)據(jù)(除日志和監(jiān)控數(shù)據(jù))都存在容器實例里的文件系統(tǒng)中,如果實例停止或者刪除,則這些數(shù)據(jù)都將丟失,無法找回;而對于有狀態(tài)服務,凡是已經(jīng)掛載了存儲卷的目錄下的文件內(nèi)容都可以隨時進行備份,備份的數(shù)據(jù)可以下載,也可以用于恢復新的服務。但對于沒有掛載卷的目錄下的數(shù)據(jù),仍然是無法備份和保存的,如果實例停止或者刪除,這些非掛載卷里的文件內(nèi)容同樣會丟失。

4)StatefulSet概述

StatefulSet是Kubernetes提供的管理有狀態(tài)應用的負載管理控制器API。在Pods管理的基礎(chǔ)上,保證Pods的順序和一致性。與Deployment一樣,StatefulSet也是使用容器的Spec來創(chuàng)建Pod,與之不同StatefulSet創(chuàng)建的Pods在生命周期中會保持持久的標記(例如Pod Name)。

5)StatefulSet特點

1)穩(wěn)定的持久化存儲,即Pod重新調(diào)度后還是能訪問到相同的持久化數(shù)據(jù),基于PVC來實現(xiàn);
2)穩(wěn)定的網(wǎng)絡(luò)標志,即Pod重新調(diào)度后其PodName和HostName不變,基于Headless Service(即沒有Cluster IP的Service)來實現(xiàn);
3)有序部署,有序擴展,即Pod是有順序的,在部署或者擴展的時候要依據(jù)定義的順序依次依次進行(即從0到N-1,在下一個Pod運行之前所有之前的Pod必須都是Running和Ready狀態(tài)),基于init containers來實現(xiàn);
4)有序收縮,有序刪除(即從N-1到0);

二、使用StatefulSet實現(xiàn)自動創(chuàng)建PVC

1)搭建NFS共享存儲

為了方便,就直接在master節(jié)點上部署NFS存儲了!

[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 *

2)創(chuàng)建rbac授權(quán)

[root@master ~]# vim rbac-rolebind.yaml
apiVersion: v1                            #創(chuàng)建一個用于認證的服務賬號
kind: ServiceAccount
metadata:
  name: nfs-provisioner
---
apiVersion: rbac.authorization.k8s.io/v1        #創(chuàng)建群集規(guī)則
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                #將服務認證用戶與群集規(guī)則進行綁定
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    

3)創(chuàng)建nfs-deployment.資源

[root@master ~]# vim nfs-deployment.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nfs-client-provisioner
spec:
  replicas: 1                              #指定副本數(shù)量為1
  strategy:
    type: Recreate                      #指定策略類型為重置
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
      serviceAccount: nfs-provisioner            #指定rbac yanl文件中創(chuàng)建的認證用戶賬號
      containers:
        - name: nfs-client-provisioner
          image: registry.cn-hangzhou.aliyuncs.com/open-ali/nfs-client-provisioner     #使用的鏡像 
          volumeMounts:
            - name: nfs-client-root
              mountPath:  /persistentvolumes             #指定容器內(nèi)掛載的目錄
          env:
            - name: PROVISIONER_NAME           #容器內(nèi)的變量用于指定提供存儲的名稱
              value: lzj
            - name: NFS_SERVER                      #容器內(nèi)的變量用于指定nfs服務的IP地址
              value: 192.168.1.1
            - name: NFS_PATH                       #容器內(nèi)的變量指定nfs服務器對應的目錄
              value: /nfsdata
      volumes:                                                #指定掛載到容器內(nèi)的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

4)創(chuàng)建SC(Storage Class)

[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環(huán)境變量中的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

5)創(chuàng)建Pod

[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:                       #定義創(chuàng)建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已經(jīng)生成
[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
#可以看出現(xiàn)在提供web頁面的服務是Apache

6)對pod進行更新并擴容

[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                           #指定并行升級的個數(shù)
  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

由此可以看出在執(zhí)行擴容操作時,并不會更改pod,這就是StatefulSet的特點!

————————————本文到此結(jié)束,感謝閱讀————————————

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI