Kubernetes K3D mit Cilium und Hubble

Cilium

Mit Cilium steht Kubernetes ein mit von Google vorangetriebenes CNI zur Verfügung. Das Projekt Cilium nutzt eBPF Filter im Linux Kernel, um Kubernetes Network Policies effizient und performant umzusetzen. Durch die Verwendung von eBPF ergibt sich ein weiterer Vorteil. Es lassen sich alle Verbindungungen im Cluster tracken. Dieses kann mit Hubble UI im Browser visualisiert werden. Dadurch kann man schnell einen Überblick über die bestehenden Verbindungen erlangen und ggf. eingreifen, wenn unerwünschter Traffic erkannt wird.

Hubble

Für die Visualisierung der Verbidnungen im Browser kommt Hubble UI zu Einsatz. Zunächst muss man den gewünschten Namespace wählen und schon wird ein Graph gezeichnet, der die Verbindungen im Browser anzeigt. Es wird ein gerichteter Graph mit den Abhängigkeiten der Pods erzeugt und auch eine Tabellarische übersicht geboten. Mit klick auf einen Pod kann eine Filterung gesetzt werden. So lässt sich schnell der angezeigte Traffic filtern und analysieren.

Setup K3D Cluster

Für das Beispiel verwende ich K3D, um einen Demo Cluster zu erstellen. Dieses geht wie immer schnell von der Hand.

Konfiguration

Zunächst definieren wir den Clusternamen, die Anzahl der Worker und den API Port als Environment Variablen, um sie später zu nutzen:

export CLUSTERNAME=cilium-demo
export CLUSTERWORKER=2
export CLUSTER_API_PORT=6443

Cluster anlegen

Nun können wir nach der Konfiguration den Cluster anlegen.

k3d cluster create $CLUSTERNAME \
-a $CLUSTERWORKER \
--api-port=$CLUSTER_API_PORT \
--k3s-server-arg "--disable=servicelb" \
--k3s-server-arg "--disable=traefik"  \
--no-lb \
--k3s-server-arg "--disable-network-policy" \
--k3s-server-arg "--flannel-backend=none" \
--image rancher/k3s:v1.20.5-alpha1-k3s2

Hinweis: Um Cilium zu nutzen müssen der LoadBalancer und Traefik nicht disabled werden. Die Komponenten habe ich nur aus Performancegründen ausgeschaltet, damit der Cluster schneller hochfährt. Sie sind für die Demo nicht relevant. Wichtig ist, dass mit –flannel-backend=none kein CNI Plugin automatisch installiert und das über –disable-network-policy der Defautl Network Policy Controller nicht geladen wird.

Korrektur der Initialisierung von Cilium

Da K3S keine Bash unter /bin/bash vorhält, funktioniert die Initialisierung von Cilium nicht korrekt. Daher muss hier manuell eingegriffen werden, um BPF Filter zu kompilieren.

for AGENT in $(seq 0 ${CLUSTERWORKER+1} 1)
do
  docker exec -it k3d-$CLUSTERNAME-agent-$AGENT mount bpffs /sys/fs/bpf -t bpf
  docker exec -it k3d-$CLUSTERNAME-agent-$AGENT mount --make-shared /sys/fs/bpf
done

docker exec -it k3d-$CLUSTERNAME-server-0 mount bpffs /sys/fs/bpf -t bpf
docker exec -it k3d-$CLUSTERNAME-server-0 mount --make-shared /sys/fs/bpf

Die shared mount müssen auf allen Nodes (agents) und Server ausgeführt werden. Dazu muss ggf. der Server Block angepasst werden. Je nach dem wieviele Agents und Server ihr beim Erstellen des Clusters angegeben habt.

Cilium und Hubble installieren

Die Installation von Cilium und Hubble ist eigentlich trivial.

helm repo add cilium https://helm.cilium.io/

helm install cilium cilium/cilium --version 1.9.5 \
   --namespace kube-system \
   --set kubeProxyReplacement=disabled \
   --set debug.enabled=true \
   --set hostServices.enabled=false \
   --set externalIPs.enabled=true \
   --set nodePort.enabled=true \
   --set hostPort.enabled=true \
   --set bpf.masquerade=false \
   --set image.pullPolicy=IfNotPresent \
   --set ipam.mode=kubernetes

helm upgrade cilium cilium/cilium --version 1.9.5 \
   --namespace kube-system \
   --reuse-values \
   --set hubble.listenAddress=":4244" \
   --set hubble.relay.enabled=true \
   --set hubble.ui.enabled=true

Nun watch warten bis alle Pods up and running sind

watch kubectl get pods -n kube-system

Hinweise zum Parameter KubeProxyReplacement

In den Blogeinträgen die man zum Thema Cilium und K3D im Internewt findet beschreiben immer das der Parameter kubeProxyReplacement auf partial stehen soll. Damit lies sich der Cluster aber nicht zum Laufen bewegen. Nicht einmal CoreDNS konnte mit der Einstellung deployt werden. Mit der Einstellung –set kubeProxyReplacement=disabled hingegen fährt der Cluster hoch und alles funtkioniert.

Port-Forwarding

Um Hubble im Browser zu öffnen muss noch ein Port-Forwarding eingerichtet werden. Dann kann unter http://localhost:12000/kube-system aufgerufen werden.

kubectl port-forward -n kube-system svc/hubble-ui --address 0.0.0.0 --address :: 12000:80    

Demo Applications installieren

Das Projekt Cilium bietet eine Demoanwendung, mit der man schnell erste Tests durchführen kann. Die Anwendungen sind einfach deployt…

# create namespace
kubectl create namespace cilium-test

# deploy demo apps
kubectl apply -n cilium-test -f https://raw.githubusercontent.com/cilium/cilium/v1.9/examples/kubernetes/connectivity-check/connectivity-check.yaml

Jetzt kann man in der UI zuschauen, wie sich der Traffic ändert und die verschiedenen Verbindungen in der UI analysieren.

Network Policies überprüfen

Wenn man eine neue Regel für Kubernetes Network Policies erstellt hat, dann taucht bestimmt die Frage der Wirksamkeit auf. Auch dieses lässt sich schön über die Oberfläche der Hubble UI darstellen. Dazu muss man oben in der Toolbar

die Auswahl auf Dropped ändern.