Utilisation avancée des Ingress HAProxy
Ce guide présente les usages avancés des objets Ingress sur Kubernetes avec le contrôleur HAProxy, adaptés à l'environnement SdV. Il s'adresse aux équipes DevOps/Ops/SRE souhaitant maîtriser l'exposition, la sécurité et la personnalisation du trafic HTTP(S).
Introduction
L'objet Ingress permet d'exposer des services internes Kubernetes à l'extérieur du cluster via des règles HTTP/S. Le contrôleur HAProxy offre de nombreuses options de personnalisation via annotations et ConfigMap. Consultez la documentation officielle HAProxy Ingress pour la liste complète des clés.
Configuration générale
Selon le scope, la configuration peut se faire :
- via des annotations sur l'objet Ingress (recommandé pour la plupart des cas)
- via une
ConfigMapglobale (réservé à l'administration du cluster)
Restrictions d'accès par IP
Pour limiter l'accès à un service selon l'adresse IP source, utilisez l'annotation suivante :
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ghost
annotations:
ingress.kubernetes.io/whitelist-source-range: 212.95.64.0/19,1.2.3.4
spec:
ingressClassName: public
rules:
- host: ghost.{{publicVIP}}.nip.io
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: ghost-svc
port:
number: 80Pour des besoins avancés, utilisez ingress.kubernetes.io/config-backend pour injecter des ACL HAProxy personnalisées :
annotations:
ingress.kubernetes.io/config-backend: |
acl whitelist src 1.2.3.4
acl protected_host hdr(host) -i ghost.{{publicVIP}}.nip.io
http-request deny if protected_host !whitelistProtection par mot de passe (basic auth)
La première étape est de créer le hash de votre mot de passe au format sha512crypt, puis l'encoder au format base64 avec le prefix <myuser> (attention à l'échappement des charactères spéciaux):
$ mkpasswd -m sha-512 -s mypassword
$6$p5yZF8jSo5dEcxJx$n49C3xodRTuWkPXIqt6kd6Lra0nJCxO9yK1HU2eX7Mt7EP3Fg4RRcaKk.IvpMSuBet.zuFQk1UeAqVO6tjG8w0
$ echo -e "myuser:\$6\$p5yZF8jSo5dEcxJx\$n49C3xodRTuWkPXIqt6kd6Lra0nJCxO9yK1HU2eX7Mt7EP3Fg4RRcaKk.IvpMSuBet.zuFQk1UeAqVO6tjG8w0" | base64
bXl1c2VyOiQ2JHA1eVpGOGpTbzVkRWN4SngkbjQ5QzN4b2RSVHVXa1BYSXF0NmtkNkxyYTBuSkN4Tzl5SzFIVTJlWDdNdDdFUDNGZzRSUmNhS2suSXZwTVN1QmV0Lnp1RlFrMVVlQXFWTzZ0akc4dzAKNous allons ensuite stocker le résultat dans un Secret:
apiVersion: v1
kind: Secret
metadata:
name: basic-auth
data:
auth: bXl1c2VyOiQ2JHA1eVpGOGpTbzVkRWN4SngkbjQ5QzN4b2RSVHVXa1BYSXF0NmtkNkxyYTBuSkN4Tzl5SzFIVTJlWDdNdDdFUDNGZzRSUmNhS2suSXZwTVN1QmV0Lnp1RlFrMVVlQXFWTzZ0akc4dzAK
type: OpaqueEnfin, ajouter les annotations suivantes au niveau de votre objet Ingress pour activer l'authentification:
annotations:
ingress.kubernetes.io/auth-type: basic
ingress.kubernetes.io/auth-secret: basic-auth
ingress.kubernetes.io/auth-realm: "Authentification Required"Certificats ACME / Let's Encrypt
Par défaut, l'ingress public SdV supporte ACME v2 (Let's Encrypt) en mode http01. Exemple :
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ghost
annotations:
ingress.kubernetes.io/cert-signer: acme
spec:
ingressClassName: public
tls:
- hosts:
- ghost.{{publicVIP}}.nip.io
secretName: ghost-cert
rules:
- host: ghost.{{publicVIP}}.nip.io
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: ghost-svc
port:
number: 80Le certificat Let's Encrypt sera stocké dans le Secret ghost-cert.
Gestion des entêtes X-Forwarded-For
Les ingress HAProxy ajoutent automatiquement l'entête HTTP X-Forwarded-For avec l'IP source réelle. Si un entête existe déjà, il est déplacé en X-Original-Forwarded-For.
$ curl ghost.212.95.76.25.nip.io
... X-Forwarded-For: 212.95.95.248 ...curl -H 'X-Forwarded-For: 1.2.3.4' ghost.212.95.76.25.nip.io
... X-Forwarded-For: 212.95.95.248 ...
... X-Original-Forwarded-For: 1.2.3.4 ...ServerAliases et multi-domaines
L'annotation ingress.kubernetes.io/server-alias permet d'associer plusieurs FQDN à la même règle d'Ingress, sans dupliquer les blocs rules. Cela simplifie la gestion des alias DNS (par exemple, www, sans-www, etc.).
Exemple : pour que ghost.{{publicVIP}}.nip.io et blog.{{publicVIP}}.nip.io pointent vers le même backend :
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ghost
annotations:
ingress.kubernetes.io/server-alias: "blog.{{publicVIP}}.nip.io,www.{{publicVIP}}.nip.io"
spec:
ingressClassName: public
rules:
- host: ghost.{{publicVIP}}.nip.io
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: ghost-svc
port:
number: 80SSL Pass Through (TLS pass-through)
Le mode SSL Pass Through permet de transmettre le trafic TLS (HTTPS) directement au backend sans terminaison SSL côté Ingress. Cela peut être utile pour des applications nécessitant la gestion de certificats côté service (SNI, mutual TLS, etc.).
Limitations :- Ce mode désactive la plupart des fonctionnalités HTTP de l'Ingress (annotations, filtrage, réécriture, etc.).
Pour activer le SSL Pass Through sur un backend, ajoutez l'annotation suivante :
annotations:
ingress.kubernetes.io/secure-backends: "true"Exemple d'Ingress avec SSL Pass Through :
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app-ssl-passthrough
annotations:
ingress.kubernetes.io/secure-backends: "true"
spec:
ingressClassName: public
rules:
- host: myapp.{{publicVIP}}.nip.io
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: myapp-svc
port:
number: 443Bonnes pratiques et notes d'exploitation
- Privilégiez les annotations pour la configuration fine.
- Utilisez
ingressClassName(publicouprivate) selon le niveau d'exposition souhaité. - Sécurisez vos Ingress (HTTPS, filtrage IP, authentification).
- Documentez chaque
Ingress(labels, annotations, description). - Vérifiez la génération automatique des certificats et leur renouvellement.
- Surveillez les logs et métriques HAProxy pour le diagnostic.
Commandes utiles
# Lister les ingress
kubectl get ingress -A
# Voir les détails d'un ingress
kubectl describe ingress <nom> -n <namespace>
# Voir les annotations d'un ingress
kubectl get ingress <nom> -n <namespace> -o yaml