Aller au contenu principal

Exposer un service avec un nom de domaine personnalisé

Votre app tourne sur le cluster Kubernetes France Nuage. Vous voulez qu'elle soit accessible via HTTPS, sur un vrai nom de domaine. Ce tutoriel couvre deux cas : le sous-domaine *.apps.france-nuage.fr (fourni par défaut) et votre propre domaine.

Ce qu'il vous faut

  • Un namespace sur votre cluster Kubernetes France Nuage
  • Un Service Kubernetes qui expose votre app sur le port 80
  • (Optionnel) Un nom de domaine dont vous contrôlez le DNS

Comment ça marche

France Nuage utilise Kingress comme contrôleur Ingress et cert-manager pour les certificats TLS. Vous déclarez un Ingress, cert-manager obtient le certificat Let's Encrypt, Kingress route le trafic. Donc pas de tickets à des ops, pas d'intervention manuelle, bienvenu dans le monde moderne !

Étape 1 : vérifier votre Service

Kingress exige que le backend pointe vers le port 80. Si votre app écoute sur un autre port (3000, 8080, etc.), le Service doit faire la traduction :

apiVersion: v1
kind: Service
metadata:
name: mon-app
spec:
selector:
app: mon-app
ports:
- port: 80 # Kingress exige le port 80 ici
targetPort: 3000 # le port réel de votre app
Port 80 obligatoire

Si le port du Service n'est pas 80, Kingress retourne une erreur 503 sans message explicite. C'est l'erreur la plus fréquente. Votre app peut écouter sur n'importe quel port, mais le Service Kubernetes doit exposer le port 80.

Étape 2 : créer l'Ingress

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: mon-app
annotations:
ingress.kubernetes.io/ssl-redirect: "true"
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
tls:
- hosts:
- mon-app.apps.france-nuage.fr
secretName: mon-app-tls
rules:
- host: mon-app.apps.france-nuage.fr
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: mon-app
port:
number: 80

Trois choses se passent alors automatiquement :

  1. cert-manager lit l'annotation cert-manager.io/cluster-issuer: "letsencrypt-prod" et demande un certificat à Let's Encrypt
  2. Le certificat est stocké dans le Secret mon-app-tls, dans votre namespace Kubernetes
  3. Kingress termine le TLS et route le trafic HTTP vers votre Service

Après l'exécution de kubectl apply, attendez 30 à 90 secondes que le certificat soit émis. Vous pourrez ensuite suivre la progression via la commande :

kubectl get certificate -n mon-namespace

Quand READY passe à True, c'est bon :).

Étape 3 : utiliser votre propre nom de domaine

Vous n'êtes pas limité à *.apps.france-nuage.fr. Pour utiliser app.votre-domaine.com :

1. Configurez votre DNS

Créez un enregistrement CNAME (ou A via un proxy DNS) qui pointe vers :

app.votre-domaine.com  →  zero-trust.france-nuage.fr

2. Mettez à jour l'Ingress

Remplacez le champs host par votre nom de domaine :

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: mon-app
annotations:
ingress.kubernetes.io/ssl-redirect: "true"
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
tls:
- hosts:
- app.votre-domaine.com
secretName: mon-app-tls
rules:
- host: app.votre-domaine.com
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: mon-app
port:
number: 80

cert-manager gère le certificat pour votre domaine de la même façon. Le CNAME vers zero-trust.france-nuage.fr fait arriver le trafic sur l'Ingress du cluster, et Kingress le route grâce au header Host.

Dépannage

Erreur 503 sans message

Votre Service n'expose pas le port 80. Vérifiez avec :

kubectl get svc mon-app -n mon-namespace -o yaml

Le champ ports[0].port doit être 80. Si votre app écoute sur 8080, utilisez targetPort: 8080 avec port: 80.

Le certificat reste "Not Ready"

kubectl describe certificate mon-app-tls -n mon-namespace
kubectl describe certificaterequest -n mon-namespace
kubectl describe order -n mon-namespace

Souvent cela veut dire que le DNS ne pointe pas encore vers le cluster (propagation), ou le host dans l'Ingress ne correspond pas au DNS.

"Connection refused" sur le domaine custom

"Connection refused" signifie que CNAME n'est pas encore propagé, vérifiez la propagation via la commande :

dig app.votre-domaine.com CNAME

La réponse de dig doit contenir zero-trust.france-nuage.fr. La propagation DNS prend de quelques secondes à 48h selon les registrars.

Exemple YAML complet

Voici un exemple de déploiement Kubernetes avec Service et Ingress et l'usage d'un domain personnalisé :

---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mon-app
spec:
replicas: 2
selector:
matchLabels:
app: mon-app
template:
metadata:
labels:
app: mon-app
spec:
containers:
- name: mon-app
image: registry.gitlab.com/mon-org/mon-app:latest
ports:
- containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
name: mon-app
spec:
selector:
app: mon-app
ports:
- port: 80
targetPort: 3000
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: mon-app
annotations:
ingress.kubernetes.io/ssl-redirect: "true"
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
tls:
- hosts:
- app.votre-domaine.com
secretName: mon-app-tls
rules:
- host: app.votre-domaine.com
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: mon-app
port:
number: 80

Pour aller plus loin