Skip to navigationSkip to main contentSkip to footerScaleway DocsSparklesIconAsk our AI
SparklesIconAsk our AI

Enabling encryption in Kapsule with Cilium

encryptionciliumkapsulewireguard

This guide explains how to enable WireGuard encryption in Scaleway’s Kapsule Managed Kubernetes service. By default, Cilium is selected as the CNI when creating a cluster. We will configure encryption via a CiliumNodeConfig resource and then verify that traffic is indeed encrypted.

Before you start

To complete the actions presented below, you must have:

  • A Scaleway account logged into the console
  • Owner status or IAM permissions allowing you to perform actions in the intended Organization
  • A functional Kubernetes Kapsule cluster.
  • kubectl installed and configured for your cluster.
  • Cilium is selected as the CNI in your cluster (default in Kapsule).

Creating a CiliumNodeConfig resource for encryption

The CiliumNodeConfig resource defines encryption settings for Cilium. It enables WireGuard encryption across all nodes in your Kapsule cluster.

  1. Prepare the Resource Definition by saving the following content to a file named cilium-encryption.yaml:
    apiVersion: cilium.io/v2
    kind: CiliumNodeConfig
    metadata:
      namespace: kube-system
      name: enable-encryption
    spec:
      nodeSelector:
          matchLabels: {}
      defaults:
          enable-wireguard: "true"
          wireguard-persistent-keepalive: "0s"
          encrypt-node: "false"
    InformationOutlineIcon
    Note
    • matchLabels: {} applies encryption to all nodes in the cluster.
    • Adjust nodeSelector if you want to target specific nodes (e.g., nodes labeled k8s.scaleway.com/managed: "true").
  2. Deploy the CiliumNodeConfig resource to your cluster using kubectl:
    kubectl apply -f cilium-encryption.yaml

Restarting the Cilium DaemonSet

After creating the CiliumNodeConfig, you must restart Cilium to apply these encryption settings.

  1. Rollout Restart Cilium using kubectl

    kubectl rollout restart daemonset cilium -n kube-system
  2. Wait for rollout completion. You can check the status of the rollout using the following command:

    kubectl rollout status daemonset cilium -n kube-system
  3. Verify the Pod status using the following kubectl command:

    kubectl get pods -n kube-system -l k8s-app=cilium

    All Cilium Pods should eventually show as Running and Ready.

Validating encryption

In this step, you will deploy test applications along with a tcpdump DaemonSet to observe network traffic before and after enabling encryption.

Deploying test applications and tcpdump

Below is an example YAML manifest that deploys:

  • An nginx Deployment and a corresponding Service.
  • A curl Deployment that continuously makes requests to nginx.
  • A tcpdump DaemonSet to capture traffic on each node’s default interface.
  1. Save the following template in a test-and-tcpdump.yaml file:

    InformationOutlineIcon
    Note

    Change the enp1s0 interface of the tcpdump DaemonSet by the default provided interface:

    kubectl -n kube-system exec ds/cilium -- ip a | grep -B2 "172.16"
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx
    spec:
      replicas: 1
      selector:
        matchLabels:
          k8s-app: nginx
      template:
        metadata:
          labels:
            k8s-app: nginx
        spec:
          terminationGracePeriodSeconds: 1
          containers:
            - name: nginx
              image: nginx:1.21.6
              ports:
                - containerPort: 80
              resources:
                limits:
                  cpu: 100m
                  memory: 100Mi
          affinity:
            podAntiAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                - topologyKey: "kubernetes.io/hostname"
                  labelSelector:
                    matchExpressions:
                    - key: k8s-app
                      operator: In
                      values:
                      - nginx
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx
    spec:
      selector:
        k8s-app: nginx
      ports:
        - protocol: TCP
          port: 80
          targetPort: 80
      type: ClusterIP
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: curl
    spec:
      replicas: 1
      selector:
        matchLabels:
          k8s-app: curl
      template:
        metadata:
          labels:
            k8s-app: curl
        spec:
          terminationGracePeriodSeconds: 1
          containers:
            - name: curl
              image: curlimages/curl:7.78.0
              command: ["/bin/sh", "-c"]
              args:
                - |
                  while sleep 2; do
                    date && curl -fsSL http://nginx
                  done
              resources:
                limits:
                  cpu: 100m
                  memory: 100Mi
          affinity:
            podAntiAffinity:
              preferredDuringSchedulingIgnoredDuringExecution:
                - weight: 50
                  podAffinityTerm:
                    topologyKey: "kubernetes.io/hostname"
                    labelSelector:
                      matchExpressions:
                        - key: k8s-app
                          operator: In
                          values:
                            - nginx
    ---
    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: tcpdump
    spec:
      selector:
        matchLabels:
          k8s-app: tcpdump
      template:
        metadata:
          labels:
            k8s-app: tcpdump
        spec:
          hostNetwork: true
          terminationGracePeriodSeconds: 1
          containers:
            - name: tcpdump
              image: alpine:latest
              securityContext:
                privileged: true
              command: ["sh"]
              args:
                - -c
                - |
                  apk add --no-cache tcpdump
                  if ! ip link show enp1s0; then
                    echo "enp1s0 not found"
                    exit 1
                  fi
                  # Capture traffic on enp1s0 for ports 80 or 51871 (WireGuard)
                  tcpdump -Anevi enp1s0 -T vxlan 2>&1 | grep -E '(([0-9]+\.){3}[0-9]+\.(80|51871))'
              resources:
                limits:
                  cpu: 100m
                  memory: 100Mi
  2. Apply the manifest using kubectl:

    kubectl apply -f test-and-tcpdump.yaml

Observing traffic before encryption

If you have not yet applied the CiliumNodeConfig and restarted Cilium, you should see traffic on port 80 in the logs of the tcpdump Pods:

kubectl logs -n default daemonset/tcpdump -f

(Select any Pod if multiple logs are shown.)

Checking encryption status in Cilium

After applying the CiliumNodeConfig and restarting Cilium, you can verify the configuration by checking each Cilium Pod:

for pod in $(kubectl -n kube-system get pod -l app.kubernetes.io/name=cilium-agent -o name); do
  echo "Pod: $pod"
  kubectl -n kube-system exec -it $pod -c cilium-agent -- cilium-dbg status | grep Encryption
done

You should see WireGuard encryption enabled.

Observing traffic after encryption

After the encryption rollout, traffic between Pods should traverse WireGuard on port 51871 (the default WireGuard port used by Cilium). Check the tcpdump logs again:

kubectl logs -n default daemonset/tcpdump -f

You should now see traffic matching port 51871, indicating the packets are encrypted via WireGuard.

Additional notes

  • Target specific nodes If you only want to enable encryption on specific nodes, modify the nodeSelector in your CiliumNodeConfig (e.g., matchLabels: { k8s.scaleway.com/managed: "true" } for managed nodes).

  • Persistence Encryption settings defined in CiliumNodeConfig persist through cluster upgrades and changes.

  • Performance impact Enabling encryption may slightly increase CPU usage on the nodes. Monitor resource utilization to ensure adequate capacity.

For more details, refer to Cilium’s WireGuard Encryption Documentation.

Questions?

Visit our Help Center and find the answers to your most frequent questions.

Visit Help CenterArrowRightIcon
SearchIcon
No Results