statefulSet
1.稳定且唯一的网络标识符2.稳定且持久的存储3.有序,平滑地部署和扩展4.有序,平滑地删除和终止5.有序地滚动更新三个组件:headless service StatefulSet volumeClaimTemplateheadless service:Headless Service也是一种Service,但不同的是会定义spec:clusterIP: None,也就是不需要Cluster IP的Service,因为没有ClusterIP,kube-proxy 并不处理此类服务,因为没有load balancing或 proxy 代理设置,在访问服务的时候会返回后端的全部的Pods IP地址,主要用于开发者自己根据pods进行负载均衡器的开发(设置了selector) 或 StatefulSet
关于headless service的介绍请查看
准备工作
如何创建
在创建StatefulSet之前需要准备的东西,值得注意的是创建顺序非常关键,创建顺序如下:1、Volume
2、Persistent Volume3、Persistent Volume Claim4、Service5、StatefulSet1)准备pv,这里我们使用以前创建的pv
https://www.cnblogs.com/linyouyi/articles/10604818.html[root@master ~]# kubectl get pvNAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGEpv001 5Gi RWO,RWX Retain Available 4spv002 5Gi RWO,RWX Retain Available 4spv003 5Gi RWO,RWX Retain Available 4spv004 5Gi RWO,RWX Retain Available 4spv005 5Gi RWO,RWX Retain Available 4s
创建Service,statefulset
[root@master ~]# vim myapp-statefulset.yaml apiVersion: v1kind: Servicemetadata: name: myappservice labels: app: statefulsetspec: ports: - port: 80 name: web clusterIP: None selector: app: myapp-pod---apiVersion: apps/v1kind: StatefulSetmetadata: name: myappspec: serviceName: myappservice //要和上面的myappservice一样 replicas: 3 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"] //此处要确保你已经有足够的pv,且模式含ReadWriteOnce resources: requests: storage: 1Gi[root@master ~]# kubectl apply -f myapp-statefulset.yaml service/myapp-statefulset unchangedstatefulset.apps/myapp created[root@master ~]# kubectl get svcNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEkubernetes ClusterIP 10.96.0.1443/TCP 2d8hmyapp-statefulset ClusterIP None 80/TCP 3m16s[root@master ~]# kubectl get stsNAME READY AGEmyapp 3/3 14s[root@master ~]# kubectl get pv //名称都是有序的,且都是从0开始创建NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGEpv001 5Gi RWO,RWX Retain Bound default/myappdata-myapp-2 73spv002 5Gi RWO,RWX Retain Bound default/myappdata-myapp-1 73spv003 5Gi RWO,RWX Retain Available 73spv004 5Gi RWO,RWX Retain Available 73spv005 5Gi RWO,RWX Retain Bound default/myappdata-myapp-0 73s[root@master ~]# kubectl get pvcNAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGEmyappdata-myapp-0 Bound pv005 5Gi RWO,RWX 49smyappdata-myapp-1 Bound pv002 5Gi RWO,RWX 47smyappdata-myapp-2 Bound pv001 5Gi RWO,RWX 45s//删除是从2到0开始有序地删除,默认不删pvc,是为了再次创建时myapp-0自动绑定回myappdata-myapp-0//myapp-1绑定回myappdata-myapp-1,myapp-2绑定回myappdata-myapp-2[root@master ~]# kubectl delete -f myapp-statefulset.yaml service "myapp-statefulset" deletedstatefulset.apps "myapp" deleted[root@master ~]# kubectl get pods -wNAME READY STATUS RESTARTS AGEmyapp-0 1/1 Running 0 7m33smyapp-1 1/1 Running 0 7m31smyapp-2 1/1 Running 0 7m29smyapp-1 1/1 Terminating 0 7m52smyapp-0 1/1 Terminating 0 7m54smyapp-2 1/1 Terminating 0 7m50smyapp-1 0/1 Terminating 0 7m53smyapp-0 0/1 Terminating 0 7m55smyapp-2 0/1 Terminating 0 7m52smyapp-1 0/1 Terminating 0 7m58smyapp-1 0/1 Terminating 0 7m58smyapp-0 0/1 Terminating 0 8m5smyapp-0 0/1 Terminating 0 8m5smyapp-2 0/1 Terminating 0 8m1smyapp-2 0/1 Terminating 0 8m1s//创建也是按顺序来的[root@master ~]# kubectl apply -f myapp-statefulset.yaml service/myapp-statefulset createdstatefulset.apps/myapp created[root@master ~]# kubectl get pods -wNAME READY STATUS RESTARTS AGEmyapp-0 0/1 Pending 0 0smyapp-0 0/1 Pending 0 0smyapp-0 0/1 ContainerCreating 0 0smyapp-0 1/1 Running 0 2smyapp-1 0/1 Pending 0 0smyapp-1 0/1 Pending 0 0smyapp-1 0/1 ContainerCreating 0 0smyapp-1 1/1 Running 0 1smyapp-2 0/1 Pending 0 0smyapp-2 0/1 Pending 0 0smyapp-2 0/1 ContainerCreating 0 0smyapp-2 1/1 Running 0 2s
查看解析
[root@master ~]# kubectl exec -it myapp-0 -- /bin/sh/ # nslookup myapp-0nslookup: can't resolve '(null)': Name does not resolveName: myapp-0Address 1: 10.244.3.13 myapp-0.myapp.default.svc.cluster.local/ # nslookup myapp-1.myappservice.default.svc.cluster.localnslookup: can't resolve '(null)': Name does not resolveName: myapp-1.myappservice.default.svc.cluster.localAddress 1: 10.244.3.15 myapp-1.myappservice.default.svc.cluster.local/ # nslookup myapp-2.myappservice.default.svc.cluster.localnslookup: can't resolve '(null)': Name does not resolveName: myapp-2.myappservice.default.svc.cluster.localAddress 1: 10.244.1.16 myapp-2.myappservice.default.svc.cluster.local/ # //解析格式nslookup myapp-0.myappservice.default.svc.cluster.localnslookup pod_name.service_name.default.svc.cluster.local
扩容
[root@master ~]# kubectl scale sts myapp --replicas=5statefulset.apps/myapp scaled[root@master ~]# kubectl get podsNAME READY STATUS RESTARTS AGEmyapp-0 1/1 Running 0 9m26smyapp-1 1/1 Running 0 9m25smyapp-2 1/1 Running 0 9m24smyapp-3 1/1 Running 0 25smyapp-4 1/1 Running 0 22s[root@master ~]# kubectl get pvcNAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGEmyappdata-myapp-0 Bound pv005 5Gi RWO,RWX 66mmyappdata-myapp-1 Bound pv002 5Gi RWO,RWX 66mmyappdata-myapp-2 Bound pv001 5Gi RWO,RWX 66mmyappdata-myapp-3 Bound pv003 5Gi RWO,RWX 61smyappdata-myapp-4 Bound pv004 5Gi RWO,RWX 58s[root@master ~]# kubectl get pvNAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGEpv001 5Gi RWO,RWX Retain Bound default/myappdata-myapp-2 67mpv002 5Gi RWO,RWX Retain Bound default/myappdata-myapp-1 67mpv003 5Gi RWO,RWX Retain Bound default/myappdata-myapp-3 67mpv004 5Gi RWO,RWX Retain Bound default/myappdata-myapp-4 67mpv005 5Gi RWO,RWX Retain Bound default/myappdata-myapp-0 67m
缩容
[root@master ~]# kubectl scale sts myapp --replicas=2[root@master ~]# kubectl get podNAME READY STATUS RESTARTS AGEmyapp-0 1/1 Running 0 11mmyapp-1 1/1 Running 0 11m查看默认更新策略View Code两种更新方式[root@master ~]# kubectl patch sts myapp -p '{"spec":{"template":{"containers[0]":{"image":{"ikubernetes/myapp:v2"}}}}}'[root@master ~]# kubectl set image sts/myapp myapp=ikubernetes/myapp:v2statefulset.apps/myapp image updated[root@master ~]# kubectl get sts -o wideNAME READY AGE CONTAINERS IMAGESmyapp 4/5 22m myapp ikubernetes/myapp:v2[root@master ~]# kubectl describe pods myapp-4Name: myapp-4Namespace: defaultPriority: 0PriorityClassName:Node: node01/10.0.1.133Start Time: Tue, 14 May 2019 00:47:32 +0800Labels: app=myapp-pod controller-revision-hash=myapp-5775ff7474 statefulset.kubernetes.io/pod-name=myapp-4Annotations: Status: RunningIP: 10.244.1.18Controlled By: StatefulSet/myappContainers: myapp: Container ID: docker://3d7e50667f84c8eab2f428c86c24cc16cae49dcb20217987fa1793e086c955a5 Image: ikubernetes/myapp:v2 Image ID: docker-pullable://ikubernetes/myapp@sha256:85a2b81a62f09a414ea33b74fb8aa686ed9b168294b26b4c819df0be0712d358 Port: 80/TCP Host Port: 0/TCP State: Running Started: Tue, 14 May 2019 00:48:05 +0800 Ready: True Restart Count: 0 Environment: Mounts: /usr/share/nginx/html from myappdata (rw) /var/run/secrets/kubernetes.io/serviceaccount from default-token-pwlvv (ro)Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True Volumes: myappdata: Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace) ClaimName: myappdata-myapp-4 ReadOnly: false default-token-pwlvv: Type: Secret (a volume populated by a Secret) SecretName: default-token-pwlvv Optional: falseQoS Class: BestEffortNode-Selectors: Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s node.kubernetes.io/unreachable:NoExecute for 300sEvents: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 84s default-scheduler Successfully assigned default/myapp-4 to node01 Warning Failed 69s kubelet, node01 Failed to pull image "ikubernetes/myapp:v2": rpc error: code = Unknown desc = Error response from daemon: Get https://registry-1.docker.io/v2/ikubernetes/myapp/manifests/v2: Get https://auth.docker.io/token?scope=repository%3Aikubernetes%2Fmyapp%3Apull&service=registry.docker.io: net/http: TLS handshake timeout Warning Failed 69s kubelet, node01 Error: ErrImagePull Normal BackOff 68s kubelet, node01 Back-off pulling image "ikubernetes/myapp:v2" Warning Failed 68s kubelet, node01 Error: ImagePullBackOff Normal Pulling 54s (x2 over 81s) kubelet, node01 Pulling image "ikubernetes/myapp:v2" ///版本已经变为v2 Normal Pulled 48s kubelet, node01 Successfully pulled image "ikubernetes/myapp:v2" Normal Created 48s kubelet, node01 Created container myapp Normal Started 48s kubelet, node01 Started container myapp
下面这两条命令意思是大于等于3的都更新为v2,也就是myapp-3,myapp-4的版本都更新为v2,
[root@master ~]# kubectl patch sts maypp -p '{"spec":{"updateStrategy":{"rollingUpdate":{"partition":3}}}}'[root@master ~]# kubectl set image sts/myapp myapp=ikubernetes/myapp:v2