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/