Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time


Status: alpha, use with caution

wireguard-cni is a CNI plugin for WireGuard.


Configure the apiserver endpoint that wg-cni should use to query configuration:

kubectl -n kube-system create configmap wg-cni-env --from-literal=KUBERNETES_APISERVER_ENDPOINT=https://<IP_ADDRESS>:<PORT>

Install wg-cni and its kubeconfig file on all nodes in the cluster:

kubectl apply -f manifests/wg-cni.yml

wg-cni is set up as a chained CNI plugin. This means you have to configure wg-cni as an additional CNI plugin in your configuration.

To do this, add wg-cni to the list of plugins:

  "type": "wg-cni",
  "kubeConfigPath": "/etc/kubernetes/wg-cni.kubeconfig"

Note that the wg-cni.kubeconfig file gets created automatically by wg-cni during installation.

wg-cni should now be ready and running - you can check with:

kubectl -n kube-system get pods -l k8s-app=wg-cni

Example: chained plugin configuration with flannel

Edit the kube-flannel-cfg configmap and add wg-cni as a chained plugin. Deploy new flannel pods for the configuration to be written. To do that, you can delete the currently running flannel pods with kubectl -n kube-system delete pods -l app=flannel.

Edit the configmap:

kubectl -n kube-system edit configmap kube-flannel-cfg

Example kube-flannel-cfg configmap:

kind: ConfigMap
apiVersion: v1
  name: kube-flannel-cfg
  namespace: kube-system
    tier: node
    app: flannel
  cni-conf.json: |
      "name": "cbr0",
      "plugins": [
          "type": "flannel",
          "delegate": {
            "hairpinMode": true,
            "isDefaultGateway": true
          "type": "portmap",
          "capabilities": {
            "portMappings": true
          "type": "wg-cni",
          "kubeConfigPath": "/etc/kubernetes/wg-cni.kubeconfig"
  net-conf.json: |
      "Network": "",
      "Backend": {
        "Type": "vxlan"


To add a WireGuard connection to a pod, two things are required:

  1. a secret with the configuration and
  2. an annotation in the pod's metadata to signal wg-cni that it should configuare a link for it and where the configuration can be found.

Note: pods that are not annotated are skipped by wg-cni.

Create a file config.json with the following structure:

  "address": "",
  "privateKey": "AAev16ZVYhmCQliIYKXMje1zObRp6TmET0KiUx7MJXc=",
  "peers": [
      "endpoint": "",
      "publicKey": "+gXCSfkib2xFMeebKXIYBVZxV/Vh2mbi1dJeHCCjQmg=",
      "allowedIPs": [
      "persistentKeepalive": "25s"

Create a secret from the file:

kubectl create secret generic wgcni-demo --from-file ./config.json

Start a new pod with a corresponding annotation:

apiVersion: v1
kind: Pod
  name: test
  annotations: "wgcni-demo"

The value wgcni-demo is the name of the secret in the pod's namespace.

Once running, the pod should have a wg<suffix> interface that is configured according to your configuration.

If an error occurs, you should find a message in the events:

kubectl get events

Roadmap / Todo

  • Switch to for netlink
  • Provide a container and manifest to install the wg-cni plugin binary and required configuration on all nodes in a cluster
  • Allow dynamic configuration through Kubernetes resources
  • Consider allowing wg-cni to be used in standalone and chained mode