pod bind node(写nodeName字段)
,最后把pod yaml回写到apiserver中。这是一个controller loop,
kube-scheduler其实也是一个特殊的kube-controller-manager
。
apiserver是一个声明式的系统,就是你给我一个应用的期望状态,我根据这个期望去做一些配置,让这个应用最终达到你的期望状态,这个就是kube-controller-manager实现的。是k8s的大脑。
控制器=控制器定义
+ 被控制对象的模版(podTemplate)
控制器定义: 是为了reconcil loop实现达到期望状态(控制器核心原理)
针对任何的api对象,都可以通过code-generator来生成。它可以生成Deepcopy,Conversion,Clientset等。Clientset用来定义我如何访问这个api对象,比如create,delete,get,list,watch等。
code-generate官方文档
流程图:
针对kube-controller-manager,code-generator生成了Informer和Lister。这两个统称为Controller Interface
。
去apiserver获取任何一个对象的时候,有两种方式,一种是get,一种是watch。针对这两种方式,Controller Interface就分为了:
消息通知接口
。它有三种event。三种event要去注册EventHandler
,event是一个完整的对象,大部分的控制器会去拿到这个对象的KeyFunc(对象的namespace+name),然后把这个key通过RateLimitinglnterface放到队列里面。
如果有一个对象频繁变更,如果把对象的完整信息放到队列里,首先队列需要的内存空间会很大,其次假如对象要变更10次,那么worker也要变更10次。而使用对象的key(例如:pod的key就是namespace_podname string
),不管有多少次变更event,推送到队列里的只有一个key,worker线程通过lister接口获取这个对象的最终状态,worker只需要根据这个最终状态变更1次即可。
k8s是一个微服务管理系统,不同的组件负责不同的职责。
以下图的deployment为例,用户创建一个deployment。
kubelet监听所有pod的变更
,如果pod的nodeName所调度的节点和本节点的Hostname一致
,就会继续检查当前pod是否已经在此节点上存在,若存在,则删除原有pod相关容器,再重新创建pod;若不存在,则调用CRI创建pod相关容器、调用CSI为容器配置存储、调用CNI为容器配置网络Garbage Collector:通过ownerReferences处理级联删除,它的内部会有一个Graph Builder,构建一个父子关系图。比如删除 deployment 时它会去扫描自己的GraphBuilder,看有没有对象的ownerReferences是这个deployment,所以也会删除对应的 replicaset 以及Pod。
deployment是利用rs做版本控制的,其中的revisionHistoryLimit是指定了rs保留版本数
。其他控制器都是通过ControllerRevision
做版本管理的,但是无法指定版本保留个数
。
k get deploy -o yaml
k get rs -o yaml
可以看到metadata有一个ownerReferences属性,代表着它的父辈是谁。这里就是nginx的deployment。uid也是deployment的uid。
k get po -o yaml
可以看到pod的ownerReferences中,指向的是nginx的rs。
我们可以清楚的发现各个对象都会记录自己的父对象是谁,这样其实就形成了一张对象相互级联的拓扑图。假如自己现在执行下面:
# delete默认是级联删除的
kubectl delete deployment xxxx
因为我创建的时候就是创建的deployment,那么对用户来说并不知道其他级联对象比如rs的存在,那么用户删除dp,应该将其他级联的也删除了。假如我们不需要级联删除的话就执行
:
# old kubelet reversion
kubectl delete deployment xxxx --cascade=false
# new kubelet reversion
kubectl delete deployment xxxx --cascade=orphan
注:deployment需要有Template是为了创建RS,RS要有template是为了根据template创建pod。RS的pod-template-hash label和deployment pod-template有命名上的弱绑定.
nginx pod名字是nginx-6cc88c7947-vh4rq,pod是由rs创建的,因此rs控制器名nginx-6cc88c7947
+随机字符串就是pod名,这样就保证了pod名的独一无二。其他控制器因为没有两层关系
。不需要pod-template-hash 命名弱绑定,因此控制器的名字都没有hash值,podname就是控制器名+随机字符串
:
[root@localhost ~]# kubectl get ds
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
lxcfs 57 57 57 57 57 <none> 179d
[root@localhost ~]# kubectl get pods|grep lxcfs
lxcfs-2xgrp 1/1 Running 0 155d
Cloud Controller Manager 是从老版本的 API Server 分离出来的。
(1)Cloud Controller Manager 主要支持:
(2)需要定制的 Cloud Controller:
(3)建议:
保护好 controller manager 的 kubeconfig:
(1)Leader Election: