Kubernetes — StatefulSet 管理与使用

目录

一、使用StatefulSet

1. Deployment 的特征

2、“有状态”的应用

3、创建有状态应用的三步骤

4、创建PV 和 PVC

5、创建StatefulSet

6、创建结果

7、创建 Headless 服务

8、使用有状态的服务

9、StatefulSet 的故障处理

1. 与无状态服务不同,有状态的StatefulSet 中一个Pod出现故障之后,可以看到

2.以web-1为例,模拟故障 

10、扩缩容和升级

 11、Pod管理策略


一、使用StatefulSet

1. Deployment 的特征

回顾Deployment,可以发现它有一些很有趣的特征,比如,所有Pod地位都是平等的,当一个Pod因故障被替换后,新的容器与其余所有Pod依然相同,因此无论请求发送到哪个Pod,返回的结果都是一致的。又或者Pod被删除后,里面的数据也随之消失

这种特性一般称其为“无状态”

2、“有状态”的应用

1. 有些情况下希望运行一些和上述不同的应用,包括使用持久化的存储,稳定的网络标志,Pod与Pod之间并不是完全平等(即使它们用同一个镜像创建)。

    这类服务通常称为“有状态”的服务,

    它的实现不在依靠ReplicaSet,而是用StatefulSet,它具备以下特性(支持多副本):

        稳定的持久化存储,Pod重新调度后访问相同的持久化数据,使用PVC来实现

        稳定的网络标识,Pod重新调度后PodName 和 HostName不变,

             基于Headless Service 实现

        Pod都有一个“序号”,可以有序的进行扩展,部署等操作

3、创建有状态应用的三步骤

参考资料: StatefulSet | Kubernetes

4、创建PV 和 PVC

1. 创建一批 PV

$ sudo mkdir /etc/exports.d /nfs{1..3}
$ sudo tee /etc/exports.d/s.exports <<EOF
/nfs1 *(rw,no_root_squash)
/nfs2 *(rw,no_root_squash)
/nfs3 *(rw,no_root_squash)
EOF
$ sudo apt -y install nfs-kernel-server
$ sudo systemctl enable --now nfs-server.service
showmount -e
Export list for k8s-master:
/nfs3 *
/nfs2 *
/nfs1 *
$ kubectl apply -f- <<EOF
apiVersion: v1
kind: PersistentVolume
metadata:
  name: mypv1
spec:
  storageClassName: my-sc    #定义了存储类型
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  nfs:
    path: /nfs1
    server: 192.168.5.100
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: mypv2
spec:
  storageClassName: my-sc
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  nfs:
    path: /nfs2
    server: 192.168.5.100
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: mypv3
spec:
  storageClassName: my-sc
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  nfs:
    path: /nfs3
    server: 192.168.5.100
EOF
$ kubectl get pv
NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
mypv1   1Gi        RWO            Recycle          Available           my-sc                   8s
mypv2   1Gi        RWO            Recycle          Available           my-sc                   8s
mypv3   1Gi        RWO            Recycle          Available           my-sc                   8s

参考资料: 持久卷 | Kubernetes

2. 在yaml 文件中定义 PVC 的模板,使系统在创建statefulset 时自动创建PVC

5、创建StatefulSet

1. 创建StatefulSet 时需要注意,

    serviceName 这一项的值必须要和后面创建的headless Service的名称一致

2. 另外matchLabels 参数和pod 的标签一致,这与deployment 相同

3. 上一步关于 volumeClaimTemplates 的配置也需要添加进 StatefulSet 配置 yaml

$ kubectl apply -f- <<EOF
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: nginx
  serviceName: nginx
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      terminationGracePeriodSeconds: 10    #删除pod的时间10s
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: stor
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: stor
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "my-sc"
      resources:
        requests:
          storage: 1Gi
EOF

参考资料: StatefulSet 基础 | Kubernetes

6、创建结果

1. 创建完成后,可以看到Pod名称按序号排序。如果查看日志,可以发现Pod的创建顺序是第一个创建完成之后再创建第二个,依次完成

$ watch -n 1 kubectl get pod
NAME    READY   STATUS    RESTARTS   AGE
`web-0` 1/1     Running   0          79s
`web-1` 1/1     Running   0          55s
`web-2` 1/1     Running   0          30s
<Ctrl-C>

2. 创建了三个PVC,名称同样以序号排序,依次和PV 做绑定

$ kubectl get pv
NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                STORAGECLASS   REASON   AGE
mypv1   1Gi        RWO            Recycle          Bound    default/stor-web-0   my-sc                   27m
mypv2   1Gi        RWO            Recycle          Bound    default/stor-web-1   my-sc                   27m
mypv3   1Gi        RWO            Recycle          Bound    default/stor-web-2   my-sc                   27m

$ kubectl get pvc
NAME         STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
stor-web-0   Bound    mypv1    1Gi        RWO            my-sc          2m51s
stor-web-1   Bound    mypv2    1Gi        RWO            my-sc          2m28s
stor-web-2   Bound    mypv3    1Gi        RWO            my-sc          2m1s

7、创建 Headless 服务

1. 创建 headless 服务,注意以下几点:

        ① 服务名称和 statefulset 中的定义一致

        ② 选择器要指向正确的Pod 标签

        ③ 指定 clusterIP:None(没有指定,DNS解析的就是每一个pod的IP)

kubectl apply -f- <<EOF  
apiVersion: v1
kind: Service
metadata:
  name: nginx    #服务名要和statefulset名要一致
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None    #headless
  selector:
    app: nginx
EOF
$ kubectl get service nginx
NAME    TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
nginx   ClusterIP   None         <none>        80/TCP    17s
$ kubectl apply -f- <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: clientpod
spec:
  containers:
    - name: clientpod
      image: busybox:1.28.3
      args:
      - /bin/sh
      - -c
      - sleep 3h
EOF
    
$ kubectl get pod clientpod     #确认pod已经运行
NAME        READY   STATUS    RESTARTS   AGE
clientpod   1/1     Running   0          2m15s

8、使用有状态的服务

1. 使用nslookup 查看 DNS 记录,可以看到对该服务的访问直接指向Pod

$ kubectl exec -it clientpod -- /bin/sh    #进入pod
/ # nslookup nginx    #解析nginx
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      nginx
Address 1: 172.16.194.83 web-0.nginx.default.svc.cluster.local
Address 2: 172.16.126.19 web-1.nginx.default.svc.cluster.local
Address 3: 172.16.194.84 web-2.nginx.default.svc.cluster.local

2. 通过对稳定的名称访问也始终可以访问到固定的Pod

/ # nslookup web-0.nginx
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      web-0.nginx
Address 1: 172.16.194.83 web-0.nginx.default.svc.cluster.local

9、StatefulSet 的故障处理

1. 与无状态服务不同,有状态的StatefulSet 中一个Pod出现故障之后,可以看到

虽然Pod的IP地址变化了,但通过不变的域名,依然可以访问到重建后的Pod

即使经过了故障和重建,Pod中保持在持久化存储(卷)中的数据依然存在

2.以web-1为例,模拟故障 

$ kubectl describe pod web-1
...输出省略...
    ClaimName:  'stor-web-1'
...输出省略...
$ kubectl get pv | grep stor-web-1    #查询所在pv
'mypv2'   1Gi        RWO            Recycle          Bound    default/stor-web-1   my-sc                   70m
$ kubectl describe pv mypv2 | grep -i path    #查看对应的路径
    Path:      '/nfs2'
$ sudo touch /nfs2/newfile    #创建文件

$ kubectl exec -it web-1 -- /bin/sh
# ls /usr/share/nginx/html    #查看文件已生成
newfile
$ kubectl get pod -o wide
NAME                                READY   STATUS      RESTARTS        AGE     IP              NODE          NOMINATED NODE   READINESS GATES
web-0                               1/1     Running     0               59m     172.16.194.83   k8s-worker1   <none>           <none>
web-1                               1/1     Running     0               59m     172.16.126.19   k8s-worker2   <none>           <none>
web-2                               1/1     Running     0               58m     172.16.194.84   k8s-worker1   <none>           <none>
$ kubectl delete pod web-1    #删除web-1,后会重新创建()
pod "web-1" deleted '与deployment区别,statefulset是有状态'
$ kubectl get pod web-1 -o wide    #查看web-1的IP已经变化
NAME    READY   STATUS    RESTARTS   AGE     IP              NODE          NOMINATED NODE   READINESS GATES
web-1   1/1     Running   0          3m29s   172.16.126.21   k8s-worker2   <none>           <none>

$ kubectl exec -it clientpod -- nslookup web-1.nginx    #依旧可以继续解析
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      web-1.nginx
Address 1: 172.16.126.21 web-1.nginx.default.svc.cluster.local
$ k exec -it web-1 -- ls /usr/share/nginx/html
newfile

10、扩缩容和升级

1. 当扩容StatefulSet时,

    可以看到Pod停止的顺序为从序号最高的开始降序终止,

    并且只有在前一个pod被完全终止后,下一个pod才开始终止。

    升级时,也是以相同顺序处理

2. 试验

$ watch -n 1 kubectl get pod    #检测pod状态

新打开一个终端

$ kubectl scale statefulset web --replicas=1    #缩容;依次从2-1删除
$ kubectl scale statefulset web --replicas=3    #扩容;依次1-2增加

 11、Pod管理策略

1. 对于某些分布式系统,StatefulSet 的顺序性保证是不必要的,或者是不应该出现的

    为了解决这个问题,在Kubernetes 1.7 中引入了podManagementPolicy

        ① OrderedReady Pod 管理策略

                statefulSets 的默认选项,保证顺序性

        ② Parallel Pod 管理策略

                并行启动、终止、升级、弹性伸缩Pod

                在变更一个Pod时不必等前一个Pod完成

2. 案例

$ kubectl delete statefulsets web    #删除statefulset
$ kubectl delete pvc stor-web-0 stor-web-1 stor-web-2    #删除pvc
$ kubectl get service nginx    #服务还在
NAME    TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
nginx   ClusterIP   None         <none>        80/TCP    61m
kiosk@k8s-master:~$ kubectl get pv     #pv还在
NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS     CLAIM                STORAGECLASS   REASON   AGE
mypv1   1Gi        RWO            Recycle          Released   default/stor-web-0   my-sc                   115m
mypv2   1Gi        RWO            Recycle          Released   default/stor-web-1   my-sc                   115m
mypv3   1Gi        RWO            Recycle          Released   default/stor-web-2   my-sc                   115m
$ kubectl apply -f- <<EOF
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: nginx
  serviceName: nginx
  # 增加 1 行
  podManagementPolicy: "Parallel" #平行
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: stor
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: stor
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "my-sc"
      resources:
        requests:
          storage: 1Gi
EOF

验证

$ watch -n 1 kubectl get pod    #动态查看pod状态

新打开终端

$ kubectl scale statefulset web --replicas=1
$ kubectl scale statefulset web --replicas=3

会发现扩缩容为同时进行

参考资料: StatefulSet 基础 | Kubernetes 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

*_花非人陌_*

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值