====== Service / Réseau Kubernetes ====== Les services permettent de publier l'accès aux Pods au sein du cluster ou à l'extérieur. Les conteneurs au sein d'un Pod partagent la même configuration réseau et sont donc accessible par la même IP interne au cluster. Il y a plusieurs possibilité selon ce que l'on souhaite faire. ===== ClusterIP ===== C'est le mode par défaut de Kubernetes lorsque l'on crée un service. Il permet d'exposer un port au sein du cluster uniquement. **Remarque** :!: L'IP n'est pas publiée en dehors du cluster. L'IP allouée ne sera accessible que par les nodes du cluster. A noter aussi que les ClusterIP sont assignées par des règles Iptables dans la table NAT. Ci-dessous un fichier YAML pour démarrer un Pod nginx et son service : vim pod_nginx_service.yml Contenu : apiVersion: v1 kind: Pod metadata: name: nginx labels: app: mywebapp spec: containers: - name: nginx image: nginx:stable ports: - containerPort: 80 # Ci-dessous on affecte un nom au port #name: http-web-svc --- apiVersion: v1 kind: Service metadata: name: nginx-service spec: # ClusterIP étant le mode par défaut, il n'est pas obligé de définir le type pour le créer. #type: ClusterIP selector: app: mywebapp ports: - name: mywebport protocol: TCP port: 8080 targetPort: 80 # Si un nom a été donné au port du conteneur on peut cibler le port par son nom. #targetPort: http-web-svc Explications, nous avons un YAML pour créer 2 objets : * **Un Pod** : * **metadata.labels.app** : Il est important de définir le nom pour qu'il soit ciblé automatiquement par le service. * **Un service**: * **metadata.name**: Définir un nom pour le service afin de l'identifier. * **spec.selector.app** : Le nom doit correspondre à **metadata.labels.app** afin que la publication du service cible le pod à publier. * **spec.ports.name**: Indiquer le nom du port * **spec.ports.protocol**: Indiquer si le port est en TCP/UDP. * **spec.ports.port** : C'est le port qui sera publié au sein du cluster. * **spec.ports.targetPort** : C'est le port ciblé coté conteneurs. Création du pod et du service : kubectl apply -f pod_nginx_service.yml Listons le pods créé : kubectl get pods Résultat attendu : NAME READY STATUS RESTARTS AGE nginx 1/1 Running 0 21s Listons les services : kubectl get services # Même commande en plus court #kubectl get svc l'IP de cluster **10.110.183.49** a été affecté au service : NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 443/TCP 8d nginx-service ClusterIP 10.110.183.49 8080/TCP 27s Pour tester l'accès au **nginx** : curl http://10.110.183.49:8080 Ci-dessous, nous allons lister les points de terminsons : kubectl get endpoints # Version courte #kubectl get ep Ce que nous constatons, c'est le service **nginx-service** cible le pod qui à l'IP **192.168.1.105** sur le port **80** : NAME ENDPOINTS AGE kubernetes 10.0.6.8:6443 8d nginx-service 192.168.1.105:80 37s Déployons un autre pod qui sera accessible par le même service : vim pod_nginx2.yml Contenu : apiVersion: v1 kind: Pod metadata: name: nginx2 labels: app: mywebapp spec: containers: - name: nginx image: nginx:stable ports: - containerPort: 80 Lancement du pod : kubectl apply -f pod_nginx2.yml Vérification des endpoints : kubectl get endpoints Ce que nous pouvons voir c'est le service cible **nginx-service** 2 pods sur le port 80 : NAME ENDPOINTS AGE kubernetes 10.0.6.8:6443 8d nginx-service 192.168.1.105:80,192.168.1.106:80 7m37s La requête ci-dessous sera alternativement redirigée vers **192.168.1.105:80** et **192.168.1.106:80** : curl http://10.110.183.49:8080 ===== NodePort ===== La création d'un service de type **NodePort** créé aussi un service **ClusterIP** mais en plus un port sera publié à l'extérieur du cluster. Un port sera ouvert sur chacun des nodes (le serveur virtuel ou physique). Les ports qui peuvent être utilisés sont supérieur à 30000. Comme pour la création d'un service ClusterIP plus haut, nous allons créer un service et lancer un Pod : vim pod_nginx_service_nodeport.yml Contenu : apiVersion: v1 kind: Pod metadata: name: nginx labels: app: mywebapp spec: containers: - name: nginx image: nginx:stable ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: nginx-service spec: type: NodePort selector: app: mywebapp ports: - name: mywebport protocol: TCP port: 8080 targetPort: 80 nodePort: 31000 On retrouve les mêmes éléments que pour la création d'un ClusterIP à la différence près que : * **Pour le service** : * **spec.type** : Doit être défini pour forcer la création de type **NodePort**. * **spec.ports.nodePort** : Définir le port qui devra écouter sur tous les nodes. On liste les services : kubectl get svc Résultat : NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 443/TCP 8d nginx-service NodePort 10.110.183.49 8080:31000/TCP 47m **Explications** : On constate que le service est de type **NodePort**. Le service dispose quand même d'un Cluster IP (10.110.183.49). Techniquement le pods est accessible en depuis les nodes ainsi : curl http://10.110.183.49:8080 Mais aussi depuis l'extérieur sur chacune des IP des nodes : curl http://10.0.6.8:31000 curl http://10.0.4.248:31000 Liste des nodes : NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME k8s-master Ready control-plane 11d v1.28.2 10.0.6.8 Debian GNU/Linux 12 (bookworm) 6.1.0-15-cloud-amd64 docker://24.0.7 k8s-node Ready 11d v1.28.2 10.0.4.248 Debian GNU/Linux 12 (bookworm) 6.1.0-15-cloud-amd64 docker://24.0.7 ===== LoadBalancer ===== :!: A approfondir :!: La création d'un service de type **LoadBalancer** créé aussi les services **NodePort** et **ClusterIP**. En revanche, il permet d'équilibrer la charge vers les nodes avec l'utilisation d'un service de LoadBalancer externe ou cloud. Fichier YAML correspond (identique à NodePort mais le type change) : apiVersion: v1 kind: Pod metadata: name: nginx labels: app: mywebapp spec: containers: - name: nginx image: nginx:stable ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: nginx-service spec: type: LoadBalancer selector: app: mywebapp ports: - name: mywebport protocol: TCP port: 8080 targetPort: 80 nodePort: 31000 ===== ExternalName ===== ===== Ingress =====