Cette série est également disponible en anglais.
Read in English
Chapitre 6
Home LabTutorialsDevOps & Infrastructure

Comment exposer un cluster Kubernetes maison sur internet avec DDNS et HTTPS

15 min de lecture
Comment exposer un cluster Kubernetes maison sur internet avec DDNS et HTTPS
Apprenez à exposer votre cluster Kubernetes domestique sur l'Internet public. Ce guide couvre la configuration du DNS dynamique, la redirection de port du routeur et le HTTPS automatique avec cert-manager.

Dans le chapitre précédent, nous avons déployé une petite application localement sur Kubernetes. Elle fonctionnait à l'intérieur du réseau domestique, mais n'est pas encore accessible depuis l'Internet public.

Pour y parvenir, nous avons besoin de plusieurs éléments :

  • un nom de domaine, par exemple : my-website.com ;
  • des enregistrements DNS pointant ce domaine vers notre adresse IP publique ;
  • le DNS dynamique (Dynamic DNS), car une adresse IP publique domestique peut changer avec le temps ;
  • la redirection de port (Port Forwarding) sur le routeur, pour que le trafic Internet atteigne le Raspberry Pi ;
  • des règles d'Ingress (Ingress Rules) Kubernetes, pour que Traefik sache quelle application doit recevoir quel nom d'hôte ;
  • des certificats HTTPS, pour que le site web soit servi de manière sécurisée.

Ne vous inquiétez pas si cela semble beaucoup ; la plupart de ces étapes sont relativement simples à réaliser et je vais tout vous expliquer dans cet article.

Étape 1 : Obtenir un nom de domaine

Pour rendre un site web accessible de n'importe où dans le monde, nous avons besoin d'un nom de domaine. Par exemple, ce blog utilise thethoughtprocess.xyz.

Un nom de domaine est le nom convivial que les gens tapent dans leur navigateur. Sans lui, ils devraient utiliser directement votre adresse IP publique, ce qui n'est pas pratique et peut changer avec le temps. De plus, avec Kubernetes, ce n'est même pas possible car l'ingress attend un nom de domaine.

Vous pouvez acheter un nom de domaine auprès de nombreux bureaux d'enregistrement (registrars), comme Cloudflare, OVH, Namecheap ou GoDaddy. Personnellement, j'aime Cloudflare car leur interface DNS Cloudflare est claire et ils fournissent de nombreuses fonctionnalités utiles gratuitement pour les petits sites web.

Dans Cloudflare, après avoir crée un compte, vous pouvez aller dans Domaines -> Enregistrements :

Enregistrement de domaine Cloudflare

Ensuite, recherchez le domaine que vous souhaitez.

Sachez que les prix peuvent varier considérablement en fonction de l'extension de domaine. Un domaine en .com, .be, .io ou .dev peut avoir des prix très différents. Certains domaines sont bon marché la première année mais plus chers au renouvellement, alors vérifiez toujours le prix de renouvellement également.

Étape 2 : Créer des enregistrements DNS

Une fois que vous possédez un domaine, vous devez indiquer à Internet vers quel serveur il doit pointer. C'est le rôle du DNS.

Le DNS est comme l'annuaire téléphonique d'Internet. Quand quelqu'un tape www.my-website.com dans son navigateur web, son ordinateur demande aux serveurs DNS : "Quelle adresse IP correspond à ce nom d'hôte ?" La réponse est généralement une adresse IPv4. Par exemple : 90.50.77.122.

Cela signifie que lorsqu'un navigateur veut visiter www.my-website.com, il se connecte au serveur à l'adresse 90.50.77.122.

Pour trouver votre adresse IPv4 publique actuelle depuis le Raspberry Pi, vous pouvez exécuter :

curl -4 ifconfig.me

Ensuite, dans Cloudflare, allez sur votre domaine et ouvrez la page DNS et puis Records.

Enregistrements DNS

Cliquez sur "Ajouter un enregistrement" et créez un enregistrement de type A comme ceci (Le type A indique une règle liant un domaine à une IPv4 ) :

Type: A
Name: www
IPv4 address: votre-ip-publique
Proxy status: Yes
TTL: Auto

Si vous voulez que le domaine racine fonctionne également, par exemple my-website.com sans www, ajoutez un autre enregistrement A :

Type: A
Name: @
IPv4 address: votre-ip-publique
Proxy status: DNS only
TTL: Auto

TTL signifie Time To Live. Il indique aux navigateurs et aux résolveurs DNS combien de temps ils peuvent mettre cet enregistrement DNS en cache avant de redemander l’information à Cloudflare. C’est important, car votre adresse IP publique peut changer par la suite comme nous allons le voir.

Proxy status activé signifie que les requêtes passent par Cloudflare avant d’atteindre votre serveur. C’est utile, car Cloudflare peut fournir HTTPS, du cache et une protection contre une partie du trafic malveillant avant qu’il n’atteigne votre réseau domestique.

À ce stade, le DNS sait où votre domaine doit pointer. Cependant, il reste un problème : sur la plupart des connexions Internet domestiques, votre adresse IP publique n'est pas garantie de rester la même.

Nous avons donc besoin d'un DNS dynamique.

Étape 3 : Configurer le DNS dynamique

La plupart des connexions Internet domestiques n'ont pas d'adresse IP publique fixe. Votre fournisseur d'accès à Internet (FAI) peut la changer à tout moment.

Cela crée un problème car les utilisateurs accèdent à votre site via www.my-website.com et le DNS fait pointer ce nom d'hôte vers votre IP publique actuelle. Cependant, si votre FAI change votre adresse IP, l'enregistrement DNS devient obsolète, les visiteurs sont envoyés à la mauvaise adresse et obtiendront une erreur.

Le DNS dynamique résout ce problème en mettant à jour automatiquement l'enregistrement DNS chaque fois que votre IP publique change. Pour cela, nous utiliserons ddclient. Son job est de vérifier régulièrement votre adresse IP publique actuelle et mettre à jour votre fournisseur DNS si l'IP a changé.

Vous pouvez exécuter ddclient dans Kubernetes, mais je préfère le faire directement sur le Raspberry Pi. Le DNS dynamique fait partie de la couche réseau de base du serveur. Il doit continuer à fonctionner même si Kubernetes est en cours de mise à jour, de redémarrage ou mal configuré.

Créer un jeton d'API Cloudflare

Avant d’installer ddclient, nous devons créer un token d’API Cloudflare. En effet, il nous faudra contacter Cloudflare pour mettre à jour les enregistrements DNS, il nous faut donc les permissions nécessaires pour le faire.

Dans Cloudflare :

  1. Allez dans Gérer le compte -> Jetons d'API.
  2. Cliquez sur Créer un jeton.
  3. Recherchez le modèle "Modifier la zone DNS".
  4. Vous pouvez limitez le jeton au domaine spécifique que vous souhaitez mettre à jour.
  5. Créez le jeton.
  6. Copiez-le immédiatement, car Cloudflare ne l'affiche qu'une seule fois.

Jeton d'API Cloudflare

Installer ddclient sur le Raspberry Pi

Nous pouvons désormais installer ddclient avec :

sudo apt update
sudo apt install ddclient

Ensuite, modifiez le fichier de configuration :

sudo nano /etc/ddclient.conf

Voici un exemple de configuration pour Cloudflare :

daemon=300
syslog=yes
ssl=yes
use=web, web=ipify-ipv4
 
protocol=cloudflare
zone=my-website.com
ttl=1
login=token
password=VOTRE_JETON_API_CLOUDFLARE
www.my-website.com
my-website.com

Laissez-moi vous expliquer :

  • daemon=300 signifie que ddclient vérifie votre IP publique toutes les 300 secondes.
  • ssl=yes signifie que ddclient communique avec Cloudflare via HTTPS.
  • protocol=cloudflare informe évidemment ddclient que le serveur DNS en amont est Cloudflare, mais vous pourriez utiliser un autre registrar s'il autorise le DNS dynamique.
  • login=token doit être littéralement le mot token pour Cloudflare ; cela pourrait changer si vous utilisez autre chose.
  • password= contient votre jeton d'API Cloudflare.
  • Les dernières lignes sont les noms d'hôtes que ddclient doit mettre à jour.

Après avoir sauvegardé ce fichier de configuration, redémarrez ddclient :

sudo systemctl restart ddclient

Et puis, vérifiez son statut :

sudo systemctl status ddclient

Vous pouvez aussi l'exécuter manuellement en mode débogage :

sudo ddclient -daemon=0 -debug -verbose -noquiet

A la fin, vous devriez avoir une réponse comme ceci :

SUCCESS:  thethoughtprocess.xyz: skipped: IP address was already set to x.x.x.x

Si tout fonctionne, Cloudflare recevra désormais automatiquement votre nouvelle IP publique chaque fois qu'elle changera.

Étape 4 : Rediriger les ports 80 et 443 sur votre routeur

Même si le DNS est correct, le trafic Internet atteint d'abord votre routeur. Votre routeur doit alors savoir où envoyer ce trafic à l'intérieur de votre réseau local. C'est ce qu'on appelle la redirection de port (port forwarding).

Pour un site web public, nous avons besoin de deux ports :

  • Port 80 pour http
  • Port 443 pour https

Dans l'interface de votre routeur, cherchez une page appelée "Redirection de port", "Ouverture de port" ou "Règles NAT" :

Redirection de port sur le routeur

Créez deux règles pointant vers l'adresse IP locale de votre Raspberry Pi sur le protocole TCP, une pour le port 80 et une pour le port 443. On vous demandera le port local et le port public ; dans notre configuration, ils doivent être identiques. Cela signifie que :

  • le trafic arrivant d'Internet sur le port 80 est dirigé vers le port 80 du Raspberry Pi
  • le trafic arrivant d'Internet sur le port 443 est dirigé vers le port 443 du Raspberry Pi

Avant de faire cela, assurez-vous que votre Raspberry Pi a une adresse IP locale statique. Sinon, votre routeur pourrait lui attribuer une IP différente plus tard, et la règle de redirection de port cesserait de fonctionner. Si vous ne l'avez pas encore configuré, vous pouvez revenir au Chapitre 3 où nous avons configuré une adresse IP statique pour Pi-Hole.

À ce stade, si vous ouvrez votre domaine dans un navigateur, vous pourriez obtenir une erreur ou une réponse 404. C'est une bonne nouvelle. Cela signifie que le trafic atteint votre cluster, mais Kubernetes ne sait pas quoi servir. On y est presque.

Le chemin de la requête ressemble maintenant à ceci :

Diagramme du chemin réseau

Étape 5 : Configurer HTTPS avec cert-manager et Let's Encrypt

Avant de déployer l'application correctement, nous devrions la sécuriser avec HTTPS. Cela nous apporte deux choses importantes :

  • chiffrement : personnes entre l'utilisateur et votre serveur ne peuvent pas lire le trafic
  • authentification : le navigateur peut vérifier que le serveur est autorisé à servir ce domaine

Avec HTTPS, votre site web présente un certificat TLS au navigateur. Le navigateur vérifie ce certificat pour prouver que votre serveur est le véritable propriétaire du domaine, puis crée une connexion chiffrée.

Pour cette configuration, nous utiliserons :

  • Let's Encrypt : une autorité de certification à but non lucratif qui délivre des certificats TLS gratuits
  • cert-manager : un contrôleur Kubernetes qui demande, stocke et renouvelle les certificats automatiquement

Étape 5.1 : Comment installer cert-manager

Le rôle de cert-manager est de :

  • demander un certificat à Let's Encrypt
  • stocker le certificat dans Kubernetes sous forme de Secret
  • renouveler le certificat automatiquement avant son expiration
  • permettre à l'ingress d'utiliser ce certificat pour le trafic HTTPS

Installation de Helm

Nous installerons cert-manager en utilisant Helm; un gestionnaire de paquets pour Kubernetes. C'est un peu comme apt ou pip, mais pour les applications Kubernetes.

Installer Helm sur Linux :

curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash

Installer Helm sur Windows :

winget install Helm.Helm

Ensuite mettez Helm à jour :

helm repo add jetstack https://charts.jetstack.io
helm repo update

Installation de cert-manager

Installez cert-manager :

helm install cert-manager jetstack/cert-manager \
  --namespace cert-manager \
  --create-namespace \
  --set crds.enabled=true

Vérifiez que les pods sont en cours d'exécution :

kubectl get pods -n cert-manager

Vous devriez voir 3 pods qui tourne pour cert-manager:

  • Le pod principal cert-manager gère la création et le renouvellement des certificats.
  • Le pod webhook valide les ressources de cert-manager lorsque vous les appliquez.
  • Le pod cainjector met à jour Kubernetes avec le certificat nécessaire pour pouvoir confiance au webhook de cert-manager. Ensemble, ils permettent à Kubernetes de demander, valider, stocker et renouveler les certificats TLS automatiquement en toute sécurité.

Création d'un ClusterIssuer

À ce stade, cert-manager ne sait toujours pas à qui demander des certificats. Nous devons donc créer un ClusterIssuer. C'est un petit fichier de configuration que nous allons charger dans Kubernetes.

Créez un fichier nommé letsencrypt.yaml :

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    email: [email protected]
    server: https://acme-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      name: letsencrypt-account-key
    solvers:
      - http01:
          ingress:
            class: traefik

Les parties importantes à comprendre sont :

  • kind: ClusterIssuer indique un type de ressource Kubernetes utilisé par cert-manager.
  • metadata.name: letsencrypt-prod est le nom que nous référencerons plus tard depuis notre Ingress.
  • email est utilisé par Let’s Encrypt pour identifier votre compte et envoyer des notifications importantes.
  • server pointe vers l’API de production de Let’s Encrypt, utilisée par cert-manager pour demander des certificats.
  • privateKeySecretRef indique à cert-manager où stocker la clé privée de votre compte Let’s Encrypt.
  • solvers.http01 signifie que nous utilisons le challenge HTTP-01. J’expliquerai cela plus tard.
  • ingress.class: traefik indique à cert-manager de créer la route temporaire de validation via Traefik, l’ingress controller utilisé par k3s.

Appliquez-le avec:

kubectl apply -f letsencrypt.yaml

Vérifiez-le :

kubectl get clusterissuer
kubectl describe clusterissuer letsencrypt-prod

Un ClusterIssuer est une ressource Kubernetes utilisée par cert-manager. cert-manager surveille cette ressource et l'utilise lorsqu'un Ingress demande un certificat.

Comment Kubernetes est-il au courant des clusterissuer? Lorsque nous avons installé cert-manager, nous avons utilisé l'option --set crds.enabled=true. Cela indique à Kubernetes que de nouveaux types de ressources existent, et que les utilisateurs peuvent les créer avec kubectl apply. Cela inclut ClusterIssuer mais aussi Certificate et plus encore.

Comment fonctionne le challenge HTTP-01

Voici un petit détail technique si vous êtes intéressé par le fonctionnement de ce mécanisme.

Let's Encrypt ne donne pas un certificat à quiconque en demande un. Vous devez d'abord prouver que vous contrôlez le domaine. Avec le challenge HTTP-01, Let's Encrypt vérifie une URL temporaire sur votre serveur :

http://votre-domaine.com/.well-known/acme-challenge/...

cert-manager crée ce point d'accès temporaire à l'intérieur du cluster et en informe Let's Encrypt, qui l'appelle ensuite depuis l'Internet public. Si Let's Encrypt reçoit le jeton attendu, le domaine est validé et le certificat peut être délivré. C'est pourquoi le port 80 doit être accessible depuis Internet, même si votre site final n'utilise que HTTPS.

Étape 5.2 : Ajouter HTTPS à l'Ingress

Nous pouvons maintenant créer des certificats, il est temps de configurer l'Ingress de l'application pour des connexions web sécurisées. Si vous avez lu le chapitre précédent sur le déploiement d'une application simple sur Kubernetes, vous devriez avoir une compréhension de base du YAML suivant qui définit l'ingress. Pouvez-vous repérer les différences ?

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: mytlswebsite-ingress
  namespace: mytlswebsite-namespace
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
    traefik.ingress.kubernetes.io/router.entrypoints: websecure
spec:
  rules:
    - host: www.my-website.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: mytlswebsite-service
                port:
                  number: 80
 
    - host: my-website.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: mytlswebsite-service
                port:
                  number: 80
    - host: my-website.home.arpa
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: mytlswebsite-service
                port:
                  number: 80
 
  tls:
    - hosts:
        - www.my-website.com
        - my-website.com
        - my-website.home.arpa
      secretName: mywebsite-tls

Par rapport à l'Ingress local du chapitre précédent, nous avons ajouté quelques éléments importants :

rules:
  - host: www.my-website.com

Cela indique à Kubernetes que cet Ingress s'applique également aux requêtes pour www.my-website.com et comme vous pouvez le voir, nous avons aussi des règles pour my-website.com et my-website.home.arpa.

cert-manager.io/cluster-issuer: letsencrypt-prod

Cela indique à cert-manager de demander un certificat en utilisant le ClusterIssuer letsencrypt-prod lorsque nous appliquons ce yaml d'ingress.

traefik.ingress.kubernetes.io/router.entrypoints: websecure

Cela indique à Traefik d'exposer cette route sur le point d'entrée HTTPS, c'est-à-dire le port 443.

  tls:
    - hosts:
        - www.my-website.com
        - my-website.com
      secretName: mywebsite-tls

Cela indique à Kubernetes que ces noms d'hôtes doivent utiliser TLS et que le certificat doit être stocké dans un Secret appelé mywebsite-tls. Vous ne créez pas ce Secret manuellement. cert-manager le crée automatiquement après la délivrance du certificat.

Si vous avez suivi l'article précédent sur le déploiement d'une application simple, vous pouvez alors appliquer l'Ingress :

kubectl apply -f ingress.yaml

Vous pouvez télécharger le code complete ici avec ce nouvel ingress : https://github.com/Local-pie/simple-tls-app

Étape 5.3 : Vérifier le certificat

Vérifiez la ressource Certificate :

kubectl get certificate -n mywebsite

Si cela a fonctionné, vous devriez voir quelque chose comme :

NAME            READY   SECRET          AGE
mywebsite-tls   True    mywebsite-tls   2m

Étape 6 : Rediriger HTTP vers HTTPS

À ce stade, HTTPS devrait fonctionner, mais HTTP peut encore être accessible.

Vous voulez généralement que les utilisateurs qui visitent :

http://www.my-website.com

soient redirigés automatiquement vers la version https :

https://www.my-website.com

Avec Traefik dans k3s, une option est de configurer une redirection globale de HTTP vers HTTPS.

Créez :

traefik-https-redirect.yaml

Ajoutez :

apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
  name: traefik
  namespace: kube-system
spec:
  valuesContent: |-
    ports:
      web:
        redirectTo:
          port: websecure

Appliquez-le :

kubectl apply -f traefik-https-redirect.yaml

Vérifiez Traefik :

kubectl rollout status deployment traefik -n kube-system

Ceci applique une redirection HTTP vers HTTPS de manière globale pour Traefik.

Si vous préférez n'appliquer les redirections qu'à des applications spécifiques, vous pouvez utiliser un Middleware Traefik à la place.

Exemple :

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: mytlswebsite-redirect-https
  namespace: mytlswebsite-namespace
spec:
  redirectScheme:
    scheme: https
    permanent: true

Ensuite, attachez-le à l'Ingress en utilisant une annotation Traefik traefik.ingress.kubernetes.io/router.middlewares comme ceci.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: mytlswebsite-ingress
  namespace: mytlswebsite-namespace
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
    traefik.ingress.kubernetes.io/router.entrypoints: websecure
    traefik.ingress.kubernetes.io/router.middlewares: mytlswebsite-namespace-mytlswebsite-redirect-https@kubernetescrd
...

Pour un petit cluster domestique où certains services sont locaux et n'ont pas besoin de https, vous préférerez peut-être utiliser l'approche par middleware.

Étape 7 : Vérifier la configuration complète

Vérifions maintenant toute la chaîne.

Vérifier le DNS

Depuis votre ordinateur :

nslookup www.my-website.com

Cela devrait renvoyer votre adresse IP publique actuelle ou l'IP de Cloudflare si vous avez utilisé le proxy Cloudflare. Vous pouvez désactiver temporairement le proxy si vous voulez voir si la résolution vers votre IP se fait correctement.

Vérifier l'Ingress

kubectl get ingress -A

Vous devriez voir votre nom d'hôte listé.

Vérifier le certificat

kubectl get certificate -n mywebsite

Vous voulez voir :

READY=True

Vérifier le Secret

kubectl get secret mywebsite-tls -n mywebsite

Le Secret doit exister dans le même namespace que l'Ingress.

Vérifier le navigateur

Ouvrez :

https://www.my-website.com

Cliquez sur la petite icône de cadenas à côté de l'URL et inspectez le certificat.

Connexion sécurisée dans le navigateur

Vous devriez voir que :

  • le certificat est valide ;
  • il a été délivré pour votre domaine ;
  • il a été délivré par Let's Encrypt ;
  • la connexion utilise HTTPS.

Ce n'était pas facile, mais nous avons maintenant un site web public HTTPS fonctionnant sur un cluster Kubernetes à la maison !

Nous avons fait beaucoup de choses, voici un résumé :

  • Le nom de domain permet aux utilisateurs d'utiliser une adresse plus compréhensible
  • Le DNS fait pointer le domaine vers votre IP publique
  • Le DNS dynamique maintient l'IP publique à jour
  • La redirection de port envoie le trafic de votre routeur au Raspberry Pi
  • Traefik reçoit le trafic HTTP et HTTPS
  • L'Ingress route les noms d'hôtes vers les bons Services Kubernetes
  • cert-manager automatise les certificats TLS
  • Let's Encrypt valide et signe les certificats

À ce stade, votre cluster Kubernetes domestique n'est plus seulement local. Il peut servir de vrais sites web sur l'Internet public, avec de vrais certificats HTTPS, depuis votre propre Raspberry Pi.

Optionnel : Utiliser l'environnement de staging de Let's Encrypt avant la production

Lorsque nous avons créé le ClusterIssuer, nous avons utilisé cette adresse

server: https://acme-v02.api.letsencrypt.org/directory

C'est une adresse de production qui crée de vrais certificats, mais si vous échouez trop de fois, ils pourraient vous appliquer une limite de taux (rate limit) et vous devrez attendre pour réessayer. Lors du test d'une solution de certificat comme cert-manager, il est conseillé d'utiliser d'abord l'URL de staging :

server: https://acme-staging-v02.api.letsencrypt.org/directory

L'environnement de staging se comporte comme la production sans une limite de taux aussi basse. Cependant, il crée des certificats de test que les navigateurs ne reconnaissent pas comme valides.

C'est utile car vous pouvez vérifier que le DNS, la redirection de port, Traefik, cert-manager et le challenge HTTP-01 fonctionnent tous avant de demander un vrai certificat.

Une fois que le certificat de staging est créé avec succès et que le Certificate affiche READY=True, revenez à l'URL de production :

server: https://acme-v02.api.letsencrypt.org/directory

Puis réappliquez le ClusterIssuer.

Pour une configuration propre, vous pouvez créer deux issuers :

letsencrypt-staging
letsencrypt-prod

Ensuite, créez un Ingress et un namespace séparés pour l’environnement de staging. Vous avez toutes les informations pour le faire désormais.

Problèmes courants

Le certificat reste en attente

Si votre certificat n'est pas prêt, vous devez découvrir pourquoi cert-manager échoue. Exécutez ces commandes pour inspecter le statut :

Tout d'abord, vérifiez le statut du certificat :

kubectl get certificates -n mywebsite

Vous voulez voir READY True. S'il indique False ou reste en attente, creusez plus profondément en décrivant le certificat :

kubectl describe certificate mywebsite-tls -n mywebsite

Regardez la section Events en bas de la sortie. Elle vous dira s'il attend qu'une commande (order) ou un défi (challenge) se termine.

Ensuite, vérifiez s'il y a un défi en attente :

kubectl get challenges -n mywebsite

Si vous voyez un défi, décrivez-le pour voir l'erreur exacte :

kubectl describe challenge -n mywebsite

Regardez les sections Events et Status. Voici ce qu'il faut rechercher :

  • Erreurs de défi ACME : Cela signifie souvent que Let's Encrypt ne peut pas atteindre le point de terminaison temporaire .well-known de votre serveur.
  • Problèmes de résolution de domaine : Assurez-vous que votre domaine pointe vers la bonne adresse IP publique.
  • Connexion refusée ou délais d'attente (timeouts) : Vérifiez que le port 80 est correctement redirigé sur votre routeur et que votre pare-feu ne bloque pas le trafic.

La plupart du temps, la cause est l'une de celles-ci :

  • Le DNS ne pointe pas vers votre IP publique actuelle ;
  • le port 80 n'est pas ouvert ;
  • le routeur ne redirige pas le port 80 vers le Raspberry Pi ;
  • le nom d'hôte de l'Ingress est incorrect ;
  • Traefik ne gère pas l'Ingress ;
  • cert-manager ne peut pas terminer son auto-vérification interne.

L'auto-vérification de cert-manager échoue

La manière dont cert-manager et Let's Encrypt fonctionnent ensemble passe par le challenge HTTP-01. Cela peut causer des problèmes car cert-manager crée un point d'accès HTTP temporaire sous :

http://votre-domaine.com/.well-known/acme-challenge/...

Avant de demander à Let's Encrypt de le valider, cert-manager vérifie d'abord depuis l'intérieur du cluster que cette URL est accessible.

Sur certains réseaux domestiques, cela peut échouer même si le site web fonctionne depuis l'Internet public.

Une raison courante est que le routeur ne prend pas en charge le NAT loopback, aussi appelé hairpin NAT. Cela signifie que les appareils à l'intérieur de votre LAN ne peuvent pas accéder à votre IP publique et être redirigés à l'intérieur du LAN.

Par exemple :

Raspberry Pi -> domaine public -> IP publique -> routeur -> retour au Raspberry Pi

Certains routeurs le supportent. D'autres non. Si vous utilisez Cloudflare avec le proxy activé comme nous l'avons configuré dans cet article, vous ne rencontrerez peut-être pas le problème classique du NAT loopback, car les requêtes internes vers votre domaine passent par Cloudflare au lieu d'aller directement à votre IP publique domestique.

Si vous n'utilisez pas Cloudflare, faites en sorte que le domaine se résolve en interne vers l'adresse IP locale de votre serveur. Si vous utilisez Pi-hole, vous pouvez y ajouter une substitution DNS locale. Par exemple :

www.my-website.com -> 192.168.0.14

Sinon, vous pouvez configurer le serveur DNS interne de k3s appelé CoreDNS. Créez ce fichier coredns-custom.yaml :

apiVersion: v1
kind: ConfigMap
metadata:
  name: coredns-custom
  namespace: kube-system
data:
  mywebsite.override: |
    hosts {
      192.168.0.15 www.my-website.com
      fallthrough
    } 

N'oubliez pas de changer 192.168.0.15 pour votre IP locale et appliquez-le :

kubectl apply -f coredns-custom.yaml
kubectl rollout restart deployment coredns -n kube-system

Vous pouvez tester la résolution DNS depuis l'intérieur de Kubernetes avec :

kubectl run -it --rm dns-test \
  --image=busybox:1.36 \
  --restart=Never \
  -- nslookup www.my-website.com

Si elle renvoie votre IP publique, le cluster utilise la résolution DNS publique.

Si elle renvoie l'IP locale de votre Raspberry Pi, le cluster utilise votre substitution interne.

#kubernetes#home-server#networking#devops
Judicael Poumay (Ph.D.)

Judicael Poumay (Ph.D.)

Suivez-moi sur LinkedIn pour du contenu hebdomadaire Judicaël Poumay

En tant que chercheur/développeur IA indépendant spécialisé en Traitement du Langage Naturel (NLP), j'ai une expertise complète dans le développement et l'intégration de systèmes d'IA, ainsi que l'analyse de données.

Votre entreprise cherche à intégrer des solutions IA, analyser des données ou renforcer son développement back-end ? Contactez-moi !

Offrez-moi une bière 🍺

Articles Similaires