iducationducation
IndexArticlesFormationsProfilOutilsBibliothech
N°014 — 2026
Navigation
01Index02Articles03Formations04Profil05Outils06Bibliothech
N°014 — 2026
iducationducation
IndexArticlesFormationsProfilOutilsBibliothech
N°014 — 2026
Navigation
01Index02Articles03Formations04Profil05Outils06Bibliothech
N°014 — 2026
Formations
YAML / Bash · Intermédiaire

Kubernetes

De Docker Compose à Kubernetes : architecture complète, distributions (K8s, K3s, K0s, MicroK8s), objets fondamentaux, networking, Ingress, scaling automatique et déploiement en production.

KubernetesK3skubectlHelmDocker
01Pourquoi Kubernetes — le problème Docker seul ne résout pas02K8s, K3s, K0s, MicroK8s — quelle distribution choisir03Architecture interne — Control Plane et Worker Nodes04Installation — K3s en production et kubectl05Objets fondamentaux — Pod, Deployment, Service, Namespace06Configuration et stockage — ConfigMap, Secret, PVC07Networking et Ingress — exposer vos services08Scaling, RBAC, Helm et production
Chapitre 7·30 min

Networking et Ingress — exposer vos services

Dans un cluster Kubernetes, chaque pod a une IP privée interne. Pour exposer une application à l'extérieur — avec un vrai domaine et du HTTPS — il faut un Ingress Controller. Ce chapitre installe NGINX Ingress, configure des règles de routage, et automatise les certificats TLS avec cert-manager.

Le réseau interne K8s

Chaque pod obtient une IP unique dans le réseau du cluster (généralement 10.244.x.x ou 10.42.x.x pour K3s). Ces IPs ne sont pas accessibles de l'extérieur.

Internet
    │
    ▼
Load Balancer / IP publique (port 80/443)
    │
    ▼
Ingress Controller (pod NGINX)
    │
    ├── /api/* → Service api-service:80 → Pods api (10.42.1.x)
    ├── /      → Service web-service:80 → Pods web (10.42.2.x)
    └── admin.example.com → Service admin-service:80

DNS interne — service discovery

K8s configure CoreDNS pour que les services se trouvent par nom :

Format : <service>.<namespace>.svc.cluster.local
 
Exemples :
- postgres.production.svc.cluster.local
- redis.production.svc.cluster.local
- mon-api.default.svc.cluster.local
 
Depuis le même namespace, le nom court suffit :
- postgres
- redis
# Tester la résolution DNS depuis un pod
kubectl run debug --image=busybox --restart=Never -it --rm -- \
  nslookup postgres.production.svc.cluster.local

Installer NGINX Ingress Controller

K3s est livré avec Traefik. On installe NGINX à la place (plus documenté, plus de fonctionnalités) :

# Via Helm
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
 
helm install ingress-nginx ingress-nginx/ingress-nginx \
  --namespace ingress-nginx \
  --create-namespace \
  --set controller.service.type=LoadBalancer

Sur K3s avec un VPS, K3s provisionne automatiquement un LoadBalancer via son composant Klipper. Vérifier :

kubectl get service -n ingress-nginx
# NAME                          TYPE           CLUSTER-IP    EXTERNAL-IP
# ingress-nginx-controller      LoadBalancer   10.43.x.x     <IP-VPS>

Créer une règle Ingress

ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: mon-app-ingress
  namespace: production
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/proxy-body-size: "10m"
spec:
  ingressClassName: nginx
  rules:
    - host: mon-app.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: mon-app
                port:
                  number: 80
    - host: api.example.com
      http:
        paths:
          - path: /v1
            pathType: Prefix
            backend:
              service:
                name: api-service
                port:
                  number: 80
kubectl apply -f ingress.yaml
kubectl get ingress -n production
# NAME               CLASS   HOSTS                          ADDRESS
# mon-app-ingress    nginx   mon-app.example.com,...        <IP-VPS>

Pointer les enregistrements DNS de vos domaines vers <IP-VPS>.

cert-manager — TLS automatique avec Let's Encrypt

cert-manager provisionne et renouvelle automatiquement les certificats TLS.

Installation

helm repo add jetstack https://charts.jetstack.io
helm repo update
 
helm install cert-manager jetstack/cert-manager \
  --namespace cert-manager \
  --create-namespace \
  --set crds.enabled=true

ClusterIssuer — définir l'autorité de certification

clusterissuer.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: votre@email.com
    privateKeySecretRef:
      name: letsencrypt-prod-key
    solvers:
      - http01:
          ingress:
            ingressClassName: nginx
kubectl apply -f clusterissuer.yaml
kubectl get clusterissuer
# NAME                READY
# letsencrypt-prod    True

Ingress avec TLS automatique

ingress-tls.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: mon-app-ingress
  namespace: production
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - mon-app.example.com
      secretName: mon-app-tls    # cert-manager crée ce secret
  rules:
    - host: mon-app.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: mon-app
                port:
                  number: 80

cert-manager détecte l'annotation, provisionne le certificat via le challenge HTTP-01, et le renouvelle automatiquement avant expiration. Le certificat apparaît dans le namespace production sous le nom mon-app-tls.

# Suivre la provision du certificat
kubectl describe certificate mon-app-tls -n production
kubectl get certificate -n production
# NAME          READY   SECRET        AGE
# mon-app-tls   True    mon-app-tls   2m

Annotations NGINX Ingress utiles

annotations:
  # Taille max des requêtes
  nginx.ingress.kubernetes.io/proxy-body-size: "50m"
 
  # Timeout (en secondes)
  nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
  nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
 
  # Rate limiting
  nginx.ingress.kubernetes.io/limit-rps: "10"
  nginx.ingress.kubernetes.io/limit-connections: "5"
 
  # CORS
  nginx.ingress.kubernetes.io/enable-cors: "true"
  nginx.ingress.kubernetes.io/cors-allow-origin: "https://mon-app.com"
 
  # Basic auth
  nginx.ingress.kubernetes.io/auth-type: basic
  nginx.ingress.kubernetes.io/auth-secret: basic-auth
  nginx.ingress.kubernetes.io/auth-realm: "Zone protégée"
 
  # Réécriture de chemin
  nginx.ingress.kubernetes.io/rewrite-target: /$2

NetworkPolicy — isolation réseau entre namespaces

Par défaut, tous les pods peuvent communiquer entre eux quelle que soit le namespace. NetworkPolicy restreint ça.

networkpolicy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: backend-isolation
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: postgres
  policyTypes:
    - Ingress
  ingress:
    - from:
        # Uniquement les pods avec le label app: mon-api dans le même namespace
        - podSelector:
            matchLabels:
              app: mon-api
      ports:
        - protocol: TCP
          port: 5432

Cette policy bloque tout accès à PostgreSQL sauf depuis les pods mon-api du namespace production. Les autres pods — même dans le même namespace — ne peuvent pas se connecter à PostgreSQL.


Le networking est opérationnel. Le dernier chapitre couvre le scaling automatique, les rolling updates, RBAC, Helm et le monitoring en production.

Précédent
Configuration et stockage — ConfigMap, Secret, PVC
Suivant
Scaling, RBAC, Helm et production

Développeur fullstack passionné. J'apprends en construisant et je documente tout — front, back, outils. Le code s'apprend mieux en public.

Naviguer

IndexTous les articlesFormationsProfilOutilsBibliothech

Ailleurs

GitHub RSS

Newsletter

Les articles, libs et découvertes. Une fois par semaine, pas plus.

© 2026 William LoreeConçu & codé à la main