KubernetesRéseauDevOpsSécurité

Kubernetes Ingress avec nginx : exposer ses services en production

26 août 2026 · Sphinx-Digital

Un Service Kubernetes de type LoadBalancer crée un load balancer cloud par service — coûteux et difficile à gérer à l’échelle. Ingress centralise tout le trafic HTTP/HTTPS entrant via un seul point d’entrée, avec routage par hostname et path.

Installer ingress-nginx

# Via Helm (recommandé)
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.replicaCount=2 \
  --set controller.nodeSelector."kubernetes\.io/os"=linux \
  --set controller.service.externalTrafficPolicy=Local

Après installation, un seul LoadBalancer cloud est créé — avec une IP externe unique. Tout le routage est géré par nginx à l’intérieur du cluster.

Premier Ingress : routage par hostname

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myapp-ingress
  namespace: production
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
    - host: api.sphinx-digital.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: api-service
                port:
                  number: 8080
    - host: admin.sphinx-digital.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: admin-service
                port:
                  number: 3000

TLS automatique avec cert-manager et Let’s Encrypt

cert-manager s’intègre nativement avec ingress-nginx pour provisionner et renouveler automatiquement des certificats Let’s Encrypt.

# Installer cert-manager
helm install cert-manager jetstack/cert-manager \
  --namespace cert-manager \
  --create-namespace \
  --set installCRDs=true
# ClusterIssuer : l'autorité Let's Encrypt
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: contact@sphinx-digital.com
    privateKeySecretRef:
      name: letsencrypt-prod
    solvers:
      - http01:
          ingress:
            class: nginx
# Ingress avec TLS automatique
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myapp-ingress
  annotations:
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - api.sphinx-digital.com
      secretName: api-tls-cert   # cert-manager crée ce Secret automatiquement
  rules:
    - host: api.sphinx-digital.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: api-service
                port:
                  number: 8080

Le certificat est provisionné en quelques minutes et renouvelé automatiquement avant expiration. Zéro intervention manuelle.

Rate limiting

annotations:
  # 100 requêtes par minute par IP
  nginx.ingress.kubernetes.io/limit-rps: "100"
  # Burst autorisé
  nginx.ingress.kubernetes.io/limit-burst-multiplier: "5"
  # Whitelist des IPs internes (pas de rate limit)
  nginx.ingress.kubernetes.io/limit-whitelist: "10.0.0.0/8,172.16.0.0/12"

Authentification basique

# Créer le fichier htpasswd
htpasswd -c auth admin
kubectl create secret generic basic-auth \
  --from-file=auth \
  -n production
annotations:
  nginx.ingress.kubernetes.io/auth-type: basic
  nginx.ingress.kubernetes.io/auth-secret: basic-auth
  nginx.ingress.kubernetes.io/auth-realm: "Accès restreint"

Headers de sécurité et CORS

annotations:
  # Headers de sécurité
  nginx.ingress.kubernetes.io/configuration-snippet: |
    more_set_headers "X-Frame-Options: SAMEORIGIN";
    more_set_headers "X-XSS-Protection: 1; mode=block";
    more_set_headers "X-Content-Type-Options: nosniff";
    more_set_headers "Referrer-Policy: strict-origin-when-cross-origin";

  # CORS pour une API consommée depuis un frontend séparé
  nginx.ingress.kubernetes.io/enable-cors: "true"
  nginx.ingress.kubernetes.io/cors-allow-origin: "https://app.sphinx-digital.com"
  nginx.ingress.kubernetes.io/cors-allow-methods: "GET, POST, PUT, DELETE, OPTIONS"
  nginx.ingress.kubernetes.io/cors-allow-headers: "Authorization, Content-Type"

Redirection www vers non-www

# Ingress dédié à la redirection
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: redirect-www
  annotations:
    nginx.ingress.kubernetes.io/permanent-redirect: "https://sphinx-digital.com$request_uri"
spec:
  ingressClassName: nginx
  rules:
    - host: www.sphinx-digital.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: ingress-nginx-controller  # dummy, la redirection se fait avant
                port:
                  number: 80

Notre formation Kubernetes couvre Ingress, cert-manager et la mise en production de services avec des ateliers sur des clusters cloud.