1. 程式人生 > 其它 >k8s基礎之四 StatefulSet有狀態

k8s基礎之四 StatefulSet有狀態

配置一個簡單的StatefulSet

  RC、Deployment、DaemonSet都是面向無狀態的服務,它們所管理的Pod的IP、名字,啟停順序等都是隨機的,而StatefulSet是什麼?顧名思義,有狀態的集合,管理所有有狀態的服務,比如MySQL、MongoDB叢集等。


  StatefulSet本質上是Deployment的一種變體,在v1.9版本中已成為GA版本,它為了解決有狀態服務的問題,它所管理的Pod擁有固定的Pod名稱,啟停順序,在StatefulSet中,Pod名字稱為網路標識(hostname),還必須要用到共享儲存。


  在Deployment中,與之對應的服務是service,而在StatefulSet中與之對應的headless service,headless service,即無頭服務,與service的區別就是它沒有Cluster IP,解析它的名稱時將返回該Headless Service對應的全部Pod的Endpoint列表。


  除此之外,StatefulSet在Headless Service的基礎上又為StatefulSet控制的每個Pod副本建立了一個DNS域名,這個域名的格式為:
$(podname).(headless server name)
  FQDN:$(podname).(server name).namespace.svc.cluster.local

  StatefulSet中每個Pod的DNS格式為statefulSetname-{0..N-1}.serviceName.namespace.svc.cluster.local,其中(用的時候只寫到服務名就能通了)
    1. serviceName為headless Service的名字
    2. 0..N-1 為Pod所在的序號,從0開始到N-1
    3. statefulSetName 為StatefulSet的名字
    4. namespace為服務所在的namespace,Headless Servie和statefulSet必須在相同的namespace
    5. .cluster.local 為ClusterDomain

特點: 

  Pod一致性:包含次序(啟動、停止次序)、網路一致性。此一致性與Pod相關,與被排程到哪個node節點無關;
  穩定的次序:對於N個副本的StatefulSet,每個Pod都在[0,N)的範圍內分配一個數字序號,且是唯一的;
  穩定的網路:Pod的hostname模式為( s t a t e f u l s e t 名 稱 ) − (statefulset名稱)-(statefulset名稱)−(序號);
  穩定的儲存:通過VolumeClaimTemplate為每個Pod建立一個PV。刪除、減少副本,不會刪除相關的卷。

一個簡單的nginx服務 web.yaml為例

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.15.2 ports: - containerPort: 80 name: web
#將上面配置檔案儲存為web.yaml 然後在另外起一個pod做客戶端訪問用,(pod命名方式上面有介紹)
kubectl apply -f web.yaml
kubectl get pod
        NAME     READY   STATUS    RESTARTS   AGE
        my-pod   1/1     Running   0          5m4s
        web-0    1/1     Running   0          19m
        web-1    1/1     Running   0          19m
        web-2    1/1     Running   0          16m
        
 kubectl exec -it my-pod -- bash
 curl web-0.nginx
 #會發現即使沒有配置ip地址也能將這個解析為podip

StatefulSet擴縮容

  建立:只有在上一個pod啟動完成後才會開始啟動下一個pod,如果上一個沒有啟動成功,將不會啟動下一個pod

  刪除:相反從下往上刪,在刪除過程中,正在刪除上面的所有pod必須是running狀態,如果不是running將會暫停,直到上面的pod全部為running才會開始刪

kubectl scale --replicas=2 sts web
#設定StatefulSet副本數,命令

StatefulSet更新策略

滾動更新:

  updateStrategy:
    rollingUpdate:
      partition: 0
    type: RollingUpdate 

StatefulSet更新策略和刪除差不多,從下往上更新,如果更新途中上面的pod掛了,那麼就會等到上面的pod running了在繼續更新

OnDelete:

在設定成OnDelete時,只有在刪除時候才會去更新映象

   updateStrategy:
    type: OnDelete
    
#修改完畢後可以刪除一個映象然後讓他自動建立,建立之後才會更新

StatefulSet灰度更新

partition: 0
#在上上面有一個這個欄位,那麼這個欄位是什麼意思呢?
    #就是小於這個值的pod,不更新(不包括等於)

思路:

我們在更新的時候,通過控制partition這個欄位,一個一個的更新,看看結果如何。如果沒問題,在繼續更新下一個

StatefulSet級聯更新和級聯刪除

級聯更新和級聯刪除

  就是刪除stat時 同時刪除Pod,預設的是級聯刪除

kubectl delete sts web

非級聯刪除

  刪除sts時 不刪除Pod

kubectl delete sts web --cascade=false
#非級聯刪除就是刪除時候多加了一個選項
#刪除statefulSet後,他所構建的pod就變成了孤兒,此時在刪除pod就沒有程序去重新構建他了