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

ModulesCKAD - Services et Networking

Module

Maîtrise les Services Kubernetes, Ingress, DNS et la communication inter-pods pour exposer tes applications.

  • 1 heure 30
  • 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.

CKAD - Services et Networking

🎯 Objectifs

Dans ce module, tu vas :

  • ✅ Comprendre les types de Services (ClusterIP, NodePort, LoadBalancer)
  • ✅ Créer et configurer des Services
  • ✅ Exposer des applications avec Ingress
  • ✅ Comprendre le DNS Kubernetes
  • ✅ Déboguer la connectivité réseau
  • ✅ Maîtriser les Network Policies

📋 Prérequis

  • Module Kubernetes - Intermédiaire complété
  • Module CKAD - Préparation lu
  • Module CKAD - Applications complété

📖 Pourquoi ce module ?

Exposer tes applications aux utilisateurs, c'est faire communiquer tes Pods. Ce module couvre les Services et Networking - 20% de la note CKAD.

Tu dois maîtriser :

  • Comment les Pods se trouvent entre eux (DNS)
  • Comment les exposer en dehors du cluster (Services)
  • Comment router le trafic (Ingress)

🔧 Types de Services

Problème

Les Pods dans Kubernetes ont des IPs, mais ces IPs sont temporaires. Quand un Pod redémarre, il a une nouvelle IP. Comment on peut y accéder de manière stable ?

Solution : Services

ClusterIP (défaut)

Expose l'app seulement à l'intérieur du cluster. Les autres Pods peuvent y accéder par un DNS stable.

yaml
apiVersion: v1
kind: Service
metadata:
  name: myapp
spec:
  type: ClusterIP  # Défaut, peut être omis
  selector:
    app: myapp
  ports:
  - port: 80        # Port du Service
    targetPort: 8080 # Port du Pod

Comment ça marche :

  • Le Service obtient une IP stable : 10.96.0.X
  • Du DNS interne : myapp.default.svc.cluster.local → 10.96.0.X
  • Les autres Pods contactent : curl http://myapp:80

NodePort

Expose l'app en dehors du cluster via un port sur chaque Node.

yaml
apiVersion: v1
kind: Service
metadata:
  name: myapp
spec:
  type: NodePort
  selector:
    app: myapp
  ports:
  - port: 80
    targetPort: 8080
    nodePort: 30000  # Port sur le Node (30000-32767)

Comment ça marche :

  • Le Service reçoit aussi une IP interne (ClusterIP)
  • ET elle écoute sur le port 30000 de chaque Node
  • De l'extérieur : curl http://node-ip:30000

LoadBalancer

Expose l'app via un Load Balancer externe (cloud provider : AWS ELB, Google Cloud LB, etc.).

yaml
apiVersion: v1
kind: Service
metadata:
  name: myapp
spec:
  type: LoadBalancer
  selector:
    app: myapp
  ports:
  - port: 80
    targetPort: 8080

Comment ça marche :

  • Le cloud provider crée un LB
  • Il reçoit une IP publique / DNS
  • Le trafic passe par le LB → NodePort → Pod

ExternalName

Redirige vers un service en dehors du cluster.

yaml
apiVersion: v1
kind: Service
metadata:
  name: external-db
spec:
  type: ExternalName
  externalName: db.example.com
  ports:
  - port: 5432

De l'intérieur du cluster, curl external-db:5432 va se résoudre en db.example.com:5432.


🚀 Ingress : Routage HTTP/HTTPS

Problème

Les Services créent plein de ports. Pour exposer plusieurs apps, tu dois gérer plusieurs ports... pas pratique.

Solution : Ingress

Ingress fait du routage HTTP/HTTPS :

  • URL basée sur le hostname : app1.example.com → Service1, app2.example.com → Service2
  • URL basée sur le path : /app1 → Service1, /app2 → Service2

Créer un Ingress

yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myapp-ingress
spec:
  rules:
  - host: myapp.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: myapp
            port:
              number: 80
  - host: api.example.com
    http:
      paths:
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 8080

PathType

TypeComportement
PrefixRoutage par préfixe : /app match /app, /app/users, etc.
ExactMatch exact : /app match que /app
ImplementationSpecificDépend du contrôleur

HTTPS avec TLS

yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myapp-ingress
spec:
  tls:
  - hosts:
    - myapp.example.com
    secretName: tls-secret  # Secret de type kubernetes.io/tls
  rules:
  - host: myapp.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: myapp
            port:
              number: 80

Ingress Controller

Pour que l'Ingress marche, tu dois avoir un Ingress Controller installé dans le cluster :

  • NGINX Ingress Controller (le plus courant)
  • Ingress fourni par le cloud provider (AWS ALB, Google Cloud LB)
  • Traefik

🌐 DNS Kubernetes

Comment ça marche

Chaque Service dans Kubernetes reçoit un DNS :

service-name.namespace.svc.cluster.local

Exemples :

  • myapp.default.svc.cluster.local
  • api.production.svc.cluster.local

Résoudre un Service

De l'intérieur d'un Pod :

bash
# DNS complet
curl http://myapp.default.svc.cluster.local:80

# Depuis le même namespace : pas besoin du namespace
curl http://myapp:80

# Via nslookup
nslookup myapp
nslookup myapp.default.svc.cluster.local

Découverte de Service

Les Pods reçoivent les variables d'environnement du Service automatiquement.

bash
# Pod dans un Deployment
k exec pod/myapp-xyz -- env | grep MYAPP

# Output :
# MYAPP_SERVICE_HOST=10.96.0.50
# MYAPP_SERVICE_PORT=80

Ainsi tu peux faire :

bash
curl http://$MYAPP_SERVICE_HOST:$MYAPP_SERVICE_PORT

🔧 Déboguer la connectivité

Quand la communication entre Pods ne marche pas :

Vérifier le Service existe

bash
k get services
k describe service myapp
k get service myapp -o yaml

Vérifier le Selector

Le Service doit avoir un sélecteur qui match les labels des Pods.

bash
# Voir les labels du Pod
k describe pod myapp-xyz
# Chercher : Labels: app=myapp, version=1.0

# Voir les sélecteurs du Service
k describe service myapp
# Chercher : Selector: app=myapp

Si le Selector ne match pas, il n'y a pas d'Endpoints.

Vérifier les Endpoints

bash
k get endpoints
k get endpoints myapp

# Si tu vois "no endpoints", c'est que le Selector ne match pas

Tester la connectivité

bash
# DNS
k run debug --image=busybox -it -- nslookup myapp
k run debug --image=busybox -it -- nslookup myapp.default.svc.cluster.local

# HTTP
k run debug --image=curlimages/curl -it -- curl http://myapp:80

# Depuis l'intérieur d'un Pod
k exec pod/client -- curl http://myapp:80

# Vérifier les ports
k exec pod/myapp -- netstat -tuln | grep 8080

🛡️ Network Policies

Problème

Par défaut, tous les Pods peuvent communiquer entre eux. C'est un problème de sécurité (tous les pods peuvent parler à tous les autres pods).

Solution : Network Policies

Une Network Policy définit qui peut parler à qui.

Exemple : Isoler un namespace

yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all
spec:
  podSelector: {}  # S'applique à TOUS les pods du namespace
  policyTypes:
  - Ingress        # Bloquer l'ingress (par défaut : tout autorisé)

Après ça, aucun trafic entrant n'est autorisé.

Autoriser certains trafics

yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-api
spec:
  podSelector:
    matchLabels:
      app: api     # S'applique aux pods "api"
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend  # Autoriser les pods "frontend"
    ports:
    - protocol: TCP
      port: 8080

Ingress vs Egress

DirectionSignification
IngressTrafic entrant (vers mon Pod)
EgressTrafic sortant (depuis mon Pod)

Pour autoriser à la fois l'ingress ET l'egress, dois les déclarer tous les deux.


🔧 Exemple complet : Multi-app avec Ingress

yaml
---
# Namespace
apiVersion: v1
kind: Namespace
metadata:
  name: production

---
# Frontend App
apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend
  namespace: production
spec:
  replicas: 2
  selector:
    matchLabels:
      app: frontend
  template:
    metadata:
      labels:
        app: frontend
    spec:
      containers:
      - name: frontend
        image: frontend:1.0
        ports:
        - containerPort: 3000

---
# Frontend Service
apiVersion: v1
kind: Service
metadata:
  name: frontend
  namespace: production
spec:
  type: ClusterIP
  selector:
    app: frontend
  ports:
  - port: 80
    targetPort: 3000

---
# API App
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api
  namespace: production
spec:
  replicas: 3
  selector:
    matchLabels:
      app: api
  template:
    metadata:
      labels:
        app: api
    spec:
      containers:
      - name: api
        image: api:2.0
        ports:
        - containerPort: 8080

---
# API Service
apiVersion: v1
kind: Service
metadata:
  name: api
  namespace: production
spec:
  type: ClusterIP
  selector:
    app: api
  ports:
  - port: 80
    targetPort: 8080

---
# Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: main-ingress
  namespace: production
spec:
  rules:
  - host: myapp.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: frontend
            port:
              number: 80
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: api
            port:
              number: 80

---
# Network Policy : deny-all
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all
  namespace: production
spec:
  podSelector: {}
  policyTypes:
  - Ingress

---
# Network Policy : allow frontend to api
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-frontend-to-api
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: api
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend
    ports:
    - protocol: TCP
      port: 8080

📊 Résumé

Service TypeAccèsUtilisation
ClusterIPInterneCommunication inter-Pods
NodePortExterne via portDéveloppement
LoadBalancerExterne via LBProduction (cloud)
ExternalNameService externeIntégration externe
ConceptUtilisation
ServiceExposer des Pods
IngressRoutage HTTP/HTTPS
DNSDécouverte de service
Network PolicySécurité réseau

🚀 Prochaines Étapes

  • CKAD : Volumes et Persistance - Stockage et données persistantes
Retour aux modules

Sur cette page

  • 🎯 Objectifs
  • 📋 Prérequis
  • 📖 Pourquoi ce module ?
  • 🔧 Types de Services
  • Problème
  • ClusterIP (défaut)
  • NodePort
  • LoadBalancer
  • ExternalName
  • 🚀 Ingress : Routage HTTP/HTTPS
  • Problème
  • Créer un Ingress
  • PathType
  • HTTPS avec TLS
  • Ingress Controller
  • 🌐 DNS Kubernetes
  • Comment ça marche
  • Résoudre un Service
  • Découverte de Service
  • 🔧 Déboguer la connectivité
  • Vérifier le Service existe
  • Vérifier le Selector
  • Vérifier les Endpoints
  • Tester la connectivité
  • 🛡️ Network Policies
  • Problème
  • Exemple : Isoler un namespace
  • Autoriser certains trafics
  • Ingress vs Egress
  • 🔧 Exemple complet : Multi-app avec Ingress
  • 📊 Résumé
  • 🚀 Prochaines Étapes