在 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 都正常。
在 Docker Engine 29.8.2 里实测默认 seccomp 配置:容器 /proc/self/status 显示 Seccomp=2(unconfined 和 --privileged 是 0);用 ctypes 发 13 个系统调用,add_key、keyctl、unshare(CLONE_NEWUSER)、bpf、userfaultfd 等 9 个在默认配置下 EPERM、unconfined 下能到达内核,mount 和 swapon 两边都是 EPERM(靠 capability 挡住)。
在 Docker Engine 29.8.2 里实测 Linux capability:默认容器 root 有 14 个(chown、dac_override、kill、net_bind_service、net_raw、mknod 等),--cap-drop ALL 后 chown、raw socket、mknod、读他人 0600 文件都被拒绝;uid 1000 的 CapEff 是 0 个,却默认能绑定 80 端口,因为容器里 ip_unprivileged_port_start 已放开,与 NET_BIND_SERVICE 无关。
在 Docker Engine 29.8.2 里实测 no-new-privileges:镜像里一份 setuid root 的程序,uid 1000 默认运行得到 euid=0 和全部 14 个 capability;加 --security-opt no-new-privileges 后 euid 仍是 1000、CapEff=0、NoNewPrivs=1;已经是 root 的进程不受影响,docker exec 进去的进程也带着这个标志。
在 Docker Engine 29.8.2 里实测 --read-only:10 个位置里只剩 /dev/shm 可写,其它(包括 /etc/hosts、/etc/resolv.conf)都是 EROFS,Python 的 tempfile 找不到可用临时目录;--tmpfs /tmp --tmpfs /run、命名卷可以开出可写的口子;tmpfs 里的写入不进 docker diff。
实测 Docker 里的 uid 映射:这台 Docker Desktop 没开 userns-remap,容器里 uid 0 就是虚拟机里的 root(uid_map 是恒等的“0 0 4294967295”);手动 unshare 出一个用户命名空间并写入“0 1000 1”后,命名空间里是 uid 0、虚拟机里看是 uid 1000,未映射的文件显示成 65534,chown 到未映射的 uid 返回 EINVAL。
在 Docker Engine 29.8.2 里实测 --privileged:capability 从 14 个变成 41 个、Seccomp 从 2 变成 0、/dev 条目从 15 个变成 169 个、/proc/sys 和 /sys 变成可写,能读虚拟机的 /dev/vda1;只 --cap-add SYS_ADMIN 就能 mount,但 seccomp 与 /dev 仍受限。
在 Docker Engine 29.8.2 里实测设备直通:--device /dev/fuse 才能在容器里看到并打开 fuse 设备;:r 后缀让写方式打开返回 EPERM,设备可以改名映射;容器里 mknod 只创建设备文件,打开仍被 EPERM,要靠 --device-cgroup-rule 放行。
在 Docker Engine 29.8.2 里实测 bridge 网络:默认 bridge 是 172.17.0.0/16,容器能按 IP 互通、不能按名字解析;自定义 bridge 网络(172.19.0.0/16)自带名字解析;不同网络之间互相隔离,docker network connect 后一个容器有两个 IP;虚拟机里每个自定义网络一个 br-… 网桥,每个容器每个网络一个 veth(4 个容器 +5)。
在 Docker Desktop(macOS)上实测 --network host:容器共用虚拟机的网络命名空间(net:[4026531833]、hostname docker-desktop),不是 Mac 的;-p 被丢弃并打印 WARNING;host 模式容器监听的端口 Mac 访问不了(Connection refused),但虚拟机里的 bridge 容器能通过 172.17.0.1 访问;两个 host 容器绑同一个端口会 Address in use。
在 Docker Engine 29.8.2 里实测内置 DNS:自定义网络上的容器 resolv.conf 是 nameserver 127.0.0.11(默认 bridge 是 192.168.65.7);容器名和 --network-alias 都能解析到容器 IP,不存在的名字退出码 1,别的网络里的名字解析不了;--dns 在自定义网络里只改上游,resolv.conf 仍是 127.0.0.11。