Outils pour utilisateurs

Outils du site


informatique:kebernetes:kube_service

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       <none>        443/TCP    8d
nginx-service   ClusterIP   10.110.183.49   <none>        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       <none>        443/TCP          8d
nginx-service   NodePort    10.110.183.49   <none>        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      <none>        Debian GNU/Linux 12 (bookworm)   6.1.0-15-cloud-amd64   docker://24.0.7
k8s-node     Ready    <none>          11d   v1.28.2   10.0.4.248    <none>        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

informatique/kebernetes/kube_service.txt · Dernière modification: 2023/12/18 08:23 par benoit