|
| 1 | +--- |
| 2 | +meta: |
| 3 | + title: Enabling Encryption in Kapsule (Kubernetes 1.31) with Cilium |
| 4 | + description: Learn how to enable WireGuard encryption in Scaleway’s Kapsule Managed Kubernetes service using Cilium. This guide covers configuration steps, verification, and testing encryption for secure network traffic. |
| 5 | +content: |
| 6 | + h1: Enabling Encryption in Kapsule (Kubernetes 1.31) with Cilium |
| 7 | + paragraph: Learn how to enable WireGuard encryption in Scaleway’s Kapsule Managed Kubernetes service using Cilium. This guide covers configuration steps, verification, and testing encryption for secure network traffic. |
| 8 | +tags: hashicorp vault kubernetes k8s easy deploy |
| 9 | +categories: |
| 10 | + - containers |
| 11 | +dates: |
| 12 | + validation: 2024-12-31 |
| 13 | + posted: 2024-12-31 |
| 14 | + validation_frequency: 24 |
| 15 | +--- |
| 16 | + |
| 17 | + |
| 18 | +This guide explains how to enable WireGuard encryption in Scaleway’s Kapsule Managed Kubernetes service. |
| 19 | +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. |
| 20 | + |
| 21 | +<Macro id="requirements" /> |
| 22 | +- A Scaleway account logged into the [console](https://console.scaleway.com) |
| 23 | +- [Owner](/identity-and-access-management/iam/concepts/#owner) status or [IAM permissions](/identity-and-access-management/iam/concepts/#permission) allowing you to perform actions in the intended Organization |
| 24 | +- A functional [Kubernetes Kapsule](/containers/kubernetes/concepts/#kubernetes-kapsule) cluster running **version 1.31**.- |
| 25 | +- `kubectl` installed and configured for your cluster. |
| 26 | +- Cilium is selected as the [CNI](/containers/kubernetes/concepts/#container-network-interface-cni) in your cluster (default in Kapsule). |
| 27 | + |
| 28 | +## Creating a `CiliumNodeConfig` resource for encryption |
| 29 | + |
| 30 | +The `CiliumNodeConfig` resource defines encryption settings for Cilium. It enables **WireGuard encryption** across all nodes in your Kapsule cluster. |
| 31 | + |
| 32 | +1. Prepare the Resource Definition by saving the following content to a file named `cilium-encryption.yaml`: |
| 33 | + ``` |
| 34 | + apiVersion: cilium.io/v2 |
| 35 | + kind: CiliumNodeConfig |
| 36 | + metadata: |
| 37 | + namespace: kube-system |
| 38 | + name: enable-encryption |
| 39 | + spec: |
| 40 | + nodeSelector: |
| 41 | + matchLabels: {} |
| 42 | + defaults: |
| 43 | + enable-wireguard: "true" |
| 44 | + enable-wireguard-userspace-fallback: "false" |
| 45 | + wireguard-persistent-keepalive: "0s" |
| 46 | + encrypt-node: "false" |
| 47 | + ``` |
| 48 | + <Message type="note"> |
| 49 | + * `matchLabels: {}` applies encryption to **all nodes** in the cluster. |
| 50 | + * Adjust `nodeSelector` if you want to target specific nodes (e.g., nodes labeled `k8s.scaleway.com/managed: "true"`). |
| 51 | + </Message> |
| 52 | +2. Deploy the `CiliumNodeConfig` resource to your cluster using `kubectl`: |
| 53 | + ``` |
| 54 | + kubectl apply -f cilium-encryption.yaml |
| 55 | + ``` |
| 56 | + |
| 57 | +## Restarting the Cilium DaemonSet** |
| 58 | + |
| 59 | +After creating the `CiliumNodeConfig`, you must restart Cilium to apply these encryption settings. |
| 60 | + |
| 61 | +1. Rollout Restart Cilium using `kubectl` |
| 62 | + ``` |
| 63 | + kubectl rollout restart daemonset cilium -n kube-system |
| 64 | + ``` |
| 65 | + |
| 66 | +2. Wait for rollout completion. You can check the status of the rollout using the following command: |
| 67 | + ``` |
| 68 | + kubectl rollout status daemonset cilium -n kube-system |
| 69 | + ``` |
| 70 | + |
| 71 | +3. Verify the pod status using the following `kubectl` command: |
| 72 | + ``` |
| 73 | + kubectl get pods -n kube-system -l k8s-app=cilium |
| 74 | + ``` |
| 75 | + All Cilium pods should eventually show as **Running** and **Ready**. |
| 76 | + |
| 77 | +## Validating Encryption |
| 78 | + |
| 79 | +In this step, you will deploy test applications along with a `tcpdump` DaemonSet to observe network traffic before and after enabling encryption. |
| 80 | + |
| 81 | +### 3.1 Deploying test applications and `tcpdump` |
| 82 | + |
| 83 | +Below is an example YAML manifest that deploys: |
| 84 | + |
| 85 | +* An **nginx** Deployment and a corresponding **Service**. |
| 86 | +* A **curl** Deployment that continuously makes requests to **nginx**. |
| 87 | +* A **tcpdump** DaemonSet to capture traffic on each node’s `kapsule0` interface. |
| 88 | + |
| 89 | +1. Save the following as `test-and-tcpdump.yaml`: |
| 90 | + ``` |
| 91 | + apiVersion: apps/v1 |
| 92 | + kind: Deployment |
| 93 | + metadata: |
| 94 | + name: nginx |
| 95 | + spec: |
| 96 | + replicas: 1 |
| 97 | + selector: |
| 98 | + matchLabels: |
| 99 | + k8s-app: nginx |
| 100 | + template: |
| 101 | + metadata: |
| 102 | + labels: |
| 103 | + k8s-app: nginx |
| 104 | + spec: |
| 105 | + terminationGracePeriodSeconds: 1 |
| 106 | + containers: |
| 107 | + - name: nginx |
| 108 | + image: nginx:1.21.6 |
| 109 | + ports: |
| 110 | + - containerPort: 80 |
| 111 | + resources: |
| 112 | + limits: |
| 113 | + cpu: 100m |
| 114 | + memory: 100Mi |
| 115 | + affinity: |
| 116 | + podAntiAffinity: |
| 117 | + requiredDuringSchedulingIgnoredDuringExecution: |
| 118 | + - topologyKey: "kubernetes.io/hostname" |
| 119 | + labelSelector: |
| 120 | + matchExpressions: |
| 121 | + - key: k8s-app |
| 122 | + operator: In |
| 123 | + values: |
| 124 | + - nginx |
| 125 | + --- |
| 126 | + apiVersion: v1 |
| 127 | + kind: Service |
| 128 | + metadata: |
| 129 | + name: nginx |
| 130 | + spec: |
| 131 | + selector: |
| 132 | + k8s-app: nginx |
| 133 | + ports: |
| 134 | + - protocol: TCP |
| 135 | + port: 80 |
| 136 | + targetPort: 80 |
| 137 | + type: ClusterIP |
| 138 | + --- |
| 139 | + apiVersion: apps/v1 |
| 140 | + kind: Deployment |
| 141 | + metadata: |
| 142 | + name: curl |
| 143 | + spec: |
| 144 | + replicas: 1 |
| 145 | + selector: |
| 146 | + matchLabels: |
| 147 | + k8s-app: curl |
| 148 | + template: |
| 149 | + metadata: |
| 150 | + labels: |
| 151 | + k8s-app: curl |
| 152 | + spec: |
| 153 | + terminationGracePeriodSeconds: 1 |
| 154 | + containers: |
| 155 | + - name: curl |
| 156 | + image: curlimages/curl:7.78.0 |
| 157 | + command: ["/bin/sh", "-c"] |
| 158 | + args: |
| 159 | + - | |
| 160 | + while sleep 2; do |
| 161 | + date && curl -fsSL http://nginx |
| 162 | + done |
| 163 | + resources: |
| 164 | + limits: |
| 165 | + cpu: 100m |
| 166 | + memory: 100Mi |
| 167 | + affinity: |
| 168 | + podAntiAffinity: |
| 169 | + preferredDuringSchedulingIgnoredDuringExecution: |
| 170 | + - weight: 50 |
| 171 | + podAffinityTerm: |
| 172 | + topologyKey: "kubernetes.io/hostname" |
| 173 | + labelSelector: |
| 174 | + matchExpressions: |
| 175 | + - key: k8s-app |
| 176 | + operator: In |
| 177 | + values: |
| 178 | + - nginx |
| 179 | + --- |
| 180 | + apiVersion: apps/v1 |
| 181 | + kind: DaemonSet |
| 182 | + metadata: |
| 183 | + name: tcpdump |
| 184 | + spec: |
| 185 | + selector: |
| 186 | + matchLabels: |
| 187 | + k8s-app: tcpdump |
| 188 | + template: |
| 189 | + metadata: |
| 190 | + labels: |
| 191 | + k8s-app: tcpdump |
| 192 | + spec: |
| 193 | + hostNetwork: true |
| 194 | + terminationGracePeriodSeconds: 1 |
| 195 | + containers: |
| 196 | + - name: tcpdump |
| 197 | + image: alpine:latest |
| 198 | + securityContext: |
| 199 | + privileged: true |
| 200 | + command: ["sh"] |
| 201 | + args: |
| 202 | + - -c |
| 203 | + - | |
| 204 | + apk add --no-cache tcpdump |
| 205 | + # Verify the Kapsule interface |
| 206 | + if ! ip link show kapsule0; then |
| 207 | + echo "kapsule0 not found" |
| 208 | + exit 1 |
| 209 | + fi |
| 210 | + # Capture traffic on kapsule0 for ports 80 or 51871 (WireGuard) |
| 211 | + tcpdump -Anevi kapsule0 -T vxlan 2>&1 | grep -E '(([0-9]+\.){3}[0-9]+\.(80|51871))' |
| 212 | + resources: |
| 213 | + limits: |
| 214 | + cpu: 100m |
| 215 | + memory: 100Mi |
| 216 | + ``` |
| 217 | + |
| 218 | +2. Apply the manifest using `kubectl`: |
| 219 | + ``` |
| 220 | + kubectl apply -f test-and-tcpdump.yaml |
| 221 | + ``` |
| 222 | + |
| 223 | +### Observing traffic before encryption |
| 224 | + |
| 225 | +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: |
| 226 | + |
| 227 | +``` |
| 228 | +kubectl logs -n default daemonset/tcpdump -f |
| 229 | +``` |
| 230 | + |
| 231 | +(Select any pod if multiple logs are shown.) |
| 232 | + |
| 233 | +### Checking encryption status in Cilium** |
| 234 | + |
| 235 | +After applying the `CiliumNodeConfig` and restarting Cilium, you can verify the configuration by checking each Cilium pod: |
| 236 | + |
| 237 | +``` |
| 238 | +for pod in $(kubectl -n kube-system get pod -l app.kubernetes.io/name=cilium-agent -o name); do |
| 239 | + echo "Pod: $pod" |
| 240 | + kubectl -n kube-system exec -it $pod -c cilium-agent -- cilium-dbg status | grep Encryption |
| 241 | +done |
| 242 | +``` |
| 243 | + |
| 244 | +You should see **WireGuard** encryption enabled. |
| 245 | + |
| 246 | +### Observing traffic after encryption |
| 247 | + |
| 248 | +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: |
| 249 | + |
| 250 | +``` |
| 251 | +kubectl logs -n default daemonset/tcpdump -f |
| 252 | +``` |
| 253 | + |
| 254 | +You should now see traffic matching **port 51871**, indicating the packets are encrypted via WireGuard. |
| 255 | + |
| 256 | +## Additional notes |
| 257 | + |
| 258 | +* **Target specific nodes** |
| 259 | + 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). |
| 260 | + |
| 261 | +* **Persistence** |
| 262 | + Encryption settings defined in `CiliumNodeConfig` persist through cluster upgrades and changes. |
| 263 | + |
| 264 | +* **Performance impact** |
| 265 | + Enabling encryption may slightly increase CPU usage on the nodes. Monitor resource utilization to ensure adequate capacity. |
| 266 | + |
| 267 | +For more details, refer to [Cilium’s WireGuard Encryption Documentation](https://docs.cilium.io/en/stable/security/network/encryption-wireguard/). |
| 268 | + |
0 commit comments