Ce TP se déroule sur un cluster DigitalOcean.
- But de l'exercice
- 1.Créer le NS red
- 2.Creer un pod dans le NS red
- 3.Vérifier que vous pouvez désactiver un Pod
- 4.Créer et appliquer une règle sur le Pod podinfo
- 5.Inspecter les Headers HTTP
- Cleanup
- Apprendre à construire une CNP L7
kubectl create ns red
Créeons un déploiement avec un réplica unique et exposons-le en tant que ClusterIP (interne)
kubectl create deployment podinfo --image=stefanprodan/podinfo --namespace=red
kubectl expose deployment podinfo --port=80 --target-port=9898 --namespace=red
3.Vérifier que vous pouvez désactiver un Pod en faisant un POST sur /readyz/disable
(fonctionnalité de l'appli podinfo)
On crée un Pod nommé debug
dans le NS red
afin de requeter en L7 le svc podinfo
:
kubectl run debug-pod -it --rm --restart=Never --image=nicolaka/netshoot --namespace=red -l auth=ok -- bash
# curl -sv http://podinfo.red.svc/readyz
On constate que /readyz
renvoit un 200.
Désactivons l'URL readyz (fonctionnalité de l'application podinfo) :
# curl -sv -X POST http://podinfo.red.svc/readyz/disable
Requêtons à nouveau /readyz
, on obtient un 503.
# curl -sv http://podinfo.red.svc/readyz
Réactivons le readyz
:
# curl -sv -X POST http://podinfo.red.svc/readyz/enable
Créer une NetworkPolicy L7 (composée éventuellement de plusieurs règles) qui
- s'applique sur les membres du déploiement
podinfo
- empêche le POST sur
/readyz/disable
- autorise le GET sur
/readyz
- depuis les pods possédant le label
auth=ok
La documentation est accessible ici : https://docs.cilium.io/en/latest/security/policy/language/#http .
Voici un exemple à adapter :
## l7-policy.yaml
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
name: "rule1"
spec:
description: "Allow HTTP GET /public from env=prod to app=service"
endpointSelector:
matchLabels:
app: service
ingress:
- fromEndpoints:
- matchLabels:
env: prod
toPorts:
- ports:
- port: "80"
protocol: TCP
rules:
http:
- method: "GET"
path: "/public"
kubectl apply -f l7-policy.yaml -n red
Pour cela, utilisez une règle CiliumNetwork Policy (CNP) L7
Des indices :
- préciser bien que la CNP s'applique à un déploiement (
app=podinfo
) - préciser que la source est le Pod
debug-pod
(run=debug-pod
) - preciser le bon port TCP à filtrer vu du Pod (relire la doc de podinfo)
Voici le résultat après application de la règle
debug-pod:~# curl -sv -X POST http://podinfo.red.svc/readyz/disable
* Host podinfo.red.svc:80 was resolved.
* IPv6: (none)
* IPv4: 10.245.82.90
* Trying 10.245.82.90:80...
* Connected to podinfo.red.svc (10.245.82.90) port 80
> POST /readyz/disable HTTP/1.1
> Host: podinfo.red.svc
> User-Agent: curl/8.6.0
> Accept: */*
>
< HTTP/1.1 403 Forbidden
< content-length: 15
< content-type: text/plain
< date: Tue, 05 Mar 2024 10:36:17 GMT
< server: envoy
<
Access denied
En déduire le composant logiciel tiers utilisé par Cilium qui bloque les appels L7.
On constate même la présence d'un process envoy
sur le Node en question, en listant les process (via nod-shell par exemple) :
root@node-7io28:/# ps -efd | grep envoy
root 108864 3075 0 13:59 ? 00:00:02 cilium-envoy -l info -c /var/run/cilium/bootstrap.pb --base-id 0 --log-format %t|%l|%n|%v
Pour être précis, le proxy envoy
est directement embarqué (embedded
) dans le pod cilium
:
<<K9s-Shell>> Pod: kube-system/cilium-zdnqd | Container: cilium-agent
root@node-o57hu:/home/cilium# ps -efd
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 Mar04 ? 00:14:41 cilium-agent --config-dir=/tmp/cilium/config-map --k8s-api-server=https://100
root 234 1 0 Mar04 ? 00:00:01 cilium-health-responder --listen 4240 --pidfile /var/run/cilium/state/health-
root 575 1 0 10:36 ? 00:00:00 cilium-envoy -l info -c /var/run/cilium/envoy/bootstrap.pb --base-id 0 --log-
root 589 0 0 10:39 pts/0 00:00:00 bash
root 597 589 0 10:39 pts/0 00:00:00 ps -efd
Pour note, il existe un autre mode (i.e daemonset
) pour l'intégration cilium/envoy, on peut identifier dans le résultat de la commande cilium version
lequel est configuré.
kubectl delete -f l7-policy.yaml -n red