基于Wireguard实现本地与kubernetes集群互通
功能已实现
未完成说明
经过多天的尝试,仍然没有实现如标题所述的 “互通”,仍然需要配合 KtConnect
才能达到 “互通” 的效果,在之后对 k8s 有更深的了解时,再完善本文。
当前效果:VPN 客户端可以访问 Pod,Pod 无法访问 VPN 客户端
# 背景
由于本地电脑资源紧缺,在开发微服务时,计划将 Nacos、MySQL、Gateway 等中间件部署在云服务器的容器中,而 Nacos 需要网络互通才可以访问服务。
# 步骤
本文基于 Kubesphere 部署
# 创建有状态副本集(StatefulSet)
添加容器
以 yaml 的方式,复制高亮部分,再根据实际情况调整。
kind: StatefulSet
apiVersion: apps/v1
metadata:
name: wireguard
namespace: xxx-xxx
labels:
app: wireguard
annotations:
kubesphere.io/creator: admin
kubesphere.io/description: vpn
spec:
replicas: 0
selector:
matchLabels:
app: wireguard
template:
metadata:
creationTimestamp: null
labels:
app: wireguard
annotations:
logging.kubesphere.io/logsidecar-config: '{}'
spec:
initContainers:
- name: init
image: 'busybox:1.32.0'
command:
- sh
- '-c'
- >-
sysctl -w net.ipv4.ip_forward=1 && sysctl -w
net.ipv4.conf.all.forwarding=1
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
imagePullPolicy: IfNotPresent
securityContext:
capabilities:
add:
- NET_ADMIN
privileged: true
containers:
- name: container-uoh9ld
image: weejewel/wg-easy
ports:
- name: udp-51820
hostPort: 51820
containerPort: 51820
protocol: UDP
- name: tcp-51821
hostPort: 51821
containerPort: 51821
protocol: TCP
env:
- name: WG_HOST
value: #公网IP#
- name: PASSWORD
value: #WEB页面登录密码#
- name: WG_ALLOWED_IPS
value: '10.0.0.0/8' # 客户端路由到VPN服务器的ip
resources:
requests:
cpu: 10m
memory: 10Mi
volumeMounts:
- name: wireguard-pvc
mountPath: /etc/wireguard
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
imagePullPolicy: IfNotPresent
securityContext:
capabilities:
add:
- NET_ADMIN
- SYS_MODULE
privileged: true
- 我只复制到 64 行,因为我没有提前创建
wireguard-pvc
,然后再在页面补充71-76
的配置 - 指定部署到某个 node 上
- 执行创建
# 可视化页面
配置 Service,然后访问 51821
暴露出去的端口,即可进行 VPN 账号管理。
# 完善
在使用可视化页面配置用户,并下载配置时,发现
AllowedIPs = xxxxx
Endpoint = xxxxx
这两个的值可能跟实际不一致的,可通过修改部署的 yaml 文件中的环境变量 (opens new window): WG_ALLOWED_IPS
、 WG_DEFAULT_DNS
、 WG_PORT
进行修改,值得注意的是,环境变量中的 WG_PORT
修改,不会影响 vpn 暴露的端口,仅仅只会影响下载 conf 文件的内容,另外两个配置也是。
提示
至此:VPN 客户端可以访问 Pod
# 为实现互联的一些尝试
- 在 yaml 文件中添加
hostNetwork: true
,位置于initContainers
属性同级。 - 待 yaml 生效后,容器所在的宿主机通过
ip addr
可查看到 wireguard 容器中的虚拟网卡 wg0,同时也将51820
、51821
端口也暴露在宿主机 ip 上。
笔记
在把 hostNetwork: false
或删除容器操作都不会自动删除宿主机上的此网卡 wg0,需要手动删除
ip link delete wg0
# 端口转发
直接公网访问 51820
有一定风险,建议改个端口。
iptables -t nat -A PREROUTING -p udp --dport 入口端口 -j REDIRECT --to-port 目的端口
笔记
在完成上述操作之后,以为可以实现在宿主机 Ping 通 VPN 客户端了,但不知道什么原因,这样的配置下,网络变得很差。
# 路由转发(未达到预期)
理论上,完成上面的步骤,宿主机下的容器应该可以与本地互通,但跨节点仍不能实现,尝试在其他节点添加路由表转发让指定 ip 段流量转发到 vpn 节点所在的宿主机,但添加后仍无法 ping 通
由于已经折腾了我三天三夜,因为还有工作需要开展,不能在这里耽误太久,因此只能通过 VPN+KtConnect 的方式实现互通。未完待续.......
# 参考资料
- 基于 Wireguard 技术的虚拟个人网络搭建:基于 wireguard 的内网穿透技术~ (opens new window)
- Kubernetes Wireguard Using Wg Easy – Sumarsono (opens new window)
- weejewel/wg-easy - Docker Image | Docker Hub (opens new window)
- pieterlange/kube-openvpn: Kubernetes native OpenVPN (opens new window)
- 如何通过 vpn 实现本地电脑与 k8s 集群的 Pod 互通 - V2EX (opens new window)