ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Moby 源码实战:用 Swarm Service Driller(ssd)排查 Docker Swarm 网络的控制面与内核数据面不一致

Moby 源码实战:用 Swarm Service Driller(ssd)排查 Docker Swarm 网络的控制面与内核数据面不一致 Moby 源码实战用 Swarm Service Drillerssd排查 Docker Swarm 网络的控制面与内核数据面不一致【免费下载链接】mobyThe Moby Project - a collaborative project for the container ecosystem to assemble container-based systems项目地址: https://gitcode.com/GitHub_Trending/mo/mobyssdSwarm Service Driller是 Moby 仓库内置的 Swarm 网络故障排查工具用于核对 Docker 守护进程内存中的网络控制面状态与内核中实际编程的数据面IPVS 负载均衡、iptables 转发规则是否一致以及各节点通过 gossip 协议同步出的控制面状态是否收敛。本文基于 README 与 ssd.py 源码完整讲解两类检查的原理、操作命令和输出判读方法帮助你在出现网络 inspect 正常但流量不通这类疑难问题时快速定位责任层。ssd 的定位控制面与数据面之间的一致性探针在 Docker Swarm 网络中服务发现与负载均衡由两部分协作完成控制面由 Docker 守护进程daemon/libnetwork 下的集群 agent维护记录每个服务的 VIP、本地负载均衡索引LocalLBIndex与后端任务列表数据面由内核实际编程overlay 网络在每个容器沙箱内用 IPVS以 fwmark 标识服务做本地负载均衡ingress 网络则用 iptables 的 DNAT 规则把发布端口转发到 ingress 沙箱。ssd 的核心职责就是把这两份账本逐条比对确认没有漂移。它当前只覆盖负载均衡IPVS 实现的一致性检查这一点在 README 中明确说明。运行方式与依赖ssd 以容器形式运行通过挂载 Docker socket 和 netns 目录获得对 daemon API 与内核网络命名空间的访问权。README 给出的标准命令为docker run -v /var/run/docker.sock:/var/run/docker.sock \ -v /var/run/docker/netns:/var/run/docker/netns \ --privileged --nethost sanimej/ssd ov2从源码看两个挂载点各有用途/var/run/docker.sockssd 通过 docker-py 客户端docker.APIClient(base_urlunix://var/run/docker.sock)见 ssd.py L141拉取network inspect --verbose的控制面数据/var/run/docker/netnsssd 用nsenter --netnamespace进入每个容器的网络沙箱执行ipvsadm -ln读取内核中真实的 IPVS 表ssd.py L94因此必须--privileged。命令的第一个参数是网络名第二个可选参数为子命令gossip-consistency默认值为default即一致性检查ssd.py L136-L145。如果第一个参数是ingress则只检查 ingress 网络。仓库提供了现成的 Dockerfile基于 Alpine预装了检查所需的工具链python2、iproute2、ipvsadm、bash、nsenterutil-linux以及网络诊断工具strace、iperf、ethtool等并将 ssd.py 设为入口python /ssd.py。你可以用它自行构建镜像替代 README 中引用的外部sanimej/ssd镜像例如docker build -t local/ssd daemon/libnetwork/cmd/ssd检查一节点内的控制面 / 数据面一致性IPVS 编程核对default模式下ssd 对指定网络执行check_network流程如下见 check_network拉取控制面真值调用network inspect --verbose从返回的Services字段提取每个服务的LocalLBIndex即 IPVS 中使用的 fwmark和任务列表的EndpointIP构建fwmark → 后端 IP 集合的期望映射读取内核真值对网络上每个容器沙箱键来自NetworkSettings.SandboxKeynsenter进其网络命名空间执行ipvsadm -ln解析输出中以FWM开头行的标记值和-开头的后端条目双向比对IPVS 中有、daemon 中没有的 LB Index → 报LB Index X present in IPVS but missing in docker daemon内核残留daemon 中有、IPVS 中没有的 → 报present in docker daemon but missing in IPVS编程丢失两边都有但后端集合不一致 → 报Incorrect LB Programming for service ...并分别打印控制面与内核 IPVS 的后端列表方便肉眼定位多出来的或少掉的实例。在 agent.go 中可以看到ServiceInfo结构的定义VIP、LocalLBIndex、Tasks、Ports——这正是 ssd 比对所依赖的network inspect --verbose输出的数据来源。README 中一个三节点集群网络ov23 个服务各 3 副本的正常输出如下每个沙箱下逐一核对所有服务后输出OK随后自动追加对ingress网络的检查$ docker run -v /var/run/docker.sock:/var/run/docker.sock \ -v /var/run/docker/netns:/var/run/docker/netns \ --privileged --nethost sanimej/ssd ov2 Verifying LB programming for containers on network ov2 Verifying container /s2.3.ltrdwef0iqf90rqauw3ehcs56... service s2... OK service s3... OK service s1... OK Verifying container /s3.3.nyhwvdvnocb4wftyhb8dr4fj8... service s2... OK service s3... OK service s1... OK Verifying container /s1.3.wwx5tuxhnvoz5vrb8ohphby0r... service s2... OK service s3... OK service s1... OK Verifying LB programming for containers on network ingress Verifying container Ingress... service web... OKingress 网络iptables 发布端口 DNAT 规则核对对ingress网络或 default 模式自动追加的 ingress 检查ssd 额外调用check_iptablesssd.py L25-L45先nsenter进入ingress_sbox网络命名空间读取eth1的 IPingress 沙箱在docker_gwbridge网络上的地址发布端口最终会被 DNAT 到该 IP对服务Ports中的每个Target: x, Publish: y条目用iptables -t nat -C DOCKER-INGRESS -p tcp --dport publish -j DNAT --to ingressIP:publish探测 nat 表DOCKER-INGRESS链中是否存在对应规则缺失时输出Service name: host iptables DNAT rule for port x - ingress sandbox ip:x missing。这与数据面实现相互印证libnetwork 的 bridge 驱动内部在主机命名空间的 nat 表 PREROUTING 中挂接DOCKER-INGRESS链见 iptabler/network.go L408服务流量经 DNAT 进入 ingress 沙箱后再由 IPVS 分发到后端。检查二跨节点控制面一致性gossip-consistencySwarm 网络状态通过 gossip 协议在集群内同步。gossip-consistency子命令验证所有节点对该网络的控制面状态是否一致READMEdocker run -v /var/run/docker.sock:/var/run/docker.sock \ -v /var/run/docker/netns:/var/run/docker/netns \ --privileged sanimej/ssd ov2 gossip-consistency三节点集群、ov2网络上的正常输出——三行 hash 完全相同即表示已收敛Node id: sjfp0ca8f43rvnab6v7f21gq0 gossip hash c57d89094dbb574a37930393278dc282 Node id: bg228r3q9095grj4wxkqs80oe gossip hash c57d89094dbb574a37930393278dc282 Node id: 6jylcraipcv2pxdricqe77j5q gossip hash c57d89094dbb574a37930393278dc282源码级实现全局服务 每节点 hash该子命令的机制比表面更巧妙ssd.py L147-L165ssd 在本地节点通过 daemon API创建一个名为gossip-hash的 global 服务其任务镜像为docker/ssd参数为网络名 gossip-hash并把/var/run/docker.sock挂载进每个任务global 服务保证集群中每个节点各运行一个任务每个任务执行gossip-hash分支inspect_network --verbose后把该节点视角下所有服务的 VIP 及任务明细字段排序逐条喂给 MD5打印节点 ID 与摘要然后signal.pause()挂起等待被收集创建服务后短暂等待用service logs gossip-hash收集全部任务的输出即每节点一行 hash最后调用remove_service清理。因此输出的每行Node id: node-id gossip hash md5对应集群中的一个节点。hash 相同说明各节点经 gossip 同步出的网络控制面状态一致如果出现不一致按 README 的建议在各节点上执行docker network inspect --verbose逐个对比输出即可定位具体差异字段通常是某个服务的任务列表或端点 IP 未同步到位。值得注意的是hash 是对排序后的状态字段计算的与任务的枚举顺序无关可以消除字段顺序造成的假阳性。故障排查建议路径结合两类检查可以形成一条从现象到结论的定位路径服务 VIP 可达性异常、个别后端失联→ 先跑 default 模式的一致性检查。若报missing in IPVS/Incorrect LB Programming问题在本机内核数据面编程可进一步用ipvsadm -ln经 nsenter 到对应沙箱与docker network inspect --verbose手工复核ingress 发布端口不通、容器内直连正常→ 关注 iptables DNAT 规则缺失输出检查iptables -t nat -L DOCKER-INGRESS -n中发布端口规则部分节点行为与主节点不一致如新加入节点上服务不可见→ 跑gossip-consistency。若 hash 不一致逐节点docker network inspect --verbosediff 出未收敛的节点与字段。适用前提与注意事项工具依赖 Linux 内核特性IPVS、iptables、netns nsenter在 Linux 节点上运行才有效ssd.py 使用 Python 2 语法print语句Dockerfile 中显式安装python2并建立python软链自行移植到 Python 3 环境需做语法迁移一致性检查当前仅覆盖 IPVS 负载均衡这一项数据面内容README 明示 currently the tool checks only for the consistency of the Load balancer其他数据面要素如路由、VXLAN 配置不在核对范围内gossip-consistency会在集群中短暂创建并删除一个 global 服务请确认当前节点具有 swarm 管理权限且集群允许创建临时服务。延伸阅读仓库内相关路径READMEssd 工具官方说明与示例输出ssd.py检查逻辑全部实现约 194 行可读性高适合作为理解 Swarm 网络数据面编程的活文档agent.goServiceInfoVIP / LocalLBIndex / Tasks / Ports结构定义即 ssd 比对的控制面数据来源service_linux.godaemon 侧通过moby/ipvs库在沙箱内创建/删除 IPVS 服务与后端的实现与 ssd 读取的内核状态一一对应networkdbgossip 同步的集群数据库层gossip-consistency校验的对象即其收敛结果。【免费下载链接】mobyThe Moby Project - a collaborative project for the container ecosystem to assemble container-based systems项目地址: https://gitcode.com/GitHub_Trending/mo/moby创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表