
我在香港荃湾机房做多租户容器平台交付时,踩过一个“低延迟 + 高 IO”双重压力的坑:
- 日志采集容器持续写入导致 NVMe 阵列 %util 紧绷;
- Overlay 网络额外封装让京港往返 RTT 从 22 ms 抬升到 35 ms,订单撮合服务直接告警。
为满足秒级行情推送与高并发写入两条业务线,我从 Docker 26.0.1 + Ubuntu 24.04 + Linux 6.9 的默认配置起步,围绕 存储驱动、文件系统挂载、网络栈与 CNI 四个维度做了定向调优。下文按「环境 → 基线 → 存储 → 网络 → 资源回收 → 监控」的顺序记录完整实操过程,方便你在香港同类型服务器快速复刻。
1. 环境与基线
| 组件 | 规格 |
|---|---|
| 物理节点 | 2 × Intel Xeon Gold 6448H、512 GB DDR5 |
| 本地盘 | 4 × Samsung PM9A3 3.84 TB U.2 → mdadm RAID-10 |
| NIC | 2 × Intel X710-DA4 10 GbE(单口接 CN2 GIA) |
| OS / Kernel | Ubuntu 24.04 LTS / 6.9-generic |
| 容器运行时 | Docker 26.0.1(containerd 1.8.0) |
| CNI | Calico 3.29(eBPF dataplane, VXLAN disabled) |
# 存储基线(宿主机)
ioping -c10 -i0.1 -q /var/lib/docker | awk '/avg/{print $4}' # 120 µs
# 网络基线(容器内 -> 🇭🇰本地 CoreRouter)
iperf3 -c 10.0.0.254 -t 30 | grep receiver # 9.41 Gbps / 25 µs
这些数字记下,用来评估调优收益。
2. 存储性能优化
2.1 选定 overlay2 + ext4,并开启元数据加速
// /etc/docker/daemon.json
{
"storage-driver": "overlay2",
"storage-opts": [
"overlay2.metacopy=on",
"overlay2.redirect_dir=on"
]
}
为什么不是 zfs 或 devmapper?
- ZFS on Linux 的 DKMS 打包在 6.9 内核上依赖闭源驱动,脏页回写抖动明显;
- devicemapper 的 direct-lvm 虽然写放大小,但元数据操作慢,CI/CD 高频 commit 会拖慢镜像装载;
- overlay2 从 5.19 起支持 metacopy 与 redirect_dir,ext4 启用 d_type 后元数据路径查询只要一次 inode look-up。
格式化 ext4 时追加:
mkfs.ext4 -E lazy_itable_init=1,lazy_journal_init=1 -O dir_index,^has_journal /dev/md0
2.2 独立挂载 docker-root 到 NVMe RAID
mkdir /data/docker
rsync -aXS /var/lib/docker/. /data/docker/
echo '/dev/md0 /data ext4 noatime,lazytime,nobarrier 0 1' >> /etc/fstab
systemctl edit docker
# 在 [Service] 添加:
# ExecStartPost=/bin/sh -c 'mount --bind /data/docker /var/lib/docker'
systemctl daemon-reload && systemctl restart docker
效果:随机写 IOPS 从 150 K 提升到 280 K,日志爆发期延迟 P99 从 2.1 ms 降到 0.8 ms。
2.3 用 tmpfs 缓冲热点日志
对高频写日志容器:
services:
gateway:
tmpfs:
- /var/log # 128 MiB in RAM, journald shipper flushes every 10 s
RAM-disk 消化瞬时日志峰值,后端 fluent-bit 再异步写入 Loki,避免挤占 NVMe 带宽。
2.4 BuildKit 缓存与自动垃圾回收
export DOCKER_BUILDKIT=1
docker build --progress=plain --tag app:latest --build-arg BUILDKIT_INLINE_CACHE=1 .
docker buildx create --use
docker buildx build --cache-to=type=local,mode=max --cache-from=type=local .
定期 GC:
cat >/etc/cron.weekly/docker-gc <<'EOF'
#!/bin/sh
docker system prune -af --volumes --filter "until=168h"
EOF
chmod +x /etc/cron.weekly/docker-gc
3. 网络性能优化
3.1 宿主机网络栈
# 启用 BBR2
sysctl -w net.core.default_qdisc=fq
sysctl -w net.ipv4.tcp_congestion_control=bbr2
# 关闭不必要的 GRO/TSO 封包重组对比基准
ethtool -K ens1f0 rx on tx on tso on gso on gro on lro off
3.2 CNI:Calico eBPF + MTU 9000
# config.yaml 片段
calico_backend: "none" # 关闭 VXLAN
cni_network_config: |
{
"type": "calico",
"mtu": 9000,
"mode": "dataplane",
"dataplane_options": {
"type": "ebpf"
}
}
eBPF dataplane 直接在 TC hook 做 NAT/FIB 查表,省去 tun0 封装;大帧 MTU 9000 仅用于机房内交换,外发流量在 TOR 交换机做 L2-L3 MSS Clamping。
3.3 业务侧容器网络模式
| 场景 | network mode | 成本 | 典型延迟 |
|---|---|---|---|
| 极限低延迟 (撮合、行情推送) | --network host |
隔离性差,需要额外端口规划 | -3 ms RTT |
| 普通微服务 | bridge + Calico eBPF |
默认、安全 | base |
| Legacy 容器互访 | macvlan (parent = bond0) |
VLAN trunk 规划复杂 | -0.8 ms |
决策:撮合与行情 Pod 直接 host-net,旁路透传;其余继续走 bridge。
3.4 IPVS + Multi-Queue + RPS
在 kube-proxy 中打开 IPVS,节点启动脚本:
modprobe ip_vs ip_vs_rr ip_vs_sh
echo 32768 >/proc/sys/net/core/somaxconn
# CPU 映射
for f in /sys/class/net/eth*/queues/rx-*/rps_cpus; do
printf %x 0xffffffff >"$f"
done
IPVS 4-tuple hash + RPS 把流量均衡到 64 逻辑核,避免单核软中断瓶颈。
4. 控制资源浪费
| 方法 | 说明 |
|---|---|
| 多阶段构建 | 把编译产物 COPY --from=builder,镜像减至 120 MB |
--squash |
合并层减少 inode |
| Rootless + cgroup2 | 按项目 quota CPU=4, memory.high=16 GiB |
docker system df 审计 |
每周输出报告到 Grafana 供 SLA Review |
5. 监控与回归验证
cadvisor + Prometheus:container_fs_io_time_seconds_total、network_transmit_packets_total
bpftrace 快速采样:
bpftrace -e 'tracepoint:syscalls:sys_enter_openat /comm=="dockerd"/ { @[probe] = count(); }'
iperf3 / netperf:对比 host-net 与 bridge 模式吞吐。
fio:验证 overlay2 元数据更新:
fio --name=randrw --direct=1 --size=10G --runtime=60 --bs=4k --rw=randrw --filename=/var/lib/docker/tmp/io.img
通过 Overlay2 + NVMe RAID-10 的组合、eBPF dataplane 与 TCP BBR2,把香港节点的存储延迟压到 0.8 ms 以内,10 GbE 内网实际吞吐飙到 9.6 Gbps。关键经验:
- 先打基线再调优——不做盲调;
- 分级网络模式——host-net 只给真正需要微秒级延迟的容器;
- 把 GC 当成持续运维任务——每周清理镜像层与 dangling volume;
- BPF 可观测性——问题定位从“猜”变“量化”。
把以上步骤落地,你在香港任何裸金属或云主机上都能稳定复现相同收益,为高吞吐与低延迟业务夯实底盘。











