k8s之statefulSet-有狀態應用副本集控制器


1.概述

  無狀態應用更關注群體,任何一個成員都可以被取代,有狀態應用關注的是個體。用deployment控制器管理的nginx、myapp等都屬於無狀態應用,像mysql、redis、zookeeper等都屬於有狀態應用,他們有的還有主從之分、先后順序之分.

  statefulset控制器能實現有狀態應用的管理,但實現起來也是非常麻煩,需要把運維管理過程寫成腳本並注入到statefulset中才能使用,雖然互聯網上有人做好了stateful的腳本,但是還是建議大家不要輕易的把redis、mysql等這樣有狀態的應用遷移到k8s上.

在k8s中,statefulset管理的應用有以下特效:

a).每一個Pod穩定且有唯一的網絡標識符;
b).穩定且持久的存儲設備;
c).要求有序、平滑的部署和擴展;
d).要求有序、平滑的終止和刪除;
e).有序的滾動更新,應該先更新從節點,再更新主節點;

statefulset由三個組件組成:

a).headless service(無頭的服務,即沒名字);
b).statefulset控制器;
c).volumeClaimTemplate(存儲卷申請模板,因為每個pod要有專用存儲卷,而不能共用存儲卷)

2.創建StatefulSet控制器

kubectl explain sts

cat stateful-demo.yaml 
apiVersion: v1
kind: Service
metadata:
  name: myapp-svc
  labels:
    app: myapp-svc
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: myapp-pod
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: myapp
spec:
  serviceName: myapp-svc
  replicas: 2
  selector:
    matchLabels:
      app: myapp-pod
  template:
    metadata:
      labels:
        app: myapp-pod
    spec:
      containers:
      - name: myapp
        image: ikubernetes/myapp:v1
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: myappdata
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: myappdata
    spec:
      accessModes: ["ReadWriteOnce"]
      #storageClassName: "gluster-dynamic"
      resources:
        requests:
          storage: 5Gi

volumeClaimTemplates:存儲卷申請模板,為每個pod定義volume;為pod所在的名稱空間自動創建pvc.

kubectl apply -f stateful-demo.yaml
kubectl get pods
NAME                             READY     STATUS             RESTARTS   AGE
myapp-0                          1/1       Running            0          4m
myapp-1                          1/1       Running            0          4m

# pod和service會被刪除,但是pvc不會被刪,所以還能恢復.
kubectl delete -f stateful-demo.yaml
 
# 解析pod時的格式:pod名.svc名.namespace名.svc.cluster.local
kubectl exec -it myapp-0 -- /bin/sh
/ # nslookup myapp-0.myapp-svc.default.svc.cluster.local
nslookup: can't resolve '(null)': Name does not resolve
Name:      myapp-0.myapp-svc.default.svc.cluster.local
Address 1: 10.244.1.110 myapp-0.myapp-svc.default.svc.cluster.local

# 將pod為5個
kubectl scale sts myapp --replicas=5
# 也可以用patch打補丁的方法來進行擴容和縮容
kubectl patch sts myapp -p '{"spec":{"replicas":2}}'
# 更新策略
kubectl explain sts.spec.updateStrategy.rollingUpdate
假設有4個pod(pod0,pod1,pod2,pod3),如果設置partition為5,那么說明大於等於5的pod更新,四個Pod就都不更新;
如果partition為4,那么說明大於等於4的pod更新,即pod3更新,其他pod都不更新;
如果partiton為3,那么說明大於等於3的pod更新,那么就是pod2和pod3更新,其他pod都不更新.
kubectl patch sts myapp -p '{"spec":{"updateStrategy":{"rollingUpdate":{"partition":4}}}}'
kubectl describe sts myapp
Update Strategy:    RollingUpdate
Partition:        4
# 把myapp升級為v2版本
kubectl set image sts/myapp myapp=ikubernetes/myapp:v2
kubectl get pods myapp-4 -o yaml
 containerStatuses:
    image: ikubernetes/myapp:v2

 

可以參考github上別人做好的有狀態應用:github k8s statefulSet redis|mysql

參考博客:http://blog.itpub.net/28916011/viewspace-2215046/

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM