知其然,知其所以然
Kubernetes 2026-10-10

原生 sidecar:restartPolicy Always 的 init 容器

在 kind 集群里实测原生 sidecar(initContainers 里 restartPolicy: Always):启动后不需要退出,startupProbe 通过后应用容器才在 +4.65 秒启动;Job 里写在 initContainers 的 sidecar 在 main 结束后被自动终止、Job 25 秒内 Complete,而写在 containers 里的 sidecar 让 Job 一直不完成;删除 Pod 时应用容器先收到 SIGTERM,退出后 0.04 秒 sidecar 才收到;sidecar 的 readinessProbe 参与 Pod 的 Ready,sidecar 崩溃只重启它自己。

Kubernetes sidecar 原生 sidecar init 容器 restartPolicy Always Job 真实验证 动画演示
Kubernetes 2026-10-10

preStop 与终止:优雅退出的时序

在 kind 集群里量出删除 Pod 的时间线:preStop 睡 5 秒时 SIGTERM 在 +5.15 秒才到、应用 +6.15 秒退出,而 EndpointSlice 里端点在 +0.15 秒就变成 terminating(ready=false);没有 preStop 时 SIGTERM 在 +0.07 秒到;preStop 比宽限期还长时钩子被截断,SIGTERM 在 +6.07 秒送达、SIGKILL 约在 +8.1 秒,Pod 8.5 秒后消失;preStop 失败只产生 FailedPreStopHook 事件,终止照常进行。

Kubernetes preStop 优雅终止 SIGTERM terminationGracePeriodSeconds EndpointSlice 真实验证 动画演示
Kubernetes 2026-10-10

terminationGracePeriodSeconds:SIGTERM 与 SIGKILL 之间发生了什么

在 kind 集群里量出 SIGTERM 与 SIGKILL 之间发生了什么:1 号进程没有 SIGTERM 处理函数时 Pod 要等满宽限期(3 秒 → 3.9 秒、8 秒 → 8.8 秒、默认 30 秒 → 30.3 秒);有 trap 时 0.8~1.2 秒退出;kubectl delete --grace-period=2 覆盖为 2.8 秒,--grace-period=0 --force 与 spec 里写 0 都是 0.1 秒;sh -c 包一层时子进程收不到 SIGTERM 要等 5.6 秒,用 trap 转发只要 0.5 秒。

Kubernetes terminationGracePeriodSeconds SIGTERM SIGKILL 优雅退出 1 号进程 真实验证 动画演示
Kubernetes 2026-10-10

CrashLoopBackOff:重启退避的时间序列

在 kind 集群里让一个容器每次运行 1 秒就崩溃,实测 CrashLoopBackOff 的退避时间序列:第 1 次重启几乎立刻,之后等待 14、26、45、83、161 秒(约 10 秒起步每次翻倍,含开销);STATUS 大部分时间是 Error,CrashLoopBackOff 只偶尔出现;多容器 Pod 中崩溃的容器各自退避,好容器不受影响;restartPolicy=Never 不重启因此没有退避;删除重建同名 Pod 后退避从头开始。

Kubernetes CrashLoopBackOff 重启退避 restartPolicy kubelet 真实验证 动画演示
Kubernetes 2026-10-10

QoS 等级:Guaranteed、Burstable、BestEffort 的划分

在 kind 节点(cgroup v2,systemd 驱动)里实测 QoS 等级:七个 Pod 的 requests/limits 组合分别得到 Guaranteed、Burstable、BestEffort;三类 Pod 的 cgroup 位置不同;Guaranteed 的 oom_score_adj 是 -997,Burstable 按 1000 − 1000×内存请求÷节点内存(32Mi → 996),BestEffort 是 1000;在线调整资源若会改变 QoS 等级则被拒绝(Pod QOS Class may not change as a result of resizing)。

Kubernetes QoS Guaranteed Burstable BestEffort cgroup oom_score_adj 真实验证 动画演示
Docker 容器原理 2026-10-10

Registry v2 API:一次 docker pull 发出了哪些 HTTP 请求

在本机 registry:2 上实测 docker push / pull 的 HTTP 请求:push 是 14 个请求(4 个 blob 先 HEAD 404、再 POST+PUT 上传,最后才 PUT manifest);本地还有层时 pull 只发 1 个 HEAD;从零拉取手工上传的镜像是 HEAD manifest、GET manifest(按摘要)、GET 两个 blob 共 4 个请求;registry 的 Accept 头不匹配时 manifest 返回 404。

Docker registry Registry v2 API docker pull docker push HTTP 真实验证 动画演示
Docker 容器原理 2026-10-10

本地 registry:自建仓库、推送与垃圾回收

在本机 registry:2 上实测自建仓库的推送与回收:默认 DELETE manifest 返回 405,开启 REGISTRY_STORAGE_DELETE_ENABLED 后返回 202 但磁盘几乎没变(8352 → 8320 KB),要 garbage-collect 才回收(8320 → 6248 KB,7 → 4 个 blob 文件);不同仓库之间推送共享层时直接 Mounted from。

Docker registry 本地仓库 垃圾回收 garbage-collect 真实验证 动画演示
Docker 容器原理 2026-10-10

docker save 的 tar 里有什么:层目录与 manifest.json

在 Docker Engine 29.8.2 里实测镜像的导出与导入:docker save 的 tar 是 4518 KB(压缩内容,而 inspect 的 Size 是 14290 KB);rmi 后 docker load 得到相同的镜像 ID;两个共用基础层的镜像一起 save 比分开少 4001 KB;docker export / import 会把镜像压成 1 层并丢掉 Env 和 Cmd。

Docker docker save docker load docker export docker import 镜像导出 真实验证 动画演示
Docker 容器原理 2026-10-10

层共享:多个镜像共用同一层时磁盘占多少

在 Docker Engine 29.8.2 里实测层共享的磁盘占用:3 个镜像共用一个 55.5MB 的基础镜像,每个的 SIZE 都是 57.6MB(SHARED 55.53MB、UNIQUE 2.104MB),四个 SIZE 相加 228.3MB,而基础加三个 UNIQUE 只有 61.8MB;删掉基础镜像的名字不影响子镜像。

Docker 层共享 磁盘占用 docker system df 镜像大小 真实验证 动画演示
Docker 容器原理 2026-10-10

overlay2 目录结构:lower、upper、work 与 merged

进到 Docker Desktop 的虚拟机里实测容器的 overlay 挂载:这个 Docker 用 containerd 的 overlayfs snapshotter(不是 overlay2),4 层镜像的容器有 5 个 lowerdir(多出一个容器创建时的层:hostname、resolv.conf、hosts 等),upperdir 初始为空,新建和修改的文件落在 upperdir,docker rm 后 upperdir 随之删除而镜像层仍在。

Docker overlayfs overlay2 lowerdir upperdir 容器文件系统 真实验证 动画演示
Docker 容器原理 2026-10-10

OverlayFS 的 copy-up:修改一个大文件第一次写入有多慢

在 Docker Desktop 里实测 OverlayFS 的 copy-up:镜像里 128 MiB 的文件,容器里第一次追加 1 字节要 155.0~2174.1 ms(3 次),之后追加约 0 ms;只 chmod 也要 179.6~862.0 ms;upperdir 里是整个文件的拷贝;放在 volume 里的同样文件追加 0.0 ms。

Docker OverlayFS copy-up 写时复制 容器性能 真实验证 动画演示
Docker 容器原理 2026-10-10

OverlayFS 里的删除:whiteout 与 opaque 目录

进入 Docker Desktop 虚拟机实测 OverlayFS 的删除:删除镜像里的文件会在 upperdir 里留下 0:0 的字符设备(whiteout),删除又重建的目录带 trusted.overlay.opaque=y,删除再同名重建的文件是普通文件;docker commit 之后镜像层里则是 .wh.名字 条目,而不是字符设备。

Docker OverlayFS whiteout opaque 删除文件 容器文件系统 真实验证 动画演示
京ICP备2026067502号-1京公网安备11010502063487号