Le modèle de réseau de Kubernetes est un ensemble de normes qui définissent le comportement du réseau entre les pods.
Il existe une variété d'implémentations différentes de ce modèle - y compris le plugin de réseau Calico, que nous avons utilisé tout au long des sections.
Le modèle de réseau Kubernetes définit la manière dont les pods communiquent entre eux, quel que soit le noeud sur lequel ils sont exécutés.
Chaque pod possède sa propre IP dans le cluster.
Tout Pod peut atteindre n'importe quel autre Pod en utilisant l'adresse IP de ce Pod. Cela crée un réseau virtuel qui permet aux pods de communiquer facilement entre eux, quel que soit le noeud sur lequel ils se trouvent.
Les plugins CNI (Container Network Interface) sont des plugins réseau K8s. Ces plugins fournissent une connectivité entre les pods selon la norme établie par le modèle de réseau kubernetes.
Il existe plusieurs plugins CNI (flannel, calico...). Chaque plugin dépend de l'utilisation que l'on va en faire. Flannel par exemple ne permet pas de mettre en place des ACLs. Calico lui le permet.
Nous avons installé dans la première section, le plugin calico.
Sans plugin CNI, les noeuds K8s resteront dans le statut NotReady jusqu'à ce qu'un plugin CNI soit installé.
Le DNS (Domaine Name System) va nous permettre de trouver l'IP d'un pod à partir d'un autre pod à partir d'un nom de domaine au lieu de son IP.
Le DNS est un pod qui tourne dans le cluster (coredns pour kubeadm). On peut le trouver dans le namespace kube-system.
Chaque pod dans notre cluster ont un nom de domaine comme celui-ci addresse-ip-pod.nom-namespace.pod.cluster.local
soit 192-168-10-100.default.pod.cluster.local
.
Entre pod, le DNS n'est pas très intéressant car il faut connaitre l'IP du pod. Cependant il devient plus intéressant quand on utilise des services.
On peut récupérer l'IP d'un pod grâce à la commande kubectl get pods -o wide ou via la commande kubectl describe.
Les politiques de réseau vont nous permettre d'autoriser ou non un flux d'aller d'un point A à un point B. Cela permet de sécuriser le cluster.
Voici les paramètres YAML utiles :
spec:
podSelector:
matchLabels:
role: db
Par défaut, les pods ne sont pas isolés. Ils sont ouverts à toute communication.
La politique de réseau (NetworkPolicy) peut s'appliquer un entrée (ingress), en sortie (egress) ou les deux.
spec:
ingress:
- from:
...
egress:
- to:
...
Avec les sélecteurs from et to on peut aussi matcher les labes :
spec:
ingress:
- from
- podSelector:
matchLabels:
app: db
On peut faire la même chose avec les namespaces :
spec:
ingress:
- from
- namespaceSelector:
matchLabels:
app: db
On peut aussi autoriser depuis un pool d'ip :
spec:
ingress:
- from:
- ipBlock:
cidr: 192.168.0.0/24
On peut spécifier un ou plusieurs ports avec le type de protocole :
spec:
ingress:
- from:
ports:
- protocol: TCP
port: 80
Création d'un nouveau namespace :
$ kubectl create namespace wiki-test
namespace/wiki-test created
$ kubectl label namespace wiki-test team=wiki-test
namespace/wiki-test labeled
On va créer un serveur nginx :
apiVersion: v1
kind: Pod
metadata:
name: wiki-nginx
namespace: wiki-test
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
Avec ça un pod client :
apiVersion: v1
kind: Pod
metadata:
name: wiki-busybox
namespace: wiki-test
labels:
app: client
spec:
containers:
- name: busybox
image: radial/busyboxplus:curl
command: ['sh', '-c', 'while true; do sleep 5; done']
On va maintenant récupérer l'IP nginx puis faire un curl depuis wiki-busybox
:
$ kubectl get pods -n wiki-test -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
wiki-busybox 1/1 Running 0 62s 192.168.194.119 k8s-worker1 <none> <none>
wiki-nginx 1/1 Running 0 3m5s 192.168.126.52 k8s-worker2 <none> <none>
$ kubectl exec -n wiki-test wiki-busybox -- curl 192.168.126.52
...
<title>Welcome to nginx!</title>
...
<h1>Welcome to nginx!</h1>
...
On va maintenant bloquer tous les flux entrant/sortant du pod nginx :
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: my-network-policy
namespace: wiki-test
spec:
podSelector:
matchLabels:
app: nginx
policyTypes:
- Ingress
- Egress
# Aucun from/to, tout est bloqué
On retente le curl :
$ kubectl exec -n wiki-test wiki-busybox -- curl 192.168.126.52
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- 0:00:33 --:--:-- 0^C
Calico bloque bien le flux. On va modifier (kubectl edit) la règle afin d'autoriser le port 80 depuis le namespace wiki-test
:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: my-network-policy
namespace: wiki-test
spec:
podSelector:
matchLabels:
app: nginx
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
team: wiki-test
ports:
- port: 80
protocol: TCP
Nginx est maintenant accessible depuis le pod wiki-busybox
:
$ kubectl exec -n wiki-test wiki-busybox -- curl 192.168.126.52
...
<title>Welcome to nginx!</title>
...
<h1>Welcome to nginx!</h1>