Incus 脚本审阅与验收SWES · 技术记录

Incus 审阅 03|容器能启动却不能联网,为什么要查 Docker 的转发规则

Incus 脚本审阅与验收 · 第 3 / 8 篇 容器已经 Running,里面却不能更新软件源。遇到这种现象,直接重装 Incus 或更换 DNS,常常只是换了一种方式重复故障。更有价值的做法,是先判断报文停在哪一层。 先把问题拆成五层

Incus 脚本审阅与验收 · 第 3 / 8 篇

容器已经 Running,里面却不能更新软件源。遇到这种现象,直接重装 Incus 或更换 DNS,常常只是换了一种方式重复故障。更有价值的做法,是先判断报文停在哪一层。

Incus 出站网络的逐层排查路径

先把问题拆成五层

检查

能证明什么

不能直接证明什么

容器有 IPv4 地址和默认路由

容器网络配置存在

能访问公网

网关可达

容器到网桥的一段路径可用

宿主机允许转发

公网 TCP 443 可连

到指定地址的 TCP 握手成功

TLS、HTTP 和软件源都正常

域名可解析

指定解析请求成功

解析后的服务可访问

apt 更新成功

实际软件源访问完成

所有业务协议都可用

建议先执行只读或低影响诊断:

incus exec vps1 -- ip -4 addr
incus exec vps1 -- ip -4 route
incus exec vps1 -- getent ahostsv4 deb.debian.org
incus exec vps1 -- timeout 8 bash -c 'echo >/dev/tcp/1.1.1.1/443'
sysctl net.ipv4.ip_forward
ip -4 route show default
iptables -L FORWARD -n -v
iptables -L DOCKER-USER -n -v

ping 失败也可能是 ICMP 被限制,不能单独宣布“断网”;而 TCP 443 成功只是对该地址的连接证据,仍需要实际软件源或业务请求确认。

为什么宿主机有 Docker 时值得检查 FORWARD

Docker 与 Incus 都会使用宿主机网络功能。Incus 官方文档记录了二者共存时的一种常见问题:Docker 设置全局转发丢弃策略,影响 Incus 实例出站。现存部署脚本中的兼容补丁,就是针对这类路径设计的。Incus 官方共存说明

这只是候选原因。如果当前使用原生 nftables 后端、没有 DOCKER-USER,或者丢包发生在另一套防火墙中,不能继续机械套用 iptables 补丁。iptables-nft 兼容工具也不等同于 Docker 原生 nftables 后端,必须先辨认实际规则系统。

补丁为什么只放行两类流量

脚本检测默认 IPv4 出口与网桥网段,在 DOCKER-USER 中加入定向规则:一条允许网桥网段向出口发送;另一条只允许返回网桥的 ESTABLISHED,RELATED 流量。它试图恢复实例主动访问外网及其返回路径,而不把全局 FORWARD 一律改成 ACCEPT。Docker 的用户自定义规则链说明

每次添加前执行 iptables -C,是为了避免同一规则重复堆积。接口和网段通过本机查询获得,优于硬编码 eth0 和固定的 10.x 网段。但如果有多出口、策略路由、VPN 或 IPv6,单一默认 IPv4 出口模型就不够了。

这个补丁不是业务入站开放器,也不是容器间隔离策略。其他 nftables 基链仍可能丢弃流量;某一条 ACCEPT 不能证明整条路径一定放行。不要因此清空防火墙,更不要关闭 Docker 的规则维护来“试试看”。Docker 防火墙说明

systemd 持久化为什么仍需要测试

脚本安装一个 oneshot 单元,设置在 Docker 与 Incus 之后执行,并启用开机运行。同时立即直接执行一次修复脚本,让当前部署能够继续。

这里有一个容易忽略的边界:After=docker.service 规定的是启动顺序,不代表“Docker 每次重启,都自动再次运行这个 oneshot”。原注释也提醒,单独重启 Docker 后必要时需重新应用。完整验收必须分别测试宿主机重启、Docker 重启和规则是否仍存在,不能只看单元已 enabled。

systemctl cat incus-docker-forward-fix.service
systemctl is-enabled incus-docker-forward-fix.service
iptables -S DOCKER-USER

最后一条用于列出规则,应逐项核对已检测到的出口、规范化网段和连接状态条件。若用 iptables -C 精确查询,也应使用相同条件,不能拿一条不同的宽规则查不到,就误判为本方案没有配置。

下一轮演进应该如何记录

保留修复前的路由、规则与失败命令;应用最小变更;用同一请求重新测试;再验证 Docker 原有业务。只有前后证据对应,才能写“这一规则修复了本次出站故障”。现有材料能证明补丁的设计和调用位置,尚不能替代特定服务器上的故障归因与重启回归。

系列阅读目录

  1. 01|一台 VPS 拆成六台“小鸡”,到底拆出了什么

  2. 02|部署之前先算清楚,3GiB 根盘与 12GiB 存储池如何配合

  3. 03|容器能启动却不能联网,为什么要查 Docker 的转发规则

  4. 04|端口不是越多越好,让每个公开入口都有归属

  5. 05|只重装一台小鸡,保住的究竟是配置还是数据

  6. 06|菜单不再秒退之后,为什么还要检查 YAML 缩进和密码记录

  7. 07|Komari 显示在线以后,还要验证什么

  8. 08|怎样才算真正做好,把“完美结果”写成可复查的验收单

感谢阅读 · 保持好奇,认真记录。浏览更多文章 ↗