目录
[1、Kubernetes 组件协作机制](#1、Kubernetes 组件协作机制)
[2、Pod 创建与工作机制流程](#2、Pod 创建与工作机制流程)
[(2)用户创建 Pod 对象用户](#(2)用户创建 Pod 对象用户)
[(3)API Server 将 Pod 信息写入 etcd](#(3)API Server 将 Pod 信息写入 etcd)
[(4)etcd 通知事件(Create)](#(4)etcd 通知事件(Create))
[(5)Controller Manager 监听到 Pod 创建事件](#(5)Controller Manager 监听到 Pod 创建事件)
[(6)Replication Controller(RC)/ ReplicaSet 保证副本数](#(6)Replication Controller(RC)/ ReplicaSet 保证副本数)
[(7)API Server 更新 etcd(记录详细信息)](#(7)API Server 更新 etcd(记录详细信息))
[(8)etcd 触发 Pod 信息更新事件](#(8)etcd 触发 Pod 信息更新事件)
[(9)Scheduler 监听到待调度的 Pod](#(9)Scheduler 监听到待调度的 Pod)
[(10)Scheduler 更新调度结果](#(10)Scheduler 更新调度结果)
[(11)etcd 确认更新 & API Server 同步结果](#(11)etcd 确认更新 & API Server 同步结果)
[(12)kubelet 在 Node 上拉取并运行容器](#(12)kubelet 在 Node 上拉取并运行容器)
[(13)API Server 更新 Pod 状态](#(13)API Server 更新 Pod 状态)
[4.1 过滤阶段(Predicate)](#4.1 过滤阶段(Predicate))
[4.2 优选阶段(Priorities)](#4.2 优选阶段(Priorities))
[5.1 nodeName(强制绑定)](#5.1 nodeName(强制绑定))
[5.2 nodeSelector(基于标签匹配)](#5.2 nodeSelector(基于标签匹配))
[6、节点亲和性与 Pod 亲和性](#6、节点亲和性与 Pod 亲和性)
[6.1 节点亲和性(NodeAffinity)](#6.1 节点亲和性(NodeAffinity))
[6.2 Pod 亲和性与反亲和性](#6.2 Pod 亲和性与反亲和性)
[7、污点(Taint) 和 容忍(Tolerations)](#7、污点(Taint) 和 容忍(Tolerations))
[7.1 污点(Taint)](#7.1 污点(Taint))
[7.2 容忍 (Tolerations)](#7.2 容忍 (Tolerations))
[9、Pod 生命周期(Phase)](#9、Pod 生命周期(Phase))
1、Kubernetes 组件协作机制
Kubernetes 通过List-Watch机制使各个组件协作、数据同步,从而实现解耦与实时一致性。
关键组件关系:
|--------------------|--------------------------------|
| 组件 | 职责 |
| kubectl / API 客户端 | 向 APIServer 发起资源创建或管理请求 |
| APIServer | 负责 API 调用、权限校验、存储交互,是集群控制的核心入口 |
| etcd | 存储集群所有状态信息 |
| Controller Manager | 维持副本数、执行自愈逻辑(扩容、重建等) |
| Scheduler | 调度器,将未分配节点的 Pod 分配到合适的 Node |
| kubelet | 节点代理,负责 Pod 生命周期管理和容器运行状态上报 |

2、Pod 创建与工作机制流程
Pod 创建的整个生命周期由多组件配合完成:
2.1典型创建过程(List-Watch 模型)
(1)三大组件启动监听(List-Watch)
- Controller Manager、Scheduler、kubelet
- 启动后会分别通过Watch API Server(HTTPS 6443 端口)监听集群资源事件变化。
-
- Controller Manager:监听副本控制类对象(如 ReplicaSet、Deployment)
- Scheduler:监听未调度的 Pod
- kubelet:监听分配到本节点的 Pod
(2)用户创建 Pod 对象用户
- 通过kubectl或其他 API 客户端发送创建 Pod 的请求给API Server。
示例:
kubectl apply -f pod.yaml
(3)API Server 将 Pod 信息写入 etcd
- API Server 校验请求后,将 Pod 的元数据存入etcd。
- 写入成功后返回确认给客户端。
(4)etcd 通知事件(Create)
- etcd 接受到 Pod 信息后,触发Create事件。
- 该事件被发送给API Server。
(5)Controller Manager 监听到 Pod 创建事件
- Controller Manager 通过 Watch 机制收到 API Server 发出的 Pod 创建事件。
(6)Replication Controller(RC)/ ReplicaSet 保证副本数
- Controller Manager 在接到 Create 事件以后,如果发现副本数量不足,则由RC/ReplicaSet创建所需副本。
- 扩容、缩容操作也都由此机制控制。
(7)API Server 更新 etcd(记录详细信息)
- Controller Manager 创建完 Pod 副本后,API Server 会将 Pod 的详细信息更新写入 etcd。
-
- 包括副本数量、副本模板、容器规格等。
(8)etcd 触发 Pod 信息更新事件
- etcd 再次发送更新事件给 API Server。
(9)Scheduler 监听到待调度的 Pod
- Scheduler Watch 到新创建的 Pod 处于 "Pending" 状态(尚未分配节点)。
- 通过调度算法(资源、亲和性、污点等)为其选择一个合适的 Node。
(10)Scheduler 更新调度结果
- Scheduler 将选定的 Node 信息写回到API Server。
- API Server 更新 etcd 中该 Pod 的 Node 绑定信息。
(11)etcd 确认更新 & API Server 同步结果
- etcd 更新成功后向 API Server 返回确认。
- API Server 同步 Pod 的最新状态(包括 Node 绑定结果)。
(12)kubelet 在 Node 上拉取并运行容器
- kubelet 监听到分配给自己的新 Pod。
- 调用容器运行时(Docker/containerd):
-
-
- 拉取镜像
-
- 创建容器
-
- 启动容器
-
- 启动成功后将 Pod 状态(Running、Failed 等)上报给 API Server。
(13)API Server 更新 Pod 状态
- API Server 将 kubelet 上报的状态写入 etcd。
- etcd 确认写入成功后,集群状态完成同步,Pod 正式进入Running状态
kubelet 持续监听 Pod 事件,是为了应对副本数变化、镜像更新等动态操作。
注意:在创建 Pod 的工作就已经完成了后,为什么 kubelet 还要一直监听呢?原因很简单,假设这个 时候 kubectl 发命令,要扩充 Pod 副本数量,那么上面的流程又会触发一遍,kubelet 会根据最新的 Pod 的部署情况调整 Node 的资源。又或者 Pod 副本数量没有发生变化,但是其中的镜像文件升级 了,kubelet 也会自动获取最新的镜像文件并且加载。

核心任务
将未绑定 Node 的 Pod(spec.nodeName == "") 分配到合适的节点。
调度目标
- **公平性:**节点间资源分配均衡
- **高效性:**集群所有资源最大化被使用
- **效率:**调度的性能要好,能够尽快地对大批量的 pod 完成调度工作
- **灵活性:**允许自定义策略(调度策略、插件)
Sheduler 是作为单独的程序运行的,启动之后会一直监听 APIServer,获取 spec.nodeName 为空的pod,对每个 pod 都会创建一个 binding,表明该 pod 应该放到哪个节点上。
调度分为几个部分:首先是过滤掉不满足条件的节点,这个过程称为预算策略(predicate);然后对通过的节点按照优先级排序,这个是优选策略(priorities);最后从中选择优先级最高的节点。如果中间任何一步骤有错误,就直接返回错误。
4、调度流程
4.1 过滤阶段(Predicate)
过滤掉不满足条件的节点。
常见过滤算法:
|--------------------|---------------------|
| 算法名 | 功能描述 |
| PodFitsResources | 检查节点剩余资源是否满足 Pod 需求 |
| PodFitsHost | 检查 NodeName 是否匹配 |
| PodFitsHostPorts | 检查端口冲突 |
| PodSelectorMatches | label 匹配 |
| NoDiskConflict | Volume 挂载冲突检测 |
若无节点满足条件,Pod 进入 Pending 状态,不断重试。
如果在 predicate 过程中没有合适的节点,pod 会一直在 pending 状态,不断重试调度,直到有
节点满足条件。 经过这个步骤,如果有多个节点满足条件,就继续 priorities 过程:按照优先级大
小对节点排序。
4.2 优选阶段(Priorities)
常见算法:
|----------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 优先级项 | 描述 |
| LeastRequestedPriority | 资源使用率越低,权重越高 |
| BalancedResourceAllocation | CPU 与内存使用率越接近越好(这个一般和上面的一起使用,不单独使用。比如 node01 的 CPU 和 Memory 使用率20:60,node02 的 CPU 和 Memory 使用率 50:50,虽然node01 的总使用率比 node02 低,但 node02 的 CPU 和Memory 使用率更接近,从而调度时会优选 node02。) |
| ImageLocalityPriority | 优先节点上已有目标镜像的节点 |
5、指定调度节点方式
5.1 nodeName(强制绑定)
pod.spec.nodeName 将 Pod 直接调度到指定的 Node 节点上,会跳过 Scheduler 的调度策略,该匹
配规则是强制匹配
5.2 nodeSelector(基于标签匹配)
pod.spec.nodeSelector:通过 kubernetes 的 label-selector 机制选择节点,由调度器调度策略匹
配 label,然后调度 Pod 到目标节点,该匹配规则属于强制约束
管理 Node 标签命令:
bash
kubectl label nodes node01 yjs=a
kubectl get nodes --show-labels
#指定标签查询 node 节点
kubectl get node -l yjs=a
#修改一个 label 的值,需要加上 --overwrite 参数
kubectl label nodes node02 yjs=b --overwrite
#删除一个 label,只需在命令行最后指定 label 的 key 名并与一个减号相连即可:
kubectl label nodes node02 yjs-
6、节点亲和性与 Pod 亲和性
6.1 节点亲和性(NodeAffinity)
bash
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution: # 硬策略
preferredDuringSchedulingIgnoredDuringExecution: # 软策略
类比理解:
你更"想去"张老师的班(软策略),还是"必须去"张老师的班(硬策略)。
操作符支持:
In、NotIn、Exists、DoesNotExist、Gt、Lt
Kubernetes 中 label selector 的键值运算关系 ,在 Kubernetes 中,很多资源(比如 Pod、
Deployment、Service)都会用 label selector(标签选择器) 来筛选对象。运算符决定"选谁"或"不选谁"。

简单理解
In / NotIn 看"名单",
Gt / Lt 看"数值",
Exists / DoesNotExist 看"有没有"。
6.2 Pod 亲和性与反亲和性

7、污点(Taint) 和 容忍(Tolerations)
7.1 污点(Taint)
节点亲和性,是Pod的一种属性(偏好或硬性要求),它使Pod被吸引到一类特定的节点。Taint 则相反,它使节点能够排斥一类特定的 Pod。
Taint 和 Toleration 相互配合,可以用来避免 Pod 被分配到不合适的节点上。每个节点上都可以应用一个或多个 taint ,这表示对于那些不能容忍这些 taint 的 Pod,是不会被该节点接受的。如果将 toleration 应用于 Pod 上,则表示这些 Pod 可以(但不一定)被调度到具有匹配 taint 的节点上。
使用 kubectl taint 命令可以 给某个 Node 节点设置污点,Node 被设置上污点之后就和 Pod 之间存在了一种相斥的关系,可以让 Node 拒绝 Pod 的调度执行,甚至将 Node 已经存在的 Pod 驱逐出去。
污点格式:
key=value:effect
每个污点有一个 key 和 value 作为污点的标签,其中 value 可以为空,effect 描述污点的作用。
当前 taint effect 支持如下三个选项:
|------------------|-------------------|
| 类型 | 描述 |
| NoSchedule | 不调度到此节点 |
| PreferNoSchedule | 尽量避免调度具有该污点的Node上 |
| NoExecute | 不调度+驱逐已存在的Pod |
7.2 容忍 (Tolerations)
设置了污点的 Node 将根据 taint 的 effect:NoSchedule、PreferNoSchedule、NoExecute 和 Pod 之间产生互斥的关系,Pod 将在一定程度上不会被调度到 Node 上。但我们可以在 Pod 上设置容忍(Tolerations),意思是设置了容忍的 Pod 将可以容忍污点的存在,可以被调度到存在污点的 Node 上。
bash
kubectl taint node node01 check=mycheck:NoExecute
vim pod3.yaml
kubectl apply -f pod3.yaml
//在两个 Node 上都设置了污点后,此时 Pod 将无法创建成功
kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE
READINESS GATES
myapp01 0/1 Pending 0 17s <none> <none> <none>
<none>
vim pod3.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp01
labels:
app: myapp01
spec:
containers:
- name: with-node-affinity
image: soscscs/myapp:v1
tolerations:
- key: "check"
operator: "Equal" #operator: "Equal" #Equal意味着这个值等于value,如果是Exists,则不需要填写value,只要有这个key就容忍
value: "mycheck"
effect: "NoExecute"
tolerationSeconds: 3600
#其中的 key、vaule、effect 都要与 Node 上设置的 taint 保持一致
#operator 的值为 Exists 将会忽略 value 值,即存在即可
#tolerationSeconds 用于描述当 Pod 需要被驱逐时可以在 Node 上继续保留运行的时间
kubectl apply -f pod3.yaml
//在设置了容忍之后,Pod 创建成功
kubectl get pods -o wideREADY STATUS RESTARTS AGE IP NODE
NOMINATED NODE READINESS GATES
myapp01 1/1 Running 0 10m 10.244.1.5 node01 <none>
<none>
NAME
//其它注意事项
(1)当不指定 key 值时,表示容忍所有的污点 key
tolerations:
- operator: "Exists"
(2)当不指定 effect 值时,表示容忍所有的污点作用
tolerations:
- key: "key"
operator: "Exists"
(3)有多个 Master 存在时,防止资源浪费,可以如下设置
kubectl taint node Master-Name node-role.kubernetes.io/master=:PreferNoSchedule
//如果某个 Node 更新升级系统组件,为了防止业务长时间中断,可以先在该 Node 设置 NoExecute 污点,把该 Node 上的 Pod 都驱逐出去
kubectl taint node node01 check=mycheck:NoExecute
//此时如果别的 Node 资源不够用,可临时给 Master 设置 PreferNoSchedule 污点,让 Pod 可在 Master 上临时创建
kubectl taint node master node-role.kubernetes.io/master=:PreferNoSchedule
//待所有 Node 的更新操作都完成后,再去除污点
kubectl taint node node01 check=mycheck:NoExecute-
8、节点维护操作
cordon & drain
kubectl cordon <node> #标记为不可调度
kubectl drain <node> --ignore-daemonsets --delete-local-data --force #驱逐 Pod
kubectl uncordon <node> #恢复可调度状态

9、Pod 生命周期(Phase)
|-----------|-----------------|
| 阶段 | 说明 |
| Pending | 已创建但未调度或拉取镜像中 |
| Running | 容器已启动运行中 |
| Succeeded | 所有容器成功终止(Job 类) |
| Failed | 容器失败退出(非0或异常) |
| Unknown | 无法获取状态(通信异常) |
详解phase 的可能状态有:
- Pending:表示APIServer创建了Pod资源对象并已经存入了etcd中,但是它并未被调度完成(比如还没有调度到某台node上),或者仍然处于从仓库下载镜像的过程中。
- Running:Pod已经被调度到某节点之上,并且Pod中所有容器都已经被kubelet创建。至少有一个容器正在运行,或者正处于启动或者重启状态(也就是说Running状态下的Pod不一定能被正常访问)。
- Succeeded:有些pod不是长久运行的,比如job、cronjob,一段时间后Pod中的所有容器都被成功终止,并且不会再重启。需要反馈任务执行的结果。
- Failed:Pod中的所有容器都已终止了,并且至少有一个容器是因为失败终止。也就是说,容器以非0状态退出或者被系统终止,比如 command 写的有问题。Unknown:表示无法读取 Pod 状态,通常是 kube-controller-manager 无法与 Pod 通信。
10、故障排查命令
|---------------|---------------------------------|
| 操作 | 命令 |
| 查看事件 | kubectl describe pod <POD> |
| 查看日志 | kubectl logs <POD> [-c 容器名] |
| 进入容器 | kubectl exec -it <POD> bash |
| 查看集群状态 | kubectl cluster-info |
| 查看节点状态 | kubectl get nodes |
| 查看 kubelet 日志 | journalctl -xefu kubelet |