实测 docker context:上下文存放在 ~/.docker/contexts/meta/名字的 sha256 目录下的 meta.json,当前上下文记在 config.json 的 currentContext;新建上下文后用 --context 或 DOCKER_CONTEXT 临时使用而不改当前配置;优先级是 -H / --context 胜过 DOCKER_HOST,DOCKER_HOST 胜过 DOCKER_CONTEXT,--context 与 -H 同时给报冲突;ssh 上下文通过 ssh 连接远端。
在 kind 集群里实测 Job:completions=6、parallelism=2 的 Job 最多同时 2 个 Pod、分 3 批共 18 秒完成,Indexed 模式给每个 Pod 序号;总是失败的 Job 在 backoffLimit=2 时 restartPolicy: Never 新建 3 个 Pod(创建时刻 0/10/30 秒的指数退避)、OnFailure 原地重启容器(restartCount 2),都以 BackoffLimitExceeded 失败;activeDeadlineSeconds=8 在 8.8 秒后以 DeadlineExceeded 失败并删掉 Pod;suspend 暂停时不创建 Pod,ttlSecondsAfterFinished=8 在完成后约 7.8 秒自动删除 Job 与 Pod。
只读查看 Docker Desktop 的引擎配置:Mac 上 ~/.docker/daemon.json 只有 builder.gc 和 experimental 两项,虚拟机里实际生效的 daemon.json 有 20 个键,其余由 Docker Desktop 补充(log-driver local、storage-driver overlayfs、default-stop-timeout 3、mtu 65535、host-gateway-ips、userland-proxy false 等),并与前面各篇观察到的行为一一对应。
在 kind 集群里让 CronJob 真实跑 5 分钟:每个 Job 睡 75 秒、每分钟一次,Allow 每个整分创建一个互相重叠的 Job,Forbid 在上一个跑完后才补建被跳过的调度(+4.0、+81.0、+160.0、+238.0 秒,越拖越晚,事件 JobAlreadyActive ×10),Replace 每个整分先删掉上一个再创建新的;suspend 150 秒后恢复只补最近那一次;startingDeadlineSeconds=10 时错过 31 秒的调度不补,等下一个整分;默认保留成功 3 个、失败 1 个历史 Job。
在 kind 集群里实测 PV 与 PVC 的配对:3Gi 的 PVC 在 2Gi/5Gi/10Gi 三个 PV 里选最小够用的 5Gi;20Gi、RWX 或存储类不同的 PVC 保持 Pending,新增匹配的 PV 后 7.4 秒自动绑定;selector 选标签、claimRef 预留给指定 PVC;Retain 的 PV 在删除 PVC 后变 Released 且不会被别人拿走,去掉 claimRef 后 4.5 秒可再次绑定;动态供给的 standard 是 WaitForFirstConsumer、reclaimPolicy Delete,PV 随 PVC 一起被删除。
在 kind 集群里实测 StorageClass 的动态供给:local-path 在 Immediate 模式下因不知道节点而 ProvisioningFailed,在 WaitForFirstConsumer 模式下等 Pod 调度后 2.2 秒 Bound 且 PV 带该节点的亲和;一次供给的事件序列 WaitForFirstConsumer → ExternalProvisioning → Provisioning → ProvisioningSucceeded(3.2 秒);不写 storageClassName 会被补成默认类,空字符串表示不动态供给,多个默认类时选最新的;存储类的 reclaimPolicy 被供给出的 PV 继承,Retain 时删 PVC 后数据仍在。
在一个嵌套的 dockerd 里实测 live-restore:默认停 dockerd 要先停掉所有容器(10.3 秒),重启后容器 exited(137);--live-restore 下停 dockerd 只要 0.1 秒,容器主进程继续运行,重启后同一个 PID、同一个 StartedAt 被重新接管;kill -9 dockerd 同样不影响;dockerd 停着时 docker 命令全部失败。Docker Desktop 默认没有开启。
在 Docker Engine 29.8.2 里实测构建缓存何时失效:只改文件修改时间不会失效,改内容才会,而且从那条 COPY 起后面全部重新执行;先 COPY 依赖清单再 COPY 源码,改源码的构建从 3.4 秒降到 0.3 秒;加注释和行尾空格不失效,改命令字符或前面插入 ENV 才失效;--no-cache-filter 只让指定阶段重跑。
在 Docker Engine 29.8.2 里实测镜像压平:一个 RUN 生成 30 MB 文件、下一个 RUN 删除,镜像仍是 76.5 MB(4 层);同一个 RUN 里生成并删除则是 13.6 MB;FROM scratch + COPY --from 把整个根文件系统压成 1 层(13.6 MB),但 ENV 和 CMD 要重新写;export | import 同样丢元数据;docker build --squash 在 BuildKit 下被忽略。
自己写 Python 分析 docker save 出来的镜像层(类似 dive):故意构造覆盖文件、删除文件、只改权限的 Dockerfile,7 层里文件字节总和 45.5 MB,被后面层覆盖或删除的浪费 26.2 MB(效率 42.4%);chmod 也会重写整个 10.5MB 的文件;合并成一条 RUN 后镜像从 87.0 MB 降到 34.6 MB,容器里的文件完全一样。
在 Docker Engine 29.8.2 里实测非 root 运行:USER app(uid 10001)后进程 CapEff 为 0、只能写 /tmp 和 HOME;COPY 默认仍归 root(要加 --chown),USER 之后创建的 WORKDIR 属于该用户;--user 可以覆盖,passwd 里没有的 uid 没有名字、HOME 是 /;USER 在构建时就生效,之后的 RUN mkdir / 会失败。
在 Docker Engine 29.8.2 里实测入口脚本的信号转发:sh 里直接 python(不 exec)时应用收不到 SIGTERM,docker stop -t 5 等满 5.2 秒后 137;exec python 0.7 秒优雅退出;trap 转发时只 wait 一次会让脚本在应用清理完之前退出(143),被打断后再 wait 一次才正确;--init 不能替脚本转发;HUP 等其它信号要自己转发。