Stop met het schrijven van Cilium Network Policies, start met Cilium Cluster-Wide Network Policies

Klaar met het copy-pasten van Cilium Network Policies? Probeer Clusterwide Policies

Stel je voor: je Kubernetes cluster bruist van activiteit. Tientallen, misschien wel honderden namespaces draaien onafhankelijk van elkaar, elk met hun eigen microservices. Het ene team heeft internettoegang nodig om AI-vectoren te bouwen en AI-modellen te downloaden. Een ander team valt onder strengere security-eisen vanwege gevoelige data. Hoe houd je dit overzichtelijk zonder te verdrinken in een spaghetti van Cilium Network Policies?

Vaak worstelen teams met het schrijven van een eindeloos aantal bijna identieke netwerk policies. Elke keer dat er een nieuwe namespace wordt aangemaakt, begint dezelfde routine opnieuw. Soms staat het zelfs in de Scrum Definition of Done! Dat moet toch eenvoudiger kunnen?

Gelukkig is er een veel simpelere manier. De oplossing: Cilium Cluster-Wide Network Policies (CCNP’s) gecombineerd met slimme namespace labeling. Dit elimineert redundantie en de inconsistenties die daarbij horen.

Policy Spaghetti

De valkuil van herhaling

  • Zie je dezelfde internet access-regels steeds opnieuw terugkomen? Wat een tijdverspilling.
  • Beheer en overzicht: Houd het simpel
    Stel je voor dat je honderden van deze policies hebt. Een snelle wijziging doorvoeren is lastig. De eenvoudigste manier is om dit centraal te doen, bij voorkeur via GitOps met bijvoorbeeld Argo CD.
  • Foutgevoeligheid: Een typefout is zo gemaakt
    Eén verkeerd cijfer in een IP-adres of een typefout in een poortnummer en de verbinding werkt niet meer – of erger nog: hij staat wagenwijd open.

Maak beheer eenvoudig: De kracht van CCNP’s en Namespace Labels

Cilium Cluster-wide Network Policies (CCNP’s) zijn krachtig omdat ze policies definiëren die gelden voor je hele cluster, niet alleen voor één enkele namespace. En het mooie is: je kunt deze CCNP’s laten reageren op labels die op namespaces zijn toegepast. Zo werkt het:

➜ ~ kubectl create namespace hello-world
namespace/hello-world created
➜  ~ kubectl run nginx -n hello-world --image docker.io/nginxdemos/hello --image-pull-policy=IfNotPresent --port 80
pod/nginx created
➜  ~ kubectl -n hello-world expose pod nginx --type LoadBalancer
service/nginx exposed
➜  ~ kubectl -n hello-world get svc
NAME    TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)        AGE
nginx   LoadBalancer   10.43.67.208   192.168.4.51   80:30715/TCP   61s
➜  ~ curl http://192.168.4.51 | grep "<title>"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 12108    0 12108    0     0   955k      0 --:--:-- --:--:-- --:--:--  985k
<title>Hello World</title>
                                                        

Copy code

Deny All Policy

Laten we beginnen met een veilige baseline. Blokkeer al het inkomende en uitgaande verkeer door een Cilium Network Policy toe te passen die al het verkeer matcht. Dit mechanisme kun je op verschillende manieren toepassen: per namespace, met een CCNP (Cilium Cluster-Wide Network Policy) of via Enforcement Mode always. (https://docs.cilium.io/en/latest/security/policy/intro/).

deny-all.yaml:
---
apiVersion: "cilium.io/v2"
kind: CiliumClusterwideNetworkPolicy
metadata:
  name: "deny-all"
spec:
  description: "Make sure namespace is locked"
  endpointSelector:
    matchExpressions:
    - key: io.kubernetes.pod.namespace
      operator: In
      values:
      - hello-world
  ingress:
  - {}
  egress:
  - {}


➜ ~ kubectl apply -f deny-all.yaml
ciliumclusterwidenetworkpolicy.cilium.io/deny-all created
                                                        

Copy code

Endpoints listen en je app lokaliseren

Label de namespace met allow-ingress-port-80=true. Dit label heb je nodig in de Cilium Cluster-Wide Network Policy endpoint selector.

➜  ~ kubectl label namespace hello-world allow-ingress-port-80=true
namespace/hello-world labeled


➜ ~ kubectl -n hello-world describe ciliumendpoint nginx
Name:         nginx
Namespace:    hello-world
Labels:       run=nginx
API Version:  cilium.io/v2
Kind:         CiliumEndpoint
...
Status:
  Encryption:
  External - Identifiers:
    k8s-namespace:          hello-world
    k8s-pod-name:           nginx
    Pod - Name:             hello-world/nginx
  Id:                       47
  Identity:
    Id:  34739
    Labels:
      k8s:io.cilium.k8s.namespace.labels.allow-ingress-port-80=true
      k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=hello-world
      k8s:io.cilium.k8s.policy.cluster=default
      k8s:io.cilium.k8s.policy.serviceaccount=default
      k8s:io.kubernetes.pod.namespace=hello-world
      k8s:run=nginx
...
                                                        

Copy code

De NGINX-pod is bekend als een Cilium Endpoint. De namespace labels, automatisch geprefixt met io.cilium.k8s.namespace.labels, worden aan het endpoint gekoppeld. Deze labels kun je gebruiken in de Network Policy endpointSelector.

Creëer een Cilium Cluster-wide Network Policy

Door de deny-all policy is de container nu niet bereikbaar:

➜  ~ curl --connect-timeout 5 -I http://192.168.4.51
curl: (28) Failed to connect to 192.168.4.51 port 80 after 5006 ms: Timeout was reached


➜  ~ kubectl -n kube-system exec ds/cilium -c cilium-agent -- cilium monitor --related-to 47
Press Ctrl-C to quit
time="2025-06-26T21:18:31Z" level=info msg="Initializing dissection cache..." subsys=monitor
Policy verdict log: flow 0x0 local EP ID 47, remote ID world, proto 6, ingress, action deny, auth: disabled, match none, 192.168.4.229:51956 -> 10.42.0.251:80 tcp SYN
xx drop (Policy denied) flow 0x0 to endpoint 47, ifindex 4, file bpf_lxc.c:2091, , identity world->34739: 192.168.4.229:51956 -> 10.42.0.251:80 tcp SYN
Policy verdict log: flow 0x0 local EP ID 47, remote ID world, proto 6, ingress, action deny, auth: disabled, match none, 192.168.4.229:51956 -> 10.42.0.251:80 tcp SYN
xx drop (Policy denied) flow 0x0 to endpoint 47, ifindex 4, file bpf_lxc.c:2091, , identity world->34739: 192.168.4.229:51956 -> 10.42.0.251:80 tcp SYN
                                                        

Copy code

Maak nu een Cilium Cluster-Wide Network Policy die alleen actief wordt als een namespace een specifiek label heeft. In dit voorbeeld: allow-ingress-port-80: “true”.

---
apiVersion: "cilium.io/v2"
kind: CiliumClusterwideNetworkPolicy
metadata:
  name: "allow-ingress-port-80"
spec:
  description: "Clusterwide Network to allow ingress http traffic"
  endpointSelector:
    matchLabels:
      io.cilium.k8s.namespace.labels.allow-ingress-port-80: "true"
  ingress:
  - fromEntities:
    - world
    toPorts:
    - ports:
      - port: "80"
        protocol: TCP


➜ ~ kubectl apply -f allow-ingress-port-80.yaml
ciliumclusterwidenetworkpolicy.cilium.io/allow-ingress-port-80 created
                                                        

Copy code

Het resultaat

De Cilium Cluster-Wide Network Policy geeft nu toegang tot de pod in de namespace. Tijd om dit te testen:

➜  ~ curl http://192.168.4.51 | grep "<title>"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 12108    0 12108    0     0  2769k      0 --:--:-- --:--:-- --:--:-- 2956k
<title>Hello World</title>
                                                        

Copy code

NGINX default web page showing server address and configuration details

Referenties

En dat werkt dus: Cilium Cluster-Wide Network Policies (CCNP’s) gecombineerd met slimme namespace labeling. Stel je voor dat je een vergelijkbare aanpak gebruikt ter vervanging van complexe, namespace-gebonden network policies voor bijvoorbeeld Prometheus, Fluentd of andere tooling.

References

Blijf op de hoogte
Door je in te schrijven voor onze nieuwsbrief verklaar je dat je akkoord bent met onze privacyverklaring.

Ready to strengthen your Cloud Security?

stefan.behlen 1
Stefan Behlen

Let's talk!


Ready to strengthen your Cloud Security?

* required

By sending this form you indicate that you have taken note of our Privacy Statement.
Privacy Overview
This website uses cookies. We use cookies to ensure the proper functioning of our website and services, to analyze how visitors interact with us, and to improve our products and marketing strategies. For more information, please consult our privacy- en cookiebeleid.