• k8s-StatefulSet控制器-十四


    一、StatefulSet概述

    RC、Deployment、DaemonSet都是面向无状态的服务,它们所管理的Pod的IP、名字,启停顺序等都是随机的,而StatefulSet管理所有有状态的服务,比如MySQL、MongoDB集群等。
    StatefulSet所管理的Pod拥有固定的Pod名称,启停顺序,在StatefulSet中,Pod名字称为网络标识(hostname),还必须要用到共享存储。
    在Deployment中,与之对应的服务是service,而在StatefulSet中与之对应的headless service,headless service,即无头服务,与service的区别就是它没有Cluster IP,解析它的名称时将返回该Headless Service对应的全部Pod的Endpoint列表。

      StatefulSet其应用场景包括:

    • 稳定的持久化存储,即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

    二、组件

      三个组件:headless service、StatefulSet、volumeClaimTemplate

      (1)headless service

    在deployment中,每一个pod是没有名称,是无序的;而statefulset中要求是必须有序的,每一个pod的名称必须是固定的。当节点挂了、删了,重建之后的标识符是不变的,每一个节点的节点名称是不能改变的。pod名称是作为识别pod的唯一标识符,必须保证其标识符的稳定持久有效;

    为了实现标识符的稳定唯一,就需要一个headless service 解析直达后端pod的ip地址,它还会还给每个pod配置一个唯一的名称。

      (2)volumeClaimTemplate

    大部分有状态副本集都会用到持久存储,但是因为数据是不一样的,每个节点都需要自己专用的存储。在deployment中pod模板中创建的存储卷是一个共享的存储卷,多个pod使用同一个存储卷,而statefulset作为面向有状态的服务,定义中的每一个pod都不能使用同一个存储卷,由此基于pod模板创建pod是不适用的,这就需要引入volumeClainTemplate,当在使用statefulset创建pod时,会自动生成一个PVC,从而请求绑定一个PV,从而有自己专用的存储卷。

    实验环境:四台主机  

        192.168.3.100   master
        192.168.3.101    node01
        192.168.3.102    node02
        192.168.3.103    store

     

      

    三、statefulSet使用

       查看资源定义清单字段:

      [root@master ~]# kubectl explain statefulset

      [root@master ~]# kubectl explain statefulset.spec
      KIND: StatefulSet
      VERSION: apps/v1

      RESOURCE: spec <Object>

      DESCRIPTION:
        Spec defines the desired identities of pods in this set.

        A StatefulSetSpec is the specification of a StatefulSet.

      FIELDS:

        podManagementPolicy <string>     #Pod管理策略
        replicas <integer>           #副本数量
        revisionHistoryLimit <integer>        #历史版本限制
        selector <Object> -required-          #选择器,必选项
        serviceName <string> -required-      #服务名称,必选项
        template <Object> -required-         #模板,必选项
        updateStrategy <Object>          #更新策略
        volumeClaimTemplates <[]Object>      #存储卷申请模板,列表对象形式

      1、创建pv

      先清除之前的pvc、pv、deploy、pod、svc...

      (1)pv资源定义清单:

      [root@master volumes]# vim pv-demo.yaml

      

      

      

      (2)创建

      [root@master volumes]# kubectl apply -f pv-demo.yaml

       

       (2)创建stateful

      (1)资源定义清单

      [root@master statefulset]# vim stateful-demo.yaml

      

      

      (2)创建

      [root@master statefulset]# kubectl apply -f stateful-demo.yaml

       

      查看:

      

      

      (3)删除

       现在有3个pod,删除的时候是从myapp-2开始进行删除的(2-1-0),关闭是逆向关闭(0-1-2);

       现在开两个连接,一个删pod,另一个监控pod状态;

       

      

      然后,现在开两个连接,一个创建pod,另一个监控pod状态;

       

      

      此时PVC不会删除,仍然是存在的,只要还是同一个statefulset,再重新创建pod时,依旧会重新去绑定原来的pvc;

       

      (3)滚动更新、扩展伸缩、版本升级

      (1)

       这里每一个pod的名称都是可以解析的;

       解析格式:

        pod_name.service_name.ns_name.cluster.local

      

      (2)pod的规模扩展、缩容

      扩展:顺序;

       [root@master statefulset]# kubectl scale sts myapp --replicas=5  #扩容至5个

       [root@master ~]# kubectl get pods -w  #动态监控pod,可见先创建myapp-3,再创建myapp-4

      

      

      缩容:逆序;

       [root@master statefulset]# kubectl patch sts myapp -p '{"spec":{"replicas":2}}'  #向配置文件打补丁的方式缩容,缩容至2个;

       

       

      (3)更新策略和版本升级

      查看资源定义清单字段:

      [root@master statefulset]# kubectl explain sts.spec.updateStrategy.rollingUpdate.partition

      以partition方式进行更新,如果更新值为2,只有myapp编号大于等于2的才会进行更新,实现类似于金丝雀部署方式,partition默认为0;

      更新时逆序进行;

      a、重新扩容至5个

      [root@master statefulset]# kubectl patch sts myapp -p '{"spec":{"replicas":5}}'

      

      b、修改更新策略

      [root@master ~]# kubectl patch sts myapp -p '{"spec":{"updateStrategy":{"rollingUpdate":{"partition":4}}}}'  #更新partition大于等于4的;

       c、更新版本

      [root@master ~]# kubectl set image sts/myapp myapp=ikubernetes/myapp:v2

       查看:

      

      

      可见,编号大于等于4的已经更新了,小于4的没有更新;

       (4)将剩余的其他Pod也更新版本

        只需要将更新策略的partition值改为0即可;

       [root@master ~]# kubectl patch sts myapp -p '{"spec":{"updateStrategy":{"rollingUpdate":{"partition":0}}}}'

       

      可见已经都已经更新;

  • 相关阅读:
    python3中try异常调试 raise 异常抛出
    基于 k8s-搭建 Kubernetes 的 web 管理界面
    PostgreSQL SERIAL创建自增列
    C++之同名覆盖、多态
    golang实现路由中间件middleware
    fastjson源码分析之序列化
    AJPFX实践 java实现快速排序算法
    AJPFX关于IO流的简单总结
    AJPFX关于多态中的动态绑定和静态绑定的总结
    关于java的arrays数组排序示例AJPFX的分享
  • 原文地址:https://www.cnblogs.com/weiyiming007/p/10338895.html
Copyright © 2020-2023  润新知