Introduction
Les comptes de service dans Kubernetes sont les identités que les pods utilisent pour interagir avec l'API Kubernetes et d'autres services du cluster. Lorsqu'un compte de service est mal configuré, les charges de travail peuvent échouer avec des erreurs d'autorisation, les jetons peuvent expirer ou des permissions trop larges peuvent devenir un incident de sécurité. Cet article fournit une liste de contrôle des opérations de production pour administrer les comptes de service Kubernetes, avec des exemples pratiques qui vont d'un problème observé à un résultat vérifié.
Ce guide est destiné aux développeurs, aux consultants DevOps et aux équipes techniques de startups qui gèrent des clusters Kubernetes en production. Il relie les opérations sur les comptes de service, les listes de contrôle, les bonnes pratiques et la maintenance à des commandes concrètes, des sorties attendues, des signaux de défaillance et des décisions de récupération. L'objectif est la sécurité opérationnelle : observer avant de modifier, limiter le rayon d'impact, utiliser des espaces réservés au lieu de secrets, vérifier le résultat et documenter comment récupérer si l'état attendu n'est pas atteint.
Tout au long de cet article, nous utilisons Kubernetes v1.28 comme version de référence. Cependant, les concepts et les commandes s'appliquent à la plupart des versions récentes. Consultez toujours les notes de version de Kubernetes pour votre version spécifique pour connaître les changements cassants.
Inventaire de la version et de l'environnement
Avant de toucher à un compte de service, vous devez connaître votre environnement. Commencez par des observations en lecture seule pour capturer l'état actuel, les versions et la topologie. Cela réduit le risque d'appliquer des modifications incompatibles avec des API ou des fonctionnalités plus anciennes.
Commencez par confirmer la version du cluster et la disponibilité de l'API :
kubectl version --short
# Exemple de sortie :
# Client Version: v1.28.2
# Server Version: v1.28.4
Vérifiez que l'API des comptes de service est disponible et listez les comptes de service existants dans l'espace de noms cible :
kubectl api-resources | grep serviceaccounts
# Sortie attendue :
# serviceaccounts sa v1 true ServiceAccount
kubectl get serviceaccounts -n production
# Exemple de sortie :
# NAME SECRETS AGE
# default 0 30d
# app-sa 1 3d
# monitoring-sa 1 5d
Notez la colonne SECRETS : dans Kubernetes v1.24+, la porte de fonctionnalité LegacyServiceAccountTokenNoAutoGeneration est activée, donc les comptes de service ne reçoivent plus automatiquement un jeton secret à longue durée de vie. Si un compte de service affiche 0 secrets, il peut s'appuyer sur des jetons projetés ou sur la création manuelle de jetons. Ceci est important pour le dépannage.
Capturez les pods exacts utilisant chaque compte de service :
kubectl get pods -n production -o json | jq -r '.items[] | "\(.metadata.name) -> \(.spec.serviceAccountName // "default")"'
# Exemple de sortie :
# web-frontend-6d4b8c9f7-abcde -> app-sa
# web-frontend-6d4b8c9f7-fghij -> app-sa
# monitoring-agent-2f8d7c6b5-klmno -> monitoring-sa
# backend-worker-7c9b8d6e5-pqrst -> default
Cet inventaire vous aide à comprendre quelles charges de travail dépendent de quelle identité. Avant d'apporter des modifications, confirmez que tout remplacement ou modification ne cassera pas ces associations.
Enregistrez également toutes les dépendances externes, telles que les rôles IAM cloud ou les magasins de secrets externes qui s'intègrent au compte de service. Par exemple, si vous utilisez AWS IAM Roles for Service Accounts (IRSA), listez les ARN de rôle IAM mappés à chaque annotation de compte de service :
kubectl get serviceaccount app-sa -n production -o yaml | grep -A1 annotations
# Exemple de sortie :
# annotations:
# eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/prod-app-role
Documenter ces associations est essentiel pour la récupération et l'audit.
Chemin de configuration sécurisé
Lorsque vous modifiez des comptes de service, suivez toujours un chemin de configuration sécurisé : utilisez des vérifications en lecture seule, créez ou patchez avec des manifestes explicites, vérifiez l'état résultant et ayez un plan de retour en arrière. Ne modifiez jamais des comptes de service en place sans enregistrer l'état d'origine.
Création d'un compte de service avec le moindre privilège
Définissez un compte de service qui inclut uniquement les annotations nécessaires et qui n'est lié à aucun secret de jeton par défaut :
apiVersion: v1
kind: ServiceAccount
metadata:
name: app-sa
namespace: production
# Annotations pour l'intégration IAM cloud si nécessaire
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/prod-app-role
automountServiceAccountToken: true # définir à false si le pod n'a pas besoin d'accès à l'API
Appliquez-le :
kubectl apply -f sa-app.yaml
Vérifiez que le compte de service existe et a les bons champs :
kubectl get serviceaccount app-sa -n production -o yaml
# Vérifiez que les annotations et automountServiceAccountToken sont comme prévu.
Liaison aux rôles avec RBAC
Les comptes de service obtiennent des permissions via des RoleBindings ou des ClusterRoleBindings. Utilisez le principe du moindre privilège : accordez uniquement ce dont la charge de travail a besoin.
Tout d'abord, inspectez les liaisons RBAC existantes pour le compte de service :
kubectl get rolebindings,clusterrolebindings -n production -o json | jq -r '.items[] | select(.subjects[]?.name == "app-sa") | "\(.kind): \(.metadata.name) -> \(.roleRef.name)"'
# Exemple de sortie :
# RoleBinding: app-sa-view -> view
Créez un Role avec des permissions spécifiques, par exemple un accès en lecture aux pods :
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader
namespace: production
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
Créez un RoleBinding pour lier le compte de service au rôle :
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: app-sa-pod-reader
namespace: production
subjects:
- kind: ServiceAccount
name: app-sa
namespace: production
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
Appliquez et vérifiez :
kubectl apply -f role.yaml -f rolebinding.yaml
kubectl auth can-i list pods --as=system:serviceaccount:production:app-sa -n production
# Attendu : yes
kubectl auth can-i delete pods --as=system:serviceaccount:production:app-sa -n production
# Attendu : no
Cela confirme que les permissions sont correctement limitées.
Gestion des montages de jetons
Par défaut, un pod monte un jeton de compte de service à /var/run/secrets/kubernetes.io/serviceaccount. Si un pod n'a pas besoin d'appeler l'API Kubernetes, désactivez-le pour réduire la surface d'attaque :
apiVersion: v1
kind: Pod
metadata:
name: static-web
spec:
serviceAccountName: default
automountServiceAccountToken: false
Vérifiez qu'aucun jeton n'est monté :
kubectl exec -it static-web -n production -- ls /var/run/secrets/kubernetes.io/serviceaccount
# Attendu : No such file or directory
Vérification et diagnostic
Après tout changement, vous devez vérifier que le compte de service se comporte comme prévu et que les charges de travail peuvent s'authentifier et s'autoriser correctement.
Vérifier la projection des jetons de compte de service
Les clusters modernes utilisent des jetons de compte de service projetés. Inspectez l'expiration et l'audience du jeton :
kubectl create token app-sa -n production --duration=1h --audience=api
# Exemple de sortie :
# eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9... (chaîne de jeton)
Cette commande génère un jeton que vous pouvez tester. Remarque : ce jeton est limité dans le temps et n'est pas persisté. Pour les workflows automatisés, utilisez l'API TokenRequest ou des bibliothèques clientes.
Tester l'accès à l'API depuis un pod
Créez un pod de débogage utilisant le compte de service et tentez une action autorisée :
kubectl run test-pod --image=alpine --restart=Never --rm -it -n production --overrides='
{
"spec": {
"serviceAccountName": "app-sa"
}
}' -- sh
À l'intérieur du pod, vérifiez le jeton monté et appelez l'API :
# À l'intérieur du pod
TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
APISERVER=https://kubernetes.default.svc
curl -sk -H "Authorization: Bearer $TOKEN" $APISERVER/api/v1/namespaces/production/pods
# Attendu : liste JSON des pods si le RBAC le permet. Si interdit, vous verrez une erreur 403.
Sortez et supprimez le pod de test automatiquement lorsque vous avez terminé.
Journaux d'audit pour les actions des comptes de service
Activez la journalisation d'audit Kubernetes pour suivre l'utilisation des comptes de service. Pour les clusters gérés, cela peut être disponible via la console du fournisseur. Pour les clusters autogérés, configurez audit-policy.yaml pour journaliser les créations de jetons de compte de service et d'autres actions :
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: Metadata
users: ["system:serviceaccount:production:app-sa"]
Ensuite, examinez les journaux pour détecter des anomalies :
grep "app-sa" /var/log/kubernetes/audit.log | tail -20
Valider ServiceAccountName dans les déploiements
Assurez-vous que les déploiements référencent des comptes de service existants. Un compte de service manquant entraîne l'échec de la planification ou de l'exécution des pods. Vérifiez avec :
kubectl get deployment web-frontend -n production -o jsonpath='{.spec.template.spec.serviceAccountName}'
# Attendu : app-sa
Si vide, il utilise par défaut default. Si le nom n'existe pas, les pods ne démarreront pas et journaliseront une erreur du type :
Error creating: pods "web-frontend-..." is forbidden: error looking up service account production/non-existent-sa: serviceaccount "non-existent-sa" not found
Modes de défaillance et récupération
Les problèmes de compte de service peuvent causer diverses défaillances. Voici les modes de défaillance courants et comment récupérer.
Défaillance : le pod échoue avec "serviceaccount not found"
Symptôme : le pod reste dans l'état Pending ou ContainerCreating, les événements affichent :
Warning FailedCreate 3s (x10 over 1m) replicaset-controller Error creating: pods "web-frontend-..." is forbidden: error looking up service account production/app-sa: serviceaccount "app-sa" not found
Diagnostic : le compte de service référencé n'existe pas dans l'espace de noms.
Récupération : créez le compte de service manquant (ou corrigez la référence).
kubectl create serviceaccount app-sa -n production
# Vérifiez
kubectl get serviceaccount app-sa -n production
Si le compte de service a été supprimé accidentellement, récupérez-le à partir de la sauvegarde ou réappliquez le manifeste.
Défaillance : accès API interdit (403)
Symptôme : les journaux d'application affichent forbidden: User "system:serviceaccount:production:app-sa" cannot list resource "pods"...
Diagnostic : les permissions RBAC sont insuffisantes.
Récupération : examinez le Role/RoleBinding. Ajoutez les permissions nécessaires avec le moindre privilège. Utilisez kubectl auth can-i pour tester :
kubectl auth can-i list pods --as=system:serviceaccount:production:app-sa -n production
# Si non, inspectez les rolebindings
kubectl get rolebinding -n production -o yaml | grep -A5 app-sa
Appliquez la liaison de rôle manquante et retestez.
Défaillance : expiration ou invalidité du jeton
Symptôme : l'application reçoit 401 Unauthorized du serveur API, les journaux affichent des erreurs de validation de jeton.
Diagnostic : le jeton monté peut être expiré (pour les jetons projetés à courte durée de vie) ou le secret de jeton du compte de service peut être manquant.
Récupération :
- Pour les jetons projetés, assurez-vous que le pod redémarre pour obtenir un nouveau jeton, ou ajustez la TokenRequest si vous utilisez une configuration personnalisée.
- Pour les jetons secrets hérités, recréez le secret et mettez à jour le compte de service si nécessaire. Cependant, notez que les jetons hérités sont dépréciés. Préférez les jetons projetés.
- Vérifiez l'expiration du jeton en utilisant
kubectl create tokenpour tester un nouveau jeton et comparer.
kubectl create token app-sa -n production --duration=1h
# Utilisez ce jeton dans un test pour voir s'il fonctionne.
Défaillance : compte de service automatisé avec IAM cloud (par exemple AWS IRSA)
Symptôme : le pod échoue à assumer le rôle IAM, les journaux affichent WebIdentityErr: failed to retrieve credentials ou similaire.
Diagnostic : l'annotation du compte de service peut être incorrecte, ou la politique de confiance du fournisseur OIDC est mal configurée.
Récupération :
- Vérifiez l'annotation :
kubectl get serviceaccount app-sa -n production -o yaml | grep role-arn - Vérifiez la politique de confiance du rôle IAM pour inclure le fournisseur OIDC du cluster et le principal du compte de service.
- Confirmez que le fournisseur OIDC est configuré sur le cluster :
kubectl describe clusterle montre généralement.
Pour des étapes détaillées, référez-vous à la documentation du fournisseur cloud.
Liste de contrôle des opérations
Utilisez la liste de contrôle suivante comme référence pour l'administration des comptes de service en production. Chaque élément inclut une commande ou une étape de vérification.
- [ ] Inventorier mensuellement les comptes de service et les liaisons
kubectl get serviceaccounts --all-namespaces
kubectl get rolebindings,clusterrolebindings --all-namespaces -o json | jq '.items[] | select(.subjects[]?.kind == "ServiceAccount") | {namespace: .metadata.namespace, name: .metadata.name, role: .roleRef.name}'
Recherchez les comptes inutilisés ou les liaisons trop larges.
Pour chaque compte de service, vérifiez les champs automountServiceAccountToken et secrets :
- [ ] Examiner les paramètres de création de jetons
kubectl get serviceaccount -o json | jq '.items[] | {name: .metadata.name, automount: .automountServiceAccountToken, secrets: [.secrets[].name]}'
Assurez-vous que seuls les comptes nécessaires ont un jeton monté.
Avant d'appliquer en production, exécutez :
- [ ] Tester les permissions RBAC dans un environnement de préproduction
kubectl auth can-i --list --as=system:serviceaccount:namespace:sa
Vérifiez que les permissions correspondent aux exigences de l'application.
Si vous utilisez des secrets à longue durée de vie, faites-les tourner et mettez à jour les déploiements :
- [ ] Faire tourner régulièrement les jetons créés manuellement
kubectl create token mysa --duration=... # ou créez un nouveau secret et patchez le compte de service
Préférez les jetons projetés à courte durée de vie ou les fournisseurs d'identité externes.
Configurez des alertes pour :
Utilisez des outils comme Prometheus et Alertmanager avec des requêtes personnalisées.
- [ ] Surveiller les événements et métriques liés aux comptes de service
- Les échecs de création de pods dus à des comptes de service manquants (
reason=FailedCreateavec un message contenantserviceaccount ... not found) - Les augmentations de réponses 401/403 du serveur API avec des noms de comptes de service.
Pour chaque mode de défaillance de cet article, assurez-vous d'avoir un runbook et que les membres de l'équipe ont pratiqué la récupération dans un environnement non productif.
- [ ] Documenter et tester les procédures de récupération
Stockez les définitions de compte de service et les rôles RBAC dans un dépôt Git. Utilisez GitOps ou CI/CD pour appliquer les changements, assurant revue et auditabilité.
- [ ] Conserver les manifestes YAML des comptes de service dans le contrôle de version
Exécutez une vérification avant déploiement :
- [ ] Valider les références de compte de service dans les manifestes de charge de travail
# Exemple : itérer sur les déploiements et vérifier l'existence du compte de service
for ns in $(kubectl get ns -o jsonpath='{.items[*].metadata.name}'); do
for deploy in $(kubectl get deploy -n $ns -o jsonpath='{.items[*].metadata.name}'); do
sa=$(kubectl get deploy $deploy -n $ns -o jsonpath='{.spec.template.spec.serviceAccountName}')
if ! kubectl get sa $sa -n $ns > /dev/null 2>&1; then
echo "Missing SA $sa for deploy $deploy in $ns"
fi
done
done
Intégrez ces vérifications dans votre pipeline CI et votre revue régulière des opérations.
Conclusion
Administrer les comptes de service Kubernetes en production exige une approche disciplinée : observer l'état, modifier de manière minimale, vérifier les résultats et préparer la récupération. La liste de contrôle fournie dans cet article vous donne une base pratique pour gérer les comptes de service en toute sécurité et efficacement.
Commencez par appliquer une vérification à faible risque de ce guide : enregistrez l'état actuel d'un compte de service, exécutez la vérification documentée, comparez le résultat avec le signal attendu et examinez les dépendances telles que RBAC, les secrets et l'intégration IAM cloud.
Un flux de travail technique fiable rend les défaillances visibles, protège les valeurs sensibles, limite les changements à la ressource visée et définit la vérification de récupération avant qu'un incident ne force la décision. Intégrez ces pratiques dans la routine de votre équipe pour garder vos clusters Kubernetes sécurisés et stables.