DevOpsFacile
AccueilParcours de formationCertificationsModulesCheat SheetÀ Propos
DevOpsFacile

Une plateforme d'apprentissage complète pour maîtriser les pratiques DevOps modernes, du débutant à l'expert.

contact@devopsfacile.fr

Formation

  • Parcours de formation
  • Modules

Informations

  • À Propos
  • Conditions d'utilisation
  • Confidentialité
  • Mentions légales

© 2026 DevOps Facile. Tous droits réservés.

Fait avec pour la communauté DevOps

ModulesCKA - Domaine 3 : Services et Réseau (20%)

Module

Modèle réseau Kubernetes, Services, DNS interne, Ingress, NetworkPolicy et CoreDNS pour la certification CKA.

  • 3 heures
  • Avancé

Formation 100 % Linux

Tous les modules nécessitent un environnement Linux. Si vous êtes sur Windows, installez d'abord WSL (Windows Subsystem for Linux) avant de continuer.

CKA - Domaine 3 : Services et Réseau (20%)

🎯 Objectifs

À la fin de ce module, tu seras capable de :

  • ✅ Expliquer le modèle réseau Kubernetes (chaque Pod a une IP unique)
  • ✅ Créer et configurer des Services (ClusterIP, NodePort, LoadBalancer, Headless)
  • ✅ Comprendre et utiliser le DNS interne du cluster
  • ✅ Configurer un Ingress avec règles de routage et TLS
  • ✅ Écrire des NetworkPolicies pour isoler les namespaces et les Pods
  • ✅ Diagnostiquer des problèmes réseau dans un cluster

📋 Prérequis

  • Module CKA : Workloads et Scheduling lu
  • Notions de base réseau : IP, ports, DNS, TCP/UDP

🌐 Le modèle réseau Kubernetes

La règle fondamentale

Kubernetes impose un modèle réseau simple :

  1. Chaque Pod reçoit une IP unique dans le cluster
  2. Tous les Pods peuvent se joindre directement sans NAT (peu importe le node)
  3. Les nodes peuvent joindre tous les Pods sans NAT

C'est le rôle du CNI (Container Network Interface) de mettre en place ce modèle. Flannel, Calico, Weave Net, Cilium sont des implémentations CNI.

bash
# Voir l'IP de chaque pod
kubectl get pods -o wide

# Voir l'IP d'un pod en détail
kubectl describe pod <nom> | grep IP

# Tester la connectivité directement entre pods
kubectl exec -it pod-a -- curl http://<IP-de-pod-b>

💡 À l'examen, si un Pod ne peut pas joindre un autre Pod, vérifie d'abord les NetworkPolicies avant de t'attaquer au CNI.


🔌 Services

Pourquoi les Services ?

Les Pods ont des IPs éphémères - elles changent à chaque redémarrage. Un Service fournit une IP stable et un nom DNS qui redirige le trafic vers les bons Pods via un selector.

ClusterIP (défaut)

Accessible uniquement depuis l'intérieur du cluster.

bash
# Mode impératif
kubectl expose deployment nginx --port=80 --target-port=80
kubectl expose deployment nginx --port=80 --target-port=8080 --name=nginx-svc

# Générer le YAML
kubectl expose deployment nginx --port=80 --dry-run=client -o yaml > svc.yaml
yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
spec:
  selector:
    app: nginx           # correspond aux labels des Pods cibles
  ports:
    - protocol: TCP
      port: 80           # port exposé par le Service
      targetPort: 8080   # port du conteneur
  type: ClusterIP

NodePort

Accessible depuis l'extérieur via <NodeIP>:<NodePort>.

bash
kubectl expose deployment nginx --type=NodePort --port=80
yaml
spec:
  type: NodePort
  ports:
    - port: 80
      targetPort: 80
      nodePort: 30080    # optionnel, entre 30000-32767 (assigné auto sinon)

LoadBalancer

Crée un load balancer externe (cloud provider requis).

bash
kubectl expose deployment nginx --type=LoadBalancer --port=80

ExternalName

Redirige vers un nom DNS externe (utile pour des services hors cluster).

yaml
apiVersion: v1
kind: Service
metadata:
  name: ma-db
spec:
  type: ExternalName
  externalName: db.example.com

Headless Service

Un Service sans IP virtuelle (clusterIP: None). Utilisé avec les StatefulSets pour adresser chaque pod individuellement.

yaml
apiVersion: v1
kind: Service
metadata:
  name: mysql-headless
spec:
  clusterIP: None           # pas d'IP virtuelle
  selector:
    app: mysql
  ports:
    - port: 3306

Chaque pod devient accessible via : mysql-0.mysql-headless.default.svc.cluster.local


🗺️ DNS interne du cluster

CoreDNS

Kubernetes utilise CoreDNS comme serveur DNS interne. Il est déployé comme un Deployment dans le namespace kube-system.

bash
kubectl get pods -n kube-system | grep coredns
kubectl get configmap coredns -n kube-system -o yaml

Format des noms DNS

# Service
<service>.<namespace>.svc.cluster.local
# → nginx-svc.default.svc.cluster.local

# Pod (moins courant)
<ip-avec-tirets>.<namespace>.pod.cluster.local
# → 10-244-1-5.default.pod.cluster.local

Résolution depuis un Pod

bash
# Depuis l'intérieur d'un pod
kubectl exec -it <pod> -- nslookup nginx-svc.default.svc.cluster.local
kubectl exec -it <pod> -- nslookup kubernetes.default.svc.cluster.local

# Forme courte (même namespace)
kubectl exec -it <pod> -- curl http://nginx-svc

# Namespace différent
kubectl exec -it <pod> -- curl http://nginx-svc.production.svc.cluster.local

# Lancer un pod de debug temporaire
kubectl run debug --image=busybox --rm -it --restart=Never -- sh

Résoudre les problèmes DNS

bash
# CoreDNS fonctionne ?
kubectl get pods -n kube-system -l k8s-app=kube-dns

# Logs CoreDNS
kubectl logs -n kube-system -l k8s-app=kube-dns

# Tester depuis un pod
kubectl exec -it <pod> -- cat /etc/resolv.conf
# nameserver doit pointer vers l'IP du Service kube-dns (souvent 10.96.0.10)

🚦 Ingress

Concept

Un Ingress définit des règles de routage HTTP/HTTPS vers des Services. Il nécessite un Ingress Controller pour fonctionner (nginx-ingress, traefik, HAProxy...).

bash
# Avec Minikube (pour les examens)
minikube addons enable ingress
kubectl get pods -n ingress-nginx

Règles de routage

yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
    - host: monapp.example.com
      http:
        paths:
          - path: /api
            pathType: Prefix
            backend:
              service:
                name: api-service
                port:
                  number: 8080
          - path: /
            pathType: Prefix
            backend:
              service:
                name: frontend-service
                port:
                  number: 80
    - host: admin.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: admin-service
                port:
                  number: 80

Ingress avec TLS

yaml
spec:
  tls:
    - hosts:
        - monapp.example.com
      secretName: tls-secret    # Secret de type kubernetes.io/tls
  rules:
    - host: monapp.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: frontend-service
                port:
                  number: 80
bash
# Créer le Secret TLS
kubectl create secret tls tls-secret \
  --cert=tls.crt \
  --key=tls.key

kubectl get ingress
kubectl describe ingress app-ingress

🛡️ NetworkPolicy

Pourquoi ?

Par défaut, tous les Pods peuvent communiquer entre eux dans un cluster Kubernetes. Les NetworkPolicies permettent de restreindre ce trafic.

⚠️ Les NetworkPolicies ne fonctionnent que si le CNI installé les supporte (Calico, Cilium, Weave Net - mais pas Flannel seul).

Modèle mental

Une NetworkPolicy s'applique à des Pods (via podSelector). Si un pod est sélectionné par au moins une NetworkPolicy, tout le trafic non explicitement autorisé est refusé.

Exemples fondamentaux

yaml
# 1. Refuser TOUT le trafic entrant dans un namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-ingress
  namespace: production
spec:
  podSelector: {}       # s'applique à TOUS les pods du namespace
  policyTypes:
    - Ingress
  # Pas de règles ingress = tout est refusé
yaml
# 2. Autoriser uniquement les pods avec app=frontend à joindre app=backend
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: backend-policy
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: backend          # s'applique aux pods backend
  policyTypes:
    - Ingress
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app: frontend # autorise uniquement les pods frontend
      ports:
        - protocol: TCP
          port: 8080
yaml
# 3. Autoriser le trafic depuis un autre namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-from-monitoring
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: backend
  policyTypes:
    - Ingress
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: monitoring
yaml
# 4. Règle Egress : restreindre le trafic sortant
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: restrict-egress
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: backend
  policyTypes:
    - Egress
  egress:
    - to:
        - podSelector:
            matchLabels:
              app: database
      ports:
        - protocol: TCP
          port: 5432
    - ports:
        - protocol: UDP
          port: 53    # autoriser le DNS !

⚠️ Si tu bloques l'Egress, n'oublie pas d'autoriser le port 53 UDP pour le DNS, sinon les pods ne peuvent plus résoudre les noms.

yaml
# 5. Combiner podSelector ET namespaceSelector (opérateur AND)
    from:
      - namespaceSelector:
          matchLabels:
            env: production
        podSelector:                  # ET (même élément de tableau)
          matchLabels:
            app: frontend

# Comparaison : opérateur OR (deux éléments séparés)
    from:
      - namespaceSelector:            # OU
          matchLabels:
            env: production
      - podSelector:                  # OU
          matchLabels:
            app: frontend

🔍 Diagnostiquer les problèmes réseau

Checklist de diagnostic

bash
# 1. Le Service existe et sélectionne les bons pods ?
kubectl get svc <nom>
kubectl describe svc <nom>          # vérifier Endpoints
kubectl get endpoints <nom>         # doit lister les IPs des pods

# 2. Le pod cible est Running et Ready ?
kubectl get pods -l app=<label> -o wide

# 3. Test de connectivité depuis l'intérieur du cluster
kubectl run debug --image=busybox --rm -it --restart=Never -- sh
# Dans le pod :
wget -qO- http://<service>.<namespace>.svc.cluster.local
nslookup <service>

# 4. Les NetworkPolicies bloquent-elles ?
kubectl get networkpolicies -n <namespace>
kubectl describe networkpolicy <nom>

# 5. kube-proxy tourne ?
kubectl get pods -n kube-system | grep kube-proxy
kubectl logs -n kube-system <kube-proxy-pod>

Cas courants

Service accessible mais pods pas répondent

bash
# Les Endpoints sont vides = le selector ne correspond à aucun pod
kubectl describe svc mon-svc | grep Endpoints
kubectl get pods --show-labels | grep <label-du-selector>

DNS ne résout pas

bash
kubectl run dns-test --image=busybox --rm -it --restart=Never -- nslookup kubernetes.default
# Si ça échoue, CoreDNS a un problème
kubectl get pods -n kube-system | grep coredns
kubectl logs -n kube-system <coredns-pod>

Ingress ne route pas

bash
kubectl describe ingress <nom>
kubectl get pods -n ingress-nginx
kubectl logs -n ingress-nginx <ingress-controller-pod>

📊 Récapitulatif des commandes clés

bash
# Services
kubectl expose deployment <name> --port=80 --type=ClusterIP
kubectl get svc -o wide
kubectl get endpoints <svc>

# DNS test
kubectl run debug --image=busybox --rm -it --restart=Never -- nslookup <service>

# Ingress
kubectl get ingress -A
kubectl describe ingress <name>

# NetworkPolicy
kubectl get networkpolicies -A
kubectl describe networkpolicy <name> -n <namespace>

# Connectivité
kubectl exec -it <pod> -- curl http://<service>
kubectl exec -it <pod> -- wget -qO- http://<service>

🚀 Prochaines Étapes

  • Domaine suivant : CKA : Stockage
  • Entraîne-toi : crée une NetworkPolicy deny-all puis autorise progressivement du trafic, vérifie à chaque étape
  • Référence : kubernetes.io/docs/concepts/services-networking/
Retour aux modules

Sur cette page

  • 🎯 Objectifs
  • 📋 Prérequis
  • 🌐 Le modèle réseau Kubernetes
  • La règle fondamentale
  • 🔌 Services
  • Pourquoi les Services ?
  • ClusterIP (défaut)
  • NodePort
  • LoadBalancer
  • ExternalName
  • Headless Service
  • 🗺️ DNS interne du cluster
  • CoreDNS
  • Format des noms DNS
  • Résolution depuis un Pod
  • Résoudre les problèmes DNS
  • 🚦 Ingress
  • Concept
  • Règles de routage
  • Ingress avec TLS
  • 🛡️ NetworkPolicy
  • Pourquoi ?
  • Modèle mental
  • Exemples fondamentaux
  • 🔍 Diagnostiquer les problèmes réseau
  • Checklist de diagnostic
  • Cas courants
  • 📊 Récapitulatif des commandes clés
  • 🚀 Prochaines Étapes