标准 Docker 环境下的完整流程
五步按顺序执行:先有规则、再有镜像、然后接入容器、用标签声明意图,最后用前后 diff 证明宿主机路由没有被写入任何新规则。全过程不重启宿主机网络栈,任一步骤失败都可直接删除加速容器回滚。
按示例口径,标准环境中五步整体耗时约 3–6 分钟,其中镜像拉取占主要部分,具体取决于仓库链路质量。全流程为增量操作,不修改已有业务容器配置,也不需要维护窗口。建议先在预发环境用同一镜像与同一份规则文件验证命中情况,确认无误后再灰度到生产。
-
准备规则文件
把分流决策从代码里抽出来,成为一份可版本管理的配置。
/opt/kl/rules.yamldefault: direct rules: - label: kl.route=proxy action: proxy - image: "registry.ci.acme.com/builder/*" action: proxy - cidr: "10.0.0.0/8" action: direct - cidr: "169.254.0.0/16" action: direct # 云元数据必须直连默认动作设为
direct,保证规则有遗漏时流量仍按原链路走;内网段与云元数据地址显式声明为直连,避免容器访问内部服务时被规则误送至隧道。各维度的优先级与写法见 分流规则优先级。 -
拉取并校验官方镜像
锁定 tag 与 digest,确保运行的是未被替换的官方构建。
终端docker pull registry.kiualanad.com.cn/kl/kl-proxy:v2.4.1 docker image inspect registry.kiualanad.com.cn/kl/kl-proxy:v2.4.1 \ --format '{{index .RepoDigests 0}}'tag 可以被重新指向,digest 不行。请把命令输出的完整 digest 写入部署基线,并与 下载页的来源核验一节给出的摘要比对;离线环境还需执行
sha256sum -c校验归档文件后再导入。 -
创建业务网络并接入容器
独立网络让加速容器与业务容器共享同一网络命名空间。
终端docker network create kl-net docker run -d --name kl-proxy \ --network kl-net \ --cap-add NET_ADMIN --device /dev/net/tun \ -v /opt/kl/rules.yaml:/etc/kl/rules.yaml:ro \ --restart unless-stopped \ registry.kiualanad.com.cn/kl/kl-proxy:v2.4.1 \ --config /etc/kl/rules.yaml --mode container docker network connect kl-net your-app--mode container表示加速只在容器网络命名空间内生效,不会写入宿主机 main 路由表。NET_ADMIN与/dev/net/tun只授予加速容器自身,用于在容器内建立隧道设备与策略路由表,不改变宿主机能力集。隔离原理见 隔离架构。 -
设置分流标签
用标签精确控制「哪些容器走加速」,无需重建镜像。
Kubernetes · DaemonSet 片段metadata: labels: kl.route: proxy # 命中优先级 100 的标签规则 annotations: kl.cn/config: /etc/kl/rules.yaml标签规则优先级最高,会覆盖镜像名与域名维度的判断;注解用于告诉注入组件去哪里读取规则文件,规则本身仍以 ConfigMap 只读挂载。集群环境的完整注入方式见 场景方案 · Kubernetes。
-
验证生效并确认宿主机零改动
用前后 diff 证明宿主机路由没有被写入任何新规则。
终端 · 校验# 1) 记录宿主机当前规则 ip rule show > /tmp/before.txt # 2) 触发一次业务请求,检查容器内命中 docker exec kl-proxy kl-ctl status # 3) 再次对比,确认 main 表零变更 ip rule show > /tmp/after.txt diff /tmp/before.txt /tmp/after.txt && echo "宿主机路由未变更" # 4) 确认 core dump 已关闭 docker exec kl-proxy sh -c 'ulimit -c'预期输出第 2 条应输出容器内的策略路由表(表 100 指向隧道设备)与规则命中统计,能看到哪条规则被命中;第 3 条的
diff无差异并打印「宿主机路由未变更」,说明 main 表新增规则数为 0;第 4 条输出0,表示崩溃转储已关闭。其他等价验证方式见 如何验证零改动。
常见异常排查
下表按「现象 → 可能原因 → 排查命令 → 处理」列出部署后最常出现的五类问题。排查命令均在宿主机执行,全部为只读操作,不会改变现有网络状态。
| 现象 | 可能原因 | 排查命令 | 处理 |
|---|---|---|---|
| 容器启动即退出 | 缺少 NET_ADMIN 或 /dev/net/tun |
docker logs kl-proxy |
补齐参数后重建容器 |
| 容器内仍走直连 | 规则文件未挂载或标签未命中 | docker exec kl-proxy kl-ctl status |
核对挂载路径与 label |
| 访问云服务失败 | 元数据地址被规则送往隧道 | docker exec kl-proxy sh -c 'curl -s 169.254.169.254' |
为 169.254.0.0/16 加 direct 规则 |
| DNS 解析缓慢 | 容器 resolv.conf 未生效 | docker exec kl-proxy cat /etc/resolv.conf |
确认 dns 模式与重启策略 |
| 内存占用偏高 | 使用 debug 镜像或连接数过多 | docker stats kl-proxy |
换用 slim/alpine 镜像 |
第一,凡是提示「规则未生效」的问题,先用 kl-ctl status 确认规则文件是否成功加载,再确认目标容器是否真的带有对应标签——两者任一缺失都会表现为流量走直连。第二,v2.4.1-debug 仅用于排障,会显著增加内存占用,问题定位后应换回 slim 或 alpine 镜像。镜像选择见 镜像瘦身与安全。
docker-compose 编排
多容器共处一台宿主机时,用 compose 把加速容器与业务容器写进同一个文件更便于版本管理。下列配置与命令行方式完全等价,字段一一对应。
services:
kl-proxy:
image: registry.kiualanad.com.cn/kl/kl-proxy:v2.4.1
container_name: kl-proxy
restart: unless-stopped
cap_add:
- NET_ADMIN
devices:
- /dev/net/tun:/dev/net/tun
volumes:
- kl-rules:/etc/kl:ro
networks:
- kl-net
command: ["--config", "/etc/kl/rules.yaml", "--mode", "container"]
your-app:
image: registry.ci.acme.com/builder/app:latest
restart: unless-stopped
networks:
- kl-net
labels:
kl.route: proxy
networks:
kl-net:
name: kl-net
volumes:
kl-rules:
driver: local
driver_opts:
type: none
o: bind
device: /opt/kl
cap_add+devices- 等价于命令行的
--cap-add NET_ADMIN --device /dev/net/tun。两者只作用于加速容器自身,用于在容器命名空间内建立隧道设备与策略路由表。 volumes→kl-rules- 等价于命令行的
-v /opt/kl/rules.yaml:/etc/kl/rules.yaml:ro。这里把宿主机目录/opt/kl声明为一个driver_opts.type=none的本地卷,再只读挂载到容器的/etc/kl,规则文件的来源路径与只读属性完全不变。 command- 等价于镜像启动参数
--config /etc/kl/rules.yaml --mode container。--mode container是宿主机路由零改写的关键,不要改成node。 labels.kl.route- 等价于在业务容器上声明分流标签,命中优先级 100 的标签规则。Docker 场景同样支持这一写法,Kubernetes 下改由 DaemonSet 注入方式实现。
compose 里同样要显式声明 kl-net 并让两个服务都加入该网络。漏掉这一段时,服务会落到默认 bridge 网络,加速容器与业务容器不在同一个网络命名空间,容器内的策略路由表互不可见,表现为规则不生效或流量仍走直连。网络隔离的边界说明见 隔离模型。
回滚与升级
快连VPN 的状态全部存在于加速容器内,没有写入宿主机的残留项,因此回滚动作只有一个:删掉加速容器。升级动作也只涉及容器本身,业务容器不需要重建。
- 回滚方式
- 执行
docker rm -f kl-proxy即完成完全回滚:容器网络命名空间内的策略路由表随容器销毁,宿主机 main 路由表、默认网关与既有防火墙规则始终未被写入,因此无需任何额外清理步骤,也不影响宿主机上已有的服务与其它容器。compose 环境下对应docker compose rm -f kl-proxy。 - 镜像升级路径
- 先拉取新 tag 并用
docker image inspect取得完整 digest,写入部署基线后再重建加速容器,业务容器无需重建。若升级后需要退回,用原 tag 与原 digest 重新拉取并重建即可回到旧版本;生产环境建议同时保留上一版本的镜像归档,便于快速回切。 - 配置版本管理
- 把
rules.yaml与镜像 tag 一起纳入版本管理:每次规则变更单独提交,提交信息中记录所对应的镜像 tag 与 digest,使「哪条规则在哪一版镜像上生效」始终可追溯。修改后按只读挂载的生效方式重新加载,无需重建业务容器。
升级完成后请重跑一次第五步的四条验证命令:前后 diff 仍应无差异、kl-ctl status 能看到新规则的命中情况、ulimit -c 仍输出 0。镜像 digest 的核对方法见 来源核验与防钓鱼。
部署过程中出现问题,如何快速回滚?
删除加速容器即可完成回滚:执行 docker rm -f kl-proxy 后,容器网络命名空间内的策略路由表随容器一并销毁,宿主机 main 路由表、默认网关与 iptables 规则始终未被写入,因此不需要额外清理步骤,也不影响宿主机上已有的服务。
修改 rules.yaml 后如何让配置生效?
规则文件以只读方式挂载到容器内的 /etc/kl/rules.yaml,修改宿主机文件后执行 docker restart kl-proxy 让进程重新加载配置即可。Kubernetes 环境下规则以 ConfigMap 挂载,修改后执行 kubectl rollout restart 重启 DaemonSet,同样不需要重建业务 Pod。
为什么必须使用独立的 kl-net 网络?
加速容器与业务容器需要共享同一个网络命名空间,快连才能在容器侧写入策略路由表。独立网络 kl-net 保证这一关系明确可控;如果业务容器仍留在默认 bridge 上,容器内的路由表与加速配置将互不可见,表现为规则不生效或流量仍走直连。