溫馨提示×

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

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

如何通過StatefulSet部署有狀態(tài)服務(wù)應(yīng)用

發(fā)布時(shí)間:2022-03-19 09:03:19 來源:億速云 閱讀:156 作者:iii 欄目:開發(fā)技術(shù)

這篇“如何通過StatefulSet部署有狀態(tài)服務(wù)應(yīng)用”文章的知識(shí)點(diǎn)大部分人都不太理解,所以小編給大家總結(jié)了以下內(nèi)容,內(nèi)容詳細(xì),步驟清晰,具有一定的借鑒價(jià)值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“如何通過StatefulSet部署有狀態(tài)服務(wù)應(yīng)用”文章吧。

    先總結(jié)后詳解:

    • 具有固定的網(wǎng)絡(luò)標(biāo)識(shí),如主機(jī)名、域名等

    • 支持持久化存儲(chǔ)

    • 可以按順序部署和擴(kuò)展

    • 可以按順序終止和刪除

    • 滾動(dòng)升級(jí)也是按照一定順序

    StatefulSet的基本概念:

    StatefulSet主要用于管理有狀態(tài)的應(yīng)用程序的工作負(fù)載的API對(duì)象。比如生產(chǎn)中的Elastic Search集群、MongoDB集群、Kafka集群、Reids集群、Zookeeper集群等。。。

    與Deployment相似的是,StatefulSet也同樣管理著基本相同容器規(guī)范的Pod。不同的是,StatefulSet為每個(gè)Pod維護(hù)了一個(gè)粘性標(biāo)識(shí)。

    這些Pod是根據(jù)相同的規(guī)范創(chuàng)建的,但是不可互換,每個(gè)Pod都有一個(gè)持久的標(biāo)識(shí)符,在重新調(diào)度時(shí)也會(huì)保留,一般格式為StatefulSetName-Number。

    比如定義一個(gè)Redis-Sentinel的StatefulSet,指定三個(gè)副本,就會(huì)依次創(chuàng)建名為Redis-Sentinel-0、Redis-Sentinel-1、Redis-Sentinel-2的三個(gè)副本。而StatefulSet的Pod的Service一般使用Headless Service(無頭服務(wù))進(jìn)行通信。

    Headless的格式為一般為:

    statefulSetName-{0..N-1}.serviceName.namespace.svc.cluster.local
    • statefulSetName:StatefulSet的名稱

    • {0…N-1}:名稱后面的序號(hào)

    • serviceName:Headless Service的名稱

    • namespace:服務(wù)所在的命名空間

    • cluster.local:Cluster Daemon(集群域)

    StatefulSet用于有以下一條或多條需求的應(yīng)用程序:

    • 需要穩(wěn)定的獨(dú)一無二的網(wǎng)絡(luò)標(biāo)識(shí)符

    • 需要持久化數(shù)據(jù)

    • 需要有序的、優(yōu)雅的部署和擴(kuò)展

    • 需要有序的自動(dòng)滾動(dòng)更新

    如果都不需要,那應(yīng)該使用Deployment部署。

    示例:定義一個(gè)StatefulSet資源

    創(chuàng)建一個(gè)nginx的StatefulSet作為示范:這個(gè)yaml啟動(dòng)兩個(gè)副本,使用nginx鏡像,注意service一定要存在。

    apiVersion: v1
    kind: Service
    metadata:
      name: nginx
      labels:
        app: nginx
    spec: 
      ports:
      - port: 80
        name: web
      clusterIP: None
      selector: 
        app: nginx
    ---
    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: web
    spec:
      serviceName: "nginx"
      replicas: 2
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx:1.18.0
            ports:
            - containerPort: 80
              name: web

    使用kubectl創(chuàng)建一下:可以看到service和statefulset副本都創(chuàng)建了

    [root@k8s-master01 ~]# kubectl create -f nginx-sts.yaml 
    service/nginx created
    statefulset.apps/web created

    查看Pod:可以看到副本的名稱是按序號(hào)從0開始的

    [root@k8s-master01 ~]# kubectl get pod
    NAME      READY   STATUS    RESTARTS       AGE
    busybox   1/1     Running   17 (50m ago)   7d18h
    web-0     1/1     Running   0              74s
    web-1     1/1     Running   0              73s

    查看service:可以看到nginx的service是沒有CLUSTER-IP的

    [root@k8s-master01 ~]# kubectl get svc
    NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
    kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   7d21h
    nginx        ClusterIP   None         <none>        80/TCP    2m43s

    擴(kuò)容副本:可以看到與deployment不同的是,新生成的Pod名稱序號(hào)是有規(guī)律的

    [root@k8s-master01 ~]# kubectl scale --replicas=3 sts web 
    statefulset.apps/web scaled
    [root@k8s-master01 ~]# kubectl get pod
    NAME      READY   STATUS              RESTARTS       AGE
    busybox   1/1     Running             17 (55m ago)   7d18h
    web-0     1/1     Running             0              6m30s
    web-1     1/1     Running             0              6m29s
    web-2     0/1     ContainerCreating   0              28s

    測試訪問一下是否可以通信:可以看到網(wǎng)絡(luò)是通的,IP直接解析到172.18.195.18上,也就是Pod的IP而不用通過一層service代理。

    [root@k8s-master01 ~]# kubectl exec -ti busybox -- sh
    / # nslookup web-0.nginx
    Server:    10.96.0.10
    Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
    Name:      web-0.nginx
    Address 1: 172.18.195.18 web-0.nginx.default.svc.cluster.local
    / # ping web-0.nginx
    PING web-0.nginx (172.18.195.18): 56 data bytes
    64 bytes from 172.18.195.18: seq=0 ttl=62 time=1.020 ms
    64 bytes from 172.18.195.18: seq=1 ttl=62 time=0.860 ms
    [root@k8s-master01 ~]# kubectl get pod -o wide 
    NAME      READY   STATUS    RESTARTS       AGE     IP               NODE           NOMINATED NODE   READINESS GATES
    busybox   1/1     Running   18 (28s ago)   7d18h   172.27.14.193    k8s-node02     <none>           <none>
    web-0     1/1     Running   0              11m     172.18.195.18    k8s-master03   <none>           <none>
    web-1     1/1     Running   0              11m     172.25.92.78     k8s-master02   <none>           <none>
    web-2     1/1     Running   0              5m9s    172.25.244.199   k8s-master01   <none>           <none>

    StatefulSet的擴(kuò)容與縮容

    StatefulSet擴(kuò)容:

    擴(kuò)容的時(shí)候會(huì)按照序號(hào)順序依次創(chuàng)建,比如我有上圖的三個(gè)web副本,我想擴(kuò)容到五個(gè),那么就會(huì)先創(chuàng)建web-3副本,只要web-3副本創(chuàng)建成功后才會(huì)創(chuàng)建web-4;如果web-3出現(xiàn)故障無法創(chuàng)建,那么后續(xù)任務(wù)將一直等待web-3的創(chuàng)建直到成功。

    StatefulSet縮容:

    縮容的時(shí)候與擴(kuò)容相反,會(huì)從最后一個(gè)開始刪除,按照web-4、web-3這樣的順序依次刪除。

    StatefulSet更新策略

    支持兩種更新策略:

    RollingUpdate:默認(rèn)的更新策略為滾動(dòng)更新,是從最后一個(gè)副本開始更新,成功后才會(huì)進(jìn)行下一個(gè)副本,更新方式為先刪除再創(chuàng)建。

    OnDelete:當(dāng)把策略改為這個(gè)時(shí),我們就需要先手動(dòng)刪除要更新的副本,才會(huì)觸發(fā)副本的更新策略。

    StatefulSet灰度發(fā)布

    利用更新策略中的Partition參數(shù)進(jìn)行簡單的灰度發(fā)布。

    如何通過StatefulSet部署有狀態(tài)服務(wù)應(yīng)用

    StatefulSet的級(jí)聯(lián)刪除和非級(jí)聯(lián)刪除

    級(jí)聯(lián)刪除:刪除StatefulSet時(shí)同時(shí)刪除Pod,默認(rèn)為級(jí)聯(lián)刪除

    [root@k8s-master01 ~]# kubectl delete sts web

    非級(jí)聯(lián)刪除:刪除StatefulSet時(shí)不會(huì)刪除Pod,注意此時(shí)再刪除Pod的話就不會(huì)再重建了

    [root@k8s-master01 ~]# kubectl delete sts web --cascade=false

    以上就是關(guān)于“如何通過StatefulSet部署有狀態(tài)服務(wù)應(yīng)用”這篇文章的內(nèi)容,相信大家都有了一定的了解,希望小編分享的內(nèi)容對(duì)大家有幫助,若想了解更多相關(guān)的知識(shí)內(nèi)容,請(qǐng)關(guān)注億速云行業(yè)資訊頻道。

    向AI問一下細(xì)節(jié)

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

    AI