2. Docker 网络基础:网络模式对鉴权请求路径的影响

在 Docker 环境下,后端鉴权拦截链路的核心瓶颈往往不在代码逻辑,而在网络层。容器网络模式决定了鉴权请求的源 IP、端口映射方式、服务发现机制以及数据包转发路径。理解 bridge、host、overlay 三种模式对鉴权请求路径的影响,是排查“鉴权失败”“鉴权超时”“鉴权上下文丢失”等故障的前提。

2.1 三种网络模式的核心差异

特性 Bridge(默认) Host Overlay(Swarm/K8s)
网络隔离 容器独立网络栈,NAT 转发 共享宿主机网络栈,无隔离 跨主机虚拟网络,VXLAN 封装
端口映射 需 -p 显式映射 直接使用宿主机端口 通过 ingress 或 LB 暴露
源 IP 保留 默认 SNAT,源 IP 变为宿主机 保留真实客户端 IP 需额外配置(如 externalTrafficPolicy: Local)
服务发现 需手动 link 或自定义网络 依赖宿主机端口 内置 DNS 轮询或 VIP
鉴权影响 源 IP 丢失,IP 白名单失效 端口冲突风险,无隔离 跨节点延迟,MTU 问题
排查要点: 鉴权服务如果依赖客户端 IP 做白名单或地理限制,bridge 模式默认的 SNAT 会导致所有请求的源 IP 变成宿主机 IP,造成鉴权误判。此时应使用 --net=host 或配置 iptables 规则保留源 IP。

2.2 Bridge 模式:鉴权请求路径与 SNAT 陷阱

Bridge 模式是 Docker 默认网络模式。每个容器通过 docker0 网桥与宿主机通信,外部请求需经过端口映射(DNAT)和源地址转换(SNAT)。

Bridge 模式鉴权请求路径(含 SNAT 陷阱) 外部客户端 IP: 203.0.113.5 宿主机 eth0 IP: 10.0.0.1 docker0 网桥 172.17.0.1 鉴权容器 172.17.0.2:8080 后端服务容器 172.17.0.3:9090 DNAT: 10.0.0.1:8080 SNAT: 源IP→172.17.0.1 内部请求,源IP保留 ⚠ 陷阱:外部请求到达鉴权容器时,源 IP 已被 SNAT 为 172.17.0.1(docker0 网关)。 鉴权服务若读取 request.remoteAddr 做 IP 白名单,将永远匹配不到真实客户端 IP。
常见故障: 在 bridge 模式下,如果鉴权服务与后端服务位于同一自定义网络(非 docker0),则容器间通信不会经过 SNAT,源 IP 保留为容器 IP。但外部请求经过端口映射时,源 IP 仍会被 SNAT。解决方案:使用 --net=host 或配置 iptables -t nat -A DOCKER ! -i docker0 -j RETURN 绕过 SNAT。

2.3 Host 模式:端口冲突与安全隔离缺失

Host 模式容器直接使用宿主机网络栈,无独立网络命名空间。鉴权请求路径最短,但代价是端口隔离和安全隔离的丧失。

Host 模式鉴权请求路径 外部客户端 IP: 203.0.113.5 宿主机网络栈 eth0: 10.0.0.1 端口 8080, 9090 直接暴露 鉴权容器 监听 0.0.0.0:8080 后端服务容器 监听 0.0.0.0:9090 直接访问 共享网络栈 localhost 通信 ⚠ 风险:两个 host 模式容器若监听同一端口(如 8080),将发生端口冲突,后启动的容器会失败。 鉴权服务与后端服务可通过 localhost 通信,但无网络隔离,容器被攻破后宿主机网络直接暴露。
适用场景: Host 模式适合对网络性能要求极高、且容器数量可控的场景(如 API 网关、负载均衡器)。在鉴权链路中,host 模式可以避免 SNAT 导致的源 IP 丢失问题,但必须通过进程管理或端口规划防止冲突。

2.4 Overlay 模式:跨主机鉴权与 VXLAN 开销

Overlay 模式用于 Docker Swarm 或 Kubernetes 集群,通过 VXLAN 隧道实现跨主机容器通信。鉴权请求可能跨越多个宿主机,引入额外的封装/解封装延迟和 MTU 问题。

Overlay 模式跨主机鉴权请求路径 客户端 宿主机 A(10.0.0.1) Ingress 网关 鉴权容器 A 10.0.1.2:8080 宿主机 B(10.0.0.2) 后端服务容器 B 10.0.1.3:9090 VXLAN 隧道(UDP 4789) 外部请求 跨主机请求 VXLAN 封装 VXLAN 解封装 ⚠ Overlay 网络常见故障点: 1. MTU 问题:VXLAN 封装增加 50 字节开销,若物理网络 MTU=1500,容器内实际可用 MTU=1450, 导致大包被分片或丢弃,鉴权请求体过大时超时。 2. 服务发现延迟:Swarm DNS 或 K8s DNS 缓存未刷新,鉴权容器解析到旧的后端服务 IP。 3. 网络策略阻断:Calico/Cilium 网络策略误拦截跨主机鉴权流量。

2.5 常见网络故障点速查表

故障现象 可能原因 涉及网络模式 排查命令/方法
鉴权日志中客户端 IP 始终为宿主机 IP Bridge 模式 SNAT 导致源 IP 被替换 Bridge iptables -t nat -L -n 查看 SNAT 规则
容器启动报端口已被占用 Host 模式端口冲突 Host ss -tlnp | grep <port> 检查端口占用
跨主机鉴权请求超时或丢包 VXLAN MTU 分片或网络策略阻断 Overlay ping -M do -s 1472 <target> 测试 MTU
鉴权服务解析后端服务 IP 错误 DNS 缓存未刷新或服务名拼写错误 Overlay / 自定义 Bridge nslookup <service_name> 检查解析结果
鉴权请求被无故拒绝 网络策略(NetworkPolicy)未放行 Overlay(K8s) kubectl describe networkpolicy 查看策略
容器间通信正常,但外部无法访问 端口映射遗漏或防火墙规则 Bridge docker port <container> 检查映射

2.6 网络模式选择建议

  • 单机开发/测试环境: 使用 Bridge 模式 + 自定义网络,避免使用默认 docker0。自定义网络支持容器名 DNS 解析,且容器间通信不经过 SNAT。
  • 生产环境单机部署: 如果鉴权服务依赖客户端真实 IP(如 IP 白名单、地理鉴权),优先使用 Host 模式,或 Bridge 模式配合 --publish-all 并手动配置 iptables 规则保留源 IP。
  • 集群环境(Swarm/K8s): 使用 Overlay 模式,但必须注意:
    - 设置容器内 MTU 为 1450(物理 MTU 1500 时);
    - 使用 externalTrafficPolicy: Local 保留客户端源 IP;
    - 定期清理 DNS 缓存或使用 headless service 直连 Pod IP。
快速验证命令: 在鉴权容器内执行 curl -s http://httpbin.org/ip 或 echo $REMOTE_ADDR(取决于鉴权服务实现),对比外部请求的实际客户端 IP,即可判断源 IP 是否被 SNAT 修改。