当创建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转发规则。
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工作负载创建流程

用户使用通过kubectl客户端发起创建StatefulSet资源对象请求至api-server。
api-server对请求用户鉴权、准入控制操作,然后将该请求事件写入到etcd存储中。
考虑到StatefulSet-controller采用非阻塞式长连接watch机制实时获取StatefulSet资源对象信息,一旦集群中有StatefulSet变化(包括创建、更新、删除),则通过api-server获取etcd中相关StatefulSet资源对象。
api-server将StatefulSet资源返回给StatefulSet-controller的watch接口长连接。
StatefulSet-controller维护StatefulSet的生命周期状态,并通过StatefulSet的模板确定副本数量,根据副本数量依序(0、1....N-1)创建Pod副本。
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的管理策略:
- 若实例管理策略为并行策略,则遍历replicas数组,所有Pod同步创建,不区分启动先后顺序。
- 若实例管理策略为有序策略,遍历replicas数组,依序(0、1....N-1)创建Pod。需确保replicas数组中的前一个Pod处于runing或ready状态。方可创建下一个Pod。
- 最后检查Pod的信息是否与StatefulSet匹配,若不匹配则更新Pod的状态。如当前StatefulSet已关联Pod,但是Pod标签不匹配则释放Pod,重新新建Pod副本关联。
4.1 更新StatefulSet工作负载Pod实例
判断statefulset的更新策略:
如果更新策略为OnDelete,则不会自动触发更新行为,需要手动删除Pod,系统对其进行重建更新。
如果更新策略为RollingUpdate,则不再关注实例管理策略。都是按顺序进行处理且等待当前Pod删除成功后才继续小于上一个Pod顺序号的Pod。
最后检查Pod的信息是否与StatefulSet匹配,若不匹配则更新Pod的状态。如当前StatefulSet已关联Pod,但是Pod标签不匹配则释放Pod,重新新建Pod副本关联。
4.2 扩缩容StatefulSet工作负载Pod实例
扩容操作:
更新statefulset的状态信息,将新建Pod的信息写入到replicas队列和condemned队列中。
遍历replicas数组,确保replicas数组中的Pod处于runing或ready状态。发现faild状态的Pod删除重建,对未创建的Pod则直接创建。
最后检查Pod的信息是否与StatefulSet匹配,若不匹配则更新Pod的状态。如当前StatefulSet已关联Pod,但是Pod标签不匹配则释放Pod,重新新建Pod副本关联。
缩容操作:
更新statefulset的状态信息。
遍历condemned数组,确保replicas数组中的Pod处于runing或ready状态。发现faild状态的Pod删除重建,对未创建的Pod则直接创建。然后按Pod名称标识符由大至小逆序删除condemned数组中若干个Pod
最后检查Pod的信息是否与StatefulSet匹配,若不匹配则更新Pod的状态。如当前StatefulSet已关联Pod,但是Pod标签不匹配则释放Pod,重新新建Pod副本关联。
4.3 删除StatefulSet工作负载Pod实例
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])
}
该函数首先判断需要删除的 Pod 是否正在终止中,如果是,则根据是否为Pod管理策略进行不同的处理。如果是有序策略,则会阻塞等待终止的 Pod 完全消失。如果不是有序策略,则直接返回,不做任何操作。
如果需要删除的 Pod 不是第一个不健康的 Pod,且当前Pod管理策略是有序策略,则会阻塞等待其他不健康 Pod 变为 Running 和 Ready 状态或者变为 Available 状态。如果不是有序策略,则直接返回,不做任何操作。
最后,如果需要删除的 Pod 不处于终止中,且满足删除条件,则会执行删除操作,并返回 true。否则,直接返回 false。
当创建statefulset资源后,k8s组件如何协作的更多相关文章
- 【Kubernetes】在K8s中创建StatefulSet
在K8s中创建StatefulSet 遇到的问题: 使用Deployment创建的Pod是无状态的,当挂在Volume之后,如果该Pod挂了,Replication Controller会再run一个 ...
- 在K8s中创建StatefulSet
在K8s中创建StatefulSet 遇到的问题: 使用Deployment创建的Pod是无状态的,当挂在Volume之后,如果该Pod挂了,Replication Controller会再run一个 ...
- Kubernetes学习之路(二十)之K8S组件运行原理详解总结
目录 一.看图说K8S 二.K8S的概念和术语 三.K8S集群组件 1.Master组件 2.Node组件 3.核心附件 四.K8S的网络模型 五.Kubernetes的核心对象详解 1.Pod资源对 ...
- k8s 组件介绍__单Master集群部署
参考链接:https://github.com/opsnull/follow-me-install-kubernetes-cluster kubernetes 概述 1.kubernetes 是什么 ...
- php私有组件以及创建自己的composer私有组件(packagist+git+composer)
1.私有组件 大多数时候我们使用的都是公开可用的开源组件,但有时候如果公司使用内部开发的PHP组件,而基于许可证和安全方面的问题不能将其开源,就需要使用私有组件.对Composer而言,这是小菜一碟. ...
- kubernets之statefulset资源
一 了解Statefulset 1.1 对比statefulset与RS以及RC的区别以及相同点 Statefulset是有状态的,而RC以及RS等是没有状态的 Statefulset是有序的,拥 ...
- 二十六、StatefulSet资源控制器
StatefulSet资源控制器 一.statefulset介绍 StatefulSet 是为了解决有状态服务的问题而设计的资源控制器. 匹配 Pod name ( 网络标识 ) 的模式为:(stat ...
- Spring源码学习-容器BeanFactory(一) BeanDefinition的创建-解析资源文件
写在前面 从大四实习至今已一年有余,作为一个程序员,一直没有用心去记录自己工作中遇到的问题,甚是惭愧,打算从今日起开始养成写博客的习惯.作为一名java开发人员,Spring是永远绕不过的话题,它的设 ...
- Mysql创建新用户后无法登录,提示 Access denied for user 'username'@'localhost' (using password: YES)
MySQL创建新用户后无法登录,提示 Access denied for user 'username'@'localhost' (using password: YES) ,多半是因为存在匿名用户, ...
- 自动帮助创建android资源xml文件的网站
自动帮助创建android资源xml文件的网站 http://android-holo-colors.com/ stack overflow上一个seekbar的例子: http://stackove ...
随机推荐
- 【Azure Developer】在App Service上放置一个JS页面并引用msal.min.js成功获取AAD用户名示例
问题描述 在App Service上放置一个JS页面并引用msal.min.js,目的是获取AAD用户名并展示. 问题解答 示例代码 <!DOCTYPE html> <html> ...
- 一些对dp突然的理解
突然想到了一些理解,感觉有些模糊,怕忘记,就赶紧记下来就是对于状态的设计 用01背包举例子吧,我们设计状态的时候一定是要保证所有可能在最后优秀的子状态在前面的时候是能够保留下来的也就是我们的状态设计要 ...
- .netCore 图形验证码,非System.Drawing.Common
netcore需要跨平台,说白点就是放在windows服务器要能用,放在linux服务器上也能用,甚至macos上. 很多时候需要使用到图形验证码,这就有问题了. 旧方案1.引入包 <Packa ...
- CF1368B
题目简化和分析: 因为要求长度最小,所以我们每个字符就应该发挥最大的价值,不会有没有作用的字符. 设有 \(x_1\) 个 \(c\) ,\(x_2\) 个 \(o\) ,\(x_3\) 个 \(d\ ...
- CF1526C1
题目简化和分析: 给您一个数组,在其中选择若干个数使得: 任意前缀和 \(\ge 0\) 数量尽可能的大 我们可以使用贪心策略,策略如下: 如果当前数为非负,必喝. 而毒药尽可能的多喝,如果喝没了,就 ...
- P4899 [IOI2018] werewolf 狼人 题解
P4899 [IOI2018] werewolf 狼人 题解 题目描述 省流: \(n\) 个点,\(m\) 条边,\(q\) 次询问,对于每一次询问,给定一个起点 \(S\) 和终点 \(T\) , ...
- 微软发布开源平台 Radius:高效构建、运行基于Dapr 云原生应用程序
Microsoft Azure 孵化团队很高兴地宣布[1]推出一个名为 Radius 的新开放应用程序平台,该平台将应用程序置于每个开发阶段的中心,重新定义应用程序的构建.管理和理解方式.Radius ...
- 小景的Dba之路--压力测试和Oracle数据库缓存
小景最近在做系统查询接口的压测相关的工作,其中涉及到了查询接口的数据库缓存相关的内容,在这里做一个汇总和思维发散,顺便简单说下自己的心得: 针对系统的查询接口,首次压测执行的时候TPS较低,平均响应时 ...
- 【Flutter】一文读懂混入类Mixin
[Flutter]一文读懂混入类Mixin 基本介绍 Mixin是一种有利于代码复用,又避免了多继承的解决方案. Mixin 是面向对象程序设计语言中的类,提供了方法的实现,其他类可以访问 Mixin ...
- Modbus转Profinet--TS-180 网关连接西门子 PLC 和工业称重仪表
项目 随着科技的高速发展,工业自动化行业对日益多样的称重需求越来越高,上海某公司在国内的一个 工业自动化项目中,监控中心系统需要远程实时采集工业称重仪表测量的各种称重参数.该系统使用的是 西门子 S7 ...