chat
很好,这一步其实已经进入 现代云计算真正的执行路径了。
你问的是:
✅ 当 CMDB 在 Kubernetes 中“分配机器资源(创建实例 / Pod)”时 从控制面到 Linux Kernel,物理世界到底发生了什么?
我们直接按 真实生产级时间线拆解。
一、先给最终物理结论
当你在 CMDB / 平台点击:
申请一个应用实例(K8s)
最终物理世界发生的是:
某台 Linux 服务器新增了一组被 cgroup + namespace 隔离的进程。
但相比 Docker:
✅ 多了一整层 分布式控制系统
整体本质:
Kubernetes = 分布式容器状态机
二、完整链路总览(极其重要)
真实路径:
CMDB
↓
平台API / PaaS
↓
Kubernetes API Server
↓
etcd(状态存储)
↓
Scheduler
↓
kubelet(目标Node)
↓
container runtime
↓
runc
↓ syscall
Linux Kernel
↓
CPU / Memory / Network / Disk
真正改变物理世界的位置只有:
✅ kubelet → runtime → runc → Kernel
三、Step 1:CMDB 发生了什么?
CMDB 创建:
{
"app": "order-service",
"cpu": "2",
"memory": "4Gi"
}
然后调用:
POST /apis/apps/v1/deployments
发送给:
Kubernetes API Server
关键认知:
Kubernetes 不创建资源
Kubernetes 只记录 期望状态(Desired State)
四、Step 2:API Server 写入 etcd
API Server 做:
validate
auth
admission
然后写入:
etcd
etcd 内:
Pod:
name: order-xxx
cpu: 2
mem: 4Gi
node: null
注意:
⚠️ Pod 仍不存在。
K8s 此刻只是说:
世界应该存在一个 Pod。
五、Step 3:Scheduler 开始工作
Scheduler 持续 Watch:
未绑定Node的Pod
它查询:
Node-A 剩余 8CPU
Node-B 剩余 1CPU ❌
Node-C 剩余 32CPU ✅
执行:
Filter → Score → Bind
最终:
Pod → Node-C
Scheduler 更新 etcd:
nodeName: node-c
⚠️ 仍然没有容器。
六、Step 4:kubelet 接管(关键转折)
每台机器运行:
kubelet
它持续 Watch:
API Server
当发现:
有Pod属于自己
kubelet 开始:
让现实世界符合声明状态
这一步极其重要:
K8s = reconciliation loop
七、Step 5:kubelet 调用 Container Runtime
kubelet 不创建容器。
它调用:
CRI(Container Runtime Interface)
例如:
- containerd
- CRI-O
调用:
RunPodSandbox()
CreateContainer()
StartContainer()
进入 runtime。
八、Step 6:containerd → runc
containerd:
- 拉镜像
- 准备 rootfs
- 生成 OCI spec
然后执行:
runc create
runc start
真正进入 Linux Kernel。
九、Step 7:Linux Kernel 真实变化(核心)
现在开始是物理世界变化。
① 创建 Namespace
runc 调用:
clone()
Kernel 创建:
| Namespace | 隔离内容 |
|---|---|
| PID | 进程 |
| NET | 网络 |
| MNT | 文件系统 |
| IPC | 信号 |
| UTS | hostname |
| USER | 用户 |
结果:
新的进程视角宇宙
② 创建 cgroup(真正资源分配)
kubelet 提前创建:
/sys/fs/cgroup/kubepods/
结构:
kubepods
└ burstable
└ podUID
└ containerID
写入:
CPU
cpu.max
限制 CPU 时间片。
Memory
memory.max=4G
Kernel memcg 生效。
物理世界改变:
Linux Scheduler 调度策略发生变化。
③ OverlayFS 挂载
镜像层:
readonly layers
+
writable layer
Kernel:
mount overlayfs
生成容器 rootfs。
④ 网络创建(最复杂)
kubelet 调用:
CNI Plugin
如:
- Calico
- Flannel
- Cilium
CNI 执行:
ip netns add
veth pair create
结构:
Pod eth0
↓
veth
↓
host bridge / vxlan / ebpf
↓
Node Network
物理变化:
✅ routing table 修改 ✅ iptables/eBPF rule 注入
十、Step 8:容器进程启动
最终:
execve()
例如:
/nginx
Linux 创建:
普通进程
只是属于:
namespace + cgroup
Pod Running。
十一、CMDB 最后才更新
流程:
Container Running
↓
kubelet report status
↓
API Server
↓
平台同步
↓
CMDB status=Running
CMDB 永远是:
最后知道的人。
十二、整个流程一句话(核心理解)
当 CMDB 在 K8s 中分配资源:
CMDB 定义期望
↓
K8s 保存状态
↓
Scheduler 选择节点
↓
kubelet 驱动 runtime
↓
runc 调 syscall
↓
Linux Kernel 创建隔离进程
↓
硬件调度规则改变
十三、物理服务器真实发生的变化
假设 Node:
64 CPU
256G RAM
新增一个 Pod 后:
物理世界仅新增:
✅ 几个 Linux 进程 ✅ 新 cgroup ✅ namespace ✅ overlay mount ✅ veth ✅ iptables/eBPF 规则
没有 VM。
十四、最重要的认知升级(AIOps核心)
K8s 故障 ≠ Pod 问题。
真实层级:
Pod
↓
cgroup
↓
Linux Scheduler
↓
NUMA
↓
CPU Cache
↓
Hardware
AI Root Cause 如果看不到:
cgroup throttle
memory reclaim
runqueue latency
就永远定位不到问题。
参考资料
- chat
- 一、先给最终物理结论
- 二、完整链路总览(极其重要)
- 三、Step 1:CMDB 发生了什么?
- 四、Step 2:API Server 写入 etcd
- 五、Step 3:Scheduler 开始工作
- 六、Step 4:kubelet 接管(关键转折)
- 七、Step 5:kubelet 调用 Container Runtime
- 八、Step 6:containerd → runc
- 九、Step 7:Linux Kernel 真实变化(核心)
- 十、Step 8:容器进程启动
- 十一、CMDB 最后才更新
- 十二、整个流程一句话(核心理解)
- 十三、物理服务器真实发生的变化
- 十四、最重要的认知升级(AIOps核心)
- 参考资料
