内容提要
本文介绍如何在K8s集群内搭建WireGuard VPN,使用wg-easy管理工具,通过NPS内网穿透实现远程访问集群网络。文章详细说明了部署配置、网络拓扑、踩坑记录(如INIT_ENABLED必须开启、禁用IPv6、配置sysctl)及客户端连接验证方法,最终实现像在内网一样直接访问Pod。
延伸解读
为什么选择 wg-easy 而不是原生 WireGuard
原生 WireGuard 配置虽不复杂,但管理多个客户端需要手动生成密钥、编写配置文件并分发,操作繁琐。wg-easy 提供 Web UI,可在浏览器中直接创建/删除客户端,并支持下载配置文件或二维码,简化了运维流程,适合需要频繁管理客户端的场景。
内网穿透方案的关键点
由于集群无公网 IP,文章使用 NPS 将公网 UDP 流量转发至 wg-easy Pod。这种方案要求 NPS 服务器和 wg-easy 的端口(1038/udp)保持一致,且客户端 Endpoint 需指向 NPS 的公网地址。此外,PersistentKeepalive 设为 25 秒可维持 UDP 穿透的长期连接,避免空闲断开。
部署中的常见坑及规避
文章记录了三个关键坑:INIT_ENABLED 必须显式设为 true,否则 INIT_* 变量不生效;Pod 内 IPv6 默认禁用,需设置 DISABLE_IPV6=true 避免 wg-quick 失败;必须通过 securityContext.sysctls 开启 net.ipv4.ip_forward 和 src_valid_mark,否则流量无法转发。这些配置直接影响 VPN 功能,部署时需特别注意。
SNAT 在集群网络中的角色
wg-easy 自动生成的 iptables MASQUERADE 规则将 VPN 客户端流量源 IP 转换为 Pod IP,使流量在集群内表现为普通 Pod 通信,无需额外路由配置。这简化了网络集成,但意味着客户端访问集群时,目标 Pod 看到的源 IP 是 wg-easy Pod 的 IP,而非客户端真实 IP,可能影响基于源 IP 的日志或策略。
Q&A
如何在K8s集群中搭建WireGuard VPN?
在K8s集群中搭建WireGuard VPN,可以使用wg-easy管理工具。首先创建Namespace和PVC,然后部署wg-easy的Deployment,配置环境变量如WG_HOST、WG_PORT、INIT_ENABLED等,并设置securityContext以启用IP转发和禁用IPv6。最后创建Service和Ingress暴露Web UI。
wg-easy是什么?它有什么优势?
wg-easy是一个带Web UI的WireGuard管理工具,可以在浏览器中创建/删除客户端,下载配置文件或二维码,简化了WireGuard的客户端管理。
为什么需要设置INIT_ENABLED=true?
INIT_ENABLED=true是必须的,否则所有INIT_*变量都不会生效,wg0.conf不会按配置生成。
如何解决Pod内IPv6被禁用导致WireGuard启动失败的问题?
在wg-easy的Deployment中添加环境变量DISABLE_IPV6=true,这样wg-easy只生成IPv4配置,避免因IPv6地址添加失败导致wg-quick up失败。
WireGuard客户端如何配置才能访问集群网络?
客户端配置中,AllowedIPs需要包含集群网段,例如10.4.0.0/16,这样客户端才会将访问集群的流量送入VPN隧道。同时建议设置PersistentKeepalive=25以维持UDP穿透连接。
如何验证WireGuard VPN连接是否成功?
在服务端执行kubectl exec -n wg-easy <pod> -- wg show,如果看到peer的endpoint和latest handshake时间,说明连接成功。客户端连上后,可以ping集群内的Pod IP来验证网络连通性。
WireGuard VPN的流量是如何从客户端到达集群Pod的?
客户端将流量加密后发送到NPS公网IP,NPS通过UDP隧道转发到wg-easy Pod的1038端口,解密后从wg0接口出来,经过SNAT(MASQUERADE)将源IP改为Pod IP,然后进入集群网络到达目标Pod。