☰
Weave容器网络实战:跨主机通信、DNS与故障排查指南
2026/10/13 9:15:41 网站建设 项目流程

1. 从零认识Weave:它到底解决什么问题

第一次接触Weave的人,十有八九是被它那句“让容器之间直接对话”的描述吸引过来的。但真到了动手阶段,问题就来了:网络插件那么多,为什么偏偏选它?它和Docker自带的bridge网络有什么本质区别?跨主机通信到底是怎么实现的?这些问题如果不搞清楚,后面遇到故障基本就是抓瞎。

Weave是一个容器网络方案,核心目标就一个:让分布在不同主机上的容器,像在同一个局域网里一样互相通信。你不需要改应用代码,不需要手动配置路由表,甚至不需要关心容器到底跑在哪台机器上。它通过在每个主机上跑一个路由组件,把各主机的容器网络“编织”成一张覆盖网络(Overlay Network)。这个名字起得很形象——Weave,编织。

它主要解决三个层面的问题。第一是跨主机通信,Docker默认的bridge网络只能让同一台主机上的容器互通,跨主机就得靠端口映射或者手动配路由,Weave直接把这一层抹平了。第二是服务发现,容器启动后IP是动态分配的,Weave内置了DNS服务,你可以直接用容器名或者别名访问,不用去查IP。第三是网络隔离与加密,不同应用之间可以通过网络分区隔离开,敏感流量还能走加密通道。

适合谁来参考?如果你正在用Docker或者容器编排工具跑多主机集群,被容器间通信折腾过,或者想找一个比手动配网桥更省心的方案,那Weave值得花时间研究。但如果你只是单机跑几个容器玩玩,坦白说,Docker自带的网络够用了,没必要上Weave增加复杂度。这篇文章我会把Weave使用中最常遇到的坑、最容易搞混的概念、以及排查问题的思路全部梳理一遍,尽量让你少走弯路。

2. Weave核心机制与关键概念拆解

2.1 覆盖网络是怎么“织”出来的

Weave的覆盖网络原理并不复杂,但理解它对于排查问题至关重要。每台运行Weave的主机上会启动一个叫weaverouter的进程,它负责维护和其他主机的连接。当你启动一个容器并接入Weave网络时,Weave会为这个容器分配一个虚拟IP(默认在10.32.0.0/12这个网段里),同时在主机上创建一个虚拟网桥(weave bridge),容器的流量先到这个网桥,然后由weaverouter决定往哪送。

跨主机通信的时候,weaverouter会把原始的数据包封装一层UDP(默认端口6783)或者TCP,通过主机的物理网络发到目标主机的weaverouter,对方拆包后再送到目标容器。这个过程对容器里的应用完全透明,应用只看到自己和对方在同一个网段里,直接发包就行。

这里有个关键点很多人会忽略:Weave的封装流量走的是主机的物理网卡,所以主机之间的基础网络必须通。如果你两台主机本身都ping不通,那Weave再怎么配也没用。另外,Weave默认使用UDP 6783做数据面传输,TCP 6783做控制面信令,如果主机之间有防火墙,这两个端口必须放开。

2.2 容器寻址与DNS命名规则

Weave给容器分配IP的方式和Docker默认的bridge网络不太一样。Docker bridge是从172.17.0.0/16里分,Weave默认从10.32.0.0/12里分,这个网段可以改,但一般不建议动,除非和你现有网络冲突。

更实用的是Weave的DNS机制。当你用weave run或者给容器设置weave.works相关的环境变量时,Weave会自动注册容器名和别名到内部的DNS服务。比如你启动一个容器叫web,另一个叫db,那么在web容器里直接ping db就能通,不需要知道db的IP是多少。这个DNS解析是Weave自己维护的,不依赖外部的DNS服务器。

但这里有个坑:容器名必须是唯一的。如果你在两台主机上各启动了一个叫web的容器,DNS解析就会冲突,Weave会随机返回其中一个的IP。所以实际使用中,建议用有意义的、带环境前缀的命名,比如prod-web-01、staging-db-02这种。

2.3 网络分区与隔离策略

Weave支持通过网络分区(network partition)来做隔离。你可以把不同的容器放到不同的分区里,默认情况下不同分区之间是不通的。这个功能在多租户或者多环境(开发、测试、生产)混布的场景下特别有用。

创建分区很简单,启动容器时指定WEAVE_CIDR或者用weave expose的时候带上分区参数就行。但要注意,分区隔离是逻辑上的,不是物理的。底层还是同一套weaverouter在转发,只是转发规则里加了过滤。所以如果你有强安全隔离需求,光靠Weave分区是不够的,还得配合其他安全措施。

另外,Weave还支持加密通信。启动weaverouter的时候加上--password参数,主机之间的流量就会用AES加密。这个加密是在封装层做的,对容器里的应用无感知。加密会带来一定的性能开销,实测下来大概会降低10%到15%的吞吐量,延迟增加0.1到0.3毫秒左右。如果你的场景对性能极其敏感,又是在可信的内网环境里,可以考虑不加密。

3. 部署与配置中的高频问题实录

3.1 安装方式选择与版本兼容性

Weave的安装方式主要有三种:直接下载二进制、用Docker镜像跑、或者通过编排工具的插件机制集成。每种方式都有各自的适用场景和坑点。

直接下载二进制是最简单的方式,从官方渠道拿到weave脚本,放到/usr/local/bin下,加执行权限就能用。但这个脚本本质上是个shell包装器,它会去拉取对应版本的weaverouter和weaveexec镜像。所以即使你用二进制方式安装,主机上还是得有Docker,而且脚本会从网络拉镜像,如果主机不能访问外网,就得提前把镜像导入。

用Docker镜像跑的方式更灵活,你可以直接docker run一个weaverouter容器,把主机的Docker socket挂进去。这种方式适合需要自定义启动参数的场景,但要注意weaveexec容器需要以特权模式运行,因为它要操作主机的网络命名空间。

版本兼容性是个大坑。Weave的版本更新比较快,不同版本之间的协议可能不兼容。如果你集群里有的主机跑的是2.8.x,有的是2.9.x,大概率会出问题。建议所有主机统一使用同一个版本,升级的时候也要全部一起升,不要滚动升级。我遇到过好几次因为版本不一致导致跨主机通信时通时不通的情况,排查起来非常费劲。

3.2 端口冲突与防火墙配置

Weave默认使用6783端口(TCP和UDP都用这个),如果这个端口被其他服务占用了,weaverouter就起不来。启动前先用netstat -tulnp | grep 6783检查一下。如果确实被占了,可以通过--port参数改端口,但改完之后所有主机都得用同样的端口,不然互相找不到。

防火墙方面,除了6783,Weave还会用到6784端口做控制面的心跳检测。有些文档只提6783,导致配了防火墙之后容器能通但状态显示异常。稳妥的做法是把6783和6784的TCP和UDP都放开。

如果你用的是云主机,除了主机本身的防火墙,还要检查安全组规则。云平台的安全组有时候和主机防火墙是两套独立的机制,只配了一个另一个没配,照样不通。这个坑我踩过不止一次,排查了半天才发现是安全组没放行。

3.3 与Docker原生网络的共存问题

Weave可以和Docker原生的bridge网络共存,但需要注意路由优先级。Docker默认会创建docker0网桥,网段是172.17.0.0/16。Weave用的是10.32.0.0/12,两者不冲突,所以一般不会有问题。

但如果你之前手动改过Docker的网段,比如改成了10.32.0.0/16,那就和Weave的默认网段重叠了。这种情况下Weave分配IP的时候会出问题,容器可能拿到一个和docker0冲突的IP,导致路由混乱。解决办法要么改Docker的网段,要么改Weave的网段,两者必须错开。

另外,如果你在用Kubernetes或者Docker Swarm这类编排工具,它们可能自带网络方案。Weave可以作为这些编排工具的CNI插件使用,但配置方式和不使用编排工具时不一样。比如在Kubernetes里,Weave是通过DaemonSet部署的,配置参数通过ConfigMap传递,不能直接用命令行参数。这个切换的时候容易搞混。

4. 典型故障排查与解决思路

4.1 容器之间ping不通的排查路径

这是最常见的问题,没有之一。排查的时候建议按以下顺序来,不要跳步。

第一步,确认两台主机本身是否互通。在主机A上ping主机B的物理IP,如果不通,那问题不在Weave,先去解决主机网络。第二步,确认weaverouter是否正常运行。在每台主机上执行weave status,看状态是不是ready。如果显示not ready或者连接数不对,说明weaverouter有问题。第三步,检查容器是否接入了Weave网络。用weave ps看容器列表,确认目标容器在里面。有时候容器启动了但忘了加weave参数,它就没接入Weave网络,自然不通。

第四步,在容器内部检查路由表。进入容器执行ip route,看默认路由是不是指向了weave网桥。如果路由不对,可能是容器启动时网络配置有问题。第五步,抓包分析。在主机上tcpdump -i any port 6783,看封装流量有没有正常收发。如果发送端有包发出但接收端没收到,基本就是防火墙或者路由问题。

这个排查路径我用了很多次,基本上能覆盖90%以上的连通性问题。剩下的10%可能是MTU问题,下面单独说。

4.2 MTU导致的诡异现象

MTU问题特别隐蔽,因为它的表现是“小包能通,大包不通”。你ping是通的,因为ping包很小,但一传文件或者跑HTTP请求就卡住。很多人遇到这种情况会以为是应用问题,查半天查不到原因。

Weave的封装会增加额外的头部开销,UDP封装大概增加50到60字节,加密的话还要再多一些。所以Weave网络的MTU要比物理网络的MTU小。如果物理网络MTU是1500,Weave容器的MTU建议设成1400左右。设置方法是在启动容器时加--mtu参数,或者在weaverouter的配置里指定。

验证MTU是否合适,可以用ping -M do -s 1372 <目标IP>,其中1372是1400减去28(IP头20字节加ICMP头8字节)。如果这个大小的包能通,说明MTU没问题。如果提示“Frag needed”,就说明MTU设大了。

4.3 DNS解析失败的常见原因

Weave的DNS解析失败通常有三个原因。第一个是容器名冲突,前面提过了,同名容器会导致解析结果不确定。第二个是DNS服务没启动,Weave的DNS是集成在weaverouter里的,如果weaverouter状态异常,DNS也会挂。第三个是容器没有正确注册,只有通过weave run启动或者显式设置了Weave网络参数的容器才会注册DNS,用docker run直接启动的容器不在Weave的DNS里。

排查的时候,先在容器里cat /etc/resolv.conf,看DNS服务器地址是不是Weave的DNS地址(通常是10.32.0.1或者你自定义的地址)。然后用nslookup <容器名>测试解析。如果解析失败,回到主机上用weave status看DNS服务是否正常。

还有一个容易忽略的点:Weave的DNS只解析Weave网络内的容器名,外部域名它不负责。所以如果你在容器里ping baidu.com不通,那不是Weave的问题,是容器本身的DNS配置问题。Weave的DNS和系统的DNS是两套机制,不要搞混。

4.4 性能问题的定位与优化

Weave的性能问题主要体现在吞吐量下降和延迟增加上。前面说过,加密会带来10%到15%的吞吐量损失,这是正常的。但如果你发现性能下降远超这个比例,那就有问题。

首先检查是不是走了UDP。Weave默认用UDP做数据面传输,UDP在某些网络环境下(比如有QoS限速的网络)性能不如TCP。可以通过--conn-limit参数调整连接数限制,或者强制走TCP。但走TCP的话延迟会更高,需要权衡。

其次检查weaverouter的CPU和内存占用。如果weaverouter进程CPU跑满,说明转发压力太大,可以考虑增加主机或者调整--max-flows参数。内存方面,weaverouter会维护连接状态表,容器数量多的时候内存占用会上升,一般每个容器几十KB到几百KB不等。

最后,避免不必要的加密。如果是在可信的内网环境,加密带来的安全收益有限,但性能开销是实打实的。可以在启动weaverouter时不加--password参数,省掉加密解密的开销。

5. 进阶使用与经验心得

5.1 与编排工具的集成要点

Weave和Kubernetes集成的时候,是通过CNI插件的方式。部署的时候要注意几个点:一是Weave的DaemonSet需要以特权模式运行,因为它要操作主机的网络命名空间;二是要配置好--ipalloc-range参数,确保和Kubernetes的Service网段、Pod网段不冲突;三是要开放6783和6784端口,Kubernetes的NetworkPolicy如果启用了,还得额外配置允许这些端口的规则。

和Docker Swarm集成相对简单一些,Swarm模式下的服务可以直接接入Weave网络。但要注意Swarm的ingress网络和Weave网络是两套东西,服务暴露端口的时候要搞清楚走的是哪套网络。

5.2 生产环境部署的注意事项

生产环境部署Weave,我有几个建议。第一,至少部署三个weaverouter实例,避免单点故障。Weave本身支持多实例,它们之间会自动选主和同步状态。第二,监控weaverouter的健康状态,可以用weave status的输出做指标采集,重点关注连接数、丢包率、延迟这些指标。第三,定期备份Weave的配置,虽然Weave的状态大部分是动态生成的,但一些自定义参数和网络分区配置还是值得备份的。

另外,升级Weave版本的时候一定要先在测试环境验证。我遇到过升级后DNS解析行为变化的情况,虽然官方文档说兼容,但实际表现还是有差异。测试环境跑一遍完整的连通性测试和性能测试,确认没问题再上生产。

5.3 常见问题速查表

问题现象可能原因排查方法解决措施
容器间ping不通主机网络不通主机间互相ping先解决主机网络
容器间ping不通weaverouter未运行weave status重启weaverouter
容器间ping不通防火墙拦截检查6783/6784端口放开端口
小包通大包不通MTU设置过大ping -M do -s 1372调小MTU到1400
DNS解析失败容器名冲突检查容器命名重命名保证唯一
DNS解析失败DNS服务未启动weave status看DNS状态重启weaverouter
性能下降明显加密开销对比加密前后性能内网可考虑关闭加密
跨主机时通时不通版本不一致检查各主机版本统一版本
启动报端口占用6783被占用netstat -tulnp改端口或释放端口
容器IP冲突网段重叠检查Docker和Weave网段修改网段避免重叠

这张表是我自己整理出来的,基本上覆盖了日常运维中80%以上的问题。遇到问题的时候先查表,能快速定位方向,然后再深入排查。

5.4 几个容易被忽略的细节

第一个细节是Weave的IP分配是持久化的。容器停止后,它的IP不会立即释放,而是保留一段时间(默认是永久保留,除非手动清理)。这意味着如果你频繁创建销毁容器,IP池可能会被耗尽。可以通过weave reset清理未使用的IP,或者调整IP保留策略。

第二个细节是Weave的网络分区和Docker的网络是两回事。Docker有--network参数,Weave也有自己的网络概念,两者不要混淆。一个容器可以同时接入Docker的bridge网络和Weave网络,这时候它会有两个IP,路由选择取决于具体的配置。

第三个细节是Weave的日志默认不输出到stdout,而是写到文件里。排查问题的时候需要去/var/log/weave或者容器内部的日志目录找。可以通过weave --log-level debug临时提高日志级别,但生产环境不建议长期开debug,日志量太大。

第四个细节是Weave对IPv6的支持有限。虽然新版本声称支持IPv6,但实际用起来还是有不少限制,比如DNS解析对IPv6的支持就不太完善。如果你的环境是IPv6为主的,建议先做充分的测试再上生产。

6. 写在最后的一些个人体会

用了几年Weave,最大的感受是它确实简化了容器跨主机通信的复杂度,但前提是你得理解它的工作原理。很多问题其实不是Weave本身的bug,而是使用者对它的机制不了解导致的。比如MTU问题、DNS命名冲突、版本兼容性,这些如果提前知道,完全可以避免。

另外,Weave的社区虽然不如一些大项目活跃,但文档质量还不错,遇到问题先去翻官方文档和GitHub issues,大部分都能找到答案。实在找不到的,抓包分析是最可靠的手段,不要靠猜。

最后分享一个小技巧:在测试环境模拟各种故障场景,比如手动停掉一个weaverouter、模拟网络延迟、制造MTU不匹配等,观察系统的表现和恢复过程。这样到了生产环境真出问题的时候,你心里有底,知道大概是什么方向,排查起来会快很多。这个习惯我坚持了很久,受益良多。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询