Introduction
Les certificats sont la pierre angulaire de la confiance dans Kubernetes. Ils authentifient les utilisateurs, les comptes de service et les composants du plan de contrôle, et ils chiffrent les communications entre le serveur API, le kubelet, etcd et les autres services critiques. Un certificat mal configuré ou expiré peut immobiliser votre cluster ou, pire, l'exposer à des attaques de type homme du milieu. Pourtant, de nombreux opérateurs traitent les certificats comme une configuration à définir une fois pour toutes.
Ce guide s'adresse aux développeurs, consultants DevOps et équipes techniques de startups qui ont besoin de renforcer la sécurité des certificats Kubernetes avec des étapes pratiques et vérifiables. Nous relierons le durcissement des certificats Kubernetes, le contrôle d'accès, la gestion des secrets et les permissions à des commandes concrètes, des sorties attendues, des signaux de défaillance et des décisions de récupération.
L'objectif opérationnel est la sécurité : observer avant de modifier, limiter le rayon d'impact, utiliser des variables fictives plutôt que des secrets, vérifier le résultat et documenter comment récupérer si l'état attendu n'est pas atteint. Chaque étape suppose un cluster Kubernetes en cours d'exécution (version 1.20+ recommandée) avec kubectl configuré et, pour certaines tâches, kubeadm disponible. Nous nous concentrons sur les clusters autogérés, mais les principes s'appliquent également aux offres managées.
Inventaire de la version et de l'environnement
Avant de toucher à un certificat, vous devez connaître votre environnement. Inventoriez la version de Kubernetes, les autorités de certification (CA) utilisées et l'emplacement des certificats.
Identifier la version du cluster et les emplacements des certificats
Exécutez :
kubectl version --short
Sortie attendue (exemple pour v1.27) :
Client Version: v1.27.3
Server Version: v1.27.3
Si votre cluster a été configuré avec kubeadm, les certificats sont stockés dans /etc/kubernetes/pki sur les nœuds du plan de contrôle. Listez-les :
sudo ls -la /etc/kubernetes/pki
Vous devriez voir des fichiers comme ca.crt, ca.key, apiserver.crt, apiserver.key, front-proxy-ca.crt, etcd/ca.crt, etc.
Vérifiez l'expiration des certificats avec kubeadm :
sudo kubeadm certs check-expiration
Exemple de sortie :
[check-expiration] Reading configuration from the cluster...
[check-expiration] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
CERTIFICATE EXPIRES RESIDUAL TIME CERTIFICATE AUTHORITY EXTERNALLY MANAGED
admin.conf Oct 05, 2024 13:02 UTC 364d ca no
apiserver Oct 05, 2024 13:02 UTC 364d ca no
apiserver-etcd-client Oct 05, 2024 13:02 UTC 364d etcd-ca no
apiserver-kubelet-client Oct 05, 2024 13:02 UTC 364d ca no
controller-manager.conf Oct 05, 2024 13:02 UTC 364d ca no
etcd-healthcheck-client Oct 05, 2024 13:02 UTC 364d etcd-ca no
etcd-peer Oct 05, 2024 13:02 UTC 364d etcd-ca no
etcd-server Oct 05, 2024 13:02 UTC 364d etcd-ca no
front-proxy-client Oct 05, 2024 13:02 UTC 364d front-proxy-ca no
scheduler.conf Oct 05, 2024 13:02 UTC 364d ca no
CERTIFICATE AUTHORITY EXPIRES RESIDUAL TIME EXTERNALLY MANAGED
ca Oct 03, 2033 13:02 UTC 9y no
etcd-ca Oct 03, 2033 13:02 UTC 9y no
front-proxy-ca Oct 03, 2033 13:02 UTC 9y no
Pour les clusters non créés avec kubeadm, inspectez le pod du serveur API ou le manifeste du pod statique pour trouver les chemins des certificats. Par exemple, sur un nœud du plan de contrôle, examinez /etc/kubernetes/manifests/kube-apiserver.yaml et notez les drapeaux --tls-cert-file et --tls-private-key-file.
Vérifier les détails des certificats avec OpenSSL
Pour voir le sujet, l'émetteur et la validité d'un fichier de certificat, utilisez :
sudo openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -subject -issuer -dates
Exemple de sortie :
subject=CN=kube-apiserver
issuer=CN=kubernetes
notBefore=Oct 5 13:02:00 2023 GMT
notAfter=Oct 5 13:02:00 2024 GMT
Auditer les secrets Kubernetes liés aux certificats
Kubernetes stocke certains certificats dans des secrets, comme le certificat de signature des jetons de compte de service. Vérifiez les secrets suspects ou inattendus dans kube-system :
kubectl get secrets -n kube-system
Recherchez des noms comme bootstrap-token-, default-token- ou tout secret TLS personnalisé. Inspectez les métadonnées d'un secret spécifique (sans révéler les données) avec :
kubectl describe secret <secret-name> -n kube-system
Remplacez <secret-name> par un nom réel de la liste (par exemple, default-token-abcde).
Chemin de configuration sûr
Maintenant que vous avez un inventaire, vous pouvez effectuer des modifications de configuration en toute sécurité. Le chemin le plus sûr est de s'appuyer sur les mécanismes intégrés de gestion des certificats de Kubernetes et d'éviter les modifications manuelles de fichiers sauf en cas d'absolue nécessité.
Utiliser kubeadm pour renouveler les certificats (recommandé)
Si votre cluster utilise kubeadm, le renouvellement des certificats est une opération contrôlée.
Tout d'abord, sauvegardez le répertoire /etc/kubernetes/pki existant :
sudo tar -czf /root/k8s-pki-backup-$(date +%Y%m%d-%H%M%S).tar.gz /etc/kubernetes/pki
Ensuite, renouvelez tous les certificats avec une seule commande (vous pouvez également en renouveler un seul) :
sudo kubeadm certs renew all
Vous verrez une sortie comme :
[renew] Reading configuration from the cluster...
[renew] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
certificate for serving the Kubernetes API renewed
certificate for the API server to connect to etcd renewed
certificate for the API server to connect to kubelet renewed
certificate for the Kubernetes API to connect to etcd renewed
certificate for the etcd server renewed
certificate for the etcd peer renewed
certificate for etcd healthcheck renewed
certificate for the apiserver to connect to the kubelet renewed
certificate for the controller-manager renewed
certificate for the scheduler renewed
certificate for the front-proxy client renewed
Done renewing certificates. You must restart the kube-apiserver, kube-controller-manager, kube-scheduler and etcd, so that they can use the new certificates.
Après le renouvellement, redémarrez les composants du plan de contrôle. Sur un cluster à pods statiques, déplacer temporairement les manifestes hors du répertoire des manifestes déclenchera le redémarrage :
sudo mv /etc/kubernetes/manifests/kube-apiserver.yaml /tmp/
sudo mv /etc/kubernetes/manifests/kube-controller-manager.yaml /tmp/
sudo mv /etc/kubernetes/manifests/kube-scheduler.yaml /tmp/
sudo mv /etc/kubernetes/manifests/etcd.yaml /tmp/
sleep 20
sudo mv /tmp/kube-apiserver.yaml /etc/kubernetes/manifests/
sudo mv /tmp/kube-controller-manager.yaml /etc/kubernetes/manifests/
sudo mv /tmp/kube-scheduler.yaml /etc/kubernetes/manifests/
sudo mv /tmp/etcd.yaml /etc/kubernetes/manifests/
Vérifiez ensuite que le serveur API répond :
kubectl get nodes
Si vous voyez la liste des nœuds sans erreur, le plan de contrôle est opérationnel.
Approuver les demandes de signature de certificat (CSR) en toute sécurité
Lorsqu'un kubelet ou un autre composant demande un certificat via une CSR, vous devez l'approuver avec précaution.
Tout d'abord, listez les CSR en attente :
kubectl get csr
Exemple de sortie :
NAME AGE SIGNERNAME REQUESTOR REQUESTEDDURATION CONDITION
csr-abcde 2m kubernetes.io/kubelet-serving system:node:node1 <none> Pending
Inspectez les détails de la CSR avant de l'approuver :
kubectl describe csr csr-abcde
Vérifiez le Requestor, le Subject, les DNS Names et les IP Addresses pour vous assurer qu'ils correspondent au nœud. Ensuite, approuvez :
kubectl certificate approve csr-abcde
Sortie attendue :
certificatesigningrequest.certificates.k8s.io/csr-abcde approved
Pour refuser si quelque chose semble anormal :
kubectl certificate deny csr-abcde
Définir des RBAC restrictives pour l'approbation des CSR
Seuls les administrateurs de cluster devraient pouvoir approuver les CSR. Vérifiez vos politiques RBAC. Par exemple, pour voir qui peut approuver les CSR :
kubectl get clusterrolebinding | grep -E 'csr|approve'
Si vous souhaitez créer un rôle dédié pour l'approbation des CSR, utilisez ce YAML :
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: csr-approver
rules:
- apiGroups: ["certificates.k8s.io"]
resources: ["certificatesigningrequests/approval"]
verbs: ["update"]
- apiGroups: ["certificates.k8s.io"]
resources: ["certificatesigningrequests"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: csr-approver-binding
subjects:
- kind: User
name: [email protected]
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: csr-approver
apiGroup: rbac.authorization.k8s.io
Appliquez-le avec kubectl apply -f csr-approver.yaml.
Protéger les clés privées
Les clés privées des CA et des certificats de service doivent avoir des permissions de fichier strictes. Par exemple :
sudo chmod 600 /etc/kubernetes/pki/ca.key
sudo chmod 600 /etc/kubernetes/pki/apiserver.key
sudo chown root:root /etc/kubernetes/pki/ca.key
sudo chown root:root /etc/kubernetes/pki/apiserver.key
Assurez-vous également que tout secret Kubernetes contenant des clés TLS est chiffré au repos et que l'accès est contrôlé. Vérifiez si le chiffrement au repos est activé en examinant les drapeaux du serveur API :
ps aux | grep kube-apiserver | grep encryption-provider-config
Si aucune sortie, le chiffrement au repos n'est pas configuré. Vous pouvez le mettre en place en créant une EncryptionConfiguration et en la référençant dans le manifeste du serveur API.
Vérification et diagnostics
Après toute modification, vérifiez que les certificats sont valides, que la rotation est terminée et que les composants se font confiance mutuellement.
Vérifier l'expiration des certificats après le renouvellement
Exécutez à nouveau la vérification de l'expiration :
sudo kubeadm certs check-expiration
Les certificats renouvelés devraient afficher un TEMPS RESTANT proche de la durée de validité d'origine (par exemple, 364j).
Tester la communication entre les composants
Vérifiez que le serveur API peut joindre les kubelets avec les nouveaux certificats. Pour un nœud spécifique, exécutez :
kubectl get --raw="/api/v1/nodes/<node-name>/proxy/healthz"
Remplacez <node-name> par un nom de nœud réel (par exemple, node1). Sortie attendue : ok.
Pour la santé d'etcd :
sudo ETCDCTL_API=3 etcdctl --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/server.crt --key=/etc/kubernetes/pki/etcd/server.key endpoint health
Sortie attendue :
https://127.0.0.1:2379 is healthy: successfully committed proposal: took = 12.345678ms
Diagnostiquer les erreurs de certificat dans les journaux
Si un composant échoue, vérifiez ses journaux. Pour le pod du serveur API :
kubectl logs -n kube-system kube-apiserver-<control-plane-hostname> | grep -i cert
Remplacez <control-plane-hostname> par votre nom d'hôte. Vous pourriez voir des erreurs comme :
x509: certificate has expired or is not yet valid
ou
tls: failed to verify client certificate: x509: certificate signed by unknown authority
Celles-ci indiquent des problèmes d'expiration ou de chaîne de confiance.
Vérifier le statut d'une CSR
Pour une CSR spécifique, vérifiez si elle a été émise :
kubectl get csr csr-abcde -o jsonpath='{.status.certificate}' | base64 -d | openssl x509 -noout -subject -issuer -dates
Cela décode le certificat émis et montre ses détails.
Modes de défaillance et récupération
Les certificats peuvent échouer de plusieurs manières. Soyez prêt à diagnostiquer et à récupérer.
Certificats expirés
Si un certificat expire, les composants affectés ne pourront pas s'authentifier. Le serveur API peut devenir indisponible ou les kubelets peuvent cesser de rapporter.
Diagnostic : Exécutez sudo kubeadm certs check-expiration et recherchez les certificats avec un TEMPS RESTANT de 0j ou négatif.
Récupération : Renouvelez immédiatement les certificats en utilisant kubeadm certs renew all (voir section précédente). Si le serveur API est hors service et que kubeadm ne peut pas se connecter, vous devrez peut-être renouveler manuellement en utilisant la clé CA :
sudo kubeadm certs renew apiserver --use-api=false --config=/etc/kubernetes/kubeadm-config.yaml
Ensuite, redémarrez les composants du plan de contrôle comme décrit.
CA incohérente ou non approuvée
Si un composant présente un certificat non signé par la CA du cluster, vous verrez des erreurs comme x509: certificate signed by unknown authority.
Diagnostic : Vérifiez l'émetteur du certificat avec openssl x509 -in <cert> -noout -issuer. Comparez avec le sujet de la CA du cluster (généralement CN=kubernetes).
Récupération : Vous devez émettre un nouveau certificat signé par la bonne CA. Pour les clusters kubeadm, utilisez kubeadm certs renew. Pour les configurations manuelles, utilisez la clé CA pour signer une nouvelle CSR.
Clé privée perdue
Si une clé privée est perdue ou compromise, le certificat correspondant est inutilisable et doit être immédiatement remplacé.
Diagnostic : Vous ne pouvez pas déchiffrer le trafic ni vous authentifier. Les journaux peuvent montrer tls: failed to find any PEM data in certificate input ou similaire.
Récupération : Générez une nouvelle paire de clés et un certificat. Pour kubeadm, vous pouvez forcer la régénération en supprimant les fichiers de certificat et de clé dans /etc/kubernetes/pki et en exécutant kubeadm init phase certs all (uniquement sur un nouveau cluster) ou kubeadm certs renew. Pour un cluster en cours d'exécution, vous devrez peut-être utiliser kubeadm init phase certs avec --config avec précaution, ou régénérer manuellement avec openssl et mettre à jour toutes les références.
Rotation des certificats causant une interruption de service
Une rotation incorrecte peut laisser des composants avec des certificats mixtes, entraînant des défaillances intermittentes.
Diagnostic : Vérifiez les journaux des composants pour les erreurs TLS. Utilisez curl -v https://<api-server-ip>:6443/healthz pour voir le certificat présenté.
Récupération : Assurez-vous que tous les composants du plan de contrôle sont redémarrés après le renouvellement. Vérifiez avec kubectl get pods -n kube-system que tous les pods fonctionnent et ne redémarrent pas en boucle.
Liste de contrôle des opérations
Utilisez cette liste pour maintenir l'hygiène des certificats de manière continue.
| Tâche | Commande / Action | Fréquence | Résultat attendu |
|---|---|---|---|
| Vérifier l'expiration des certificats | sudo kubeadm certs check-expiration | Mensuelle | Tous les certificats ont au moins 30 jours de temps restant |
| Examiner les approbations de CSR | kubectl get csr --field-selector=spec.signerName=kubernetes.io/kubelet-serving | Hebdomadaire | Aucune CSR en attente inattendue |
| Auditer les RBAC pour les opérations sur certificats | kubectl get clusterrolebindings -o yaml | grep -B5 -A5 certificates.k8s.io | Trimestrielle | Seuls les utilisateurs autorisés ont les permissions approve/update |
| Vérifier les permissions des fichiers PKI | sudo stat -c '%a %n' /etc/kubernetes/pki/*.key | Mensuelle | Les clés privées sont 600 et appartiennent à root |
| Sauvegarder le répertoire PKI | sudo tar -czf /backup/pki-$(date +%F).tar.gz /etc/kubernetes/pki | Avant tout changement | La sauvegarde se termine sans erreurs |
| Tester le certificat du serveur API | echo | openssl s_client -connect <api-server-ip>:6443 2>/dev/null | openssl x509 -noout -dates | Mensuelle | Certificat non expiré |
| Vérifier le chiffrement au repos | ps aux | grep kube-apiserver | grep encryption-provider-config | Trimestrielle | Drapeau présent si les secrets doivent être chiffrés |
| Surveiller les échecs de poignée de main TLS | Rechercher dans les journaux les erreurs x509 | Hebdomadaire | Aucune erreur récente dans les journaux du plan de contrôle |
Remplacez les variables fictives comme <api-server-ip> par votre IP réelle (par exemple, 192.168.1.10).
Conclusion
Le renforcement de la sécurité des certificats Kubernetes n'est pas une tâche ponctuelle ; il nécessite une inspection régulière, une rotation contrôlée et des contrôles d'accès stricts. En suivant les pratiques de ce guide, vous pouvez prévenir les pannes et les failles de sécurité causées par une mauvaise gestion des certificats.
Commencez par une vérification à faible risque : exécutez kubeadm certs check-expiration sur votre cluster dès aujourd'hui. Enregistrez l'état actuel, mettez en place un rappel mensuel pour le renouvellement et examinez qui a la permission d'approuver les CSR. Ces petites étapes construiront une base solide pour la sécurité des certificats.
N'oubliez pas : un flux de travail technique fiable rend les défaillances visibles, protège les valeurs sensibles, limite les modifications à la ressource prévue et définit la vérification de récupération avant qu'un incident ne force la décision.