First of all you need a key pair for the server. Use the following command to generate the public and private keys:
# Generate privatekey
docker run --rm -i masipcat/wireguard-go wg genkey > privatekey
# Generate publickey from privatekey
docker run --rm -i masipcat/wireguard-go wg pubkey < privatekey > publickey
docker-compose.yaml
version: '3.3'
services:
wireguard:
image: masipcat/wireguard-go:latest
cap_add:
- NET_ADMIN
sysctls:
- net.ipv4.ip_forward=1
volumes:
- /dev/net/tun:/dev/net/tun
# Folder with 'publickey', 'privatekey' and 'wg0.conf'
- ./wireguard:/etc/wireguard
environment:
- WG_COLOR_MODE=always
- LOG_LEVEL=info
ports:
- 51820:51820/udp
# Uncomment the following line when 'AllowedIPs' is '0.0.0.0/0'
# privileged: true
restart: always
docker-compose up -d
Steps to deploy Wireguard-go to a k8s cluster:
privatekey
for the wireguard server in the Secret
objectwg0.conf
kubectl apply -f wireguard.yaml
to deploy wireguardwireguard.yaml
kind: Secret
apiVersion: v1
metadata:
name: wg-secret
type: Opaque
data:
# Generate and encode the server private key: `wg genkey | base64`
privatekey: REPLACE_WITH_BASE64_PRIVKEY
---
kind: ConfigMap
apiVersion: v1
metadata:
name: wg-configmap
data:
wg0.conf: |
[Interface]
Address = 10.33.0.1/24
ListenPort = 51820
PostUp = wg set wg0 private-key /etc/wireguard/privatekey && iptables -t nat -A POSTROUTING -s 10.33.0.0/24 -o eth0 -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -s 10.33.0.0/24 -o eth0 -j MASQUERADE
# [Peer]
# PublicKey =
# AllowedIPs = 10.33.0.2/32
---
kind: Service
apiVersion: v1
metadata:
name: wireguard
labels:
app: wireguard
spec:
type: LoadBalancer
ports:
- name: wg
protocol: UDP
port: 51820
targetPort: 51820
selector:
app: wireguard
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: wireguard
spec:
replicas: 1
selector:
matchLabels:
app: wireguard
template:
metadata:
labels:
app: wireguard
spec:
initContainers:
- name: sysctls
image: busybox
command:
- sh
- -c
- sysctl -w net.ipv4.ip_forward=1 && sysctl -w net.ipv4.conf.all.forwarding=1
securityContext:
capabilities:
add:
- NET_ADMIN
privileged: true
containers:
- name: wireguard
image: masipcat/wireguard-go:latest
command:
- sh
- -c
- echo "Public key '$(wg pubkey < /etc/wireguard/privatekey)'" && /entrypoint.sh
ports:
- containerPort: 51820
protocol: UDP
name: wireguard
- containerPort: 8080
protocol: TCP
name: healthcheck
livenessProbe: &probe
httpGet:
path: /
port: healthcheck
readinessProbe: *probe
env:
- name: LOG_LEVEL
value: info
- name: ENABLE_HEALTHCHECK
value: "true"
securityContext:
capabilities:
add:
- NET_ADMIN
privileged: true
resources:
requests:
memory: 64Mi
cpu: "100m"
limits:
memory: 256Mi
volumeMounts:
- name: cfgmap
mountPath: /etc/wireguard/wg0.conf
subPath: wg0.conf
- name: secret
mountPath: /etc/wireguard/privatekey
subPath: privatekey
volumes:
- name: cfgmap
configMap:
name: wg-configmap
- name: secret
secret:
secretName: wg-secret
/etc/wireguard/wg0.conf
[Interface]
# Assign you an IP (that's not in use) and add it to server configmap
Address = 10.33.0.2/32
# generate private key using `wg genkey`
PrivateKey = <your private key>
[Peer]
# Wireguard server public key
PublicKey = AbC...XyZ=
# LoadBalancer IP (replace with your LoadBalancer ip)
Endpoint = 1.2.3.4:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
(This example only works with OS that use openresolv
)
/etc/wireguard/wg0.conf
[Interface]
...
# Configure kube-dns ip address as dns resolver in you local machine (resolves names like 'your-service.default.svc.cluster.local')
PostUp = printf "nameserver 10.90.0.5\nsearch default.svc.cluster.local svc.cluster.local cluster.local" | resolvconf -a %i
[Peer]
...
# Change AllowedIPs to 10.0.0.0/8 if you only want to connect to k8s pods/services
AllowedIPs = 10.0.0.0/8