WireGuard VPN deployed on Kubernetes cluster

So you have installed a home lab kubernetes and now you need a secure method to get to your apps, this is where WireGuard steps in to the rescue.
This is a ‘quick and dirty’ solution cuz in a perfect world, a few things should be done differently like passing the environment variables with a config map, here i just shove them into the container section of the deployment, is good enough for a partisan like me who only wants to connect to his home lab from remote, and for that purpose WireGuard is ideal.
This is a tutorial for those who want to deploy WireGuard VPN server on a kubernetes cluster, and be able to access kubernetes services from out of the home lab network.

NodePort service will be used to expose WireGuard VPN to clients.
HostPath volume will be used as a persistent volume for app data.

REF: docker image –> https://docs.linuxserver.io/images/docker-wireguard

Prerequisites:

  • A Kubernetes cluster
  • DNS name
  • Basic kubernetes understanding

Create a ‘deployment.yaml’ file, there we will add all our resources:
   NOTE: it is better to pass the environment variables variables with a ConfigMap.
         1. Namespace
         2. Deployment
         3. StorageClass
         4. PersistentVolume
         5. PersistenVolumeClaim
         6. Service

Only 3 values have to be changed for this to work:
   NOTE: here you can read more about environment variables.

         1. Line 36: add your DNS.
         2. Line 65: add your hostpath.
         3. Line 93: add your hostpath.
         4. Line 117: select a port between 30000 and 32767

apiVersion: v1
kind: Namespace
metadata:
  name: wireguard-ns
  labels:
    name: wireguard
---
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: wireguard-ns
  name: wireguard-deployment
  labels:
    app: wireguard
spec:
  replicas: 1
  selector:
    matchLabels:
      app: wireguard
  template:
    metadata:
      labels:
        app: wireguard
    spec:
      containers:
      - name: wireguard
        image: lscr.io/linuxserver/wireguard:latest
        env:
        - name: PUID
          value: "1000"
        - name: GUID
          value: "1000"
        - name: TZ
          value: "Asia/Jerusalem"
        - name: SERVERURL
          value: "some-dns.duckdns.org"
        - name: SERVERPORT
          value: "51820"
        - name: PEERS
          value: "1"
        - name: PEERDNS
          value: "auto"
        - name: INTERNAL_SUBNET
          value: "10.13.13.0"
        - name: ALLOWEDIPS
          value: "0.0.0.0/0"
        securityContext:
          capabilities:
            add: ["NET_ADMIN", "SYS_MODULE"]
        ports:
          - name: udp-port
            containerPort: 51820
            protocol: UDP
        volumeMounts:
            - name: wireguard-config
              mountPath: /config      
            - name: lib-modules
              mountPath: /lib/modules
      volumes:
        - name: wireguard-config2
          persistentVolumeClaim:
              claimName: wireguard-pv-claim
        - name: wireguard-config
          hostPath:
            path: /home/rke/stmp/rke-persistent-volumes/wireguard-pv_2
        - name: lib-modules
          hostPath:
            path: /lib/modules
---
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: local-storage-for-wireguard
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: wireguard-pv-volume
  labels:
    type: local
spec:
  storageClassName: local-storage-for-wireguard
  claimRef:
    name: wireguard-pv-claim
    namespace: wireguard-ns
  capacity:
    storage: 2Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/home/rke/stmp/rke-persistent-volumes/wireguard-pv_2"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: wireguard-pv-claim
  namespace: wireguard-ns
spec:
  storageClassName: local-storage-for-wireguard
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 2Gi
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: wireguard
  name: wireguard
  namespace: wireguard-ns
spec:
  ports:
  - nodePort: 32003
    port: 51820
    protocol: UDP
    targetPort: 51820
  selector:
    app: wireguard
  type: NodePort


Run the deployment

k apply -f deployment.yaml

Check the container logs, you should see something like this:

Next you should install a WireGuard Client and scan the barcode.
you can find clients for download here.

There is no good indication if you are really connected or not, so after connecting with the WireGuard Client check the server to see if there is a handshake:

And thats about it…. that will be enough for you to be able to get to your lab kubernetes services.