当创建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 ...
随机推荐
- Meteors 题解
Meteors 蒟蒻初学整体二分,写一篇题解记录一下思考与看法. 题目大意 在一个环形的轨道上分别着若干国家的空间站,在接下来的一段时间内会出现若干次陨石,每次出现在环形的某一段轨道,每个国家都想收集 ...
- C++中const和constexpr的多文件链接问题
C++语言支持分离编译,在多文件编程中:变量或函数可以被声明多次,但却只能被定义一次.如果要在多个文件中使用同一个变量,变量的定义能且只能出现在一个文件中,在其他使用该变量的文件中需要声明该变量.如果 ...
- C# WebBrowser document.execCommand()解析
// // Summary: // 对文档执行指定的命令. // // Parameters: ...
- Linux g++减小可执行文件大小
去掉参数-g,产生不带有调试信息的可执行文件 加上参数-O2,产生尽可能小和尽可能快的代码 strip 可执行文件 去掉目标文件中的一些符号表.调试符号表信息,以减小程序的大小 参考文献: g++重要 ...
- .Net Core3中微信退款证书本地调试正常读取证书,在服务器IIS中加载不到证书文件
如图,在开发微信退款功能时,需要用到微信提供的证书文件.本地开发调试时是正常的,但放到服务器(WinServer 2012 R2)中,则报错提示找不到文件. 网上找了一堆骚操作都没什么卵用,最后在其中 ...
- JZYZ作业好题
文章目录 敲砖块 Circle 敲砖块 首先把砖块向左对齐, 这样选择第 ( i , j ) (i,j) (i,j)块的前提是第 ( i − 1 , j ) , ( i − 1 , j + 1 ) ( ...
- 使用 Hexo 搭建个人博客并部署到云服务器
目录 1 整体流程 2. 本地环境准备 2.1 安装 Node.js 和 Git 2.2 安装 Hexo 3. 服务端环境准备 3.1 Nginx 环境配置 3.1.1 安装 Nginx 3.1.2 ...
- 计算网络之IPv6配置DHCP服务及acl
一.DHCPv6服务 DHCP即动态主机地址分配协议,在前面已经启动过IPv4的动态主机分配了, 还是来介绍两种方式 接口模式 全局模式 现在需要了解的就是DHCHv6,即基于IPv6的动态主机地址分 ...
- 轻松一刻|Walrus CLI与CI/CD工具集成,轻松部署2048游戏
Walrus 是一款开源的基于平台工程理念.以应用为中心.以完整应用系统自动化编排交付为目标进行设计开发的云原生应用平台,简化和自动化应用部署与发布流程并与现有的 CI/CD 流水线无缝集成.今天我们 ...
- js做四则运算时,精度丢失问题及解决方法
一.前言:这个问题可以说是程序员必踩的坑,因此网上针对该问题的分析有很多也很详细,解决方法也比较统一,写法也是大同小异,本以为预期效果真能如他们所说是完美的,然而效果却是差强人意. 二.问题:首先,先 ...