• StatefulSet
    • Using StatefulSets(使用StatefulSet)
    • Limitations(限制)
    • Components(组件)
    • Pod Selector(Pod选择器)
    • Pod Identity(Pod身份)
      • Ordinal Index(有序的索引)
      • Stable Network ID(稳定的网络ID)
      • Stable Storage(稳定的存储)
    • Deployment and Scaling Guarantees(部署和缩放保证)
      • Pod Management Policies(Pod管理策略)
        • OrderedReady Pod Management(OrderedReady的Pod管理)
        • Parallel Pod Management(并行 Pod管理)
    • Update Strategies(更新策略)
      • On Delete
      • Rolling Updates
        • Partitions(分区)
    • What’s next(下一步)
    • 原文
    • 很赞的博客

    StatefulSet

    StatefulSet有两个维度的抽象:

    • 拓扑状态:有时候多个实例之间并非对等关系,可能需要按顺序启动,又或者,某个Pod挂掉后,新创建的Pod必须和原先Pod的网络标识一样,这样,原先的访问者才可能使用访问原先Pod的方法,访问到新Pod。
    • 存储状态:即使Pod挂掉被重建,访问的存储应该是同一份。
    • 本质:StatefulSet是一种特殊的Deployment,只不过这个Deployment的Pod名称+编号固定,编号的顺序固定了Pod之间的拓扑关系;而编号对应的Persist Volume,绑定了Pod与持久化存储之间的关系。因此,Pod即使被重建,状态也不会改变。·

    StatefulSet是用于管理有状态应用的工作负载API对象。StatefulSet在1.8中是beta版本。

    管理Deployment以及一组 Pods 的伸缩,并为这些Pod的排序和唯一性提供保证。

    像 Deployment 一样,StatefulSet管理基于相同容器spec的Pod。与Deployment不同,StatefulSet会为每个Pod保留粘性身份。这些Pod是从相同的spec创建的,但不可互换:每个Pod都有一个持久化的标识符,即使重新调度也仍然会使用该标识符。

    StatefulSet与任何其他Controller的模式相同。您可在StatefulSet对象中定义期望状态,StatefulSet Controller会从当前状态进行必要的更新,从而达到期望状态。

    Using StatefulSets(使用StatefulSet)

    StatefulSet适用于以下场景:

    • 稳定、唯一的网络标识。
    • 稳定、持久化的存储。
    • 有序、优雅的部署和缩放(即:部署有顺序、扩展也有顺序)。
    • 有序、优雅的删除和终止。
    • 有序、自动的滚动更新。

    在上文中,“稳定”是Pod调度(重新调度)持久化的代名词。如果应用程序不需要任何稳定的标识符或有序部署、删除或缩放,则应该使用提供无状态副本的Controller部署应用。 诸如 Deployment 或者 ReplicaSet 可能更适合您的无状态需求。

    Limitations(限制)

    • StatefulSet是一个beta资源(处于Beta阶段的资源),在1.5之前的Kubernetes版本中不可用。
    • 与所有其他alpha/beta资源一样,可传给apiserver一个--runtime-config 选项来禁用StatefulSet。
    • 给定Pod的存储必须由 PersistentVolume Provisioner 根据请求的 storage class 提供,或由管理员预先设置。
    • 删除/缩容StatefulSet将不会删除与StatefulSet关联的Volume。这样做是为了确保数据安全性,这通常比自动清除StatefulSet所有相关资源更有价值。
    • StatefulSet目前需要一个 Headless Service 负责Pod的网络身份。您有责任创建此Service。

    Components(组件)

    下面的示例演示了StatefulSet的组件。

    • 名为nginx的Headless Service,用于控制网络域名。
    • 名为web的StatefulSet,它有一个Spec,表示有3个nginx副本。
    • volumeClaimTemplates将使用PersistentVolume Provisioner提供的 PersistentVolumes ,从而提供稳定的存储。
    1. kind: PersistentVolume
    2. apiVersion: v1
    3. metadata:
    4. name: pv-volume
    5. labels:
    6. type: local
    7. spec:
    8. storageClassName: manual
    9. capacity:
    10. storage: 10Gi
    11. accessModes:
    12. - ReadWriteOnce
    13. hostPath:
    14. path: "/mnt/data"
    15. ---
    16. kind: PersistentVolumeClaim
    17. apiVersion: v1
    18. metadata:
    19. name: pv-claim
    20. spec:
    21. storageClassName: manual
    22. accessModes:
    23. - ReadWriteOnce
    24. resources:
    25. requests:
    26. storage: 3Gi
    27. ---
    28. apiVersion: v1
    29. kind: Service
    30. metadata:
    31. name: nginx
    32. labels:
    33. app: nginx
    34. spec:
    35. ports:
    36. - port: 80
    37. name: web
    38. clusterIP: None
    39. selector:
    40. app: nginx
    41. ---
    42. apiVersion: apps/v1
    43. kind: StatefulSet
    44. metadata:
    45. name: web
    46. spec:
    47. selector:
    48. matchLabels:
    49. app: nginx # has to match .spec.template.metadata.labels
    50. serviceName: "nginx"
    51. replicas: 3 # by default is 1
    52. template:
    53. metadata:
    54. labels:
    55. app: nginx # has to match .spec.selector.matchLabels
    56. spec:
    57. terminationGracePeriodSeconds: 10
    58. containers:
    59. - name: nginx
    60. image: nginx
    61. ports:
    62. - containerPort: 80
    63. name: web
    64. volumeMounts:
    65. - name: task-pv-storage
    66. mountPath: /usr/share/nginx/html
    67. volumes:
    68. - name: task-pv-storage
    69. persistentVolumeClaim:
    70. claimName: task-pv-claim

    Pod Selector(Pod选择器)

    您必须设置StatefulSet的spec.selector 字段以匹配其.spec.template.metadata.labels 的Label。在Kubernetes 1.8之前, spec.selector 字段被默认为省略。 在1.8及更高版本中,如未指定匹配的Pod Selector将会导致在StatefulSet创建过程中验证错误。

    Pod Identity(Pod身份)

    StatefulSet Pod有唯一的身份,包括序数(ordinal)、稳定的网络标识和稳定的存储。 身份会绑定到Pod(具有粘性),不管Pod被调度到哪个Node上。

    Ordinal Index(有序的索引)

    对于一个有N个副本的StatefulSet,StatefulSet中的每个Pod将被分配一个整数序号,范围[0,N),并且唯一。

    Stable Network ID(稳定的网络ID)

    StatefulSet中的每个Pod,从StatefulSet的名称和Pod的序数派生其主机名。 构造的主机名的模式是 $(statefulset name)-$(ordinal) 。上面的例子中,将会创建名为web-0,web-1,web-2 的Pod。StatefulSet可以使用 Headless Service 来控制其Pod的域名。此Service管理的域名的格式为: $(service name).$(namespace).svc.cluster.local ,其中“cluster.local”是集群域名。在创建每个Pod时,它将会获得一个匹配的DNS子域,采用以下形式: $(podname).$(governing service domain) ,其中governing service由StatefulSet上的serviceName字段定义。

    以下是Cluster Domain、Service名称、StatefulSet名称以及如何影响StatefulSet的Pod的DNS名称的一些示例。

    Cluster Domain Service (ns/name) StatefulSet (ns/name) StatefulSet Domain Pod DNS Pod Hostname
    cluster.local default/nginx default/web nginx.default.svc.cluster.local web-{0..N-1}.nginx.default.svc.cluster.local web-{0..N-1}
    cluster.local foo/nginx foo/web nginx.foo.svc.cluster.local web-{0..N-1}.nginx.foo.svc.cluster.local web-{0..N-1}
    kube.local foo/nginx foo/web nginx.foo.svc.kube.local web-{0..N-1}.nginx.foo.svc.kube.local web-{0..N-1}

    请注意,除非 otherwise configured ,Cluster Domain将被设为cluster.local

    Stable Storage(稳定的存储)

    Kubernetes为每个VolumeClaimTemplate创建一个 PersistentVolume 。 在上面的nginx示例中,每个Pod将收到一个PersistentVolume,其中包含名为my-storage-class 的StorageClass和1 Gib的存储。如果未指定StorageClass,则将使用默认StorageClass。当一个Pod被重新调度到一个Node上时,它的volumeMounts 将挂载与其PersistentVolume Claims相关联的PersistentVolume。请注意,当Pod或StatefulSet被删除时,与Pod的PersistentVolume Claims相关联的PersistentVolumes不会被删除。这必须手动完成。

    Deployment and Scaling Guarantees(部署和缩放保证)

    • 对于具有N个副本的StatefulSet,当部署Pod时,它们将按从{0..N-1}的顺序创建。
    • 当Pod被删除时,它们按从{N-1..0}的顺序终止。
    • 在将扩容操作应用于Pod之前,它的所有“前辈”必须Running and Ready。
    • 在Pod终止之前,所有的“后辈”必须完全关闭。

    StatefulSet不应该将 pod.Spec.TerminationGracePeriodSeconds 设为0。这种做法是不安全,强烈不建议您这么做。 有关进一步说明,请参阅 force deleting StatefulSet Pods 。

    当创建上述的nginx示例时,将以web-0、web-1、web-2的顺序部署三个Pod。在web-0正在 Running and Ready ,web-1将不被部署,而在web-1 Running and Ready之前web-2将不被部署。 如果web-0失败,在web-1 Running and Ready之后,但在启动web-2之前,web-2将不会启动,直到web-0成功重启并Running and Ready。

    如果用户通过patch StatefulSet来scale部署的示例,例如设置replicas=1 ,则web-2将首先被终止。在web-2完全关闭和删除之前,web-1不会被终止。如果web-0失败发生在web-2终止并完全关闭之后、web-1终止之前,web-1将不会终止,除非web-0已经Running and Ready。

    Pod Management Policies(Pod管理策略)

    在Kubernetes 1.7及更高版本中,StatefulSet允许您放松其排序保证,同时通过.spec.podManagementPolicy 字段保留其唯一性和身份保证。

    OrderedReady Pod Management(OrderedReady的Pod管理)

    OrderedReady Pod管理是StatefulSet的默认值。 它实现了上述 行为。

    Parallel Pod Management(并行 Pod管理)

    Parallel Pod管理告诉StatefulSet Controller 并行启动或终止所有Pod,并且不要等待Pod在启动或终止另一个Pod之前变为“Running”和“Ready”或完全终止。

    Update Strategies(更新策略)

    在Kubernetes 1.7及更高版本中,StatefulSet的 .spec.updateStrategy 字段允许您配置和禁用StatefulSet中Pod的容器、标签、资源最小要求/最大限制、Annotation的滚动更新。

    On Delete

    OnDelete 更新策略实现了遗留(1.6和以前)的行为。 当 spec.updateStrategy 未指定时,这是默认策略。当StatefulSet的 .spec.updateStrategy.type 设置为OnDelete ,StatefulSet Controller将不会自动更新StatefulSet中的Pod。用户必须手动删除Pod以使Controller创建新的Pod,以反映对StatefulSet的.spec.template 进行的修改。

    Rolling Updates

    RollingUpdate更新策略为在StatefulSet中的Pod实现自动的滚动更新。当StatefulSet的.spec.updateStrategy.type设置为RollingUpdate 时,StatefulSet Controller将在StatefulSet中删除并重新创建每个Pod。它将按照Pod终止(从最大序号到最小)的顺序进行,每次更新一个Pod。 在更新其“前辈”之前,它将等待正在更新的Pod进入Running and Ready状态。

    Partitions(分区)

    可以通过指定 .spec.updateStrategy.rollingUpdate.partition 来对 RollingUpdate 更新策略进行分区。 如果指定了分区,则当StatefulSet的 .spec.template 更新时,具有大于或等于分区的序数的所有 .spec.template 被更新。具有小于分区的序数的所有Pods将不会更新,即使删除它们,也会使用以前的版本重新创建。 如果StatefulSet的 .spec.updateStrategy.rollingUpdate.partition 大于其 .spec.replicas ,则 .spec.replicas 更新将不会传播到其Pod。在大多数情况下,您不需要使用分区,但如果您想要进行阶段更新、金丝雀部署或执行分阶段发布,分区将非常有用。

    What’s next(下一步)

    • Follow an example of deploying a stateful application.
    • Follow an example of deploying Cassandra with Stateful Sets.

    原文

    https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/

    很赞的博客

    在K8s中创建StatefulSet:http://www.cnblogs.com/puyangsky/p/6677308.html