Kubernetes netwerk

Netwerk connecties binnen een Kubernetes omgeving kan een ingewikkelde zaak zijn. Pod networks, service networks, cluster IPs, container ports, host ports, node ports… soms zien we door de bomen het bos niet meer. Wellicht kan dit artikel wat licht doen schijnen op het ‘Kuberetes netwerk‘.

POD netwerk

Om bij de basis te beginnen, pods bevatten één of meerdere containers die samen op dezelfde node zijn geïnstalleerd en delen (dus) een gezamelijke netwerk. Dit houdt in dat alle containers in een pod elkaar kunnen bereiken via localhost. Als er bijvoorbeeld een WordPress container is die ‘luistert’ op TCP poort 8080 dan is deze voor alle overige containers bereikbaar via http://localhost:8080.

De default interface van Master is ‘eth0‘ met IP adres 192.168.1.10 en is verbonden met de interface genaamd ‘cni0‘ met IP adres 10.244.0.1
De default interface van Worker1 is ‘eth0‘ met IP adres 192.168.1.11 en is verbonden met de interface genaamd ‘cni0‘ met IP adres 10.244.1.1.
Worker2 heeft IP adres 192.168.1.12 op ‘eth0‘ en 10.244.2.1 op ‘cni0

Onderling kunnen de nodes dus via eth0 met elkaar communiceren en de pods communiceren onderling via een overlay-network. Deze gebruikt de ‘cni0‘ virtuele interface op Worker1 en dat overlay-network is dus 10.244.1.0/32. Op Worker2 is dat overlay-network 10.244.2.0/32. Alle pods krijgen een IP adres van het overlay-network en kunnen zo dus met elkaar communiceren. (CNI staat voor Container Network Interface) en wordt aangemaakt tijdens de initiële fase van de master(s) met de kubeadm parameter –pod-network-cidr
Een kubectl voorbeeld om pod IP’s te tonen:

$ kubectl get pods -o wide
NAME                       READY   STATUS    RESTARTS   AGE    IP             NODE
hypriot-578c989b88-9plzz   1/1     Running   0          133m   10.244.1.102   worker1                           
nginx-654ddfd749-qqxq9     1/1     Running   0          138m   10.244.1.99    worker1              
nginx2-57bbd47f4d-xbkfv    1/1     Running   0          3d5h   10.244.2.81    worker2              

Zoals gezegd, kunnen alle pods communiceren met elkaar, zelfs als ze op een andere node zijn deployed. Flannel is de default route voor dit netwerk en deze heeft eth0 weer als default gateway. Vanaf de Worker1 node:

$ ip route get 10.244.2.81
10.244.2.81 via 10.244.2.0 dev flannel.1 src 10.244.1.0
     cache

Hierdoor is de nginx2 pod op worker2 bereikbaar voor de pods op worker1 en vice versa. Uiteraard kan een NetworkPolicy gebruikt worden om te voorkomen dat pods van verschillende namespaces elkaar kunnen bereiken. Helaas werkt flannel niet met networkpolicies maar daar kan eventueel Calico op gezet worden. Een voorbeeld: (networkpolicy.yml)

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-from-other-namespaces
spec:
  podSelector:
    matchLabels:
  ingress:  
  - from: 
    - podSelector: {} 

apply dit dan in de te isoleren namespace.