ljzsdut
GitHubToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeToggle Dark/Light/Auto modeBack to homepage
Edit page

2.7 K8s控制器资源对象之 Stateful Set

六、StatefulSet

简称:sts

控制有状态的Pod的控制器

特征

StatefulSet一般用于管理具有以下特性的应用:

  • 要求有稳定且唯一的网络标识符,即Pod重新调度后,其PodName和HostName不变(Pod的IP会改变),基于Headless Service来实现。Pod名称一次是stsNAME-0、stsNAME-1、stsNAME-2...
  • 要求有稳定且持久的存储,即Pod重新调度后,还是能访问到相同的持久化数据。基于pvc来实现。
  • 要求有序、平滑的部署和扩展,即当spec.podManagementPolicy=OrderedReady时,Pod是有顺序的,在部署或扩展的时候要依据定义的顺序依次进行(即从0到N-1,在下一个Pod运行之前,所有之前的Pod必须是Running或Ready状态)。其他可选值:Parallel
  • 要求有序、平滑的终止和删除,即从N-1到0依次删除
  • 要求有序的滚动更新:比如MySQL主从要先更新从,再更新主

组件

StatefulSet一般有三个组件:

  • headless service

    • StatefulSet中的每个Pod的名称是固定的,而且是可以被解析的。headless service为Pod分配一个DNS域名作为识别Pod的唯一标识符,podName命名格式为stsNAME-0|1|2...。该名称的FQDN格式为podName.headlessServiceName[.nsName.svc.cluster.local] 。例如myapp-0.myapp-svc.default.svc.cluster.local,可以简写为podName.serviceName
    • StatefulSet使用Headless服务来控制Pod的域名,这个域名的FQDN格式为serviceName.nsName.svc.cluster.local
  • volumeClaimTemplate

    • StatefulSet中的每一个Pod都有自己的存储卷,它们不能共用一个存储卷 。VolumeClaimTemplate(卷声明模板)会为每一个Pod自动创建1个专有的volume。实现方式是:它根据声明的资源大小等信息为每一个Pod来先创建pvc并绑定pv,最后将pvc创建为volume。每个PVC的名称格式为VolumeClaimTemplateNAME-PodNAME,而且该名称是可以被dns解析。在下面的例子中,VolumeClaimTemplate会为每个Pod自动创建一个Volume(大小为2Gb)。
    • 因为Pod的名字是固定且唯一的,而且pvc的名字隐含了pod名字,实现volume与pod的关联映射。所以当Pod被调度到其他node节点上时,依然会根据pod名字选择相对应的volume,这就实现了数据与pod绑定。注意,当Pod或者StatefulSet被删除时,对应的PVC不会被删除,这个删除操作必须手动来执行(手动删除pvc后,pv会随之删除)。
  • StatefulSet控制器

    • StatefulSet由headless Service和volumeClaimTemplates组成。Service中的多个Pod将会被分别编号(为pod分配持久性DNS名称),并挂载volumeClaimTemplates中声明的pvc卷。注意svc必须在sts之前创建。Pod启动时会按照顺序启动、更新、逆序关闭。

    • sts中的volumeClaimTemplates在地位上相当于deployment中的pvc,实现了sc和pv的绑定。所以sts中无需使用pvc来进行sc和pv的绑定。

示例

apiVersion: v1
kind: Service
metadata:
  name: myapp-svc
  labels:
    app: myapp-svc
spec:
  ports:
  - name: web
    port: 80
  clusterIP: None #设置为None,表示启用headless Service
  selector:
    app: myapp-pod
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: myapp #会将pod的2个副本按顺序命名为myapp-0,myapp-1,并按照顺序启动、逆序关闭。
spec:
  serviceName: myapp-svc   #指定headless Service
  replicas: 2
  selector:
    matchLabels:
      app: myapp-pod
  updateStrategy:  #更新策略
    type: RollingUpdate
    rollingUpdate:
      partition: 0
  template:
    metadata:
      labels:
        app: myapp-pod
    spec:
      containers:
      - name: myapp   
        image: ikubernetes/myapp:v5
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: myappdata  #volumeClaimTemplates的名字
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:  #该模板作用:为每一个pod自动创建pvc、然后创建pvc类型的volume
  - metadata:
      name: myappdata   #为每个pod分配一个pvc,pvc名称为:volumeClaimTemplatesname-podname
    spec:
      accessModes:
      - "ReadWriteOnce"
      storageClassName: "nfs-sc-retain" #指定StorageClass实现自动创建pv,如果不指定,需要事先创建pv
      resources:
        requests:
          storage: 2Gi

支持扩缩容、动态更新、更新策略(分区更新:只允许pod的index≥N的进行更新)。