• kubernetes学习控制器之StatefulSet控制器


    StatefulSet介绍

    一、StatefulSet概述

    StatefulSet是用来管理stateful(有状态)应用的
    StatefulSet管理Pod时,确保Pod有一个按序增长的ID
    与Deployment最大的不同是StatefulSet始终将一系列不变的名字分配给Pod.这些Pod从一个模板创建,但是并不能相互替换

    二、StatefulSet使用场景

    对于有如下要求的应用程序,StatefulSet非常适用
    需要稳定、唯一的网络标识(dnsname)
    每个Pod始终对应各自的存储路径(PersistantVolumeClaimTemplate)
    按顺序的增加副本、减少副本,并在减少副本时执行清理
    安顺序自动的执行滚动更新

    如果一个应用不需要一个稳定的网络标识,或者不需要按顺序部署、删除、增加副本,应该用deployment(无状态)控制器

    三、StatefulSet的限制

    Pod的存储要么由storage clas对应的PersistentVolume Provisioner提供,要么由集群管理员事先创建

    删除或scale down一个StatefulSet将不会删除其对应的数据卷,这样保证数据安全

    删除StatefulSet时,将无法保证Pod正常终止.如果要按顺序优雅的终止StatefulSet中的Pod,可以在删除StatefulSet之前,将scale down 到0 

    当使用默认的Pod Management Policy(OrderedReady)进行滚动更新时,可能进入一个错误状态,并需要人工介入

    用一个StatefulSet实例深入了解

    创建StatefulSet实例

    一、下面是一个StatefulSet的例子,由如下内容组成:

    • 一个名为nginx-service的Headless service,用于控制网络域
    • 一个名为web的StatefulSet,副本为2
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-service    #headless service的名称
      labels:
        app: nginx   #自定义标签
    spec:
      ports:
      - port: 80
        name: web
      clusterIP: None
      selector:
        app: nginx   #关联app: nginx的pod
    ---
    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: web-d      #statefulset控制器的名称
    spec:
      selector:
        matchLabels:
          app: nginx    #关联app: nginx的pod进行控制
      serviceName: "nginx-service" #指定headless service
      replicas: 2
      template:
        metadata:
          labels:
            app: nginx  #pod的标签
        spec:
          terminationGracePeriodSeconds: 10
          containers:
          - name: nginx   #pod里容器的名称
            image: nginx:1.7.9
            ports:
            - containerPort: 80
              name: web

    二、Pod的标识

    StatefulSet中的Pod具备一个唯一标识,该标识由以下几部分组成

    • 序号
    • 稳定的网络标识
    • 稳定的存储

    2.1序号

    假设一个StatefulSet的副本数为N,其中每个Pod都会被分配一个需要,序号的取值范围从0开始,并且该需要在StatefulSet是唯一的.

    Pod的Name是StatefulSet的Name + 序号;比如这个配置文件里,有两个副本,第一个Pod的Name就是web-d-0,第二个Pod的Name就是web-d-1

    2.2稳定的网络ID

    1)StatefulSet中Pod的hostname格式为$(statefulSet name)-$(Pod序号),上面的例子将要创建2个Pod,第一个Pod的Name为:web-d-0,第二个Pod的Name为web-d-1

    2)StatefulSet可以使用Headless service来控制其Pod所在的域;该域(domain)的格式为: $(service name).$(namespace).svc.cluster.local;

    上面例子的域就是:nginx-service.defaule.svc.cluster.local

    3)StatefulSet中每个Pod都被分配一个dnsNmae,格式为:$(pod name).$(所在域)

    上面的例子 Pod的dnsName就是 web-d-0.nginx-server.default.svc.cluster.local,其他pod可以通过这个地址找到它

    2.3稳定的存储

    kubernetes为每一个VolumeClaimTemplate创建一份PersistentVolum(存储卷).在上面的例子中,每一个Pod都将由StorageClass(存储类)my-storage-class为其创建一个1GB大小的存储卷.

    • 当Pod或StatefulSet被删除时,其关联的PersistentVolumeClaim(存储卷声明)以及背后的PersistentVolume(存储卷)仍然存在
    • 如果相同的Pod或StatefulSet被再次创建,则新建的web-d-0的Pod扔将挂载到原来名为web-d-0的Pod所挂载的存储卷声明及存储卷
    • 这确保了web-d-0、web-d-1等,不管被删除多少次,都将"稳定"的使用各自的所对应的存储内容

    StatefulSet的部署和伸缩

    一、部署和伸缩StetafulSet时的执行顺序

    • 在创建一个副本数为 N 的 StatefulSet 时,其 Pod 将被按 {0 ... N-1} 的顺序逐个创建
    • 在删除一个副本数为 N 的 StatefulSet (或其中所有的 Pod)时,其 Pod 将按照相反的顺序(即 {N-1 ... 0})终止和删除
    • 在对 StatefulSet 执行扩容(scale up)操作时,新增 Pod 所有的前序 Pod 必须处于 Running(运行)和 Ready(就绪)的状态
    • 终止和删除 StatefulSet 中的某一个 Pod 时,该 Pod 所有的后序 Pod 必须全部已终止

    StatefulSet 中 pod.spec.terminationGracePeriodSeconds 不能为 0

    上面例子中StatefulSet被创建时:

    • Pod web-0、web-1、web-2 将被按顺序部署
    • web-0 处于 Running 和 Ready 状态之前,web-1 不会创建;web-1 处于 Running 和 Ready 状态之前,web-2 不会创建
    • 如果 web-1 已处于 Running 和 Ready 的状态,web-2 尚未创建,此时 web-0 发生了故障,则在 web-0 成功重启并达到 Running 和 Ready 的状态之前,web-2 不会创建
    • 如果用户对这个 StatefulSet 执行缩容(scale down)操作,将其副本数调整为 1,则:
      • web-2 将被首先终止;在 web-2 已终止并删除之后,才开始终止 web-1
      • 假设在 web-2 终止并删除之后,web-1 终止之前,此时 web-0 出现故障,则,在 web-0 重新回到 Running 和 Ready 的状态之前,kubernetes 将不会终止 web-1

    二、Pod管理策略

    • OrderedReady

      OrderedReady 是 .spec.podManagementPlicy 的默认值。其对 Pod 的管理方式已经在 部署和伸缩 StatefulSet 时的执行顺序 详细描述

    • Parallel

      .spec.podManagementPlicy 的取值为 Parallel,则 StatefulSet Controller 将同时并行地创建或终止其所有的 Pod。此时 StatefulSet Controller 将不会逐个创建 Pod,等待 Pod 进入 Running 和 Ready 状态之后再创建下一个 Pod,也不会逐个终止 Pod。

       注意:此选项只影响到伸缩(scale up/scale down)操作。更新操作不受影响。

    StatefulSet的更新策略

    On Delete

    如果StatefulSet的.spec.updateStrategy.type字段被设置为OnDelete,当修改.spce.template的内容时,StatefulSet Controller将不会自动更新Pod.必须得手动删除Pod,重新用修改的过得配置文件创建的时候,才会按照修改过得配置文件 创建Pod

    Rolling Updates

    .spec.updateStrategy字段的默认值是RollingUpdates,该策略为StatefulSet实现了Pod的自动滚动更新,在用户更新StatefulSet的.spec.template字段的时候,StatefulSet Controller将自动的删除并重建StatefulSet中的每个Pod,处理顺序如下:

        1)从序号最大的Pod开始,逐个删除和更新每一个Pod,直到序号最小的Pod被更新

        2)当正在更新的Pod达到了Running和Ready状态后,才继续更新其前序Pod

        Partitions参数:

            通过指定.spce.updateStrtegy.rollingUpdate.partition字段,可以分片(partitioned)执行rolling update更新策略;当更新StatefulSet的.spec.template时:

                ··序号大于或等于.spce.updateStrtegy.rollingUpdate.partition的Pod将被删除重建

                ··序号小于.spce.updateStrtegy.rollingUpdate.partition的Pod将不会更新,即使手工删除该Pod,kubernetes也会使用前一个版本的.spec.template重建该Pod

                ··如果.spce.updateStrtegy.rollingUpdate.partition大于.spec.replicas,更新.spec.template将不会影响任何Pod

                 大部分情况,都用不到.spce.updateStrtegy.rollingUpdate.partition参数,除非:执行预发布、执行金丝雀更新、执行按阶段更新

    参考以下文档:https://kuboard.cn/learning/k8s-intermediate/workload/wl-statefulset/#statefulset-%E6%A6%82%E8%BF%B0

  • 相关阅读:
    mockm remote 不能正常使用的解决方案
    uviewui 的 bug 当 url 的 query 参数中有 http://127.0.0.1/ 并且省略请求前缀的时候, 就会导致请求无法发送出去
    检查 nodmeon 是否可以修改文件后重启应用
    mocha 如何延迟指定时间后再运行所有用例
    使用 babel 编译 js 为 es5 支持 ie
    git 摘取提交
    Makefile学习笔记
    使用 Service Worker 缓解网站 DDOS 攻击
    如何热更新长缓存的 HTTP 资源
    网站图片无缝兼容 WebP/AVIF
  • 原文地址:https://www.cnblogs.com/chadiandianwenrou/p/11934700.html
Copyright © 2020-2023  润新知