有状态副本集 (SS, Stateful Set) 作为 Controller 为 Pod 提供唯一的标识。它可以保证部署和 scale 的顺序。
StatefulSet 是为了解决有状态服务的问题(对应 Deployments 和 ReplicaSets 是为无状态服务而设计),其应用场景包括:
- 稳定的持久化存储,即 Pod 重新调度后还是能访问到相同的持久化数据,基于 PVC 来实现
- 稳定的网络标志,即 Pod 重新调度后其 PodName 和 HostName 不变,基于 Headless Service(即没有 Cluster IP 的 Service)来实现
- 有序部署,有序扩展,即 Pod 是有顺序的,在部署或者扩展的时候要依据定义的顺序依次依次进行(即从 0 到 N-1,在下一个 Pod 运行之前所有之前的 Pod 必须都是 Running 和 Ready 状态),基于 init containers 来实现
- 有序收缩,有序删除(即从 N-1 到 0)
从上面的应用场景可以发现,StatefulSet 由以下几个部分组成:
- 用于定义网络标志(DNS domain)的 Headless Service
- 用于创建 PersistentVolumes 的 volumeClaimTemplates
- 定义具体应用的 StatefulSet
StatefulSet 中每个 Pod 的 DNS 格式为statefulSetName-{0..N-1}.serviceName.namespace.svc.cluster.local,其中
serviceName为 Headless Service 的名字0..N-1为 Pod 所在的序号,从 0 开始到 N-1statefulSetName为 StatefulSet 的名字namespace为服务所在的 namespace,Headless Servic 和 StatefulSet 必须在相同的 namespace.cluster.local为 Cluster Domain
使用 Stateful Set
Stateful Set 适用于有以下某个或多个需求的应用:
- 稳定,唯一的网络标志。
- 稳定,持久化存储。
- 有序,优雅地部署和 scale。
- 有序,优雅地删除和终止。
- 有序,自动的滚动升级。
在上文中,稳定是 Pod (重新)调度中持久性的代名词。 如果应用程序不需要任何稳定的标识符、有序部署、删除和 scale,则应该使用提供一组无状态副本的 controller 来部署应用程序,例如 Deployment 或 ReplicaSet 可能更适合您的无状态需求。
yaml 示例
下面的示例中描述了 StatefulSet 中的组件。
- 一个名为 nginx 的 headless service,用于控制网络域。
- 一个名为 web 的 StatefulSet,它的 Spec 中指定在有 3 个运行 nginx 容器的 Pod。
- volumeClaimTemplates 使用 PersistentVolume Provisioner 提供的 PersistentVolumes 作为稳定存储。
apiVersion: v1kind: Servicemetadata:name: nginxlabels:app: nginxspec:ports:- port: 80name: webclusterIP: Noneselector:app: nginx---apiVersion: apps/v1beta1kind: StatefulSetmetadata:name: webspec:serviceName: "nginx"replicas: 3template:metadata:labels:app: nginxspec:terminationGracePeriodSeconds: 10containers:- name: nginximage: gcr.io/google_containers/nginx-slim:0.8ports:- containerPort: 80name: webvolumeMounts:- name: wwwmountPath: /usr/share/nginx/htmlvolumeClaimTemplates:- metadata:name: wwwannotations:volume.beta.kubernetes.io/storage-class: anythingspec:accessModes: ["ReadWriteOnce"]resources:requests:storage: 1Gi
