当创建statefulset资源后,k8s组件如何协作

本文分享自华为云社区《当创建StatefulSet后,k8s会发生什么?》,作者:可以交个朋友 。

一、StatefulSet介绍

StatefulSet 是用来管理有状态应用的工作负载对象,StatefulSet 管理基于相同容器规约的一组 Pod,使用持久标识符为工作负载Pod提供持久存储。和Deployment 类似,也属于副本控制器,但和Deployment不同的是, StatefulSet 为它们的每个 Pod 维护了一个有粘性的 ID。无论该类Pod的生命周期如何变化,每个 Pod 的标识符ID不会变化。另外还支持服务实例有序部署和扩展,并提供有状态应用程序所需的有序启动和终止策略。

StatefulSet工作负载之间使用Headless Service来定义Pod网路标识,生成可解析的DNS域名名称记录,用于同一StatefulSet工作负载彼此Pod之间的通信。

二、StatefulSet工作负载访问方式

与其他的工作负载(如Deployment)的对外访问方式相似,但有所区别。Deployent工作负载使用service(带有IP地址的服务)提供对外服务访问,但在一些特殊场景中,客户端访问不需要kubernetes中service实现的负载均衡功能,而是由客户端直接去发现/选择服务端的后端实例访问,就需要一种特殊的服务"Headless service"。这是一种没有访问入口(即service没有IP地址)的service。kube-proxy不会为这种类型的service(Headless service)创建iptables/ipvs转发规则。

yaml 复制代码
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:
  selector:
    matchLabels:
      app: nginx # 必须匹配 .spec.template.metadata.labels
  serviceName: "nginx"
  replicas: 3 # 默认值是 1
  minReadySeconds: 10 # 默认值是 0
  template:
    metadata:
      labels:
        app: nginx # 必须匹配 .spec.selector.matchLabels
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: nginx
        image: registry.k8s.io/nginx-slim:0.8
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "my-storage-class"
      resources:
        requests:
          storage: 1Gi

其中StatefulSet关联的pod与pvc、pv的关系如下图:

三、StatefulSet工作负载创建流程

  1. 用户使用通过kubectl客户端发起创建StatefulSet资源对象请求至api-server。

  2. api-server对请求用户鉴权、准入控制操作,然后将该请求事件写入到etcd存储中。

  3. 考虑到StatefulSet-controller采用非阻塞式长连接watch机制实时获取StatefulSet资源对象信息,一旦集群中有StatefulSet变化(包括创建、更新、删除),则通过api-server获取etcd中相关StatefulSet资源对象。

  4. api-server将StatefulSet资源返回给StatefulSet-controller的watch接口长连接。

  5. StatefulSet-controller维护StatefulSet的生命周期状态,并通过StatefulSet的模板确定副本数量,根据副本数量依序(0、1....N-1)创建Pod副本。

  6. api-server接收到StatefulSet-controller创建结果后,更新etcd存储中的StatefulSet状态信息和Pod创建事件。

四、StatefulSet-Controller工作原理

在StatefulSet中,Informer和Event Handler是两个重要的组件

  • **informer:**是一个Kubernetes API客户端,用于监视Kubernetes API中的资源对象的变化并更新到本地缓存中。当资源对象的状态发生变化时,Informer会触发Event Handler。
  • **Event Handler:**是一个回调函数,用于处理Informer发出的事件,Event Handler会根据事件的类型,执行相应的操作。
  • **Manage Revision:**用于标识StatefulSet的每个更新版本,通过Manage Revision,可以查看StatefulSet的更新历史,以便在需要时回滚到先前的版本。
  • Manger pods in order: 管理StatefulSet中pod的启动顺序,
  • Update in order: 有序的更新Pod。查看 Pod 期望的状态是否符合要求,不满足则删除重建,
  • **Update Status:**管理StatefulSet对象的更新状态。
  • replicas数组:存放可用Pod的ord值(Pod名称中ID标识符),(0 <= ord < Spec.replicas)
  • condemned数组:存放需要删除pod的ord值(Pod名称中ID标识符),(ord >= Spec.replicas)
  • 创建StatefulSet工作负载Pod实例

判断StatefulSet的管理策略:

  1. 若实例管理策略为并行策略,则遍历replicas数组,所有Pod同步创建,不区分启动先后顺序。
  2. 若实例管理策略为有序策略,遍历replicas数组,依序(0、1....N-1)创建Pod。需确保replicas数组中的前一个Pod处于runing或ready状态。方可创建下一个Pod。
  3. 最后检查Pod的信息是否与StatefulSet匹配,若不匹配则更新Pod的状态。如当前StatefulSet已关联Pod,但是Pod标签不匹配则释放Pod,重新新建Pod副本关联。

4.1 更新StatefulSet工作负载Pod实例

  1. 判断statefulset的更新策略:

  2. 如果更新策略为OnDelete,则不会自动触发更新行为,需要手动删除Pod,系统对其进行重建更新。

  3. 如果更新策略为RollingUpdate,则不再关注实例管理策略。都是按顺序进行处理且等待当前Pod删除成功后才继续小于上一个Pod顺序号的Pod。

  4. 最后检查Pod的信息是否与StatefulSet匹配,若不匹配则更新Pod的状态。如当前StatefulSet已关联Pod,但是Pod标签不匹配则释放Pod,重新新建Pod副本关联。

4.2 扩缩容StatefulSet工作负载Pod实例

扩容操作

  1. 更新statefulset的状态信息,将新建Pod的信息写入到replicas队列和condemned队列中。

  2. 遍历replicas数组,确保replicas数组中的Pod处于runing或ready状态。发现faild状态的Pod删除重建,对未创建的Pod则直接创建。

  3. 最后检查Pod的信息是否与StatefulSet匹配,若不匹配则更新Pod的状态。如当前StatefulSet已关联Pod,但是Pod标签不匹配则释放Pod,重新新建Pod副本关联。

缩容操作:

  1. 更新statefulset的状态信息。

  2. 遍历condemned数组,确保replicas数组中的Pod处于runing或ready状态。发现faild状态的Pod删除重建,对未创建的Pod则直接创建。然后按Pod名称标识符由大至小逆序删除condemned数组中若干个Pod

  3. 最后检查Pod的信息是否与StatefulSet匹配,若不匹配则更新Pod的状态。如当前StatefulSet已关联Pod,但是Pod标签不匹配则释放Pod,重新新建Pod副本关联。

4.3 删除StatefulSet工作负载Pod实例

如下processCondemned函数主要介绍删除StatefulSet工作负载Pod

kotlin 复制代码
func (ssc *defaultStatefulSetControl) processCondemned(ctx context.Context, set *apps.StatefulSet, firstUnhealthyPod *v1.Pod, monotonic bool, condemned []*v1.Pod, i int) (bool, error) {
	logger := klog.FromContext(ctx)
	if isTerminating(condemned[i]) {
		if monotonic {
			logger.V(4).Info("StatefulSet is waiting for Pod to Terminate prior to scale down",
				"statefulSet", klog.KObj(set), "pod", klog.KObj(condemned[i]))
			return true, nil
		}
		return false, nil
	}
	if !isRunningAndReady(condemned[i]) && monotonic && condemned[i] != firstUnhealthyPod {
		logger.V(4).Info("StatefulSet is waiting for Pod to be Running and Ready prior to scale down",
			"statefulSet", klog.KObj(set), "pod", klog.KObj(firstUnhealthyPod))
		return true, nil
	}
	if !isRunningAndAvailable(condemned[i], set.Spec.MinReadySeconds) && monotonic && condemned[i] != firstUnhealthyPod {
		logger.V(4).Info("StatefulSet is waiting for Pod to be Available prior to scale down",
			"statefulSet", klog.KObj(set), "pod", klog.KObj(firstUnhealthyPod))
		return true, nil
	}

	logger.V(2).Info("Pod of StatefulSet is terminating for scale down",
		"statefulSet", klog.KObj(set), "pod", klog.KObj(condemned[i]))
	return true, ssc.podControl.DeleteStatefulPod(set, condemned[i])
}
  1. 该函数首先判断需要删除的 Pod 是否正在终止中,如果是,则根据是否为Pod管理策略进行不同的处理。如果是有序策略,则会阻塞等待终止的 Pod 完全消失。如果不是有序策略,则直接返回,不做任何操作。

  2. 如果需要删除的 Pod 不是第一个不健康的 Pod,且当前Pod管理策略有序策略,则会阻塞等待其他不健康 Pod 变为 Running 和 Ready 状态或者变为 Available 状态。如果不是有序策略,则直接返回,不做任何操作。

  3. 最后,如果需要删除的 Pod 不处于终止中,且满足删除条件,则会执行删除操作,并返回 true。否则,直接返回 false。

点击关注,第一时间了解华为云新鲜技术~

相关推荐
虚伪的空想家7 小时前
rook-ceph配置dashboard代理无法访问
ceph·云原生·k8s·存储·rook
幽蓝计划8 小时前
HarmonyOS NEXT仓颉开发语言实战案例:动态广场
华为·harmonyos
Connie145112 小时前
k8s多集群管理中的联邦和舰队如何理解?
云原生·容器·kubernetes
幽蓝计划15 小时前
HarmonyOS NEXT仓颉开发语言实战案例:电影App
华为·harmonyos
伤不起bb16 小时前
Kubernetes 服务发布基础
云原生·容器·kubernetes
HMS Core17 小时前
HarmonyOS免密认证方案 助力应用登录安全升级
安全·华为·harmonyos
伍哥的传说17 小时前
鸿蒙系统(HarmonyOS)应用开发之手势锁屏密码锁(PatternLock)
前端·华为·前端框架·harmonyos·鸿蒙
国际云,接待18 小时前
微软服务器安全问题
运维·服务器·云原生·云计算·azure
funnycoffee12318 小时前
Huawei 6730 Switch software upgrade example版本升级
java·前端·华为
制造数字化方案研究院18 小时前
59页|PPT|华为集成服务交付ISD业务变革总体方案:业务规则、流程、IT、组织及度量“四位一体”的管理体系
运维·华为