• 六、K8S之StatefulSet


    StatefulSet

    一、概念

    Deployment一样StatefulSet也是中一种可以帮助我们部署和扩展Pod控制器,使用Deployment时多数时候不需要在意Pod的调度方式。如果需要关心Pod的部署顺序、对应持久化存储或者要求Pod拥有固定的网络标识时,就需要StatefulSet控制器来完成调度工作

    每个由StatefulSet创建出来的Pod都拥有一个序号(从0开始,启动完成才会进行下一个)和固定的网络标识。并且可以在yaml中定义添加**VolumeClaimTemplate**来声明Pod存储的PVC

    StatefulSet 对于需要满足以下一个或多个需求的应用程序很有价值:

    • 稳定的、唯一的网络标识符。
    • 稳定的、持久的存储。
    • 有序的、优雅的部署和扩缩。
    • 有序的、自动的滚动更新。

    二、使用

    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx
      labels:
        app: nginx
    spec:
      ports:
      - port: 80
        name: web
      clusterIP: None
      selector:
        app: nginx
    ---
    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: web
    spec:
      serviceName: "nginx"
      replicas: 2
      selector:
        matchLabels:
          app: nginx  # 使用标签选择器,筛选标签里有app等于nginx的pods
      template:
        metadata:
          labels:
            app: nginx  # 创建一个带有标签app=nginx的pods
        spec:
          containers:
          - name: nginx
            image: nginx:1.7.9
            ports:
            - containerPort: 80
              name: web
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    这里创建了一个StatefulSet对象,关联了带有app=nginx的pods,并且还指定了名为nginx的service

    为什么StatefulSet还需要指定service呢? service已经使用标签选择器选中了pods,StatefulSet通过关联 Service,可以为 StatefulSet 中的每个 Pod 分配一个稳定的网络标识(如 DNS 域名),使其可以从集群内和集群外进行访问。这种关联有助于实现有状态应用程序的可靠通信和外部访问。

    比如想访问上面的pod可以使用, 格式为:pod名称.service名称.命名空间.svc.集群后缀,但后面的可以简写,比如:

    ping  web-0.nginx
    
    • 1

    三、扩缩容

    3.1、使用命令直接扩容
    kubectl scale sts web --replicas=5
    
    • 1
    3.2、缩容
    kubectl scale sts web --replicas=3
    
    • 1

    缩容完后再看日志

    kubectl describe sts web
    
    
    ---------------------------------------------
      Type    Reason            Age    From                    Message
      ----    ------            ----   ----                    -------
      Normal  SuccessfulCreate  29m    statefulset-controller  create Pod web-0 in StatefulSet web successful
      Normal  SuccessfulCreate  29m    statefulset-controller  create Pod web-1 in StatefulSet web successful
      Normal  SuccessfulCreate  4m28s  statefulset-controller  create Pod web-2 in StatefulSet web successful
      Normal  SuccessfulCreate  4m26s  statefulset-controller  create Pod web-3 in StatefulSet web successful
      Normal  SuccessfulCreate  4m24s  statefulset-controller  create Pod web-4 in StatefulSet web successful
      Normal  SuccessfulDelete  10s    statefulset-controller  delete Pod web-4 in StatefulSet web successful
      Normal  SuccessfulDelete  3s     statefulset-controller  delete Pod web-3 in StatefulSet web successful
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    从日志里可以看出,StatefulSet的pods管理是有顺序

    四、更新

    4.1、普通更新

    先使用命令进行修改内容后保存

    kubectl edit sts web
    
    • 1

    statefulSet与depolyment的更新区别在于,statefulSet是有序的,按照倒叙进行一个一个的更新,看如下日志

    kubectl describe sts web
    
    ------------------------------------------
      Type    Reason            Age                       Message
      Normal  SuccessfulDelete  19s                   delete Pod web-2 in StatefulSet web successful
      Normal  SuccessfulCreate  18s (x2 over 10m)     create Pod web-2 in StatefulSet web successful
      Normal  SuccessfulDelete  16s                   delete Pod web-1 in StatefulSet web successful
      Normal  SuccessfulCreate  14s (x2 over 35m)     create Pod web-1 in StatefulSet web successful
      Normal  SuccessfulDelete  12s                   delete Pod web-0 in StatefulSet web successful
      Normal  SuccessfulCreate  11s (x2 over 35m)     create Pod web-0 in StatefulSet web successful
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    4.2、灰度更新/金丝雀发布

    这是一种逐步升级 StatefulSet 的策略,它可以在不影响整个应用程序的情况下测试新版本的 Pod,并逐步将新版本的 Pod 逐步引入到应用程序中。

    下面我们将操作一个场景,目前有三个nginx版本为1.9.1的pod,我们需要将这些pod切换成1.7.1的版本,但是不知道1.7.1版本是否有问题的情况下,我们需要先多扩展一个1.7.1的pod,如果这个1.7.1的没有问题了,我们就把另外所有的pod都换成这个版本

    修改内容

    kubectl edit sts web
    
    • 1

    修改部分

    
    # 将镜像换成1.7.1
    - image: nginx:1.7.1
    
    #  把partition 设置为 3,那么此时滚动更新时,只会更新那些 序号 >= 3 的 pod
    updateStrategy:
        rollingUpdate:
          partition: 3
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里,我们将partition设置为 3,而我们现在最大的pod序号是2(从0开始),所以这次修改内容并不会影响到原来的pod版本

    4.3、删除更新策略

    把更新模式设置为删除策略时,在更新 StatefulSet 配置文件时,不会触发pods的更新。相反,需要手动删除旧的pod,k8s才会创建一个新版本的Pod

    spec:
      updateStrategy:
        type: OnDelete  # 或 RollingUpdate
    
    • 1
    • 2
    • 3

    五、非级联删除

    当我们使用普通删除sts的命令时,会把下面的pods也删除了,如果我们只是想删除sts,不删下面的pods可以使用非级联删除命令

    kubectl delete sts web --cascade=false
    
    • 1
  • 相关阅读:
    RASP技术进阶系列(二):东西向Web流量的智能检测防御
    设计模式学习笔记 - 开源实战四(中):剖析Spring框架中用来支持扩展的设计模式
    Python Wordcloud报错:Only supported for TrueType fonts,多种解决方案
    bson数据通过BulkOperations批量入库mongo表报重复ID处理
    【案例卡】clickhouse:多行数据拼接在一行
    如果需要在Log4j中记录特定的异常信息,应该如何实现?如何动态地更改Log4j的日志级别?
    如何利用ChatGPT进行论文撰写?
    【王道数据结构】第三章 栈和队列
    硬件大熊原创合集(2022/11更新)
    商城系统需求分析
  • 原文地址:https://blog.csdn.net/qq_39381892/article/details/133849042