k8s

前置工作: docker配置中“渡渡鸟”的国内镜像同步站配置镜像加速器

[root@k8s-master01 ~]# cat /etc/docker/daemon.json
{
"data-root": "/data/docker",
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "100"
},
"insecure-registries": ["harbor.fangpch.com"],
"registry-mirrors": [
"https://docker.aityp.com",
"https://docker.1ms.run",
"https://docker.xuanyuan.me"
]
}

 

pod:

主进程(PID 1)不是指 Pod 里的某一个特定容器,而是指 Pod 中【每一个容器】内部自己的主进程。
为了让你彻底理清这个概念,我们从以下三个维度来拆解:

1. 什么是“主进程(PID 1)”?

在 Linux 系统(容器底层就是 Linux)中,当一个容器被启动时,它会运行你在 YAML 中配置的 command(或者 Dockerfile 中的 ENTRYPOINT)。
  • 这个启动命令在容器内部产生的第一个进程,就是主进程(PID 1)
  • 核心铁律:只要这个 PID 1 还在运行,容器就处于 Running 状态;一旦这个 PID 1 退出了,K8s 就认为这个容器“死”了。

2. 多容器 Pod 中,restartPolicy 是如何工作的?

假设你的 Pod 里有 3 个容器(A、B、C)。restartPolicy: Always 是作用在 Pod 级别的,但 Kubelet 在执行时,是分别盯着每一个容器的:
  • 如果容器 A 的 PID 1 崩溃退出了:Kubelet 发现 A 死了,就会只重启容器 A。容器 B 和 C 完全不受影响,继续正常运行。
  • 如果容器 B 的 PID 1 也崩溃了:Kubelet 就会去重启容器 B。
  • 如果 A、B、C 全都崩溃退出了:Kubelet 会把它们挨个重启。
所以,restartPolicy 就像是 Kubelet 给每个容器派发的“独立监工”,谁挂了,Kubelet 就重启谁。
 
进程突然挂掉(退出),是由 restartPolicy 触发重启的;而存活探针(Liveness Probe)和就绪探针(Readiness Probe)都不会因为进程挂掉而触发重启。
为了让你彻底搞懂如何判断,我们需要理清它们三者的“管辖范围”和“判断方法”:

1. 到底是谁让它重启的?(职责划分)

  • restartPolicy(重启策略):负责“进程级”的兜底。
    只要容器的主进程(PID 1)退出了(无论是正常退出还是崩溃退出),Kubelet 就会立刻介入,根据 restartPolicy(如 Always)来重启容器。
  • 存活探针(Liveness Probe):负责“应用级”的自救。
    它只在进程还在运行,但应用卡死(假死/死锁)时发挥作用。如果存活探针失败,Kubelet 会主动杀死这个容器,然后触发 restartPolicy 进行重启。
  • 就绪探针(Readiness Probe):绝对不负责重启。
    就绪探针失败,只会把 Pod 从 Service 的 Endpoints 中剔除(切断流量),容器依然活着,绝对不会重启

2. 我怎么判断到底是哪个触发的?(实战排查)

当 Pod 发生重启时,你可以通过以下两个命令来像“侦探”一样找出真凶:

第一步:看重启次数和当前状态

bash
 
 
 
1kubectl get pod <pod-name>
看 RESTARTS 列是否增加了。如果增加了,说明发生了重启。

第二步:看 Pod 的详细事件(核心证据)

bash
 
 
 
1kubectl describe pod <pod-name>
重点看输出结果最下方的 Events(事件) 和 Containers(容器状态) 部分:
场景 A:进程自己挂掉的(restartPolicy 触发)
如果你看到类似这样的信息,说明是进程自己崩溃了,Kubelet 只是按规矩把它拉起来:
text
 
 
 
1Containers:
2  myapp:
3    State:          Waiting
4      Reason:       CrashLoopBackOff
5    Last State:     Terminated
6      Reason:       Error
7      Exit Code:    137  (或 1, 139 等)
注:Exit Code 非 0 表示异常退出,Kubelet 根据 Always 策略自动重启。Events 中通常没有 Unhealthy 警告。
场景 B:存活探针失败导致的重启(Liveness Probe 触发)
如果你看到类似这样的信息,说明应用假死了,被探针“处决”了:
text
 
 
 
1Events:
2  Type     Reason     Age   From               Message
3  ----     ------     ----  ----               -------
4  Warning  Unhealthy  2m    kubelet, node-01   Liveness probe failed: HTTP probe failed with statuscode: 500
5  Normal   Killing    2m    kubelet, node-01   Container myapp failed liveness probe, will be restarted
注:明确出现了 Liveness probe failed 和 will be restarted,这是存活探针杀人的铁证。
场景 C:就绪探针失败(Readiness Probe 触发)
如果你看到类似这样的信息,说明应用没准备好,被切断了流量,但没有重启
text
 
 
 
1Events:
2  Type     Reason     Age   From               Message
3  ----     ------     ----  ----               -------
4  Warning  Unhealthy  2m    kubelet, node-01   Readiness probe failed: HTTP probe failed with statuscode: 503
注:只有 Readiness probe failed没有 will be restarted,且 RESTARTS 次数不会增加。

总结

  • 进程没了 -> 找 restartPolicy
  • 进程还在但卡死 -> 找 Liveness Probe
  • 进程还在但还没准备好接客 -> 找 Readiness Probe
通过 kubectl describe pod 看 Events 里的 Reason 和 Message,你就能百分之百确定是谁在背后操纵了容器的生死!
 
K8s 控制平面(API Server)只负责下发“期望状态”,而真正干活的是运行在每个节点上的 Kubelet。
  • 自动接管:Kubelet 会持续监听并对比 Pod 的期望状态和实际状态。如果某个容器崩溃了,Kubelet 会自动调用容器运行时(如 containerd)把它重启起来,根本不需要人工干预。
  • 同生共死:当用户执行 kubectl delete pod 时,Kubelet 会接管这个删除指令,向 Pod 内的所有容器发送终止信号(SIGTERM),并在优雅期过后强制清理它们,最后释放网络和存储资源。
一句话总结你的感悟:
在 K8s 的世界里,不要试图去“微操”单个容器。把 Pod 当作一个不可分割的“命运共同体”,把容器的生老病死交给 Kubelet 去自动兜底,这才是云原生时代正确的运维姿势!
 
 
labels加载容器上还是pod上
 
 
 
在 Kubernetes 中,标签(Labels)是加载在 Pod 级别(以及 Node、Service 等其他 K8s 对象上),而不是加载在单个容器(Container)上的。

为什么标签加在 Pod 上?

这与我们之前讨论过的 K8s 核心设计哲学完全一致:
  • Pod 是最小逻辑单元:标签的作用是对资源进行分类、分组和关联(例如让 Service 通过选择器找到对应的 Pod,或者让 Node 亲和性规则决定 Pod 调度到哪台机器)。
  • 容器只是执行单元:Pod 内的所有容器共享同一个网络 IP 和存储卷。K8s 把 Pod 作为一个整体来管理,因此用来标识和选择资源的标签自然也是打在 Pod 这个“逻辑外壳”上的。

如何在 YAML 中配置?

在编写 YAML 清单时,标签(labels)是写在 Pod 的 metadata 字段下的,而不是写在 spec.containers 里面:
yaml
 
 
 
1apiVersion: v1
2kind: Pod
3metadata:
4  name: my-pod
5  labels:               # <--- 标签写在这里,属于 Pod 级别
6    app: nginx
7    environment: prod
8spec:
9  containers:           # <--- 容器配置里没有 labels 字段
10    - name: nginx
11      image: nginx:1.14.2

补充说明

虽然标签是打在 Pod 上的,但一个 Pod 可以包含多个容器。当你通过标签(如 app: nginx)选中了这个 Pod 时,实际上也就间接选中了它里面的所有容器。
此外,除了 Pod,Kubernetes 中的其他资源对象(如 Node 节点、Service、Deployment 等)也都拥有自己的标签系统,它们各自独立,互不干扰。
 
 
 
 
钩子执行失败对业务容器有什么影响,这两个是并行启动的,会不会不相干
 
 
 
这是一个非常关键且容易让人产生误解的问题!
你的直觉很敏锐,它们确实是“并行启动”的(即容器主进程和 postStart 钩子同时被触发),但这绝对不意味着它们“不相干”
如果钩子执行失败,对业务容器有着极其致命的直接影响业务容器会被直接杀死(终止),并根据重启策略决定是否重启
为了让你彻底理清这个逻辑,我们需要从官方文档的定义和底层的执行机制来剖析:

1. 为什么“并行”还会互相影响?

Kubernetes 官方文档对 postStart 的描述是:“postStart 处理函数与容器的代码是异步执行的,但 Kubernetes 的容器管理逻辑会一直阻塞等待 postStart 处理函数执行完毕”。
这句话听起来很矛盾,但它的真实含义是:
  • 异步执行:容器的主进程(ENTRYPOINT)和 postStart 钩子是被同时触发启动的。
  • 管理逻辑阻塞:虽然主进程在跑,但 Kubelet(容器管理逻辑)在底层会一直盯着 postStart。如果 postStart 挂起或执行时间过长,Pod 会一直卡在 ContainerCreating 状态,无法进入 Running 状态。

2. 钩子失败的具体影响

无论是 postStart(启动后钩子)还是 preStop(停止前钩子),只要它们执行失败(比如脚本报错、HTTP 请求超时等),Kubernetes 的处理机制都非常简单粗暴:
  • 直接杀死容器:Kubelet 会立即终止该容器的主进程。
  • 触发重启:如果 Pod 的 restartPolicy 是 Always(默认值),容器被杀死后会被重新拉起,这就可能导致容器陷入反复启动又失败的死循环(CrashLoopBackOff)。

3. 一个形象的比喻

你可以把 postStart 钩子看作是容器启动时的“入职安检”
  • 容器的主进程就像是“新员工”,安检(钩子)和员工上班(主进程)是同时开始的。
  • 但是,如果新员工在安检时被发现违规(钩子执行失败),虽然他已经坐在了工位上(主进程可能在跑),但公司保安(Kubelet)会立刻把他赶出公司(杀死容器),让他重新走入职流程(重启)。

总结与最佳实践

虽然它们是并行触发的,但 postStart 钩子拥有对容器生死的“一票否决权”
因此,在实际生产环境中,Kubernetes 官方强烈建议:
  • 保持钩子轻量级:钩子处理程序应该尽可能轻量,避免执行耗时过长的操作。
  • 重型初始化用 Init Container:如果你有需要长时间运行、且必须在主业务进程启动前完成的初始化任务,千万不要放在 postStart 里,而应该使用 Init Container(初始化容器)。Init 容器是串行执行的,只有它成功退出了,主容器才会被创建。
 
posted @ 2026-04-25 16:21  *Tesla*  阅读(21)  评论(0)    收藏  举报
       [00:00.000] 作词 : 陈信荣
    [00:01.000] 作曲 : 周传雄
    [00:02.000] 编曲 : 周传雄
    [00:03.000] 制作人 : 周传雄
    [00:29.259]过完整个夏天
    [00:34.742]忧伤并没有好一些
    [00:41.185]开车行驶在公路无际无边
    [00:47.320]有离开自己的感觉
    [00:52.453]
    [00:53.347]唱不完一首歌
    [00:59.370]疲倦还剩下黑眼圈
    [01:05.596]感情的世界伤害在所难免
    [01:11.703]黄昏再美终要黑夜
    [01:18.292]依然记得从你口中说出再见坚决如铁
    [01:24.732]昏暗中有种烈日灼身的错觉
    [01:30.171]黄昏的地平线
    [01:33.230]划出一句离别
    [01:36.313]爱情进入永夜
    [01:42.165]
    [01:42.881]依然记得从你眼中滑落的泪伤心欲绝
    [01:49.290]混乱中有种热泪烧伤的错觉
    [01:54.774]黄昏的地平线
    [01:57.816]割断幸福喜悦
    [02:00.915]相爱已经幻灭
    [02:07.171]
    [02:19.647]唱不完一首歌
    [02:25.497]疲倦还剩下黑眼圈
    [02:31.753]感情的世界伤害在所难免
    [02:37.881]黄昏再美终要黑夜
    [02:42.994]
    [02:44.363]依然记得从你口中说出再见坚决如铁
    [02:50.872]昏暗中有种烈日灼身的错觉
    [02:56.291]黄昏的地平线
    [02:59.393]划出一句离别
    [03:02.507]爱情进入永夜
    [03:08.340]
    [03:09.205]依然记得从你眼中滑落的泪伤心欲绝
    [03:15.531]混乱中有种热泪烧伤的错觉
    [03:20.937]黄昏的地平线
    [03:23.991]割断幸福喜悦
    [03:27.025]相爱已经幻灭
    [03:34.375]
    [03:58.563]依然记得从你口中说出再见坚决如铁
    [04:04.694]昏暗中有种烈日灼身的错觉
    [04:10.141]黄昏的地平线
    [04:13.156]划出一句离别
    [04:16.228]爱情进入永夜
    [04:21.297]
    [04:22.863]依然记得从你眼中滑落的泪伤心欲绝
    [04:29.401]混乱中有种热泪烧伤的错觉
    [04:34.714]黄昏的地平线
    [04:37.774]割断幸福喜悦
    [04:40.913]相爱已经幻灭
    [05:39.200] 配唱制作人 : 吴佳明
    [05:39.533] 钢琴 : 周传雄
    [05:39.866] 吉他 : 许华强
    [05:40.199] 鼓 : Gary Gideon
    [05:40.532] 贝斯 : Andy Peterson
    [05:40.865] 弦乐编写 : 吴庆隆
    [05:41.198] 弦乐 : 孔朝晖/顾文丽/隋晶晶/梁中枢/尹淑占/王言/关旗
    [05:41.531] 和声编写 : 周传雄
    [05:41.864] 和声 : 周传雄
    [05:42.197] 录音师 : 林世龙/沈文钏/Geoffrey Lee
    [05:42.530] 混音师 : 王晋溢
    [05:42.863] 录音室 : 强力/HASAYAKE/Atomic & Audioplex (Singapore)
    [05:43.196] 混音室 : 白金
    [05:43.529] OP : Sony/ATV Music Publishing Taiwan/哈萨雅琪有限公司
    [05:43.862] SP : Sony/ATV Music Publishing Taiwan​