前言:

 前面文中对通过DaemonSet、存储资源对象,实现了在指定节点中运行一个守护进程。

 在真实的业务场景中,部署的服务都是有状态的、且有数据需要持久化的;那么如何实现呢?

 那么接下来学习一种更加重要的资源——StatefulSets。

一、StatefulSets 介绍

  StatefulSet 是用来管理有状态应用的工作负载 API 对象。

  StatefulSet 用来管理某 Pod 集合的部署和扩缩, 并为这些 Pod 提供持久存储和持久标识符。

  与Deployment 类似,StatefulSet 管理基于相同容器规约的一组 Pod。但和 Deployment 不同的是,StatefulSet 为它们的每个 Pod 维护了一个有粘性的ID。这些 Pod 是基于相同的规约来创建的,但是不能相互替换:无论怎么调度,每个 Pod 都有一个永久不变的 ID。

  如果希望使用存储卷为工作负载提供持久存储,可以使用 StatefulSet 作为解决方案的一部分。 尽管 StatefulSet 中的单个 Pod 仍可能出现故障, 但持久的 Pod 标识符使得将现有卷与替换已失败 Pod 的新 Pod 相匹配变得更加容易。

 应用场景:

· StatefulSets 对于需要满足以下一个或多个需求的应用程序很有价值:

  • 稳定的、唯一的网络标识符。
  • 稳定的、持久的存储。
  • 有序的、优雅的部署和缩放。
  • 有序的、自动的滚动更新。

 使用限制:

  • 给定 Pod 的存储必须由 PersistentVolume 驱动 基于所请求的 storage class 来提供,或者由管理员预先提供。
  • 删除或者收缩 StatefulSet 并不会删除它关联的存储卷。 这样做是为了保证数据安全,它通常比自动清除 StatefulSet 所有相关的资源更有价值。
  • StatefulSet 当前需要无头服务 来负责 Pod 的网络标识。你需要负责创建此服务。
  • 当删除 StatefulSets 时,StatefulSet 不提供任何终止 Pod 的保证。 为了实现 StatefulSet 中的 Pod 可以有序地且体面地终止,可以在删除之前将 StatefulSet 缩放为 0。
  • 在默认 Pod 管理策略(OrderedReady) 时使用 滚动更新,可能进入需要人工干预 才能修复的损坏状态

二、StatefulSets使用方式

  • 创建StatefulSets

   创建StatefulSets的yaml格式:

apiVersion: apps/v1
kind: StatefulSet #StatefulSet类型
metadata:
  name: web #StatefulSet 名称
spec:
  #service名称
  serviceName: "nginx"
  #Pod数量
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  #Pod定义
  template:
    metadata:
      labels:
        app: nginx
    spec:
      #容器设置
      containers:
        - name: nginx
          #镜像名称
          image: nginx:1.9.6
          ports:
            - containerPort: 80
              name: web
          volumeMounts:
            #持久化存储名称
            - name: www
              mountPath: /usr/share/nginx/html
  #持久化存储定义
  volumeClaimTemplates:
    - metadata:
        #名称
        name: www
      spec:
        #访问方式
        accessModes: ["ReadWriteOnce"]
        #资源定义
        resources:
          requests:
            storage: 1Gi

  应用该yaml后Pod创建顺序如下:

>>kubectl apply -f web.yaml
service/nginx created
statefulset apps/web created

>>kubectl get pods -w -l app=nginx NAME READY STATUS RESTARTS AGE web-0 0/1 Pending 0 0s web-0 0/1 Pending 0 0s web-0 0/1 ContainerCreating 0 1s web-0 1/1 Running 0 3s web-1 0/1 Pending 0 0s web-1 0/1 Pending 0 0s web-1 0/1 ContainerCreating 0 0s web-1 1/1 Running 0 2s

  可见:StatefulSets中Pod顺序创建成功。  

  再查看下Nginx中持久化存储资源:

kubectl get pvc -l app=nginx
NAME        STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
www-web-0   Bound    pvc-c431e9d6-0dba-4c1d-ba83-b9f1d5b8824a   1Gi        RWO            standard       137m
www-web-1   Bound    pvc-58070d7f-9fec-4e28-b77b-b15fdf30c965   1Gi        RWO            standard       124m
  • 扩容/缩容StatefulSets

   StatefulSet策略:

    • 对于包含 N 个 副本的 StatefulSet,当部署 Pod 时,它们是依次创建的,顺序为 0..N-1
    • 当删除 Pod 时,它们是逆序终止的,顺序为 N-1..0
    • 在将缩放操作应用到 Pod 之前,它前面的所有 Pod 必须是 Running 和 Ready 状态。
    • 在 Pod 终止之前,所有的继任者必须完全关闭。

    扩容:StatefulSet 按序号索引顺序的创建每个 Pod,并且会等待前一个 Pod 变为 Running 和 Ready 才会启动下一个 Pod

#扩容Pod数量为4
>>kubectl scale sts web --replicas=4
statefulset.apps/web scaled

#查看pod变化
>>kubectl get pods -w -l app=nginx
NAME    READY   STATUS    RESTARTS   AGE
web-0   1/1     Running   0          53m
web-1   1/1     Running   0          53m
web-2   0/1     Pending   0          0s
web-2   0/1     Pending   0          0s
web-2   0/1     Pending   0          3s
web-2   0/1     ContainerCreating   0          3s
web-2   1/1     Running             0          6s
web-3   0/1     Pending             0          0s
web-3   0/1     Pending             0          0s
web-3   0/1     Pending             0          2s
web-3   0/1     ContainerCreating   0          2s
web-3   1/1     Running             0          4s    

    缩容:会按照与 Pod 序号索引相反的顺序每次删除一个 Pod。在删除下一个 Pod 前会等待上一个被完全关闭

#缩容为2个pod
>>kubectl scale -n default statefulset web --replicas=2

#查看Pod变化:
>>kubectl get pods -w -l app=nginx
NAME    READY   STATUS    RESTARTS   AGE
web-0   1/1     Running   0          59m
web-1   1/1     Running   0          59m
web-2   1/1     Running   0          4m30s
web-3   1/1     Running   0          4m24s
web-3   1/1     Terminating   0          7m23s
web-3   0/1     Terminating   0          7m24s
web-3   0/1     Terminating   0          7m25s
web-3   0/1     Terminating   0          7m25s
web-2   1/1     Terminating   0          7m31s
web-2   0/1     Terminating   0          7m32s
web-2   0/1     Terminating   0          7m33s
web-2   0/1     Terminating   0          7m33s

   注意:扩容时会根据设置自动创建久化存储资源(PVC)并关联到Pod,当缩容时,PVC不会同步删除。当再次扩容时;会自动绑定到之前的PVC上。   

  • StatefulSets更新策略

   更新策略由 StatefulSet API Object 的spec.updateStrategy 字段决定。这个特性能够用来更新一个 StatefulSet 中的 Pod 的 container images,resource requests,以及 limits,labels 和 annotations。 RollingUpdate滚动更新是 StatefulSets 默认策略。

   OnDelete:当 StatefulSet 的 .spec.updateStrategy.type 设置为 OnDelete 时,它的控制器将不会自动更新 StatefulSet 中的 Pod。 用户必须手动删除 Pod 以便让控制器创建新的 Pod,以此来对 StatefulSet 的 .spec.template 的变动作出反应

   滚动更新:RollingUpdate 更新策略对 StatefulSet 中的 Pod 执行自动的滚动更新。 在没有声明 .spec.updateStrategy 时,RollingUpdate 是默认配置。 当 StatefulSet 的 .spec.updateStrategy.type 被设置为 RollingUpdate 时, StatefulSet 控制器会删除和重建 StatefulSet 中的每个 Pod。 它将按照与 Pod 终止相同的顺序(从最大序号到最小序号)进行,每次更新一个 Pod。 它会等到被更新的 Pod 进入 Running 和 Ready 状态,然后再更新前一个

  • StatefulSets删除

   StatefulSet 同时支持级联和非级联删除。使用非级联方式删除 StatefulSet 时,StatefulSet 的 Pod 不会被删除。使用级联删除时,StatefulSet 和它的 Pod 都会被删除。

   StatefulSet 永远不会删除和一个 Pod 相关联的 PersistentVolumes。 当你重建这个 StatefulSet 并且重新启动了Pod时,它原本的 PersistentVolume 会被重新挂载

   非级联删除:Pod不会删除

#非级联删除statefulset
kubectl delete statefulset web --cascade=orphan

    查看状态:Pod信息,所有Pod依旧运行

   级联删除:StatefulSet 和它的 Pod 都会被删除

#级联删除
kubectl delete statefulset web

    查看状态:Pod逐步从Pod1->Pod0删除      

三、总结

  StatefulSet 是一种较常用的资源类型,能够稳定、有序的部署和扩缩Pod集合, 并为这些 Pod 提供持久存储和持久标识符。 

版权声明:本文为cwsheng原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/cwsheng/p/15086313.html