把服务从 x86 服务器迁到 ARM64 服务器,我以为这是个换镜像的问题。真正花掉一个下午的,是网络语义。
同一个地址,两个含义
服务里配置了 127.0.0.1 去访问同机的另一个容器。在旧环境它工作正常,新环境却一直连接被拒。
原因是网络模式:
host 网络下,127.0.0.1 是宿主机自己;<br />bridge 网络下,127.0.0.1 是这个容器自己。
服务以为在访问别人,其实一直在访问自己——而那个端口在自己身上并没有开。
怎么定位
做一个最简对比表:在两种网络模式、两个方向上分别执行同一条连接测试,把结果并排放在一起。差异一旦被并排放置,"配置写错了"和"语义不同"就立刻区分开了。
结论落在配置上:内部互访统一走服务名而不是回环地址,只在真正需要"本机"语义时用 127.0.0.1。
连带的两件事
迁移 CI Runner 时又遇到一组同类问题:ARM64 镜像要重新构建、bind mount 的目录权限要跟着新架构的 UID 对齐、CI 触发和手工部署两条路径如果用的挂载参数不同,会出现"CI 能跑、手动不行"这种最费解的差异。
所以最后统一成一条规则:两条路径使用同一套挂载与权限参数,差异只允许出现在镜像标签上。