在 Docker Engine 29.8.2 里实测僵尸进程:不 wait 的 PID 1 留下 50 个僵尸;--init 只能收孤儿(孤儿 50 个 → 0 个僵尸),父进程还活着时僵尸照旧 50 个;僵尸占着进程号,--pids-limit 40 下 39 个僵尸后创建子进程失败;docker top 看不到僵尸,容器里的 ps 才看得到。
在 Docker Engine 29.8.2 里实测 --init:PID 1 变成 /sbin/docker-init(tini 0.19.0,601296 字节,VmRSS 508 kB,运行时从虚拟机只读挂载进容器,不在镜像里),你的程序是 PID 7;子进程的退出码(3、137、143)原样穿过;能自己处理信号的程序有没有 init 都收到 SIGUSR1;启动开销中位数 175 ms 对 170 ms,在抖动范围内。
在 kind 集群里实测 LimitRange:没写 resources 的 Pod 在准入时被补上默认 request/limit(并留下 limit-ranger 注解),默认值自己若违反 maxLimitRequestRatio 会让所有未写的 Pod 被拒绝;只写 limit 时 request 取 limit 的值;超出 max、低于 min、limit/request 比过大的 Pod 与超出范围的 PVC 都被拒绝并写明数值;修改 LimitRange 不影响已有的 Pod。
在 kind 集群里实测 ResourceQuota:创建 Pod 时 status.used 立即累加;requests.cpu、pods 等超限的 Pod 在创建那一刻被拒绝(exceeded quota: …, requested/used/limited),Deployment 能创建但 ReplicaSet 创建 Pod 被拒、READY 只有 2/5;配额里有 requests/limits 时 Pod 必须写明,配合 LimitRange 补默认值才能通过;count/configmaps 限制个数;scopes: [BestEffort] 只统计 BestEffort Pod,删除后用量立即归零。
在 Docker Engine 29.8.2 里实测 --ulimit:默认 nofile 是 1048576、nproc 无限制;nofile=64 时只能再打开 61 个文件(扣掉 0/1/2);soft 不能超过 hard、普通用户的 hard 只能降不能升;nproc 按用户 uid 在系统范围内统计,两个同 uid 容器占掉 14 个进程后,新容器 nproc=20 只能再建 5 个。
在 kind 集群里实测优先级与抢占:PriorityClass 在准入时写入 pod.spec.priority(没写是 0,不存在的类被拒绝);两个 worker 被低优先级 Pod 占满后,高优先级 Pod 先得到 nominatedNodeName,受害者 low3 被设上 deletionTimestamp、事件 Preempted、条件 DisruptionTarget(PreemptionByScheduler),等它 12 秒宽限期结束后高优先级 Pod 才在第 13.1 秒 Running;受害者选优先级最低的;preemptionPolicy: Never 的 Pod 不抢占。
在 Docker Engine 29.8.2(cgroup v2)里实测 CPU 限制:--cpus 0.5/1/2 让满负荷的容器平均只占 0.50/1.00/2.02 个 CPU(cpu.max 的配额/周期),--cpu-quota 25000 是 0.25;--cpu-shares 没有竞争时不限制(shares 2 仍用满 2.00 个 CPU),同一 CPU 上争抢时按权重分,1024 对 512 约 1.57:1,shares 被换算成非线性的 cpu.weight(512 → 59、1024 → 100、2048 → 174)。
在 Docker Engine 29.8.2 里实测 CPU 节流对延迟的影响:30 ms 的任务在 --cpus 0.5 下 p50 从 30.0 变成 71.7 ms(累计被节流 2622 ms),周期改成 10 ms 后变成 56.3 ms;5 ms 的短任务 p50 不变但 p95 到 17.4 ms;4 进程并行 160 ms CPU 的任务在 --cpus 1 下最慢 188 ms(不限制 67 ms),全部被节流。
在 Docker Engine 29.8.2(cgroup v2)里实测 --memory 与 --memory-swap:只给 --memory 64m 时 swap 也被限在 64 MiB(memory.swap.max=67108864),--memory-swap 是内存加 swap 的总和;分配 200 MiB 时,不允许 swap 的容器在 50 MiB 被杀,允许 64 MiB swap 的在 110 MiB 被杀,swap 不限的 200 MiB 全部分配完(151 MiB 在 swap 里);--memory-reservation 对应 memory.low。
在 kind 集群里实测 PodDisruptionBudget:5 个 Pod 下 minAvailable 2 / 50% / maxUnavailable 1 / 50% / 100% 分别允许中断 3 / 2 / 1 / 3 / 0 个(百分比向上取整);Eviction API 在预算用完时返回 429 TooManyRequests,替代 Pod 就绪(6.0 秒)后才恢复;kubectl drain 被 PDB 拦住时每 5 秒重试、共用 6 秒,而 kubectl delete pod 绕过 PDB;unhealthyPodEvictionPolicy 为 AlwaysAllow 时不健康的 Pod 可以被驱逐,默认的 IfHealthyBudget 则返回 429。
在 Docker Engine 29.8.2 里实测容器 OOM:退出码 137、OOMKilled=True,docker events 里 die 前有 oom 事件,虚拟机内核日志有 “Memory cgroup out of memory: Killed process … (python)”;多进程容器里只杀吃内存的进程,容器仍 running 但 OOMKilled 已是 True;cgroup 的 memory.events 里 max 37、oom_kill 1;--oom-kill-disable 在 cgroup v2 上被丢弃。
在 Docker Engine 29.8.2 里实测 --pids-limit:对应 cgroup 的 pids.max(不限制是 max);线程也算进程数(limit 50 创建了 49 个线程后失败);--pids-limit 64 的容器里跑 fork 炸弹,进程数停在 64、pids.events 里 35 次 fork 失败,docker stop 与 docker ps 都正常。