kubernetes Statefulset控制器

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: kubernetes Statefulset控制器

什么是StatefulSet?

StatefulSet是为了解决有状态服务的问题(Deployments和ReplicaSets专为无状态服务设计的)而设计,其应用场景包括

    1.稳定的持久化存储,即Pod重新调度后还是能访问到相同的持久化数据,基于PVC来实现
    2.稳定的网络标志,即Pod重新调度后其PodName和HostName不变,基于Headless Service(即没有Cluster IP的Service)来实现
    3.有序部署,有序扩展,即Pod是有顺序的,在部署或者扩展的时候要依据定义的顺序依次进行(即从0到N-1,在下一个Pod运行之前所有之前的Pod必须都是Running和Ready状态),基于init containers来实现
    4.有序收缩,有序删除(即从N-1到0)

    StatefulSet由哪几部分组成?

    从上面的应用场景可以发现,StatefulSet由以下几个部分组成

      1.通过Headless Service生成可解析的DNS记录
      2.通过volumeClaimTemplates创建pvc和对应的pv绑定
      3.定义StatefulSet来创建pod

      StatefulSet的yaml文件组成?

      StatefulSet中每个Pod的DNS格式为statefulSetName-{0..N-1}.serviceName.namespace.svc.cluster.local,其中

      1.serviceName为Headless Service的名字
      2.0..N-1为Pod所在的序号,从0开始到N-1
      3.statefulSetName为StatefulSet的名字
      4.namespace为服务所在的namespace,Headless Servic和StatefulSet必须在相同的namespace
      5..cluster.local为Cluster Domain

      学习Statefulset之后需要掌握如下

      1.如何创建 StatefulSet
      2.通过StatefulSet 怎样管理它的 Pod
      3.如何删除 StatefulSet
      4.如何对 StatefulSet 进行扩容/缩容
      5.如何更新一个 StatefulSet 的 Pod

      部署一个web应用

      作为开始,使用如下示例创建一个StatefulSet。它创建了一个Headless Service nginx 用来发布StatefulSet web中的Pod的IP地址。

      cat  statefulset.yaml

      apiVersion: v1
      kind: Service
      metadata:
        name: nginx
        labels:
          app: nginx
      spec:
        ports:
        - port: 80
          name: web
        clusterIP: None
        selector:
          app: nginx
      ---
      apiVersion: apps/v1beta1
      kind: StatefulSet
      metadata:
        name: web
      spec:
        serviceName: "nginx"
        replicas: 2
        template:
          metadata:
            labels:
              app: nginx
          spec:
            containers:
            - name: nginx
              image: nginx
              ports:
              - containerPort: 80
                name: web
              volumeMounts:
              - name: www
                mountPath: /usr/share/nginx/html
        volumeClaimTemplates:
        - metadata:
            name: www
          spec:
            accessModes: [ "ReadWriteOnce" ]
            resources:
              requests:
                storage: 1Gi

      为什么要使用volumeClaimTemplate?

      对于有状态应用都会用到持久化存储,比如mysql主从,由于主从数据库的数据是不能存放在一个目录下的,每个mysql节点都需要有自己独立的存储空间。而在deployment中创建的存储卷是一个共享的存储卷,多个pod使用同一个存储卷,它们数据是同步的,而statefulset定义中的每一个pod都不能使用同一个存储卷,这就需要使用volumeClainTemplate,当在使用statefulset创建pod时,会自动生成一个PVC,从而请求绑定一个PV,每一个pod都有自己专用的存储卷。Pod、PVC和PV对应的关系图如下:

      通过statefulset部署pod,并且观察pod创建的过程

      你需要使用两个终端窗口。在第一个终端中,使用kubectl get 来查看 StatefulSet的Pods的创建情况。

        kubectl get pods -w -l app=nginx

        在另一个终端中,使用

          kubectl  apply  -f  statefulset.yaml

          来创建定义在statefulset.yaml 中的 Headless Service 和 StatefulSet。

          上面的命令创建了两个Pod,每个都运行了一个NGINX web 服务器。获取 nginxService和web StatefulSet来验证是否成功的创建了它们。

          1.查看service

            kubectl get service nginx

            显示如下:

            NAME      CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE

            nginx           None                 80/TCP    12s

            2.查看statefulset

              kubectl get statefulset

              显示如下:

              NAME      DESIRED   CURRENT   AGE

              web             2              1              20s

              顺序创建Pod

              对于一个拥有N个副本的StatefulSet,Pod被部署时是按照{0..N-1}的序号顺序创建的。在第一个终端中使用 kubectl get检查输出。

                kubectl get pods -w -l app=nginx

                显示如下:

                NAME      READY     STATUS    RESTARTS   AGE

                web-0     0/1       Pending   0          0s

                web-0     0/1       Pending   0         0s

                web-0     0/1       ContainerCreating   0         0s

                web-0     1/1       Running   0         19s

                web-1     0/1       Pending   0         0s

                web-1     0/1       Pending   0         0s

                web-1     0/1       ContainerCreating   0         0s

                web-1     1/1       Running   0         18s

                请注意在 web-0 Pod 处于Running和Ready状态后 web-1 Pod才会被启动。

                StatefulSet中的Pod

                StatefulSet 中的 Pod 拥有一个唯一的顺序索引和稳定的网络身份标识

                检查 Pod 的顺序索引

                获取 StatefulSet 的 Pod。

                  kubectl get pods -l app=nginx

                  显示如下:

                  NAME      READY     STATUS    RESTARTS   AGE

                  web-0          1/1       Running          0         1m

                  web-1          1/1       Running           0          1m

                  如同StatefulSets概念中所提到的,StatefulSet中的Pod拥有一个具有黏性的、独一无二的身份标志。这个标志基于StatefulSet控制器分配给每个Pod的唯一顺序索引。Pod的名称的形式为-。webStatefulSet 拥有两个副本,所以它创建了两个 Pod:web-0 和 web-1

                  使用稳定的网络身份标识

                  每个Pod都拥有一个基于其顺序索引的稳定的主机名(statefulset创建的pod的主机名由statefulset的名称和有序索引组成),使用kubectl exec 在每个Pod中执行hostname

                  for i in 0 1; do kubectl exec web-$i -- sh -c 'hostname'; doneweb-0
                  web-1

                  使用kubectl run运行一个提供nslookup命令的容器,该命令来自于dnsutils包。通过对Pod的主机名执行nslookup,你可以检查他们在集群内部的DNS地址。

                    kubectl exec -it  web-1 -- /bin/bash
                    apt-get  install  dns-utils -y 
                    nslookup web-0.nginx.default.svc.cluster.local


                    在一个终端中查看StatefulSet的Pod。

                      kubectl get pod -w -l app=nginx

                      在另一个终端中使用 kubectl delete 删除StatefulSet中所有的Pod。

                        kubectl delete pod -l app=nginx

                        显示如下:

                        pod "web-0" deleted

                        pod "web-1" deleted

                        等待StatefulSet重启它们,并且两个Pod都变成Running和Ready状态。

                          kubectl get pod -w -l app=nginx

                          显示如下:

                          NAME      READY     STATUS                  RESTARTS      AGE

                          web-0     0/1          ContainerCreating      0                  0s

                          NAME      READY     STATUS                 RESTARTS        AGE

                          web-0     1/1       Running                         0                   2s

                          web-1     0/1       Pending                         0                   0s

                          web-1     0/1       Pending                         0                  0s

                          web-1     0/1     ContainerCreating          0                   0s    

                          web-1  1/1       Running                      0                  34s

                          使用 kubectl exec 和 kubectl run 查看 Pod 的主机名和集群内部的 DNS 表项

                            for i in 0 1; do kubectl exec web-$i -- sh -c 'hostname'; done

                            显示如下:

                            web-0

                            web-1

                            web-2

                              kubectl exec -it  web-1 -- /bin/bash
                                apt-get  install  dnsutils -y   #安装nslookup命令的
                                  nslookup web-0.nginx.default.svc.cluster.local

                                  Pod 的序号、主机名、SRV 条目和记录名称没有改变,但和 Pod 相关联的 IP 地址可能发生了改变。这就是为什么不要在其他应用中使用 StatefulSet 中的 Pod 的 IP 地址进行连接,这点很重要。如果你需要查找并连接一个 StatefulSet 的活动成员,你应该查询 Headless Service 的 CNAME。和 CNAME 相关联的 SRV 记录只会包含 StatefulSet 中处于 Running 和 Ready 状态的 Pod。如果你的应用已经实现了用于测试 liveness 和 readiness 的连接逻辑,你可以使用 Pod 的 SRV 记录(web-0.nginx.default.svc.cluster.local, web-1.nginx.default.svc.cluster.local)。因为他们是稳定的,并且当你的 Pod 的状态变为 Running 和 Ready 时,你的应用就能够发现它们的地址。

                                  域名对应的表格:


                                  导入稳定的存储

                                  获取 web-0web-1 的 PersistentVolumeClaims


                                    kubectl get pvc -l app=nginx

                                    显示如下:


                                    StatefulSet控制器创建了两个PersistentVolumeClaims,绑定到两个PersistentVolumes。NGINX web服务器默认会加载位于/usr/share/nginx/html/index.html的index文件。StatefulSets spec中的volumeMounts字段保证了 /usr/share/nginx/html 文件夹由一个 PersistentVolume 支持。将Pod的主机名写入它们的 index.html 文件并验证NGINX web服务器使用该主机名提供服务。

                                      for i in 0 1 2 ; do kubectl exec web-$i -- sh -c 'echo $(hostname) > /usr/share/nginx/html/index.html'; don


                                        for i in 0 1 2; do kubectl exec -it web-$i -- curl localhost; done

                                        显示如下:

                                        web-0

                                        web-1

                                        请注意,如果你看见上面的 curl 命令返回了403 Forbidden的响应,你需要像修改挂载的目录的权限:

                                          for i in 01 2; do kubectl exec web-$i -- chmod 755 /usr/share/nginx/html; done

                                          修改之后重新尝试上面的 curl 命令。

                                          相关实践学习
                                          通过Ingress进行灰度发布
                                          本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
                                          容器应用与集群管理
                                          欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
                                          相关文章
                                          |
                                          4月前
                                          |
                                          Kubernetes 容器 Perl
                                          【Azure K8S | AKS】在AKS中创建 StatefulSet 示例
                                          【Azure K8S | AKS】在AKS中创建 StatefulSet 示例
                                          |
                                          1月前
                                          |
                                          Kubernetes 监控 调度
                                          【赵渝强老师】K8s的DaemonSet控制器
                                          DaemonSet控制器确保每个节点上运行一个Pod副本,适用于监控、日志收集等场景。通过示例创建DaemonSet并查看Pod信息,展示了其自动扩展和回收的能力。视频讲解和代码示例详细说明了DaemonSet的使用方法和调度机制。
                                          |
                                          1月前
                                          |
                                          Kubernetes 调度 容器
                                          【赵渝强老师】K8s中Job控制器单工作队列的串行方式
                                          Kubernetes中的Job控制器用于管理一次性任务,确保任务完成后不再重启。本文介绍了Job的工作原理、运行方式及示例,包括创建Job、查看Job和Pod信息等步骤,并附有视频讲解。
                                          |
                                          1月前
                                          |
                                          Kubernetes 双11 容器
                                          【赵渝强老师】Kubernetes中的控制器
                                          Kubernetes通过控制器管理Pod的生命周期,以应对不同场景需求,如Deployment、DaemonSet、Job等。控制器可自动调整Pod数量和重启故障Pod,确保系统稳定运行。视频讲解和详细内容见下文。
                                          |
                                          1月前
                                          |
                                          Kubernetes 应用服务中间件 nginx
                                          【赵渝强老师】K8s中的Deployment控制器
                                          Kubernetes中的Deployment用于部署无状态应用程序,管理Pod的数量、更新方式和资源限制。通过创建和管理ReplicaSet,Deployment可以实现Pod的自动扩缩容、滚动更新和回滚。本文介绍了Deployment的基本概念,并通过一个具体的示例演示了如何使用Deployment创建、更新和管理Pod。
                                          |
                                          1月前
                                          |
                                          存储 Kubernetes 调度
                                          【赵渝强老师】K8s中Deployment控制器与StatefulSet控制器的区别
                                          K8s中的Deployment控制器用于管理无状态应用程序,关注Pod数量、更新方式等;而StatefulSets控制器则管理有状态应用程序,提供持久存储和唯一标识符,适用于需要稳定网络标识符和持久化存储的场景。两者的主要区别在于是否维护状态和顺序。
                                          |
                                          1月前
                                          |
                                          存储 Kubernetes 调度
                                          【赵渝强老师】K8s的有状态控制器StatefulSet
                                          在Kubernetes中,StatefulSets用于部署有状态应用程序,提供持久存储和唯一标识符。与Deployment不同,StatefulSets确保Pod的标识符在重新调度后保持不变,适用于需要稳定网络标识符和持久存储的场景。本文介绍了StatefulSets的创建、扩容与缩容、更新与回滚等操作,并提供了具体示例和视频讲解。
                                          |
                                          1月前
                                          |
                                          Kubernetes Linux 调度
                                          【赵渝强老师】K8s的周期性任务控制器CronJob
                                          本文介绍了K8s中的CronJob控制器,它类似于Linux的crontab命令,用于管理和调度定时作业。CronJob可以设置在未来某一时间运行作业一次或在指定时间点重复运行作业。文章通过一个示例展示了如何创建和使用CronJob控制器,包括创建配置文件、应用配置、查看Pod信息和日志等步骤。同时,还解释了CronJob的时间表示方式及其限制。
                                          |
                                          1月前
                                          |
                                          Kubernetes 调度 容器
                                          【赵渝强老师】K8s的Job控制器多工作队列的并行方式
                                          Kubernetes Job 是一次性任务控制器,用于控制 Pod 中的容器执行特定任务。本文介绍了 Job 控制器的工作原理、运行方式及多工作队列并行执行的示例。示例中创建了 5 个作业,以 3 个队列并行执行,整个过程需 2 分钟。文中还提供了详细的 YAML 文件配置和执行命令。
                                          |
                                          7月前
                                          |
                                          运维 Kubernetes 监控
                                          Kubernetes详解(十九)——Kubernetes Pod控制器
                                          Kubernetes详解(十九)——Kubernetes Pod控制器
                                          104 3