写在前面
我想变成一棵树. 开心时在秋天开花; 伤心时在春天落叶。——烽火戏诸侯《剑来》
Kubernetes 控制器管理器
是一个守护进程
,内嵌随 Kubernetes
一起发布的核心控制回路
。 控制回路是一个永不休止的循环
(所以说K8S中的控制管理器是一个死循环),用于调节系统状态。
在 Kubernetes 中,每个控制器是一个控制回路
,通过API 服务器监视集群的共享状态
, 并尝试进行更改以将当前状态转为期望状态
。目前,Kubernetes 自带的控制器例子包括副本控制器
、节点控制器
、命名空间控制器
和服务账号控制器
等。
Controller Manager 原理分析
Controller Manager
作为集群内部的管理控制中心
,当某个Node意外宕机
时, Controller Manager
会及时发现此故障并执行自动化修复流程
,确保集群始终处于预期的工作状态
。
Controller Manager
内部包含Replication Controller
, Node Controller
, ResourceQuota Controller
, Namespace Controller
, ServiceAccount Controller
, Token Controller
,Service Controller
及Endpoint Controller
等多个Controller,每种Controller都负责一种具体的控制流程,而Controller Manager
正是这些Controller的核心管理者。
副本控制器(Replication Controller)
其实对这个有些模糊,RC资源现在用的已经很少了,不知道这里只是指RC还是说RS,deploy都是由Replication Controller控制的
Replication Controller
的核心作用是确保在任何时候集群中一个RC所关联的Pod副本数量保持预设值
。
需要注意的一点是: 只有当Pod的重启策略是Always时(RestartPolicy=Always), Replication Controller才会管理该Pod的操作(例如创建、销毁、重启等)
RC
中的pod模板
一旦创建完成,就和RC中的模板没有任何关系。 Pod可以通过修改标签来实现脱离RC
的管控。可以用于 将Pod从集群中迁移、数据修复等调试 。
对于被迁移的Pod
副本, RC
会自动创建一个新的,副本替换被迁移的副本。需要注意的是,删除一个RC不会影响它所创建的Pod,如果想删除一个RC所控制的Pod,则需要将该RC的副本数(Replicas)属性设置为0,这样所有的Pod副本都会被自动删除。
Replication Controller
的职责:
Replication Controller
的职责
确保当前集群中有且仅有N个Pod实例, N是RC中定义的Pod副本数量。
通过调整RC的spec.replicas属性值来实现系统扩容或者缩容。
通过改变RC中的Pod模板(主要是镜像版本)来实现系统的滚动升级。
使用场景
使用场景
重新调度(Rescheduling):副本控制器都能确保指定数量的副本存在于集群中
弹性伸缩(Scaling),手动或者通过自动扩容代理修改副本控制器的spec.replicas属性值,非常容易实现扩大或缩小副本的数量。
滚动更新(Rolling Updates),副本控制器被设计成通过逐个替换Pod的方式来辅助服务的滚动更新。即现在的deployment资源的作用,通过新旧两个RC 实现滚动更新
节点控制器(Node Controller)
kubelet
进程在启动时通过API Server
向master注册自身的节点信息,并定时向API Server
汇报状态信息, API Server
接收到这些信息后,将这些信息更新到etcd
中, etcd
中存储的节点信息包括节点健康状况
、节点资源
、节点名称
、节点地址信息
、操作系统版本
、Docker 版本
、kubelet版本等
。
节点健康状况包含“就绪” (True)
“未就绪” (False)
和“未知" (Unknown)
三种。
Node Controller
通过API Server
实时获取Node
的相关信息,实现管理和监控集群中的各个Node节点的相关控制功能, Node Controller的核心工作流程如图。
Node Controller的核心工作流程如图
Controller Manager
在启动时如果设置了-cluster-cidr
参数,那么为每个没有设置Spec.PodCIDR
的Node节点生成一个CIDR
地址,并用该CIDR
地址设置节点的Spec.PodCIDR
属性,这样做的目的是防止不同节点的CIDR
地址发生冲突。
逐个读取节点信息,多次尝试修改nodestatusMap
中的节点状态信息,将该节点信息和Node Controller
的nodeStatusMap
中保存的节点信息做比较。
节点状态
如果判断出没有收到kubelet发送的节点信息
、第1次收到节点kubelet
发送的节点信息,或在该处理过程中节点状态变成非“健康”状态
则在nodeStatusMap中保存该节点的状态信息
,并用Node Controller所在节点的系统时间作为探测时间和节点状态变化时间。
如果判断出在指定时间内收到新的节点信息
,且节点状态发生变化
则在nodeStatusMap中保存该节点的状态信息
,并用NodeController所在节点的系统时间作为探测时间和节点状态变化时间。
如果判断出在指定时间内收到新的节点信息
,但节点状态没发生变化
则在nodeStatusMap中保存该节点的状态信息
,并用Node Controller所在节点的系统时间作为探测时间,用上次节点信息中的节点状态变化时间作为该节点的状态变化时间。
如果判断出在某一段时间(gracePeriod)内没有收到节点状态信息
则设置节点状态为“未知” (Unknown),并且通过API Server保存节点状态
。
如果节点状态变为非“就绪”状态
则将节点加入待删除队列
,否则将节点从该队列中删除
。
如果节点状态为非“就绪”状态
,且系统指定了Cloud Provider
,则Node Controller
调用Cloud Provider
查看节点,若发现节点故障,则删除etcd中的节点信息,并删除和该节点相关的Pod等资源的信息。
资源控制器(ResourceQuota Controller)
Kubernetes
提供了资源配额管理( ResourceQuotaController
),确保了指定的资源对象在任何时候都不会超量占用系统物理资源,导致整个系统运行紊乱甚至意外宕机,对整个集群的平稳运行和稳定性有非常重要的作用。
Kubernetes支持资源配额管理。
配置级别
容器 级别
,可以对CPU和Memory进行限制。
Pod级别
,可以对一个Pod内所有容器的可用资源进行限制。
Namespace
级别,为Namespace (多租户)级别的资源限制,Pod数量;Replication Controller数量; Service数量;ResourceQuota数量;Secret 数量;可持有的PV (Persistent Volume)数量。
Kubernetes的配额管理是通过Admission Control (准入控制)
来控制的,Admission Control
当前提供了两种方式的配额约束,分别是LimitRanger
与ResourceQuota
。其中
LimitRanger
作用于Pod和Container
上,
ResourceQuota
则作用于Namespace
上,限定一个Namespace
里的各类资源的使用总额。
如果在Pod定义
中同时声明了LimitRanger
,则用户通过API Server
请求创建或修改资源时, Admission Control
会计算当前配额的使用情况,如果不符合配额约束,则创建对象失败。
对于定义了ResourceQuota
的Namespace
, ResourceQuota Controller
组件则负责定期统计和生成该Namespace下
的各类对象的资源使用总量,统计结果包括Pod, Service,RC、Secret和Persistent Volume
等对象实例个数,以及该Namespace
下所有Container
实例所使用的资源量(目前包括CPU和内存)
,然后将这些统计结果写入etcd
的resourceQuotaStatusStorage
目录(resourceQuotas/status
)中。
ResourceQuota Controller 流程圖
命名空间(Namespace Controller)
通过API Server可以创建新的Namespace并保存在etcd中, Namespace Controller
定时通过API Server
读取这些Namespace信息。
删除步骤
如果Namespace被API标识为优雅删除
(通过设置删除期限,即DeletionTimestamp属性被设置
),则将该NameSpace的状态设置成”Terminating
“并保存到etcd
中。同时Namespace Controller删除该Namespace下的ServiceAccount, RC, Pod.Secret, PersistentVolume, ListRange, ResourceQuota和Event等 资源对象 。
当Namespace
的状态被设置成”Terminating
“后,由Admission Controller
的NamespaceLifecycle
插件来 阻止 为该Namespace
创建新的资源。
在Namespace Controller
删除完该Namespace
中的所有资源对象
后, Namespace Controller
对该Namespace
执行finalize
操作,删除Namespace
的spec.finalizers域
中的信息
如果Namespace Controller
观察到Namespace设置了删除期限
,同时Namespace的spec.finalizers域值是空
的,那么Namespace Controller
将通过API Server删除该Namespace资源
。
Service Controller(服务控制器)与Endpoint Controller
Service, Endpoints与Pod的关系
Endpoints
表示一个Service对应的所有Pod副本的访问地址
,而EndpointsController
就是负责生成和维护所有Endpoints
对象的控制器。
–
Endpoint Controller负责监听Service和对应的Pod副本的变化
Endpoint Controller监听
如果监测到Service被删除
,则删除和该Service同名的Endpoints对象。
如果监测到新的Service被创建或者修改
,则根据该Service信息获得相关的Pod列表,然后创建或者更新Service对应的Endpoints对象。
如果监测到Pod的事件
,则更新它所对应的Service的Endpoints对象(增加、删除或者修改对应的Endpoint条目)
Endpoints对象是在哪里被使用的呢?
每个Node
上的kube-proxy
进程,kube-proxy
进程获取每个Service
的Endpoints
,实现了Service
的负载均衡
功能。
Service Controller
的作用,它其实是属于Kubernetes集群与外部的云平台之间的一个接口 控制器
。
Service Controller监听Service的变化,如果是一个LoadBalancer
类型的Service (externalLoadBalancers-true)
,则Service Controller
确保外部的云平台上该Service对应的LoadBalancer实例被相应地创建、删除及更新路由转发表(根据Endpoints的条目)。
yaml 资源文件
相关启动参数小伙伴可以移步官网查看: https://kubernetes.io/zh/docs/reference/command-line-tools-reference/kube-controller-manager/
┌──[ root@vms81.liruilongs.github.io] - [ ~/ansible/k8s- svc- create] └─$kubectl get pods kube- controller- manager- vms81.liruilongs.github.io - o yaml - n kube- systemapiVersion : v1kind : Podmetadata : annotations : kubernetes.io/config.hash : 49b7654103f80170bfe29d034f806256 kubernetes.io/config.mirror : 49b7654103f80170bfe29d034f806256 kubernetes.io/config.seen : "2021-12-14T23:02:32.958181106+08:00" kubernetes.io/config.source : file seccomp.security.alpha.kubernetes.io/pod : runtime/default creationTimestamp : "2021-12-14T15:02:33Z" labels : component : kube- controller- manager tier : control- plane name : kube- controller- manager- vms81.liruilongs.github.io namespace : kube- system ownerReferences : - apiVersion : v1 controller : true kind : Node name : vms81.liruilongs.github.io uid : b1e00933- c091- 4a1f- b470- 1418cbe5bc20 resourceVersion : "296478" uid : ac955a42- 0c15- 44f8- 9217- cacc59c8f410spec : containers : - command : - kube- controller- manager - - - allocate- node- cidrs=true - - - authentication- kubeconfig=/etc/kubernetes/controller- manager.conf - - - authorization- kubeconfig=/etc/kubernetes/controller- manager.conf - - - bind- address=127.0.0.1 - - - client- ca- file=/etc/kubernetes/pki/ca.crt - - - cluster- cidr=10.244.0.0/16 - - - cluster- name=kubernetes - - - cluster- signing- cert- file=/etc/kubernetes/pki/ca.crt - - - cluster- signing- key- file=/etc/kubernetes/pki/ca.key - - - controllers=*, bootstrapsigner, tokencleaner - - - kubeconfig=/etc/kubernetes/controller- manager.conf - - - leader- elect=true - - - port=0 - - - requestheader- client- ca- file=/etc/kubernetes/pki/front- proxy- ca.crt - - - root- ca- file=/etc/kubernetes/pki/ca.crt - - - service- account- private- key- file=/etc/kubernetes/pki/sa.key - - - service- cluster- ip- range=10.96.0.0/12 - - - use- service- account- credentials=true image : registry.aliyuncs.com/google_containers/kube- controller- manager: v1.22.2 imagePullPolicy : IfNotPresent livenessProbe : failureThreshold : 8 httpGet : host : 127.0.0.1 path : /healthz port : 10257 scheme : HTTPS initialDelaySeconds : 10 periodSeconds : 10 successThreshold : 1 timeoutSeconds : 15 name : kube- controller- manager resources : requests : cpu : 200m startupProbe : failureThreshold : 24 httpGet : host : 127.0.0.1 path : /healthz port : 10257 scheme : HTTPS initialDelaySeconds : 10 periodSeconds : 10 successThreshold : 1 timeoutSeconds : 15 terminationMessagePath : /dev/termination- log terminationMessagePolicy : File volumeMounts : - mountPath : /etc/ssl/certs name : ca- certs readOnly : true - mountPath : /etc/pki name : etc- pki readOnly : true - mountPath : /usr/libexec/kubernetes/kubelet- plugins/volume/exec name : flexvolume- dir - mountPath : /etc/kubernetes/pki name : k8s- certs readOnly : true - mountPath : /etc/kubernetes/controller- manager.conf name : kubeconfig readOnly : true dnsPolicy : ClusterFirst enableServiceLinks : true hostNetwork : true nodeName : vms81.liruilongs.github.io preemptionPolicy : PreemptLowerPriority priority : 2000001000 priorityClassName : system- node- critical restartPolicy : Always schedulerName : default- scheduler securityContext : seccompProfile : type : RuntimeDefault terminationGracePeriodSeconds : 30 tolerations : - effect : NoExecute operator : Exists volumes : - hostPath : path : /etc/ssl/certs type : DirectoryOrCreate name : ca- certs - hostPath : path : /etc/pki type : DirectoryOrCreate name : etc- pki - hostPath : path : /usr/libexec/kubernetes/kubelet- plugins/volume/exec type : DirectoryOrCreate name : flexvolume- dir - hostPath : path : /etc/kubernetes/pki type : DirectoryOrCreate name : k8s- certs - hostPath : path : /etc/kubernetes/controller- manager.conf type : FileOrCreate name : kubeconfigstatus : conditions : - lastProbeTime : null lastTransitionTime : "2021-12-20T00:28:14Z" status : "True" type : Initialized - lastProbeTime : null lastTransitionTime : "2021-12-21T13:10:56Z" status : "True" type : Ready - lastProbeTime : null lastTransitionTime : "2021-12-21T13:10:56Z" status : "True" type : ContainersReady - lastProbeTime : null lastTransitionTime : "2021-12-20T00:28:14Z" status : "True" type : PodScheduled containerStatuses : - containerID : docker: //6af720a0409f3bb3ffd8ddd7995faf749c43145fea39f28ff54a235f4644385b image : registry.aliyuncs.com/google_containers/kube- controller- manager: v1.22.2 imageID : docker- pullable: //registry.aliyuncs.com/google_containers/kube- controller- manager@sha256: 91ccb477199cdb4c63fb0c8fcc39517a186505daf4ed52229904e6f9d09fd6f9 lastState : terminated : containerID : docker: //5b5e8d4cc06d08ecd4d5940e3cdceb55728c410738698c14d144c454772cb17e exitCode : 255 finishedAt : "2021-12-21T13:10:04Z" reason : Error startedAt : "2021-12-21T00:31:52Z" name : kube- controller- manager ready : true restartCount : 19 started : true state : running : startedAt : "2021-12-21T13:10:32Z" hostIP : 192.168.26.81 phase : Running podIP : 192.168.26.81 podIPs : - ip : 192.168.26.81 qosClass : Burstable startTime : "2021-12-20T00:28:14Z"
原文始发于微信公众号(山河已无恙):关于 Kubernetes中kube-controller-managerr的一些笔记
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/80759.html