【Linux39-12】Kubernetes存储之 StatefulSet 控制器通过 Headless Service 管理Pod、扩容/缩容


1. StatefulSet 控制器简介


StatefulSet 控制器官方文档:https://kubernetes.io/zh/docs/tutorials/stateful-application/basic-stateful-set/

StatefulSet 是用来管理有状态应用的工作负载 API 对象。
StatefulSet 用来管理 Deployment 和扩展一组 Pod,并且能为这些 Pod 提供序号唯一性保证。

和 Deployment 相同的是,StatefulSet 管理了基于相同容器定义的一组 Pod。但和 Deployment 不同的是,StatefulSet 为它们的每个 Pod 维护了一个固定的 ID。这些 Pod 是基于相同的声明来创建的,但是不能相互替换:无论怎么调度,每个 Pod 都有一个永久不变的 ID。

StatefulSet 和其他控制器使用相同的工作模式。你在 StatefulSet 对象 中定义你期望的状态,然后 StatefulSet 的 控制器 就会通过各种更新来达到那种你想要的状态。

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

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

在上面,稳定意味着 Pod 调度或重调度的整个过程是有持久性的。如果应用程序不需要任何稳定的标识符或有序的部署、删除或伸缩,则应该使用由一组无状态的副本控制器提供的工作负载来部署应用程序,比如 Deployment 或者 ReplicaSet 可能更适用于您的无状态应用部署需要。

给定 Pod 的存储必须由 PersistentVolume 驱动 基于所请求的 storage class 来提供,或者由管理员预先提供。

删除或者收缩 StatefulSet 并不会删除它关联的存储卷。这样做是为了保证数据安全,它通常比自动清除 StatefulSet 所有相关的资源更有价值。

StatefulSet 当前需要 headless 服务 来负责 Pod 的网络标识。您需要负责创建此服务。

当删除 StatefulSets 时,StatefulSet 不提供任何终止 Pod 的保证。为了实现 StatefulSet 中的 Pod 可以有序和优雅的终止,可以在删除之前将 StatefulSet 缩放为 0

在默认 Pod 管理策略(OrderedReady) 时使用 滚动更新,可能进入需要 人工干预 才能修复的损坏状态。

StatefulSet将应用状态抽象成了两种情况:

  • 拓扑状态:应用实例必须按照某种顺序启动。新创建的Pod必须和原来Pod的网络标识一样
  • 存储状态:应用的多个实例分别绑定了不同存储数据。

StatefulSet给所有的Pod进行了编号,编号规则是:$(statefulset名称)-$(序号),从0开始。

Pod被删除后重建,重建Pod的网络标识也不会改变,Pod的拓扑状态按照Pod的“名字+编号”的方式固定下来,并且为每个Pod提供了一个固定且唯一的访问入口,即Pod对应的DNS记录,同时重建时保证每个pod挂载到原来的卷上。

2. 创建无存储 StatefulSet 示例


2.1 创建 Headless service


创建目录:volumes/StatefulSet

在这里插入图片描述

#  service.yaml 
apiVersion: v1
kind: Service
metadata:
 name: nginx-svc
 labels:
  app: nginx
spec:
 ports:
 - port: 80
   name: web
 clusterIP: None
 selector:
  app: nginx

2.2 创建StatefulSet


  • 指定服务为创建的无头服务:nginx-svc

特点:

  • 指定StatefulSet名称为 web,pod命名自动为 web-数字编号
  • 发现名称根据副本个数依次排序,从 0 开始:web-0web-1web-2web-3
  • 上一个pod处于 Running和Ready 后再去创建下一个pod
  • 名称是它们的唯一标识

在这里插入图片描述

# pod.yml
apiVersion: apps/v1
kind: StatefulSet
metadata:
 name: web
spec:
 serviceName: "nginx-svc"
 replicas: 2
 selector:
  matchLabels:
   app: nginx
 template:
  metadata:
   labels:
    app: nginx
  spec:
   containers:
   - name: nginx
     image: myapp:v1
     ports:
     - containerPort: 80
       name: web

2.3 测试


检查pod在集群内部的地址: headless service 的 CNAME 指向 SRV 记录(记录每个 Running 和 Ready 状态的 Pod)。SRV 记录指向一个包含 Pod IP 地址的记录表项。

在这里插入图片描述

删除StatefulSet并重建,检查集群内部IP: 发现Pod 的序号、主机名、SRV 条目和记录名称没有改变,但和 Pod 相关联的 IP 地址发生了改变

在这里插入图片描述

kubectl delete -f pod.yml

3. StatefulSet 写入存储示例


3.1 创建 StatefulSet


  • 在【Linux39-11】中提供了动态pv

在这里插入图片描述

创建:StatefulSet 控制器创建了两个 PersistentVolumeClaims,绑定到两个 PersistentVolumes。(因为是动态pv,所有的 pv 都是自动创建和绑定的)

在这里插入图片描述

# 修改上一个pod.yml
apiVersion: apps/v1
kind: StatefulSet
metadata:
 name: web
spec:
 serviceName: "nginx-svc"
 replicas: 2
 selector:
  matchLabels:
   app: nginx
 template:
  metadata:
   labels:
    app: nginx
  spec:
   containers:
   - name: nginx
     image: myapp:v1
     ports:
     - containerPort: 80
       name: web
     volumeMounts:
       - name: www
         mountPath: /usr/share/nginx/html
 volumeClaimTemplates:
  - metadata:
     name: www
    spec:
     storageClassName: managed-nfs-storage
     accessModes:
     - ReadWriteOnce
     resources:
      requests:
       storage: 1Gi

3.2 测试


1)将主机名写入nfs服务器共享文件的测试页文件中

在这里插入图片描述

2)进入集群用 curl 命令测试

在这里插入图片描述

3)删除StatefulSet并重建,发现尽管内部IP变化,但测试页内容不变

虽然 web-0web-1 被重新调度了,但它们仍然继续监听各自的主机名,因为和它们的 PersistentVolumeClaim 相关联的 PersistentVolume 被重新挂载到了各自的 volumeMount 上。不管 web-0 和 web-1 被调度到了哪个节点上,它们的 PersistentVolumes 将会被挂载到合适的挂载点上


在这里插入图片描述
在这里插入图片描述

4. 扩容/缩容 StatefulSet


扩容/缩容 StatefulSet 指增加或减少它的副本数。通过更新 replicas 字段完成。

  • 控制器会按照与 Pod 序号索引相反的顺序每次删除一个 Pod。在删除下一个 Pod 前会等待上一个被完全关闭

0)弹缩StatefulSet之前,需先清楚是否能弹缩该应用

kubectl get statefulsets <stateful-set-name>

在这里插入图片描述

方式1: kubectl scale

kubectl scale statefulsets <stateful-set-name> --replicas=

在这里插入图片描述

方式2: kubectl patch

kubectl patch sts <stateful-set-name> -p '{"spec":{"replicas":3}}'

在这里插入图片描述

方式3: kubectl edit

kubectl edit statefulsets <stateful-set-name>

在这里插入图片描述
在这里插入图片描述

其他 StatefulSet 策略 查询官方文档

猜你喜欢

转载自blog.csdn.net/weixin_46069582/article/details/114646609