kubernetes组件 Controller manager深刻认知
- Controller manager
- 常见的controller
- Controller manager的工作流程
- informer的内部机制
- 控制器的协同工作原理
- ReplicaSet controller 是如何被管理的?
- statefuleset 和deployment controller是如何控制滚动升级的
- statefuleset的滚动升级策略
- deployment 的滚动升级策略
- 一个经典的金丝雀发布请求监控图
- Controller 如何为statefuleset 设置DNS规则
- deployment 为什么需要三级对象才能实现rollingupdate? 而daemonset、statefuleset 为何可以呢?
- deploy 和daemonset 的toleration有何区别?
- namespace controller
- garbage controller
- 如何解除ownerReferences 的父子关系图?
- 来自生产的经验
- 高可用
- 高可用-leader election
Controller manager
Controller manager是真正负责资源管理的组件,它主要负责容器的副本数管理、节点状态维护、节点网段分配等。
它由众多控制器组成是Kubernetes负责实现生命式API和控制器模式的核心。
常见的controller
Controller manager的工作流程
informer的内部机制
控制器的协同工作原理
ReplicaSet controller 是如何被管理的?
以ReplicaSet为例,它会周期地检测理想的“目标容器数”和真实的“当前容器数”是否相同。如果不相等,则会将实际的容器数调整到目标容器数。
当设置一个ReplicaSet的副本数为10的时候,如果实际的容器数小于10,则会执行调用Apiserver创建Pod。如果当前容器数大于10,则会执行删除Pod操作。ReplicaSet检测过程如图
statefuleset 和deployment controller是如何控制滚动升级的
statefuleset的滚动升级策略
statefuleset的rollingupdate每次只升级一个partition,也就是有状态副本集的一个实例,例如mysql实例升级版本, 待确认0没问题之后。 再升级1. 需要人手动改。 无状态的滚动升级则不需要人介入。
template:metadata:annotations:kubectl.kubernetes.io/restartedAt: "2022-09-22T14:41:17+08:00"creationTimestamp: nulllabels:app: nginxspec:containers:- image: 10.50.10.185/harbortest/nginx:1.7.1imagePullPolicy: IfNotPresentname: nginxports:- containerPort: 80name: webprotocol: TCPresources: {}terminationMessagePath: /dev/termination-logterminationMessagePolicy: FilevolumeMounts:- mountPath: /usr/share/nginx/htmlname: wwwdnsPolicy: ClusterFirstrestartPolicy: AlwaysschedulerName: default-schedulersecurityContext: {}terminationGracePeriodSeconds: 30updateStrategy:rollingUpdate:partition: 0type: RollingUpdate
deployment 的滚动升级策略
maxSurge: 每次最多升级多少个pod.
maxUnavailable:每次不可用pod的数量。
spec:progressDeadlineSeconds: 600replicas: 3revisionHistoryLimit: 10selector:matchLabels:app: nginx-podstrategy:rollingUpdate:maxSurge: 25%maxUnavailable: 25%type: RollingUpdate
一个经典的金丝雀发布请求监控图
Controller 如何为statefuleset 设置DNS规则
POD ip变了没关系,因为有DNS 记录,别的用户调用的是域名。域名永远会指向新的podip。
deployment 为什么需要三级对象才能实现rollingupdate? 而daemonset、statefuleset 为何可以呢?
使用了同一的版本管理controllerrevision 对象 。
这是statefuleset的controllerrevision, 也是通过hash值的变化确定其名称,和deployment相比较少了一层rs。
这是因为deploy这个对象出现的早,后面的对象设计演进更加先进了。
k get controllerrevision -n dev
NAME CONTROLLER REVISION AGE
web-58968dc4b7 statefulset.apps/web 2 64d
web-5d6c5f6975 statefulset.apps/web 1 150d
controllerrevision 的内容
⚡ root@master1 /etc/kubernetes k get controllerrevision web-58968dc4b7 -n dev -oyaml
apiVersion: apps/v1
data:spec:template:$patch: replacemetadata:annotations:kubectl.kubernetes.io/restartedAt: "2022-09-22T14:41:17+08:00"creationTimestamp: nulllabels:app: nginxspec:containers:- image: 10.50.10.185/harbortest/nginx:1.7.1imagePullPolicy: IfNotPresentname: nginxports:- containerPort: 80name: webprotocol: TCPresources: {}terminationMessagePath: /dev/termination-logterminationMessagePolicy: FilevolumeMounts:- mountPath: /usr/share/nginx/htmlname: wwwdnsPolicy: ClusterFirstrestartPolicy: AlwaysschedulerName: default-schedulersecurityContext: {}terminationGracePeriodSeconds: 30
kind: ControllerRevision
metadata:annotations:kubectl.kubernetes.io/last-applied-configuration: |{"apiVersion":"apps/v1","kind":"StatefulSet","metadata":{"annotations":{},"name":"web","namespace":"dev"},"spec":{"replicas":2,"selector":{"matchLabels":{"app":"nginx"}},"serviceName":"nginx","template":{"metadata":{"labels":{"app":"nginx"}},"spec":{"containers":[{"image":"10.50.10.185/harbortest/nginx:1.7.1","name":"nginx","ports":[{"containerPort":80,"name":"web"}],"volumeMounts":[{"mountPath":"/usr/share/nginx/html","name":"www"}]}]}},"volumeClaimTemplates":[{"metadata":{"name":"www"},"spec":{"accessModes":["ReadWriteOnce"],"resources":{"requests":{"storage":"1Gi"}}}}]}}creationTimestamp: "2022-09-22T06:41:17Z"labels:app: nginxcontroller.kubernetes.io/hash: 58968dc4b7name: web-58968dc4b7namespace: devownerReferences:- apiVersion: apps/v1blockOwnerDeletion: truecontroller: truekind: StatefulSetname: webuid: f85c72ef-4c47-4ccd-bf37-ff074aecb666resourceVersion: "20488479"uid: f7659ffe-5d5d-4db3-aecd-f868312b7a9a
revision: 2
deploy 和daemonset 的toleration有何区别?
daemon set
和节点比较亲密不容易被驱逐,一般都没有tolerationseconds,会一直赖着不走直到条件满足,
注意看这个promtail的pod yaml,这个组件是用来收集日志的.
apiVersion: v1
kind: Podlabels:controller-revision-hash: 7d4595d8k8s.kuboard.cn/layer: monitork8s.kuboard.cn/name: kuboard-promtailpod-template-generation: "1"name: kuboard-promtail-2d8wsnamespace: kuboard
...terminationGracePeriodSeconds: 30tolerations:- effect: NoSchedulekey: node-role.kubernetes.io/masteroperator: Exists- effect: NoExecutekey: node.kubernetes.io/not-readyoperator: Exists- effect: NoExecutekey: node.kubernetes.io/unreachableoperator: Exists- effect: NoSchedulekey: node.kubernetes.io/disk-pressureoperator: Exists- effect: NoSchedulekey: node.kubernetes.io/memory-pressureoperator: Exists- effect: NoSchedulekey: node.kubernetes.io/pid-pressureoperator: Exists- effect: NoSchedulekey: node.kubernetes.io/unschedulableoperator: Existsvolumes:- configMap:defaultMode: 420name: kuboard-promtail-configmapname: config- hostPath:
deployment
和节点关系不大,总结来说就是 “不行我就走”。
namespace controller
删除一个ns时会级联删除该ns下的所有对象。这是如何做到的呢?
通过uid属性
ns的删除机制?
ns是标记删除,finalizer 为空则真正删除。
garbage controller
ownerReferences 表明这个pod来自哪里?是sts、deploy、daemon 哪个对象呢? 他们之间都是通过ownerReferences来进行关联的。
这就构建出了父子关系图。
graphbuilder. 扫描这些对象,构建这个关系图。
同样删除的时候,会通过这个父子关系图进行级联删除。
如何解除ownerReferences 的父子关系图?
应用场景是啥呢?
删除的时候通过传入 --cascade=orphan 来完成
# --cascade='background': Must be "background", "orphan", or "foreground". Selects the deletion cascading strategy
来自生产的经验
高可用
Leader Election
Kubenetes 提供基于 configmap 和 endpoint 的 leader election 类库
Kubernetes 采用leader election 模式启动 component 后』会创建对应 endpoint, leader 信息 annotate 至U endponit 上。
高可用-leader election
现在一般都不使用EP,使用新的对象lease
这类似于一个文件所,k8s 通过lease 来确保唯一一个controller运行。
# k get lease kube-controller-manager -oyaml -n kube-system
apiVersion: coordination.k8s.io/v1
kind: Lease
metadata:creationTimestamp: "2022-06-26T07:04:24Z"name: kube-controller-managernamespace: kube-systemresourceVersion: "37461454"uid: d9e4245d-4e88-4f6b-900c-ac473bbe3201
spec:acquireTime: "2022-10-19T06:54:48.349009Z"holderIdentity: master2_5099ba2c-f421-43e6-8f3a-7b09363610d1leaseDurationSeconds: 15leaseTransitions: 9renewTime: "2022-11-25T08:22:57.622771Z"
可以看到mster2 抢到了锁. 来控制controller manager