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: null labels: app: nginx spec: containers: - image: 10.50.10.185/harbortest/nginx:1.7.1 imagePullPolicy: IfNotPresent name: nginx ports: - containerPort: 80 name: web protocol: TCP resources: {} terminationMessagePath: /dev/termination-log terminationMessagePolicy: File volumeMounts: - mountPath: /usr/share/nginx/html name: www dnsPolicy: ClusterFirst restartPolicy: Always schedulerName: default-scheduler securityContext: {} terminationGracePeriodSeconds: 30 updateStrategy: rollingUpdate: partition: 0 type: RollingUpdate
deployment 的滚动升级策略
maxSurge: 每次最多升级多少个pod.
maxUnavailable:每次不可用pod的数量。
spec: progressDeadlineSeconds: 600 replicas: 3 revisionHistoryLimit: 10 selector: matchLabels: app: nginx-pod strategy: 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: replace metadata: annotations: kubectl.kubernetes.io/restartedAt: "2022-09-22T14:41:17+08:00" creationTimestamp: null labels: app: nginx spec: containers: - image: 10.50.10.185/harbortest/nginx:1.7.1 imagePullPolicy: IfNotPresent name: nginx ports: - containerPort: 80 name: web protocol: TCP resources: {} terminationMessagePath: /dev/termination-log terminationMessagePolicy: File volumeMounts: - mountPath: /usr/share/nginx/html name: www dnsPolicy: ClusterFirst restartPolicy: Always schedulerName: default-scheduler securityContext: {} 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: nginx controller.kubernetes.io/hash: 58968dc4b7 name: web-58968dc4b7 namespace: dev ownerReferences: - apiVersion: apps/v1 blockOwnerDeletion: true controller: true kind: StatefulSet name: web uid: f85c72ef-4c47-4ccd-bf37-ff074aecb666 resourceVersion: "20488479" uid: f7659ffe-5d5d-4db3-aecd-f868312b7a9a revision: 2
deploy 和daemonset 的toleration有何区别?
daemon set
和节点比较亲密不容易被驱逐,一般都没有tolerationseconds,会一直赖着不走直到条件满足,
注意看这个promtail的pod yaml,这个组件是用来收集日志的.
apiVersion: v1 kind: Pod labels: controller-revision-hash: 7d4595d8 k8s.kuboard.cn/layer: monitor k8s.kuboard.cn/name: kuboard-promtail pod-template-generation: "1" name: kuboard-promtail-2d8ws namespace: kuboard ... terminationGracePeriodSeconds: 30 tolerations: - effect: NoSchedule key: node-role.kubernetes.io/master operator: Exists - effect: NoExecute key: node.kubernetes.io/not-ready operator: Exists - effect: NoExecute key: node.kubernetes.io/unreachable operator: Exists - effect: NoSchedule key: node.kubernetes.io/disk-pressure operator: Exists - effect: NoSchedule key: node.kubernetes.io/memory-pressure operator: Exists - effect: NoSchedule key: node.kubernetes.io/pid-pressure operator: Exists - effect: NoSchedule key: node.kubernetes.io/unschedulable operator: Exists volumes: - configMap: defaultMode: 420 name: kuboard-promtail-configmap name: 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-manager namespace: kube-system resourceVersion: "37461454" uid: d9e4245d-4e88-4f6b-900c-ac473bbe3201 spec: acquireTime: "2022-10-19T06:54:48.349009Z" holderIdentity: master2_5099ba2c-f421-43e6-8f3a-7b09363610d1 leaseDurationSeconds: 15 leaseTransitions: 9 renewTime: "2022-11-25T08:22:57.622771Z"
可以看到mster2 抢到了锁. 来控制controller manager