美文网首页
k8s中statefulset资源类型的深入理解

k8s中statefulset资源类型的深入理解

作者: PENG先森_晓宇 | 来源:发表于2020-09-17 17:26 被阅读0次

    简介

    statefulset是为了解决有状态服务的问题,而产生的一种资源类型(deployment和replicaSets是解决无状态服务而设计的)。

    这里可能有人说,mysql是有状态服务吧,但我使用的是deploment资源类型,mysql的data数据通过pv的方式存储在第三方文件系统中,也能解决mysql数据存储问题。

    是的,如果你的mysql是单节点,使用deployment类型确实可以解决数据存储问题。但是如果你的有状态服务是集群,节点之间有主备或者主从之分,且每个节点分片存储的情况下,deployment则不适用这种场景,因为deployment不会保证pod的有序性,集群通常需要主节点先启动,从节点在加入集群,statefulset则可以保证,其次deployment资源的pod内的pvc是共享存储的,而statefulset下的pod内pvc是不共享存储的,每个pod拥有自己的独立存储空间,正好满足了分片的需求,实现分片的需求的前提是statefulset可以保证pod重新调度后还是能访问到相同的持久化数据。

    适用statefulset常用的服务有elasticsearch集群,mogodb集群,redis集群等等。

    应用场景

    • 稳定的不共享持久化存储:即每个pod的存储资源是不共享的,且pod重新调度后还是能访问到相同的持久化数据,基于pvc实现。
    • 稳定的网络标志:即pod重新调度后其PodName和HostName不变,且PodName和HostName是相同的,基于Headless Service来实现的。
    • 有序部署,有序扩展:即pod是有顺序的,在部署或者扩展的时候是根据定义的顺序依次依序部署的(即从0到N-1,在下一个Pod运行之前所有之前的pod必都是Running状态或者Ready状态),是基于init containers来实现的。
    • 有序收缩:在pod删除时是从最后一个依次往前删除,即从N-1到0.

    基于上面的特性,可以发现statefulset由以下几个部分组成:

    • 用于定义网络标志(DNS domain)的headless service
    • 用于创建pvc的volumeClaimTemplates
    • 具体的statefulSet应用

    简单示例

    创建一个headless service,service.yaml文件。

    kind: Service
    apiVersion: v1
    metadata:
      name: elasticsearch
      namespace: laravel
      labels:
        run: elasticsearch
    spec:
      clusterIp: None
      ports:
        - protocol: TCP
          name: web
          port: 9200
          targetPort: 9200
      selector:
        name: elasticsearch
    

    注意:该headless类型service和clusterIp类型的serivice有明显区别,spec下是clusterIp: None

    接着创建一个statefulSet的资源,statefulset.yaml文件。

    kind: statefulSet
    apiVersion: extensions/v1beta1
    metadata:
      name: elasticsearch
      namespace: laravel
      labels:
        name: elasticsearch
    spec:
      serviceName: elasticsearch
      replicas: 2
      template:
        metadata:
          labels:
            name: elasticsearch
        spec:
          containers:
            - name: elasticsearch
              image: elasticsearch:6.8.9
              ports:
                - name: elasticsearch-port
                  containerPort: 9200
                  protocol: TCP
              volumeMounts:
                - name: elasticsearch-pvc
                  mountPath: "/usr/share/elasticsearch/data"
          volumesClaimTemplates:
            - metadata:
                name: elasticsearch-pvc
                annotations:
                  volume.beta.kubernetes.io/storage-class: "managed-nfs-storage"
              spec:
                accessModes: [ "ReadWriteMany" ]
                resources:
                  requests:
                    storage: 1Gi
    

    可以注意到statefulset资源pvc的创建是使用的volumesClaimTemplates,会在俩个pod中分别创建一个资源互相隔离的pvc。

    在spec相比deployment多了一个serviceName配置,该值就是对应的headless service。

    扩展

    • statefulset资源扩容
    kubectl scale statefulset elasticsearch --replicas=5
    
    • statefulset资源缩容
    kubectl patch statefulset elasticsearch -p '{"spec":{"replicas":3}}'
    
    • statefulset镜像更新
      目前不支持直接更新image,需要配个patch来间接实现
    kubectl patch statefulset elasticsearch --type='json' -p='[{"op":"replace","path":"/spec/template/spec/containers/0/image","value":"elasticsearch:7.9.0"}]'
    
    • 删除statefulset和service
    kubectl delete statefulset elasticsearch
    kubectl delete service elasticsearch
    

    删除statefulset后,pvc不会自动删除需要我们手动删除

    更新statefulset

    v1.7+支持statefulset的自动更新,通过spec.updateStrategy设置更新策略,目前支持俩种策略:

    • OnDelete:默认方式,当spec.template更新时,并不立即删除旧的pod,而是等待用户手动删除旧的pod后自动创建新的pod。兼容v1.6版本的行为。
    • RollingUpdate: 当spec.template更新时,自动删除旧的pod并创建新的pod替换。在更新时,这些pod是按照逆序的方式进行,依次删除,创建并等待pod变成ready状态才进行下一个pod的更新。

    partitions设置

    RollingUpdate更新策略还支持Partitions,通过spec.updateStategy.rollingUpdate.partition来设置。当partition设置后,只有序号大于或者等于partition的pod会在spec.templdate更新的时候滚动更新,而其他pod则保持不变(即便是删除后也是使用以前版本重新创建)。

    pod管理策略

    v1.7+可以通过.spec.podManagementPolicy设置pod的管理策略,支持以下俩中方式

    • OrderedReady:默认方式,按照pod的次序依次创建每个pod并等待ready之后才创建后面的pod。
    • Parallel:并行创建或删除pod,和deployment类型的pod一样。(不等待前面的pod ready就开始创建所有的pod)。

    总结

    使用statefulset资源类型的服务通常有以下几点特点

    • 有状态服务
    • 多节点部署,集群部署
    • 节点有主从(备)之分。集群通常是主节点先运行,从节点后续运行并加入集群,这里就用statefulset资源的有序部署的特性
    • 节点之间数据分片存储,这里使用到了statefulSet资源的存储隔离的特性,以及保证pod重新调度后还是能访问到相同的持久化数据

    注意事项

    • 还在beta状态,需要v1.5以上才支持
    • 所有pod的volume必须使用pv或者storageclass,需要事先创建好
    • 为来保证数据安全,删除statefulset时不会删除pvc
    • statefulset需要一个headless service,需要在statefulset之前创建好

    相关文章

      网友评论

          本文标题:k8s中statefulset资源类型的深入理解

          本文链接:https://www.haomeiwen.com/subject/tqllyktx.html