- 网络
- 云原生
【免费下载链接】weave
Simple, resilient multi-host containers networking and more.
本指南讲解如何通过 Kubernetes addon(DaemonSet 清单)把 Weave Net 部署为 Kubernetes 集群的 CNI 网络插件:它会在每个节点上自动运行 Weave 路由器与 Network Policy Controller(NPC),实现 Pod 网络互通与基于 NetworkPolicy 的流量隔离。读完本文,你将掌握从单命令安装、GKE/EKS 环境适配、资源配置与 Pod 驱逐防护,到环境变量定制、日志诊断与数据面加密加固的完整实战方案。
安装
在安装 Weave Net 之前,请先确认防火墙没有阻断以下端口:TCP 6783 与 UDP 6783/6784。这些端口用于节点间控制面与数据面的通信,更多细节参见仓库内的 FAQ。
单命令安装
在已启用 CNI 的 Kubernetes 集群上,Weave Net 可以仅用一条命令安装完成:
$ kubectl apply -f https://github.com/weaveworks/weave/releases/download/v2.8.1/weave-daemonset-k8s.yaml重要提醒:这份默认配置不会开启加密。如果你的数据面流量不受保护,恶意攻击者可能借此访问 Pod 网络,请继续阅读下文"加固部署"一节了解替代方案。
命令执行后数秒内,每个节点上都会出现一个 Weave Net Pod;此后新建的任意 Pod 都会被自动接入 Weave 网络。
注意:该命令要求 Kubernetes 1.4 及以上版本,并建议 master 节点至少具备两个 CPU 核心。
关于 CNI:CNI(Container Network Interface)是 Linux 容器配置网络接口的提议标准。如果你的集群尚未启用 CNI,可以通过 kubeadm 快速引导一个支持 CNI 的集群,也可以按照官方文档手动配置 CNI。此外,Weave Net 依赖标准portmapCNI 插件来实现hostport功能,请确保portmap插件已安装到/opt/cni/bin目录(集群安装器如 kubeadm 通常会自动安装,手动配置 CNI 时则需要自己安装)。
仓库中自带与上述官方清单同构的本地版本,可直接查看其内容以理解 addon 结构:weave-daemonset-k8s-1.11.yaml(另有 1.9 版 与 1.8 版)。从清单可以看到,addon 由三部分构成:
- 一个init 容器
weave-init:运行 init.sh,负责探测内核模块(如br_netfilter、xt_set)、设置bridge-nf-call-iptables,并把 Weave CNI 插件二进制安装到宿主机的/opt/cni/bin(或 GCI 系统上的回退目录/home/kubernetes/bin); - 主容器
weave:运行 launch.sh 启动 Weave 路由器(weaver); - 辅助容器
weave-npc:运行 Network Policy Controller。
该 DaemonSet 以hostNetwork: true方式运行、挂载宿主机/var/lib/weave持久化 IPAM 数据,并设置了priorityClassName: system-node-critical与容忍(tolerations),确保它能被调度到带污点的节点。
从旧版 Weave CNI 插件迁移
如果你的集群此前通过完整安装方式使用过 Weave CNI 插件,必须在应用 Weave-kube addon 之前先将其卸载:关闭 Kubernetes,并在所有节点上执行:
weave reset- 移除任何自行配置的启动项(例如
systemd单元) rm /opt/cni/bin/weave-*
然后重新启动 Kubernetes,再按上文方式安装 addon。
在 GKE 上安装
在 Google Kubernetes Engine(GKE)上,必须在启动 Weave Net 前授予用户创建 Kubernetes Role 的权限,这是使用基于角色的访问控制(RBAC)的前提,请参照 GKE 官方关于 role-based access control 的指引操作。
在 EKS 上安装
Amazon EKS 默认安装amazon-vpc-cni-k8sCNI。改用 Weave Net 作为 CNI 的步骤如下:
- 按官方文档说明的方式创建 EKS 集群;
- 运行
kubectl delete ds aws-node -n kube-system删除amazon-vpc-cni-k8sDaemonSet; - 在每个节点上删除
/etc/cni/net.d/10-aws.conflist; - 修改实例安全组,放行 TCP 6783 与 UDP 6783/6784 端口;
- 清空 iptables 的 nat、mangle、filter 表,清除
amazon-vpc-cni-k8s遗留的 iptables 配置; - 重启 kube-proxy Pod 以重新配置 iptables;
- 按上文安装步骤应用 weave-net DaemonSet;
- 删除现有 Pod,使它们在 Weave 的 Pod CIDR 地址空间内被重建。
请注意:虽然 Pod 可以连接 Kubernetes API server,但 API server 无法主动连接 Pod,因为 API server 所在节点运行在 EKS 管理的网络上、并不接入 Weave Net。
升级 DaemonSet
DaemonSet 定义采用 [RollingUpdate] 滚动更新策略(仓库清单中的updateStrategy.type: RollingUpdate,并带minReadySeconds: 5让每个新 Pod 先就绪 5 秒再滚动下一个)。因此当你kubectl apply一个新版本时,Kubernetes 会自动逐个重启 Weave Net Pod,无需手动干预。
CPU 与内存需求
Kubernetes 按节点管理 [资源配额],只把 Pod 调度到有足够空闲资源的节点上。仓库内示例清单中,weave与weave-npc容器各请求cpu: 50m(约 0.05 核),这对小规模集群通常够用,但生产环境应持续监控实际用量并按需调整 requests。
不建议随意设置 CPU 或内存的limit,除非你对此非常有经验——因为 Linux 内核实现资源限额的行为有时会出乎意料。
在单核单节点集群上,由于其他 Kubernetes 组件已占用约 95% 的 CPU,Weave Net 可能根本无法被调度安装。最直接的解决办法是使用至少两个 CPU 核心的机器。
Pod 驱逐
当节点 CPU、内存或磁盘耗尽时,Kubernetes 可能决定驱逐一个或多个 Pod,其中也可能包括 Weave Net Pod——这会导致 Pod 网络功能中断。
降低被驱逐概率的办法是修改 DaemonSet,把 requests 调大,并让 limit 等于该值。这样 Kubernetes 会对该 Pod 应用"guaranteed"(有保证)而非"burstable"(突发)的资源策略。但磁盘空间的 request 无法通过同样方式设置,因此请留意此问题并监控资源使用,确保其始终低于 100%。
可以通过以下命令发现被驱逐的 Pod。kubectl get events的输出示例:
LASTSEEN COUNT NAME KIND TYPE REASON SOURCE MESSAGE 1m 1 mypod-09vkd Pod Warning Evicted kubelet, node-1 The node was low on resource: memory.kubectl get pods的输出示例:
NAME READY STATUS RESTARTS AGE IP NODE mypod-09vkd 0/1 Evicted 0 1h <none> node-1如果集群中出现这种情况,请考虑上文提到的手段以减少影响。
功能特性
Pod 网络
Weave Net 提供一个连接所有 Pod 的网络,完整实现了 Kubernetes 的网络模型。Kubernetes 通过 CNI 接口把 Pod 接入 Weave Net;而 [Services]、[Service Discovery via DNS] 与 [Ingress] 等更高层网络特性,均由 Kubernetes 在 Pod 网络之上自行实现。使用 Kubernetes addon 时,WeaveDNS 会被禁用(launch.sh 中 weaver 以--no-dns启动,正是为 Kubernetes 场景关闭内置 DNS)。
网络策略
[Kubernetes Network Policies] 允许你基于命名空间和标签安全地隔离 Pod。addon 中的weave-npc容器即为此而设:它监听 Kubernetes API 中的 NetworkPolicy 对象,并将规则翻译为宿主机上的 iptables 链与 ipset(参见 weave-npc/main.go 中的createBaseRules,其维护了WEAVE-NPC主链以及 ingress/egress 相关的默认与自定义子链)。关于网络策略的配置方法,请参阅官方 walkthrough 与 NetworkPolicy API 对象定义。
注意:从 Weave Net 1.9 版本起,Network Policy Controller 默认放行所有组播流量——因为同一个组播地址可能被多个 Pod 共用,无法为它们单独实现隔离规则。可以通过在 YAML 中给weave-npc增加--allow-mcast=false参数来关闭该行为(即拦截全部组播流量)。
注意:由于入站流量会被 SNAT(masquerade),只有以下两种场景下在 ingress 规则中使用ipBlock选择器才有意义:限制访问带externalTrafficPolicy=Local注解的 Service;或通过podIP直接访问 Pod 时。
故障排查
排查的第一步是确认 Weave Net 是否正常运行。此前kubectl apply只是请求下载并启动它;如果启动阶段出错,细节只会出现在容器日志中。
检查运行状态:
$ kubectl get pods -n kube-system -l name=weave-net NAME READY STATUS RESTARTS AGE weave-net-1jkl6 2/2 Running 0 1d weave-net-bskbv 2/2 Running 0 1d weave-net-m4x1b 2/2 Running 0 1d集群中每个节点应有一行对应记录;每行 STATUS 应为 "Running",READY 应为 2/2(weave与weave-npc两个容器)。如果看到 "Error" 或 "CrashLoopBackoff" 之类的状态,请查看对应容器的日志。
阅读日志
从上面的 Pod 列表中任选一个,查看其日志:
$ kubectl logs -n kube-system weave-net-1jkl6 weave如果日志较长,建议把输出重定向到文件中查看。
默认情况下weave容器的日志级别为info。若需要更详细的日志,可以通过 DaemonSet 中weave容器的EXTRA_ARGS环境变量为--log-level标志设置期望级别:
containers: - command: - /home/weave/launch.sh name: weave env: - name: EXTRA_ARGS value: --log-level=debug也可以把--log-level设为warning或error,只记录异常情况。(这个EXTRA_ARGS机制在 launch.sh 中会被直接透传给/home/weave/weaver进程,weave-npc容器同样通过 launch.sh 透传$EXTRA_ARGS。)
许多 Kubernetes 网络问题发生在比 Weave Net 更高的层次上,Kubernetes 官方的 Service Debugging Guide 提供了详细的逐步排查指引。
通过 weave status 检查运行状态
运行起来之后,可以用 Weave Net 的 CLI 命令查看状态,有两种等价方式:
方式一:安装weave脚本后直接运行:
$ weave status Version: 2.0.1 (up to date; next check at 2017/07/10 13:49:29) Service: router Protocol: weave 1..2 Name: 42:8e:e8:c4:52:1b(host-0) Encryption: disabled PeerDiscovery: enabled Targets: 3 Connections: 3 (2 established, 1 failed) Peers: 3 (with 6 established connections) TrustedSubnets: none Service: ipam Status: ready Range: 10.32.0.0/12 DefaultSubnet: 10.32.0.0/12方式二:如果不想在宿主机上安装额外软件,用kubectl命令也能得到完全相同的结果。先找出 Weave Net Pod:
$ kubectl get pods -n kube-system -l name=weave-net -o wide NAME READY STATUS RESTARTS AGE IP NODE weave-net-1jkl6 2/2 Running 0 1d 10.128.0.4 host-0 weave-net-bskbv 2/2 Running 0 1d 10.128.0.5 host-1 weave-net-m4x1b 2/2 Running 0 1d 10.128.0.6 host-2可以看到 Kubernetes 在每个宿主机上各部署了一个 Weave Net Pod,用于互联所有主机。然后:
- 选一个 Pod 执行命令(通常选第一个即可,例如
weave-net-1jkl6); - 用
kubectl exec运行weave status; - 由于命令在容器内执行,需指定绝对路径
/home/weave/weave并加上--local:
$ kubectl exec -n kube-system weave-net-1jkl6 -c weave -- /home/weave/weave --local status Version: 2.0.1 (up to date; next check at 2017/07/10 13:49:29) Service: router Protocol: weave 1..2 Name: 42:8e:e8:c4:52:1b(host-0) Encryption: disabled PeerDiscovery: enabled Targets: 3 Connections: 3 (2 established, 1 failed) Peers: 3 (with 6 established connections) TrustedSubnets: none Service: ipam Status: ready Range: 10.32.0.0/12 DefaultSubnet: 10.32.0.0/12排查被拦截的连接
如果怀疑合法流量被 Weave Network Policy Controller 拦截,首先检查所在节点上weave-npc容器的日志。先找出相关主机上的 Weave Net Pod:
$ kubectl get pods -n kube-system -o wide | grep weave-net weave-net-08y45 2/2 Running 0 1m 10.128.0.2 host1 weave-net-2zuhy 2/2 Running 0 1m 10.128.0.4 host3 weave-net-oai50 2/2 Running 0 1m 10.128.0.3 host2比如要看 host2 的情况,就选weave-net-oai50并运行:
$ kubectl logs <weave-pod-name-as-above> -n kube-system weave-npc当 Weave NPC 拦截连接时,会记录被拦截流量的以下细节:
- 使用的协议;
- 源 IP 与源端口;
- 目的 IP 与目的端口。
示例如下:
TCP connection from 10.32.0.7:56648 to 10.32.0.11:80 blocked by Weave NPC. UDP connection from 10.32.0.7:56648 to 10.32.0.11:80 blocked by Weave NPC.需要注意的坑
- Weave Net 在 iptables 1.8 及以上版本的主机上无法工作,只支持 iptables 1.6。
- 不要在 kube-proxy 上开启
--masquerade-all:这会把每条 Pod 间通信的源地址改写,导致基于"哪些 Pod 可以通信"的网络策略无法正确执行。 - 如果给 kube-proxy 设置了
--cluster-cidr,务必保证它与传给 Weave Net 的IPALLOC_RANGE(见下文)一致。 - 每个节点必须开启 IP 转发,Pod 才能访问 Kubernetes Service 或其他网段的地址。用
sysctl net.ipv4.ip_forward检查,结果应为1。(注意开启 IP 转发可能带来安全影响。) - Weave Net 可以在 minikube v0.28 及以上版本运行,但需先禁用 minikube 自带的默认 CNI 配置。
- Weave Net 与 containerd 1.6.0 至 1.6.4 版本存在兼容性问题,详见下文 "FailedCreatePodSandBox"。
排查 FailedCreatePodSandBox 错误
如果集群使用containerd运行时(版本 1.6.0 至 1.6.4),Weave Net 将无法为 Pod 分配 IP 地址。除使用 HostNetworking 的 Pod 外,其余 Pod 都会卡在ContainerCreating状态。
用kubectl describe检查受影响的 Pod,例如:
$ kubectl describe pod -n kube-system coredns-78fcd69978-dbxs9事件区会反复出现类似下面的错误:
Warning FailedCreatePodSandBox 3m6s kubelet Failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network for sandbox "09a23f79c96333b9f54e12df54e817837c8021cbaa32bdfeefbe2a1fb215d9ef": plugin type="weave-net" name="weave" failed (add): unable to allocate IP address: Post "http://127.0.0.1:6784/ip/09a23f79c96333b9f54e12df54e817837c8021cbaa32bdfeefbe2a1fb215d9ef": dial tcp 127.0.0.1:6784: connect: connection refused用下面的方法确认 containerd 版本是否受影响。kubectl get nodes -o wide:
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME host-1 Ready control-plane,master 13m v1.22.10 172.21.107.129 <none> Debian GNU/Linux 11 (bullseye) 5.10.0-14-amd64 containerd://1.6.4最后一列显示容器运行时及其版本。也可以直接运行:
$ containerd -v containerd containerd.io 1.6.4 212e8b6fa2f44b9c21b2798135fc6fb7c53efc16解决办法是把 containerd 升级到 v1.6.5 及以上。例如在 Debian 上使用 Docker 官方软件源时:
sudo apt install containerd.io=1.6.6-1问题根源是 cni v1.1.0 的行为变更导致 Weave 出现回归,该问题在 cni v1.1.1 中修复;containerd 1.6.5 起使用 cni 1.1.1 及以上版本。
修改配置选项
手动编辑 YAML 文件
可以从 releases 页面下载 YAML 文件后手动编辑。例如:
- 通过向 YAML 中
command:数组添加参数,可向 Weave 路由器进程(weaver)传递额外参数(在 launch.sh 中,EXTRA_ARGS与命令行剩余参数都会拼接到 weaver 的启动命令之后); - 通过环境变量设置参数,将其插入 YAML 文件,例如:
containers: - name: weave env: - name: IPALLOC_RANGE value: 10.0.0.0/16可设置的环境变量
| 变量 | 含义与默认值 |
|---|---|
CHECKPOINT_DISABLE | 设为 1 时禁用新版本检查(默认为空,即开启检查) |
CONN_LIMIT | 节点间连接数的软上限,默认 200(与 launch.sh 中CONN_LIMIT=${CONN_LIMIT:-200}一致) |
HAIRPIN_MODE | Weave Net 默认在容器veth对的桥接侧开启 hairpin;若内核开启 hairpin 会崩溃(部分内核存在此问题),可设HAIRPIN_MODE=false关闭 |
IPALLOC_RANGE | Weave Net 使用的 IP 地址范围及其子网(CIDR 格式;默认10.32.0.0/12,源码见 launch.sh 第 40 行) |
EXPECT_NPC | 设为 0 关闭 Network Policy Controller(默认为开启,launch.sh中EXPECT_NPC=${EXPECT_NPC:-1},为 0 时去掉--expect-npc参数) |
KUBE_PEERS | Kubernetes 集群中对端节点地址列表(默认从 API server 动态获取;kube-utils/main.go 的getKubePeers会遍历 Node 的 InternalIP/ExternalIP 并排除自身) |
IPALLOC_INIT | 设置 IP Address Manager 的初始化模式(默认为在所有KUBE_PEERS之间用consensus达成一致,见launch.sh的IPALLOC_INIT="consensus=$(peer_count $KUBE_PEERS)") |
WEAVE_EXPOSE_IP | 设置 Weave 网络通往宿主机网络的网关 IP;把 addon 作为静态 Pod 配置时很有用(launch.sh中通过weave --local expose $WEAVE_EXPOSE_IP生效) |
WEAVE_METRICS_ADDR | Weave Net 守护进程对外提供 Prometheus 风格指标的地址与端口(默认0.0.0.0:6782,见launch.sh) |
WEAVE_PASSWORD | 对端会话密钥生成时使用的共享密钥,用于加密对端间流量 |
WEAVE_STATUS_ADDR | Weave Net 守护进程提供状态请求服务的地址与端口(默认禁用;只有设置了该变量时launch.sh才会附加--status-addr) |
WEAVE_MTU | Weave Net 默认 MTU 为 1376 字节;底层网络限制更紧时可调小,支持 jumbo frames 时可调大以提升性能,详见 fastdp MTU 说明 |
NO_MASQ_LOCAL | 设为 0 可关闭对带service.spec.externalTrafficPolicy=Local注解 Service 的客户端源 IP 保留;该特性仅在使用 Weave IPAM(默认)时生效(launch.sh中默认为--no-masq-local,为 0 时去掉该参数) |
IPTABLES_BACKEND | 设为nft时使用nftables后端替代iptables(默认为iptables;launch.sh未设置时会自动探测 legacy/nft 两种后端,若显式指定nft则把/sbin/iptables*符号链接指向iptables-nft*) |
加固部署
如前文"配置选项"所述,设置WEAVE_PASSWORD环境变量即可开启数据面加密;当你无法确认节点之间网络(fabric)的安全性时,这是推荐做法。
另一种选择是使用trusted-subnets,只白名单承载 k8s 节点的子网。需要注意的是,视具体场景而定,这可能仍然允许集群内恶意的容器访问 Weave 数据面。
更完整的替代方案请阅读 Securing Connections Across Untrusted Networks 文档。
此外,建议从 Pod 的 capabilities 中移除CAP_NET_RAW以提升安全性:默认情况下 Pod 可以伪造网络上任意的数据包,这会催生诸如 DNS 欺骗之类的攻击。在 DaemonSet 中按如下方式配置:
securityContext: capabilities: drop: ["NET_RAW"]- 网络
- 云原生
【免费下载链接】weave
Simple, resilient multi-host containers networking and more.
相关推荐
Weave Net 与 Kubernetes / Mesos 的 CNI 集成实战:插件安装、网络配置与故障排查
Weave Net 与 Kubernetes / Mesos 的 CNI 集成实战:插件安装、网络配置与故障排查 本文以 Weave Net 官方文档 site
网络云原生Composio 集成 Google Tasks:OAuth 配置选型与授权故障排查全指南
Composio 集成 Google Tasks:OAuth 配置选型与授权故障排查全指南 本文面向在 Composio 平台上接入 Google Tasks
人工智能AI Agent工具调用MCP 服务MCP ClientsWeave Net故障排查指南:解决10个常见网络问题
Weave Net故障排查指南:解决10个常见网络问题 Weave Net作为简单、弹性的多主机容器网络解决方案,在实际使用中可能会遇到各种网络连接问题。这份完
网络云原生
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考