Introduction
Les certificats Kubernetes sécurisent chaque composant du plan de contrôle et des nœuds worker. Lorsque les certificats expirent ou sont mal configurés, le cluster peut devenir partiellement ou totalement indisponible. Cet article explique les concepts avancés de certificats avec des commandes concrètes, des sorties attendues et des étapes de récupération. Vous apprendrez à inspecter les certificats, approuver et signer des demandes de signature de certificat (CSR, Certificate Signing Request), configurer la rotation des certificats clients kubelet, mettre en place le TLS mutuel (mTLS) pour les charges de travail et dépanner les échecs courants. L'accent est mis sur la sécurité opérationnelle : observer avant de changer, limiter le rayon d'impact et vérifier chaque étape.
Ce guide s'adresse aux développeurs, ingénieurs DevOps et équipes techniques de startups exécutant Kubernetes en production ou s'y préparant. Vous devez avoir une familiarité de base avec kubectl et l'architecture du cluster. Tous les exemples utilisent Kubernetes v1.28 et OpenSSL 3.x, mais les concepts s'appliquent aux versions récentes.
Inventaire de la version et de l'environnement
Avant de toucher aux certificats, rassemblez la version exacte du cluster, les emplacements des certificats et les dates d'expiration. Cet inventaire en lecture seule évite les modifications accidentelles et vous donne une base de référence pour la récupération.
Exécutez les commandes suivantes et enregistrez la sortie :
kubectl version --short
# Client Version: v1.28.2
# Server Version: v1.28.2
Listez tous les certificats utilisés par le plan de contrôle sur un cluster kubeadm (chemins par défaut) :
sudo ls -l /etc/kubernetes/pki/
# ca.crt, ca.key, apiserver.crt, apiserver.key, etc.
Vérifiez l'expiration du certificat du serveur API :
sudo openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -dates
# notBefore=Jan 1 00:00:00 2024 GMT
# notAfter=Jan 1 00:00:00 2025 GMT
Pour les certificats clients kubelet sur un nœud worker, inspectez la configuration du kubelet :
sudo cat /var/lib/kubelet/config.yaml | grep clientCAFile
# clientCAFile: /etc/kubernetes/pki/ca.crt
Le certificat de service du kubelet est souvent auto-généré et stocké dans /var/lib/kubelet/pki/. Vérifiez son expiration et son sujet :
sudo openssl x509 -in /var/lib/kubelet/pki/kubelet-server-current.pem -noout -subject -dates
# subject=O = system:nodes, CN = system:node:worker-1
# notBefore=... notAfter=...
Enregistrez les numéros de série et empreintes des certificats actuels pour comparaison ultérieure :
sudo openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -serial -fingerprint -sha256
Chemin de configuration sûr
Les modifications de certificats peuvent vous bloquer hors du cluster. Travaillez toujours d'abord sur un cluster de test, sauvegardez le répertoire PKI existant et suivez une approche de changement minimal.
Sauvegarde des certificats
Sur chaque nœud du plan de contrôle, créez une sauvegarde horodatée de /etc/kubernetes/pki/ :
sudo tar -czf /backup/kubernetes-pki-$(date +%Y%m%d%H%M%S).tar.gz -C /etc/kubernetes pki
Pour les certificats kubelet sur les workers, sauvegardez /var/lib/kubelet/pki/ de manière similaire.
Renouvellement d'un certificat du plan de contrôle avec kubeadm
Kubeadm fournit une commande de renouvellement sûre. D'abord, vérifiez quels certificats arrivent à expiration :
sudo kubeadm certs check-expiration
# [apiserver] Certificate will expire on 2025-01-01
# [apiserver-etcd-client] Certificate will expire on 2025-01-01
# etc.
Renouvelez tous les certificats à la fois (sur chaque nœud du plan de contrôle) :
sudo kubeadm certs renew all
Redémarrez les composants du plan de contrôle pour prendre en compte les nouveaux certificats :
sudo systemctl restart kubelet
# Attendez quelques secondes, puis vérifiez que le serveur API répond
kubectl get nodes
Si vous devez renouveler uniquement le certificat du serveur API :
sudo kubeadm certs renew apiserver
Après le renouvellement, vérifiez la nouvelle date d'expiration :
sudo openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -dates
Configuration de la rotation des certificats clients kubelet
Le kubelet peut demander automatiquement de nouveaux certificats clients à l'approche de leur expiration. Activez la rotation dans le fichier de configuration du kubelet /var/lib/kubelet/config.yaml :
rotateCertificates: true
serverTLSBootstrap: true
Puis redémarrez le kubelet :
sudo systemctl restart kubelet
Pour approuver automatiquement la CSR en attente, vous pouvez configurer le gestionnaire de contrôleurs avec --cluster-signing-duration=8760h (1 an) et mettre en place un approbateur. Pour une approbation manuelle, voir la section suivante.
Vérification et diagnostics
Après tout changement de certificat, vérifiez que tous les composants sont sains et que les certificats sont valides.
Vérification de l'expiration des certificats dans le cluster
Utilisez kubeadm certs check-expiration sur les nœuds du plan de contrôle, et pour les certificats de service kubelet, inspectez-les sur chaque worker. Une approche plus automatisée consiste à utiliser un outil comme kube-cert-manager (obsolète) ou un système de surveillance avec un exportateur de certificats. Pour une vérification rapide de tous les certificats maîtres :
sudo kubeadm certs check-expiration
# Sortie attendue : liste des certificats avec dates d'expiration
Vérification de la connectivité du serveur API
Depuis un poste de travail avec kubectl, exécutez :
kubectl get --raw='/healthz?verbose'
# [ok]etcd ok
# [ok]poststarthook/start-kube-apiserver-admission-initializer ok
# ...
Si le certificat du serveur API est invalide, vous pouvez voir x509: certificate has expired or is not yet valid. Vérifiez les journaux du serveur API :
sudo journalctl -u kube-apiserver -n 50 --no-pager | grep -i certificate
Diagnostic des problèmes d'approbation de CSR
Lorsqu'un nœud ou un utilisateur demande un certificat, un objet CertificateSigningRequest est créé. Listez les CSR en attente :
kubectl get csr
# NAME AGE SIGNERNAME REQUESTOR CONDITION
# node-csr- 10s kubernetes.io/kube-apiserver-client-kubelet system:node:worker-1 Pending
Inspectez les détails de la CSR :
kubectl describe csr node-csr-xxxx
# Events: ...
Approuvez la CSR après avoir vérifié le demandeur et l'utilisation :
kubectl certificate approve node-csr-xxxx
Si la CSR est refusée, vérifiez le nom du signataire et le demandeur. Les erreurs courantes incluent des permissions RBAC manquantes pour le jeton de bootstrap du nœud ou un nom de signataire incorrect.
Modes de défaillance et récupération
Les certificats échouent silencieusement jusqu'à leur expiration. Voici des scénarios d'échec courants et les étapes de récupération exactes.
Certificat du serveur API expiré
Symptômes : les commandes kubectl échouent avec Unable to connect to the server: x509: certificate has expired.
Récupération :
- Sur un nœud du plan de contrôle, confirmez l'expiration :
sudo openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -dates
- Renouvelez le certificat :
sudo kubeadm certs renew apiserver
- Redémarrez le kubelet pour déclencher le redémarrage du pod statique :
sudo systemctl restart kubelet
- Vérifiez la connectivité :
kubectl get nodes
Certificat client kubelet non renouvelé
Symptômes : les journaux du kubelet montrent Failed to rotate client certificate et peuvent cesser de publier le statut.
Vérifiez les paramètres de rotation :
sudo grep -E 'rotateCertificates|serverTLSBootstrap' /var/lib/kubelet/config.yaml
Si rotateCertificates: false, définissez-le sur true, redémarrez le kubelet, puis vérifiez la présence d'une nouvelle CSR :
kubectl get csr | grep node-csr
Approuvez la CSR manuellement si aucun approbateur automatique n'est configuré :
kubectl certificate approve <csr-name>
Vérifiez que le kubelet a un nouveau certificat client :
sudo openssl x509 -in /var/lib/kubelet/pki/kubelet-client-current.pem -noout -dates
Échec de configuration mTLS pour une charge de travail
Si un pod ne parvient pas à se connecter à un service exigeant le mTLS, vérifiez les certificats montés dans le pod. Par exemple, une application attend /etc/tls/tls.crt et /etc/tls/tls.key :
kubectl exec -it <pod-name> -- ls -l /etc/tls/
# tls.crt, tls.key
kubectl exec -it <pod-name> -- openssl x509 -in /etc/tls/tls.crt -noout -subject -dates
Si le certificat est pour le mauvais nom d'hôte, la connexion échouera. Assurez-vous que les SAN du certificat incluent le nom DNS du service. Vous pouvez vérifier les SAN avec :
openssl x509 -in tls.crt -noout -ext subjectAltName
Mise en œuvre du mTLS pour une charge de travail
Le TLS mutuel (mTLS) vérifie à la fois les identités du client et du serveur. Dans Kubernetes, cela implique souvent de créer une CA, d'émettre des certificats client et serveur, et de configurer l'application pour les présenter.
Création d'une CA privée et émission de certificats avec OpenSSL
- Générez une clé de CA et un certificat auto-signé :
openssl genrsa -out ca.key 2048
openssl req -x509 -new -nodes -key ca.key -sha256 -days 365 -out ca.crt -subj "/CN=my-ca"
- Générez une clé de serveur et une demande de signature de certificat (CSR) avec des SAN pour le nom DNS du service :
openssl genrsa -out server.key 2048
openssl req -new -key server.key -out server.csr -subj "/CN=my-service.default.svc" -config <(cat <<EOF
[req]
distinguished_name=dn
[dn]
[SAN]
subjectAltName=DNS:my-service.default.svc,DNS:my-service.default.svc.cluster.local
EOF
)
Remarque : la syntaxe exacte peut varier ; utilisez un fichier de configuration openssl approprié pour la production. Signez le certificat du serveur :
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 365 -sha256 -extensions SAN -extfile <(echo "subjectAltName=DNS:my-service.default.svc,DNS:my-service.default.svc.cluster.local")
- Générez un certificat client de manière similaire, avec un CN représentant l'identité du client (par exemple,
my-client).
Stockage des certificats dans des Secrets Kubernetes
Créez un Secret contenant le certificat et la clé du serveur :
kubectl create secret tls my-service-tls --cert=server.crt --key=server.key
Pour le certificat de CA auquel les clients doivent faire confiance :
kubectl create secret generic my-ca --from-file=ca.crt
Montez le secret dans la spécification de votre pod :
volumes:
- name: tls
secret:
secretName: my-service-tls
- name: ca
secret:
secretName: my-ca
containers:
- name: app
volumeMounts:
- name: tls
mountPath: "/etc/tls"
readOnly: true
- name: ca
mountPath: "/etc/ca"
readOnly: true
Configurez votre application pour utiliser le certificat serveur et exiger des certificats clients signés par votre CA.
Plongée dans l'API de demande de signature de certificat (CSR)
L'API CSR de Kubernetes permet aux utilisateurs et aux charges de travail de demander des certificats signés par la CA du cluster. Comprendre le flux aide au dépannage et à l'automatisation.
Cycle de vie d'une CSR
- Un client génère une clé et une CSR.
- Le client soumet un objet
CertificateSigningRequestà l'API Kubernetes. - Un administrateur ou un contrôleur approuve la CSR.
- Le gestionnaire de contrôleurs signe la CSR en utilisant la CA configurée.
- Le certificat signé est récupéré via le champ
status.certificatede la CSR.
Inspection d'un objet CSR
Obtenez toutes les CSR :
kubectl get csr
Affichez le YAML de la CSR :
kubectl get csr <name> -o yaml
Champs importants :
spec.request: CSR encodée en base64.spec.signerName: par exemple,kubernetes.io/kube-apiserver-client.spec.usages: par exemple,client auth.status.conditions: afficheApproved,DeniedouFailed.
Approuvez ou refusez avec :
kubectl certificate approve <name>
kubectl certificate deny <name>
Pour récupérer le certificat signé :
kubectl get csr <name> -o jsonpath='{.status.certificate}' | base64 -d > client.crt
Signataires CSR courants
kubernetes.io/kube-apiserver-client: pour les certificats clients des utilisateurs.kubernetes.io/kube-apiserver-client-kubelet: pour les certificats clients kubelet.kubernetes.io/kubelet-serving: pour les certificats de service kubelet.
Assurez-vous que le gestionnaire de contrôleurs de votre cluster a les drapeaux de signataire appropriés :
--cluster-signing-cert-file=/etc/kubernetes/pki/ca.crt
--cluster-signing-key-file=/etc/kubernetes/pki/ca.key
Stratégies de rotation des certificats
Au-delà de kubeadm, vous devrez peut-être planifier la rotation des certificats de la CA. La rotation de la CA du cluster est perturbatrice et nécessite une orchestration minutieuse.
Rotation de la CA avec kubeadm (manuelle)
Kubeadm ne prend pas en charge la rotation automatique de la CA. Pour faire tourner la CA, vous devez :
- Générer une nouvelle CA.
- Réémettre tous les certificats des composants.
- Distribuer la nouvelle CA à tous les nœuds.
- Redémarrer tous les composants.
C'est une opération à haut risque. Testez toujours sur un cluster non productif et ayez un plan de retour en arrière. Certains outils comme kubeadm certs renew peuvent aider avec les certificats des composants, mais pas avec la CA elle-même.
Rotation des certificats de service kubelet
Les certificats de service kubelet sont utilisés pour le point de terminaison HTTPS du kubelet (port 10250). Ils peuvent être renouvelés automatiquement si le kubelet est démarré avec serverTLSBootstrap: true et que les CSR sont approuvées. Le kubelet demande un nouveau certificat de service lorsque le certificat actuel approche de l'expiration.
Surveillez les CSR en attente pour garantir que la rotation a lieu :
kubectl get csr -o go-template='{{range .items}}{{.metadata.name}} {{.spec.signerName}} {{range .status.conditions}}{{.type}}={{.reason}}{{end}}{{"\n"}}{{end}}'
Liste de contrôle opérationnelle
Utilisez cette liste pour assurer l'hygiène des certificats et la sécurité opérationnelle.
Vérifications quotidiennes/hebdomadaires
- Exécutez
kubeadm certs check-expirationsur tous les nœuds du plan de contrôle. Si un certificat expire dans les 30 jours, planifiez le renouvellement. - Vérifiez les CSR en attente qui peuvent indiquer des problèmes de bootstrap de nœud :
kubectl get csr | grep Pending. - Vérifiez les certificats clients kubelet sur les nœuds worker :
sudo openssl x509 -in /var/lib/kubelet/pki/kubelet-client-current.pem -noout -dates. - Surveillez les journaux du serveur API pour les erreurs de certificat :
sudo journalctl -u kube-apiserver --since "1 hour ago" | grep -i certificate.
Liste de contrôle avant renouvellement
- Sauvegardez le répertoire PKI.
- Documentez les numéros de série et empreintes des certificats actuels.
- Identifiez tous les composants affectés par le renouvellement.
- Planifiez une fenêtre de maintenance si un temps d'arrêt est prévu.
Vérification après renouvellement
- Exécutez
kubectl get nodesetkubectl get pods -n kube-systempour confirmer la santé du cluster. - Vérifiez les dates des certificats avec
openssl x509 -noout -dates. - Vérifiez l'état de rotation du kubelet en cherchant de nouvelles CSR et les conditions approuvées.
- Testez l'accès externe au serveur API si vous utilisez un équilibreur de charge.
Conclusion
Les certificats Kubernetes sont fondamentaux pour la sécurité et la disponibilité du cluster. En suivant les procédures d'inventaire, de configuration sûre, de vérification et de récupération de cet article, vous pouvez gérer les certificats en toute confiance. Observez toujours avant de changer, sauvegardez les fichiers critiques et vérifiez chaque étape avec des commandes concrètes. Commencez par des vérifications à faible risque comme la liste des dates d'expiration des certificats et la surveillance des CSR, puis passez à des renouvellements et rotations contrôlés. Une approche disciplinée de la gestion des certificats évite les pannes et maintient votre cluster sécurisé.