CoreOS: Operator

StatefulSet:

  cattle, pet

  PetSet -> StatefulSet

  1、稳定且唯一的网络标识符;

  2、稳定且持久的存储;

  3、有序、平滑的部署和扩展;

  4、有序、平滑的终止和删除;

  5、有序的滚动更新;

  三个组件:headless service、StatefulSet、volumeClaimTemplate

   pod_name.service_name.ns_name.svc.cluster.local

    myapp-0.myapp.default.svc.cluster.local

 

master:

[root@master manifests]# mkdir chapter9
[root@master manifests]# cd chapter9/
[root@master chapter9]# vim 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:v5
        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: 2Gi

stor01:

[root@stor01 ~]# showmount -e
Export list for stor01.smoke.com:
/data/volumes/v5 172.20.0.0/16
/data/volumes/v4 172.20.0.0/16
/data/volumes/v3 172.20.0.0/16
/data/volumes/v2 172.20.0.0/16
/data/volumes/v1 172.20.0.0/16

master:

[root@master chapter9]# kubectl get pv
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM           STORAGECLASS   REASON    AGE
pv001     2Gi        RWO,RWX        Retain           Available                                            2d
pv002     5Gi        RWO            Retain           Available                                            2d
pv003     20Gi       RWO,RWX        Retain           Available                                            2d
pv004     10Gi       RWO,RWX        Retain           Bound       default/mypvc                            2d
pv005     10Gi       RWO,RWX        Retain           Available                                            2d
[root@master chapter9]# kubectl get pvc
NAME      STATUS    VOLUME    CAPACITY   ACCESS MODES   STORAGECLASS   AGE
mypvc     Bound     pv004     10Gi       RWO,RWX                       2d
[root@master chapter9]# kubectl get pods
NAME                             READY     STATUS    RESTARTS   AGE
myapp-deploy-67f6f6b4dc-642hc    1/1       Running   0          10d
myapp-deploy-67f6f6b4dc-d4cpv    1/1       Running   0          10d
myapp-deploy-67f6f6b4dc-rqj8g    1/1       Running   0          10d
pod-cm-3                         1/1       Running   0          23h
pod-secret-1                     1/1       Running   0          58m
pod-vol-hostpath                 1/1       Running   0          6d
pod-vol-pvc                      1/1       Running   0          2d
tomcat-deploy-588c79d48d-6r8dw   1/1       Running   0          8d
tomcat-deploy-588c79d48d-cjlj9   1/1       Running   0          8d
tomcat-deploy-588c79d48d-r7nfq   1/1       Running   0          8d
[root@master chapter9]# kubectl delete pods pod-vol-pvc
[root@master chapter9]# kubectl delete pods/pod-cm-3 pods/pod-secret-1
[root@master configmap]# kubectl get deploy
NAME            DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
myapp-deploy    3         3         3            3           10d
tomcat-deploy   3         3         3            3           9d
[root@master configmap]# kubectl delete deploy/myapp-deploy deploy/tomcat-deploy
[root@master configmap]# kubectl get pv
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM           STORAGECLASS   REASON    AGE
pv001     2Gi        RWO,RWX        Retain           Available                                            2d
pv002     5Gi        RWO            Retain           Available                                            2d
pv003     20Gi       RWO,RWX        Retain           Available                                            2d
pv004     10Gi       RWO,RWX        Retain           Bound       default/mypvc                            2d
pv005     10Gi       RWO,RWX        Retain           Available                                            2d
[root@master configmap]# kubectl get pvc
NAME      STATUS    VOLUME    CAPACITY   ACCESS MODES   STORAGECLASS   AGE
mypvc     Bound     pv004     10Gi       RWO,RWX                       2d
[root@master configmap]# kubectl delete pvc/mypvc
[root@master configmap]# kubectl get pv
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM           STORAGECLASS   REASON    AGE
pv001     2Gi        RWO,RWX        Retain           Available                                            2d
pv002     5Gi        RWO            Retain           Available                                            2d
pv003     20Gi       RWO,RWX        Retain           Available                                            2d
pv004     10Gi       RWO,RWX        Retain           Released    default/mypvc                            2d
pv005     10Gi       RWO,RWX        Retain           Available                                            2d
[root@master configmap]# kubectl delete pv --all
[root@master configmap]# cd ../volumes/
[root@master volumes]# vim pv-demo.yaml 
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv001
  labels:
    name: pv001
spec:
  nfs:
    path: /data/volumes/v1
    server: stor01.smoke.com
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 5Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv002
  labels:
    name: pv002
spec:
  nfs:
    path: /data/volumes/v2
    server: stor01.smoke.com
  accessModes: ["ReadWriteOnce"]
  capacity:
    storage: 5Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv003
  labels:
    name: pv003
spec:
  nfs:
    path: /data/volumes/v3
    server: stor01.smoke.com
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 5Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv004
  labels:
    name: pv004
spec:
  nfs:
    path: /data/volumes/v4
    server: stor01.smoke.com
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 10Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv005
  labels:
    name: pv005
spec:
  nfs:
    path: /data/volumes/v5
    server: stor01.smoke.com
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 10Gi
[root@master volumes]# kubectl get pv
[root@master volumes]# kubectl apply -f pv-demo.yaml 
[root@master volumes]# kubectl get pv
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM     STORAGECLASS   REASON    AGE
pv001     5Gi        RWO,RWX        Retain           Available                                      57s
pv002     5Gi        RWO            Retain           Available                                      57s
pv003     5Gi        RWO,RWX        Retain           Available                                      57s
pv004     10Gi       RWO,RWX        Retain           Available                                      57s
pv005     10Gi       RWO,RWX        Retain           Available                                      57s
[root@master chapter9]# kubectl get svc
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)             AGE
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP             16d
myapp        ClusterIP   10.107.225.188   <none>        80/TCP              11d
tomcat       ClusterIP   10.103.159.201   <none>        8080/TCP,8009/TCP   9d
[root@master chapter9]# kubectl delete svc/myapp svc/tomcat
[root@master volumes]# cd ../chapter9/
[root@master chapter9]# kubectl explain sts
[root@master chapter9]# kubectl explain sts.spec
[root@master chapter9]# vim stateful-demo.yaml 
apiVersion: v1
kind: Service
metadata:
  name: myapp
  labels:
    app: myapp
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: myapp-pod
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: myapp
spec:
  serviceName: myapp
  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" ]
      resources:
        requests:
          storage: 5Gi
[root@master chapter9]# kubectl apply -f stateful-demo.yaml 
[root@master chapter9]# kubectl get svc
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   16d
myapp        ClusterIP   None         <none>        80/TCP    16s
[root@master chapter9]# kubectl get sts
NAME      DESIRED   CURRENT   AGE
myapp     3         3         1m
[root@master chapter9]# kubectl get pvc
NAME                STATUS    VOLUME    CAPACITY   ACCESS MODES   STORAGECLASS   AGE
myappdata-myapp-0   Bound     pv002     5Gi        RWO                           5m
myappdata-myapp-1   Bound     pv001     5Gi        RWO,RWX                       5m
myappdata-myapp-2   Bound     pv003     5Gi        RWO,RWX                       5m
[root@master chapter9]# kubectl get pv
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM                       STORAGECLASS   REASON    AGE
pv001     5Gi        RWO,RWX        Retain           Bound       default/myappdata-myapp-1                            42m
pv002     5Gi        RWO            Retain           Bound       default/myappdata-myapp-0                            42m
pv003     5Gi        RWO,RWX        Retain           Bound       default/myappdata-myapp-2                            42m
pv004     10Gi       RWO,RWX        Retain           Available                                                        42m
pv005     10Gi       RWO,RWX        Retain           Available                                                        42m
[root@master chapter9]# kubectl get pods
NAME               READY     STATUS    RESTARTS   AGE
myapp-0            1/1       Running   0          5m
myapp-1            1/1       Running   0          5m
myapp-2            1/1       Running   0          5m
pod-vol-hostpath   1/1       Running   0          7d
[root@master chapter9]# kubectl get pods -w
NAME               READY     STATUS    RESTARTS   AGE
myapp-0            1/1       Running   0          6m
myapp-1            1/1       Running   0          6m
myapp-2            1/1       Running   0          6m
pod-vol-hostpath   1/1       Running   0          7d
[root@master chapter9]# kubectl delete -f stateful-demo.yaml 
[root@master chapter9]# kubectl get pods -w    #删除一个个删除
NAME               READY     STATUS    RESTARTS   AGE
myapp-0            1/1       Running   0          6m
myapp-1            1/1       Running   0          6m
myapp-2            1/1       Running   0          6m
pod-vol-hostpath   1/1       Running   0          7d
myapp-1   1/1       Terminating   0         6m
myapp-0   1/1       Terminating   0         6m
myapp-2   1/1       Terminating   0         6m
myapp-1   0/1       Terminating   0         6m
myapp-0   0/1       Terminating   0         6m
myapp-2   0/1       Terminating   0         6m
myapp-1   0/1       Terminating   0         6m
myapp-1   0/1       Terminating   0         6m
myapp-0   0/1       Terminating   0         6m
myapp-0   0/1       Terminating   0         6m
myapp-2   0/1       Terminating   0         6m
myapp-2   0/1       Terminating   0         6m
[root@master chapter9]# kubectl get pods -w
NAME               READY     STATUS    RESTARTS   AGE
pod-vol-hostpath   1/1       Running   0          7d
[root@master chapter9]# kubectl apply -f stateful-demo.yaml 
[root@master chapter9]# kubectl get pods -w    #创建一个个创建
NAME               READY     STATUS    RESTARTS   AGE
pod-vol-hostpath   1/1       Running   0          7d
myapp-0   0/1       Pending   0         0s
myapp-0   0/1       Pending   0         0s
myapp-0   0/1       ContainerCreating   0         0s
myapp-0   1/1       Running   0         1s
myapp-1   0/1       Pending   0         0s
myapp-1   0/1       Pending   0         0s
myapp-1   0/1       ContainerCreating   0         0s
myapp-1   1/1       Running   0         2s
myapp-2   0/1       Pending   0         0s
myapp-2   0/1       Pending   0         0s
myapp-2   0/1       ContainerCreating   0         0s
myapp-2   1/1       Running   0         1s
[root@master chapter9]# kubectl delete -f stateful-demo.yaml 
[root@master chapter9]# kubectl get pods -w
NAME               READY     STATUS    RESTARTS   AGE
pod-vol-hostpath   1/1       Running   0          7d
myapp-0   0/1       Pending   0         0s
myapp-0   0/1       Pending   0         0s
myapp-0   0/1       ContainerCreating   0         0s
myapp-0   1/1       Running   0         1s
myapp-1   0/1       Pending   0         0s
myapp-1   0/1       Pending   0         0s
myapp-1   0/1       ContainerCreating   0         0s
myapp-1   1/1       Running   0         2s
myapp-2   0/1       Pending   0         0s
myapp-2   0/1       Pending   0         0s
myapp-2   0/1       ContainerCreating   0         0s
myapp-2   1/1       Running   0         1s
myapp-1   1/1       Terminating   0         3m
myapp-0   1/1       Terminating   0         3m
myapp-2   1/1       Terminating   0         3m
myapp-2   0/1       Terminating   0         3m
myapp-0   0/1       Terminating   0         3m
myapp-1   0/1       Terminating   0         3m
myapp-2   0/1       Terminating   0         3m
myapp-2   0/1       Terminating   0         3m
myapp-0   0/1       Terminating   0         3m
myapp-0   0/1       Terminating   0         3m
myapp-1   0/1       Terminating   0         3m
myapp-1   0/1       Terminating   0         3m
[root@master chapter9]# kubectl get pvc    #pvc不会删除,再创建继续绑定,持续存储
NAME                STATUS    VOLUME    CAPACITY   ACCESS MODES   STORAGECLASS   AGE
myappdata-myapp-0   Bound     pv002     5Gi        RWO                           19m
myappdata-myapp-1   Bound     pv001     5Gi        RWO,RWX                       19m
myappdata-myapp-2   Bound     pv003     5Gi        RWO,RWX                       19m
[root@master chapter9]# kubectl apply -f stateful-demo.yaml 
[root@master chapter9]# kubectl describe pods myapp-2 
Volumes:
  myappdata:
    Type:       PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
    ClaimName:  myappdata-myapp-2    #无论怎么创建都绑定同一个pvc
    ReadOnly:   false
  default-token-jrx89:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-jrx89
    Optional:    false
[root@master chapter9]# kubectl get pods
NAME               READY     STATUS    RESTARTS   AGE
myapp-0            1/1       Running   0          8m
myapp-1            1/1       Running   0          8m
myapp-2            1/1       Running   0          8m
pod-vol-hostpath   1/1       Running   0          7d
[root@master chapter9]# kubectl exec -it myapp-0 -- /bin/sh
/ # nslookup myapp-0.myapp.default.svc.cluster.local    #无头服务要跟上无头服务名称
nslookup: can't resolve '(null)': Name does not resolve

Name:      myapp-0.myapp.default.svc.cluster.local
Address 1: 10.244.1.44 myapp-0.myapp.default.svc.cluster.local
/ # nslookup myapp-1.myapp.default.svc.cluster.local
nslookup: can't resolve '(null)': Name does not resolve

Name:      myapp-1.myapp.default.svc.cluster.local
Address 1: 10.244.2.53 myapp-1.myapp.default.svc.cluster.local
/ # nslookup myapp-2.myapp.default.svc.cluster.local
nslookup: can't resolve '(null)': Name does not resolve

Name:      myapp-2.myapp.default.svc.cluster.local
Address 1: 10.244.1.45 myapp-2.myapp.default.svc.cluster.local
[root@master chapter9]# kubectl get pvc    #pvc名字都隐含了pod名字,所以使得可以持续为同一个pod所使用
NAME                STATUS    VOLUME    CAPACITY   ACCESS MODES   STORAGECLASS   AGE
myappdata-myapp-0   Bound     pv002     5Gi        RWO                           48m
myappdata-myapp-1   Bound     pv001     5Gi        RWO,RWX                       48m
myappdata-myapp-2   Bound     pv003     5Gi        RWO,RWX                       48m
[root@master chapter9]# kubectl get pods -w
[root@master chapter9]# kubectl scale sts myapp --replicas=5    #扩容为5个
[root@master ~]# cd manifests/chapter9/
[root@master chapter9]# kubectl get pods -w
NAME               READY     STATUS    RESTARTS   AGE
myapp-0            1/1       Running   0          23h
myapp-1            1/1       Running   0          23h
myapp-2            1/1       Running   0          23h
pod-vol-hostpath   1/1       Running   0          8d
myapp-3   0/1       Pending   0         0s
myapp-3   0/1       Pending   0         0s
myapp-3   0/1       Pending   0         0s
myapp-3   0/1       ContainerCreating   0         0s
myapp-3   1/1       Running   0         2s
myapp-4   0/1       Pending   0         0s
myapp-4   0/1       Pending   0         0s
myapp-4   0/1       Pending   0         0s
myapp-4   0/1       ContainerCreating   0         0s
myapp-4   1/1       Running   0         1s
[root@master chapter9]# kubectl get pvc
NAME                STATUS    VOLUME    CAPACITY   ACCESS MODES   STORAGECLASS   AGE
myappdata-myapp-0   Bound     pv002     5Gi        RWO                           23h
myappdata-myapp-1   Bound     pv001     5Gi        RWO,RWX                       23h
myappdata-myapp-2   Bound     pv003     5Gi        RWO,RWX                       23h
myappdata-myapp-3   Bound     pv004     10Gi       RWO,RWX                       43s
myappdata-myapp-4   Bound     pv005     10Gi       RWO,RWX                       41s
[root@master chapter9]# kubectl get pods -w
NAME               READY     STATUS    RESTARTS   AGE
myapp-0            1/1       Running   0          23h
myapp-1            1/1       Running   0          23h
myapp-2            1/1       Running   0          23h
myapp-3            1/1       Running   0          1m
myapp-4            1/1       Running   0          1m
pod-vol-hostpath   1/1       Running   0          8d
[root@master chapter9]# kubectl patch sts myapp -p '{"spec":{"replicas":2}}'    #缩减为2个pod
[root@master chapter9]# kubectl get pods -w
NAME               READY     STATUS    RESTARTS   AGE
myapp-0            1/1       Running   0          23h
myapp-1            1/1       Running   0          23h
myapp-2            1/1       Running   0          23h
myapp-3            1/1       Running   0          1m
myapp-4            1/1       Running   0          1m
pod-vol-hostpath   1/1       Running   0          8d
myapp-4   1/1       Terminating   0         3m
myapp-4   0/1       Terminating   0         3m
myapp-4   0/1       Terminating   0         3m
myapp-4   0/1       Terminating   0         3m
myapp-3   1/1       Terminating   0         3m
myapp-3   0/1       Terminating   0         3m
myapp-3   0/1       Terminating   0         3m
myapp-3   0/1       Terminating   0         3m
myapp-2   1/1       Terminating   0         23h
myapp-2   0/1       Terminating   0         23h
myapp-2   0/1       Terminating   0         23h
myapp-2   0/1       Terminating   0         23h
[root@master chapter9]# kubectl explain sts.spec
[root@master chapter9]# kubectl explain sts.spec.updateStrategy
[root@master chapter9]# kubectl explain sts.spec.updateStrategy.rollingUpdate
[root@master chapter9]# kubectl patch sts myapp -p '{"spec":{"replicas":5}}'
[root@master chapter9]# kubectl describe sts myapp
Update Strategy:    RollingUpdate

[root@master chapter9]# kubectl explain sts.spec
[root@master chapter9]# kubectl explain sts.spec.updateStrategy
[root@master chapter9]# kubectl explain sts.spec.updateStrategy.rollingUpdate
[root@master chapter9]# kubectl patch sts myapp -p '{"spec":{"updateStrategy":{"rollingUpdate":{"partition":4}}}}'    #修改更新策略分区为大于等于4
[root@master chapter9]# kubectl describe sts myapp
Update Strategy:    RollingUpdate
  Partition:        4
[root@master chapter9]# kubectl get pods -w
NAME               READY     STATUS    RESTARTS   AGE
myapp-0            1/1       Running   0          23h
myapp-1            1/1       Running   0          23h
myapp-2            1/1       Running   0          17m
myapp-3            1/1       Running   0          17m
myapp-4            1/1       Running   0          17m
pod-vol-hostpath   1/1       Running   0          8d
[root@master chapter9]# kubectl set image --help
[root@master chapter9]# kubectl set image sts/myapp myapp=ikubernetes/myapp:v2
[root@master chapter9]# kubectl get pods -w
NAME               READY     STATUS    RESTARTS   AGE
myapp-0            1/1       Running   0          23h
myapp-1            1/1       Running   0          23h
myapp-2            1/1       Running   0          17m
myapp-3            1/1       Running   0          17m
myapp-4            1/1       Running   0          17m
pod-vol-hostpath   1/1       Running   0          8d
myapp-4   1/1       Terminating   0         33m
myapp-4   0/1       Terminating   0         33m
myapp-4   0/1       Terminating   0         33m
myapp-4   0/1       Terminating   0         33m
myapp-4   0/1       Pending   0         0s
myapp-4   0/1       Pending   0         0s
myapp-4   0/1       ContainerCreating   0         0s
myapp-4   1/1       Running   0         1s
[root@master chapter9]# kubectl get sts -o wide
NAME      DESIRED   CURRENT   AGE       CONTAINERS   IMAGES
myapp     5         5         1d        myapp        ikubernetes/myapp:v2
[root@master chapter9]# kubectl get pods -o wide
NAME               READY     STATUS    RESTARTS   AGE       IP            NODE
myapp-0            1/1       Running   0          1d        10.244.1.44   node01.smoke.com
myapp-1            1/1       Running   0          1d        10.244.2.53   node02.smoke.com
myapp-2            1/1       Running   0          34m       10.244.2.55   node02.smoke.com
myapp-3            1/1       Running   0          34m       10.244.1.47   node01.smoke.com
myapp-4            1/1       Running   0          1m        10.244.1.49   node01.smoke.com
pod-vol-hostpath   1/1       Running   0          8d        10.244.2.43   node02.smoke.com
[root@master chapter9]# kubectl get pods myapp-4 -o yaml
status:
  conditions:
  - lastProbeTime: null
    lastTransitionTime: 2020-07-03T13:41:01Z
    status: "True"
    type: Initialized
  - lastProbeTime: null
    lastTransitionTime: 2020-07-03T13:41:02Z
    status: "True"
    type: Ready
  - lastProbeTime: null
    lastTransitionTime: null
    status: "True"
    type: ContainersReady
  - lastProbeTime: null
    lastTransitionTime: 2020-07-03T13:41:01Z
    status: "True"
    type: PodScheduled
  containerStatuses:
  - containerID: docker://a60ecec5422ab8751644714fbf12d630fae082de565ec421af7d18142c159d15
    image: ikubernetes/myapp:v2    #版本升级为v2
    imageID: docker-pullable://ikubernetes/myapp@sha256:85a2b81a62f09a414ea33b74fb8aa686ed9b168294b26b4c819df0be0712d358
    lastState: {}
    name: myapp
    ready: true
    restartCount: 0
    state:
      running:
        startedAt: 2020-07-03T13:41:02Z
  hostIP: 172.20.0.66
  phase: Running
  podIP: 10.244.1.49
  qosClass: BestEffort
  startTime: 2020-07-03T13:41:01Z
[root@master chapter9]# kubectl get pods myapp-3 -o yaml
status:
  conditions:
  - lastProbeTime: null
    lastTransitionTime: 2020-07-03T13:07:09Z
    status: "True"
    type: Initialized
  - lastProbeTime: null
    lastTransitionTime: 2020-07-03T13:07:11Z
    status: "True"
    type: Ready
  - lastProbeTime: null
    lastTransitionTime: null
    status: "True"
    type: ContainersReady
  - lastProbeTime: null
    lastTransitionTime: 2020-07-03T13:07:09Z
    status: "True"
    type: PodScheduled
  containerStatuses:
  - containerID: docker://e5fd6f3d53fe85c0919011204961c86335a33e65930363106f5dfc15e0b8991f
    image: ikubernetes/myapp:v1    #myapp-3还是v1
    imageID: docker-pullable://ikubernetes/myapp@sha256:9c3dc30b5219788b2b8a4b065f548b922a34479577befb54b03330999d30d513
    lastState: {}
    name: myapp
    ready: true
    restartCount: 0
    state:
      running:
        startedAt: 2020-07-03T13:07:11Z
  hostIP: 172.20.0.66
  phase: Running
  podIP: 10.244.1.47
  qosClass: BestEffort
  startTime: 2020-07-03T13:07:09Z
[root@master chapter9]# kubectl get pods myapp-0 -o yaml
status:
  conditions:
  - lastProbeTime: null
    lastTransitionTime: 2020-07-02T13:40:21Z
    status: "True"
    type: Initialized
  - lastProbeTime: null
    lastTransitionTime: 2020-07-02T13:40:22Z
    status: "True"
    type: Ready
  - lastProbeTime: null
    lastTransitionTime: null
    status: "True"
    type: ContainersReady
  - lastProbeTime: null
    lastTransitionTime: 2020-07-02T13:40:21Z
    status: "True"
    type: PodScheduled
  containerStatuses:
  - containerID: docker://589b75812a1e0e2e4e2cc2948390f8738c0d69fecc2283f9c7bbadfa4260dcb7
    image: ikubernetes/myapp:v1    myapp-0也是v1版本
    imageID: docker-pullable://ikubernetes/myapp@sha256:9c3dc30b5219788b2b8a4b065f548b922a34479577befb54b03330999d30d513
    lastState: {}
    name: myapp
    ready: true
    restartCount: 0
    state:
      running:
        startedAt: 2020-07-02T13:40:22Z
  hostIP: 172.20.0.66
  phase: Running
  podIP: 10.244.1.44
  qosClass: BestEffort
  startTime: 2020-07-02T13:40:21Z
[root@master chapter9]# kubectl get pods -w
NAME               READY     STATUS    RESTARTS   AGE
myapp-0            1/1       Running   0          1d
myapp-1            1/1       Running   0          1d
myapp-2            1/1       Running   0          44m
myapp-3            1/1       Running   0          44m
myapp-4            1/1       Running   0          10m
pod-vol-hostpath   1/1       Running   0          8d
[root@master chapter9]# kubectl patch sts myapp -p '{"spec":{"updateStrategy":{"rollingUpdate":{"partition":0}}}}'
[root@master chapter9]# kubectl get pods -w
NAME               READY     STATUS    RESTARTS   AGE
myapp-0            1/1       Running   0          1d
myapp-1            1/1       Running   0          1d
myapp-2            1/1       Running   0          44m
myapp-3            1/1       Running   0          44m
myapp-4            1/1       Running   0          10m
pod-vol-hostpath   1/1       Running   0          8d
myapp-3   1/1       Terminating   0         47m
myapp-3   0/1       Terminating   0         47m
myapp-3   0/1       Terminating   0         47m
myapp-3   0/1       Terminating   0         47m
myapp-3   0/1       Pending   0         0s
myapp-3   0/1       Pending   0         0s
myapp-3   0/1       ContainerCreating   0         0s
myapp-3   1/1       Running   0         1s
myapp-2   1/1       Terminating   0         47m
myapp-2   0/1       Terminating   0         47m
myapp-2   0/1       Terminating   0         47m
myapp-2   0/1       Terminating   0         47m
myapp-2   0/1       Pending   0         0s
myapp-2   0/1       Pending   0         0s
myapp-2   0/1       ContainerCreating   0         0s
myapp-2   1/1       Running   0         2s
myapp-1   1/1       Terminating   0         1d
myapp-1   0/1       Terminating   0         1d
myapp-1   0/1       Terminating   0         1d
myapp-1   0/1       Terminating   0         1d
myapp-1   0/1       Pending   0         0s
myapp-1   0/1       Pending   0         0s
myapp-1   0/1       ContainerCreating   0         0s
myapp-1   1/1       Running   0         1s
myapp-0   1/1       Terminating   0         1d
myapp-0   0/1       Terminating   0         1d
myapp-0   0/1       Terminating   0         1d
myapp-0   0/1       Terminating   0         1d
myapp-0   0/1       Pending   0         0s
myapp-0   0/1       Pending   0         0s
myapp-0   0/1       ContainerCreating   0         0s
myapp-0   1/1       Running   0         2s
[root@master chapter9]# kubectl get pods -o wide 
NAME               READY     STATUS    RESTARTS   AGE       IP            NODE
myapp-0            1/1       Running   0          3m        10.244.1.51   node01.smoke.com
myapp-1            1/1       Running   0          3m        10.244.2.57   node02.smoke.com
myapp-2            1/1       Running   0          3m        10.244.2.56   node02.smoke.com
myapp-3            1/1       Running   0          4m        10.244.1.50   node01.smoke.com
myapp-4            1/1       Running   0          17m       10.244.1.49   node01.smoke.com
pod-vol-hostpath   1/1       Running   0          8d        10.244.2.43   node02.smoke.com
[root@master chapter9]# curl 10.244.1.51
<html>
<head><title>403 Forbidden</title></head>
<body bgcolor="white">
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.12.2</center>
</body>
</html>
[root@master chapter9]# curl 10.244.1.51/hostname.html
myapp-0
[root@master chapter9]# kubectl get pods myapp-0 -o yaml
status:
  conditions:
  - lastProbeTime: null
    lastTransitionTime: 2020-07-03T13:55:03Z
    status: "True"
    type: Initialized
  - lastProbeTime: null
    lastTransitionTime: 2020-07-03T13:55:05Z
    status: "True"
    type: Ready
  - lastProbeTime: null
    lastTransitionTime: null
    status: "True"
    type: ContainersReady
  - lastProbeTime: null
    lastTransitionTime: 2020-07-03T13:55:03Z
    status: "True"
    type: PodScheduled
  containerStatuses:
  - containerID: docker://b15c81fb898fa499e689469bda2d929e2bc2f6d9cdc121cf49a1095fee982538
    image: ikubernetes/myapp:v2   #已经是v2版本
    imageID: docker-pullable://ikubernetes/myapp@sha256:85a2b81a62f09a414ea33b74fb8aa686ed9b168294b26b4c819df0be0712d358
    lastState: {}
    name: myapp
    ready: true
    restartCount: 0
    state:
      running:
        startedAt: 2020-07-03T13:55:04Z
  hostIP: 172.20.0.66
  phase: Running
  podIP: 10.244.1.51
  qosClass: BestEffort
  startTime: 2020-07-03T13:55:03Z
[root@master chapter9]# kubectl get pods -o go-template={.status.containerStatuses[0].image}
{.status.containerStatuses[0].image}[root@master chapter9]# 
[root@master chapter9]# kubectl get pods -o go-template={status.containerStatuses[0].image}
{status.containerStatuses[0].image}[root@master chapter9]# 

kubernetes statefulset redis:

https://github.com/CommercialTribe/kube-redis/blob/develop/k8s/redis-node-statefulset.yaml

https://github.com/k8sdevopscookbook/src/commit/77a39cde468567bc68582b8bea38246c12675da1

master:

[root@master chapter9]# vim etcd-statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: etcd
  labels:
spec:
  serviceName: etcd
  # changing replicas value will require a manual etcdctl member remove/add
  #   # command (remove before decreasing and add after increasing)
  replicas: 3
  selector:
    matchLabels:
      app: etcd-member
  template:
    metadata:
      name: etcd
      labels:
        app: etcd-member
    spec:
      containers:
      - name: etcd
        image: "quay.io/coreos/etcd:v3.2.16"
        ports:
        - containerPort: 2379
          name: client
        - containerPort: 2380
          name: peer
        env:
        - name: CLUSTER_SIZE
          value: "3"
        - name: SET_NAME
          value: "etcd"
        volumeMounts:
        - name: data
          mountPath: /var/run/etcd
        command:
          - "/bin/sh"
          - "-ecx"
          - |
            IP=$(hostname -i)
            PEERS=""
            for i in $(seq 0 $((${CLUSTER_SIZE} - 1))); do
                PEERS="${PEERS}${PEERS:+,}${SET_NAME}-${i}=http://${SET_NAME}-${i}.${SET_NAME}:2380"
            done
            # start etcd. If cluster is already initialized the `--initial-*` options will be ignored.
            exec etcd --name ${HOSTNAME} \
              --listen-peer-urls http:/${IP}:2380 \
              --listen-client-urls http://${IP}:2379,http://127.0.0.1:2379 \
              --advertise-client-urls http://${HOSTNAME}.${SET_NAME}:2379 \
              --initial-advertise-peer-urls http://${HOSTNAME}.${SET_NAME}:2380 \
              --initial-cluster-token etcd-cluster-1 \
              --initial-cluster ${PEERS} \
              --initial-cluster-state new \
              --data-dir /var/run/etcd/default.etcd
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      storageClassName: gluster-dynamic
      accessModes:
        - "ReadWriteOnce"
      resources:
        requests:
          storage: 1Gi