Tunnels without the bloat,WireGuard.
A fast, modern, open-source VPN protocol that builds encrypted point-to-point tunnels with state-of-the-art cryptography and a tiny codebase. This guide walks through the core peer-and-key model, the smallest useful two-machine tunnel, a full Kubernetes DaemonSet deployment, Docker, and mesh automation with Netmaker.
Peers, not clients
WireGuard's model is symmetric — every device is a peer with a key pair, and the public keys themselves form the access control list. One UDP port, a handful of config lines, and the tunnel is up.
- Keys — public keys are the ACL; generate with wg genkey.
- Routing — AllowedIPs decides what flows through each peer.
- NAT — PersistentKeepalive holds firewall mappings open.
On this page
What this guide covers
How WireGuard works
The peer model, key pairs, and the five config fields — PrivateKey, PublicKey, AllowedIPs, Endpoint, PersistentKeepalive — that do most of the work.
Peer-to-peer + Kubernetes
The smallest useful two-machine tunnel, then a full step-by-step DaemonSet and ConfigMap deployment across cluster nodes.
Docker
Running WireGuard in a container — Compose notes, firewall prep, and opening UDP 51820 through ufw.
Netmaker automation
Automate WireGuard meshes from homelab to enterprise with Netmaker's highly available Helm install.
Start here
Information
WireGuard is a modern, high-performance VPN application designed to be simple, fast, and secure. It utilizes state-of-the-art cryptography to establish encrypted connections between devices, ensuring privacy and security over the internet. Unlike traditional VPN solutions, WireGuard is lightweight, with a minimal codebase that reduces the potential for vulnerabilities and improves performance. It is cross-platform, supporting major operating systems like Linux, Windows, macOS, iOS, and Android, and is known for its ease of configuration and seamless integration into existing network infrastructures. WireGuard’s efficiency and robust security make it an ideal choice for both personal and enterprise use.
Core concepts
How WireGuard Works
WireGuard connects peers, not clients and servers — the model is symmetric. Each peer has a key pair: a private key it keeps secret and a public key it shares. A peer accepts an encrypted packet only if it is signed by a known public key listed in its config, so the public keys themselves form the access control list.
Three fields do most of the work in every config:
| Field | Meaning |
|---|---|
PrivateKey | This peer’s secret key (from wg genkey) |
PublicKey | The remote peer’s public key, under [Peer] |
AllowedIPs | Which IPs are accepted from and routed to that peer |
Endpoint | The remote peer’s reachable IP:port |
PersistentKeepalive | Seconds between keepalives to hold a NAT mapping open |
Hands on
Basic Peer-to-Peer Tunnel
Before the Kubernetes deployment, here is the smallest useful setup — two machines linked over a single UDP port. Generate a key pair on each peer:
umask 077wg genkey | tee privatekey | wg pubkey > publickeyServer (/etc/wireguard/wg0.conf):
[Interface]PrivateKey = <Server_Private_Key>Address = 10.0.0.1/24ListenPort = 51820
[Peer]PublicKey = <Client_Public_Key>AllowedIPs = 10.0.0.2/32Client (/etc/wireguard/wg0.conf):
[Interface]PrivateKey = <Client_Private_Key>Address = 10.0.0.2/24
[Peer]PublicKey = <Server_Public_Key>Endpoint = server.example.com:51820AllowedIPs = 10.0.0.0/24PersistentKeepalive = 25Bring the tunnel up on both ends with wg-quick up wg0 (and down with wg-quick down wg0). Check live status and handshake times with sudo wg. Setting the client’s AllowedIPs to 0.0.0.0/0 instead would route all its traffic through the server — a full VPN.
-
Tutorial:
This is a step-by-step tutorial on setting up WireGuard for a Kubernetes cluster to enable access to containers from different networks via WireGuard!
-
Prepare Kubernetes Cluster:
Ensure that you have a running Kubernetes cluster. You can use a managed service like GKE, EKS, or AKS, or set up your cluster using tools like Minikube, kubeadm, or k3s.
-
Install WireGuard on Nodes:
Install WireGuard on all Kubernetes nodes. The following instructions are for Ubuntu, but they can be adapted for other distributions.
Terminal window sudo apt updatesudo apt install -y wireguard -
Configure WireGuard Keys:
Generate WireGuard keys on each node.
This example below shows how to generate keys on a single node:
Terminal window umask 077wg genkey | tee privatekey | wg pubkey > publickeyRepeat this step for each node in the cluster and keep a record of each node’s private and public keys.
-
Create WireGuard Configuration:
Create a WireGuard configuration file for each node. Below is an example configuration (
wg0.conf) for a node:[Interface]PrivateKey = <Node_Private_Key>Address = 10.0.0.1/24ListenPort = 51820[Peer]PublicKey = <Peer_Node_Public_Key>Endpoint = <Peer_Node_IP>:51820AllowedIPs = 10.0.0.2/32PersistentKeepalive = 25- Replace
<Node_Private_Key>with the node’s private key. - Replace
<Peer_Node_Public_Key>with the peer node’s public key. - Replace
<Peer_Node_IP>with the peer node’s IP address. - Adjust the
AddressandAllowedIPsfields as needed.
- Replace
-
Deploy WireGuard DaemonSet:
Create a Kubernetes DaemonSet to deploy WireGuard on all nodes.
Save the following YAML to a file named
wireguard-daemonset.yaml:apiVersion: apps/v1kind: DaemonSetmetadata:name: wireguardnamespace: kube-systemspec:selector:matchLabels:name: wireguardtemplate:metadata:labels:name: wireguardspec:hostNetwork: truecontainers:- name: wireguardimage: k8s.gcr.io/pause:3.1 # Use a pause containersecurityContext:privileged: truevolumeMounts:- name: wireguard-configmountPath: /etc/wireguard- name: lib-modulesmountPath: /lib/modulesvolumes:- name: wireguard-confighostPath:path: /etc/wireguard- name: lib-moduleshostPath:path: /lib/modulesDeploy the DaemonSet:
Terminal window kubectl apply -f wireguard-daemonset.yaml -
Create WireGuard ConfigMap:
Create a ConfigMap to store the WireGuard configuration files. Save the following YAML to a file named
wireguard-configmap.yaml, and include the configuration for each node:apiVersion: v1kind: ConfigMapmetadata:name: wireguard-confignamespace: kube-systemdata:wg0.conf: |[Interface]PrivateKey = <Node1_Private_Key>Address = 10.0.0.1/24ListenPort = 51820[Peer]PublicKey = <Node2_Public_Key>Endpoint = <Node2_IP>:51820AllowedIPs = 10.0.0.2/32PersistentKeepalive = 25[Peer]PublicKey = <Node3_Public_Key>Endpoint = <Node3_IP>:51820AllowedIPs = 10.0.0.3/32PersistentKeepalive = 25Replace the placeholders with actual keys and IPs.
Apply the ConfigMap:
Terminal window kubectl apply -f wireguard-configmap.yaml -
Create WireGuard Init Container:
Modify the DaemonSet to include an init container that sets up WireGuard.
Update
wireguard-daemonset.yaml:apiVersion: apps/v1kind: DaemonSetmetadata:name: wireguardnamespace: kube-systemspec:selector:matchLabels:name: wireguardtemplate:metadata:labels:name: wireguardspec:hostNetwork: trueinitContainers:- name: setup-wireguardimage: busyboxcommand: ["sh", "-c", "cp /etc/wireguard-config/wg0.conf /etc/wireguard/wg0.conf && wg-quick up wg0"]volumeMounts:- name: wireguard-configmountPath: /etc/wireguard-config- name: wireguardmountPath: /etc/wireguardcontainers:- name: wireguardimage: k8s.gcr.io/pause:3.1securityContext:privileged: truevolumeMounts:- name: wireguardmountPath: /etc/wireguard- name: lib-modulesmountPath: /lib/modulesvolumes:- name: wireguard-configconfigMap:name: wireguard-config- name: wireguardhostPath:path: /etc/wireguard- name: lib-moduleshostPath:path: /lib/modulesUpdate the DaemonSet:
Terminal window kubectl apply -f wireguard-daemonset.yaml -
Verify WireGuard Setup:
Check the status of WireGuard on each node:
Terminal window sudo wgYou should see the WireGuard interface
wg0and its peers. -
Access Containers Across Networks:
Now, your nodes are connected via WireGuard. You can access containers across different networks by using the WireGuard IP addresses.
For example, if you have a pod on Node 1 with a WireGuard IP of
10.0.0.1, you can access it from Node 2 using that IP. -
Conclusion:
You have successfully set up WireGuard on a Kubernetes cluster, enabling secure communication between containers across different networks. This setup can be expanded and customized to fit more complex networking requirements.
Containers
Docker
Installing WireGuard on Docker!
-
Docker Compose
- Github
src=“data/wireguard/docker-compose.yml”
description=“This is a docker compose for wireguard.”
- Embed is disabled as of right now.
- Github
src=“data/wireguard/docker-compose.yml”
description=“This is a docker compose for wireguard.”
-
Ubuntu Installation Guide
- Core Pre-Installation
- Make sure your docker install is setup! If you need more information, please visit our Docker application page.
- Check your firewall, are you using
ufw,iptablesornftables
- Firewall
- Wireguard will be operating on the
UDPport of51820. - For:
ufw- To enable the port through
ufwrunsudo allow 51821/udp
- To enable the port through
- Wireguard will be operating on the
- Core Pre-Installation
Mesh automation
Netmaker
- Netmaker is a Wireguard automation application that handles self-hosted homelabs to small business / enterprise networking.
- Official Github Repo
Netmaker Install
Section titled “Netmaker Install”-
Advance install for netmaker allows the setup of a highly available installation within Kubernetes through helm.
-
The default settings may not install
wireguardat the kernel level (for security reasons) and default to Postgres for storage.- Not having kernel level wireguard may cause performance drops and they recommend that you install wireguard before beginning.
-
Helm Install Commands:
-
Terminal window helm repo add netmaker https://gravitl.github.io/netmaker-helm/helm repo update -
If you do not have
helmorkubernetessetup, we recommend you visit our kubernetes setup.
-
-
The storage of the certificates will be an issue for this netmaker cluster, they recommend two types of storage classes:
RWO-Read Write Once- Storage instance where only a single node is allowed to access the storage volume at a time for read and write access.RWX-Read Write Many- Storage instance where many nodes can concurrently read and write to the storage volume.
Questions
Frequently asked
What is WireGuard?
WireGuard is an open-source VPN protocol that creates fast, encrypted point-to-point tunnels. It uses modern cryptography, runs in the Linux kernel for high performance, and has a very small codebase — a few thousand lines — which reduces its attack surface.
How does WireGuard differ from OpenVPN?
WireGuard is far smaller and faster. It runs in the kernel with modern fixed cryptography and connects almost instantly, whereas OpenVPN runs in userspace with configurable ciphers and higher overhead. WireGuard configs are also much simpler.
What are AllowedIPs in a WireGuard config?
AllowedIPs serves two roles — it defines which source IPs are accepted from a peer (a cryptographic access control list) and which destination IPs are routed through that peer. Setting 0.0.0.0/0 routes all traffic through the tunnel.
What is PersistentKeepalive in WireGuard?
PersistentKeepalive sends a small packet every N seconds to keep a NAT or firewall mapping open. It is needed when a peer sits behind NAT and must remain reachable; a value of 25 seconds is the common default.
What port does WireGuard use?
WireGuard uses a single UDP port, 51820 by default, set with ListenPort. Because it is UDP-only, you must allow that port through firewalls like ufw, iptables, or nftables on the server side.
