KEEL · 龙骨 · A CURRICULUM FOR THE AI ERA
00 · Pod — keel 龙骨
类型:主题概念 · 应用课对应:02 章 · 清单解剖
类型:主题概念 · 应用课对应:02 章 · 清单解剖
这一页只回答四件事:它为什么会出现、它是什么、它长什么样、它怎么工作。
一、它为什么会出现
从 Docker 过来的人会撞上一个很具体的错位:
在 Docker 里,你 run 出来的东西叫「容器」,容器就是那个单位。
到了集群里,kubectl get pods 出来的行叫 Pod,名字还是自己拼的。
你要看它的地址,得 get pods -o wide,而地址并不属于容器。
这个错位不是命名习惯不同。集群要干的事是"把一份工作放到某台机器上,并在它坏掉时补一个"——
那么它必须能回答一个问题:一次放上去的、以及一次换掉的,到底是多大的一块?
如果答案是"一个容器",就会缺一块:有些容器必须和别人待在一起才能工作。一个负责业务、
一个负责把日志转发出去,它们得在同一台机器上、用同一个地址、看同一份文件。
拆成两个可以各自调度的单位,这件事就没法表达。
所以调度的单位不是容器。它多出来的那一层,就是为了让"必须一起的那些容器"有地方放。
二、它是什么
一句话:Pod 是集群里最小的一次调度单位——一个能被放上某台机器、也能被整个换掉的盒子,
里面装着一个或多个容器,它们共享同一个地址。
由此有两个直接后果,都是日常要用的判断:
- 换掉的是整个盒子,不是里面的容器。 盒子被换掉时,里面所有容器一起重造,
地址也跟着重新分配——所以"更新一个容器"在集群里从来不是原地操作。 - 一个盒子里有几个容器,
get pods的READY那一列会告诉你。1/1是"要 1 个、起来了 1 个"。
它不是这两样东西——混淆会带来误判:
- 不是"容器的另一个名字"。 一个 Pod 里可以有多个容器,它们才共享地址。
把 Pod 读成容器,会在读READY、读地址归属、读"为什么它整个被替换"时连环出错。 - 不是虚拟机。 它不带来独立内核、不带来独立操作系统。里面容器共享的照旧是节点的内核,
你在 Docker 那层学的边界一条都没变松。
三、它长什么样
一个 Pod 自己写出来的样子,和它在列表里的样子,是同一件事的两面。
列表里(kubectl get pods,Kubernetes v1.37.0):
NAME READY STATUS RESTARTS AGE
web-565bc6668-c9g8d 1/1 Running 0 33s
这是一行 Pod,READY 的分母读的是容器。 地址不在这里,加 -o wide 才看得到:
NAME READY STATUS RESTARTS AGE IP NODE
web-565bc6668-c9g8d 1/1 Running 0 36s 10.244.0.8 keel-lab-control-plane
它自己写出来的样子(-o yaml 的骨架,省略掉大量由集群填写的字段):
apiVersion: v1
kind: Pod
metadata:
name: web-565bc6668-c9g8d
labels:
app: web
spec:
containers: # ← 这里可以有多个;它们共享下面的地址
- name: web
image: nginx:1.27-alpine
status:
phase: Running
podIP: 10.244.0.8 # ← 地址在这一层,不在容器上
两处要读准:containers 是列表(这就是"一个盒子可以装多个"的写法),podIP 在 status 里、和 containers 同级(这就是"地址属于盒子不属于容器"的写法)。
四、它怎么工作
一个 Pod 从被提到到消失,五步:
① 提出 你交的模板被算成一份 Pod 定义(名字、镜像、标签、要多少资源)
② 落位 调度器找一台装得下它的节点,把它交给那台节点
③ 造物 那台节点上的组件按定义把里面的容器挨个造出来,并分配一个地址给它
④ 就绪 里面该起来的容器都起来了,这个 Pod 才算 Ready
⑤ 替换 它被删掉时,整份定义连同地址一起作废;要补,就按同一份定义再造一个全新的
第 ⑤ 步是全部误会里最要紧的一步:没有"修复"这个动作,只有"重造"。
所以你删掉一个 Pod 之后看到的那个新名字、新地址,不是原物被救回来了,
而是同一份定义被又执行了一遍。
五、它会带出哪些概念
- 控制器:第 ⑤ 步说"要补就再造一个",可"谁决定要补"是另一个东西。→ 01 控制器
- Service:地址随 Pod 一起作废,那么总得有一个不变的东西站在前面。→ 02 Service
- 节点:第 ② 步"找一台装得下的"里,"装得下"是谁在算、按什么算。→ 03 节点
- 探针:第 ④ 步"它才算 Ready"里,谁在判定 Ready、判错了会怎样。→ 应用课 03 章
六、回到应用课
| 应用课里的那句话 | 现在你知道它为什么成立 |
|---|---|
01 章:"调度失败的原因是没有任何节点满足这个 Pod 的 requests" |
账是按整个 Pod 里所有容器的 requests 之和算的,不是按某一个容器算的——这就是为什么多容器共处一个盒子会互相影响能不能落位 |
| 02 章:"Service 不创建 Pod,只『选择』 Pod" | 标签写在Pod 上(metadata.labels),所以 Service 维护的那份名单是盒子的名单;盒子被换掉,名单跟着换 |
| 02 章:"改了 Pod 标签……Deployment 完全正常,4 个 Pod 都 Running 且 Ready" | 改的是盒子身上的标记,跟盒子里跑什么无关——所以它能同时做到"服务全挂"和"每个容器都健康" |
| 03 章:"健康被拆成三个判断,因为『进程活着』与『能服务』是两件事" | 探针探的是盒子里的那个容器,但结论写在盒子的状态上——你在 get pods 里看到的 READY 就是这份结论 |
这一页改变了你的哪个判断:以后读 kubectl get pods,你要先问一句"这一行的单位是什么"——
名字、地址、READY 的分母、以及它会不会被整个替换,四件事全挂在"盒子"这个单位上,
任何一条按"容器"去理解都会推错。
自测题
kubectl get pods -o wide里IP那一列,为什么在-o yaml里不是写在containers下面?- 删掉一个 Pod 之后回来的那个,名字和地址都变了。这个"变"是替换还是修复?