## Introduction

Les comptes de service Kubernetes sont un élément fondamental de la sécurité du cluster, fournissant une identité aux processus s'exécutant dans les pods. Ce ne sont pas des comptes d'utilisateurs ; ils sont plutôt utilisés par les applications pour s'authentifier auprès de l'API Kubernetes ou de services externes. En tant qu'administrateur de cluster ou ingénieur DevOps, comprendre comment créer, inspecter et gérer les comptes de service est essentiel pour sécuriser vos charges de travail et garantir un fonctionnement fluide.

Ce guide propose une collection pratique de commandes kubectl et de flux de travail pour administrer les comptes de service. Il couvre les bases telles que la création d'un compte de service, sa liste et son inspection, ainsi que la gestion des jetons et secrets associés. Il aborde ensuite la liaison avec le contrôle d'accès basé sur les rôles (RBAC, Role-Based Access Control), l'intégration dans les pods et le dépannage. Chaque section comprend des exemples de commandes concrets, les sorties attendues et des conseils pour réagir en cas de problème.

Que vous prépariez l'examen d'Administrateur Kubernetes Certifié (CKA, Certified Kubernetes Administrator) ou que vous gériez des clusters de production, ces commandes constituent le cœur de votre boîte à outils opérationnelle quotidienne. À la fin de ce guide, vous serez en mesure de gérer les comptes de service en toute confiance, de diagnostiquer les échecs d'authentification et de mettre en œuvre un accès à moindre privilège pour vos applications.

## Inventaire de la version et de l'environnement

Avant d'exécuter toute commande relative aux comptes de service, vérifiez votre environnement. Les exemples de ce guide supposent un cluster Kubernetes version 1.20 ou ultérieure, car l'API de demande de jeton et les jetons de compte de service liés sont devenus stables à cette époque. Vérifiez toujours la version de votre cluster :

```bash
kubectl version --short
```

Sortie attendue (exemple) :

```
Client Version: v1.25.0
Server Version: v1.25.3
```

Vérifiez également que vous disposez des autorisations nécessaires pour gérer les comptes de service. En règle générale, vous avez besoin de cluster-admin ou d'un rôle qui accorde les droits create, get, list, watch et delete sur les serviceaccounts et les secrets dans les espaces de noms concernés. Si vous utilisez un service Kubernetes géré comme EKS, GKE ou AKS, assurez-vous que votre identité IAM ou cloud est mappée à un rôle Kubernetes disposant de ces droits.

Une vérification rapide consiste à lister tous les comptes de service dans l'espace de noms par défaut :

```bash
kubectl get serviceaccounts
```

Sortie attendue :

```
NAME      SECRETS   AGE
default   1         15d
```

Le compte de service `default` existe dans chaque espace de noms et est automatiquement monté dans les pods à moins qu'un compte de service spécifique ne soit assigné. Pour les charges de travail en production, évitez d'utiliser le compte de service par défaut ; créez-en un dédié avec des autorisations minimales.

## Création d'un compte de service

La création d'un compte de service est simple. Utilisez la commande impérative :

```bash
kubectl create serviceaccount my-app-sa
```

Sortie attendue :

```
serviceaccount/my-app-sa created
```

Pour le créer de manière déclarative, enregistrez le YAML suivant dans `sa.yaml` :

```yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: my-app-sa
  namespace: default
```

Puis appliquez :

```bash
kubectl apply -f sa.yaml
```

Après la création, inspectez le compte de service pour voir ses détails :

```bash
kubectl get serviceaccount my-app-sa -o yaml
```

Dans Kubernetes 1.24+, les comptes de service n'obtiennent plus automatiquement un secret de jeton à longue durée de vie. Au lieu de cela, les jetons sont obtenus via l'API TokenRequest ou en créant manuellement un secret de type `kubernetes.io/service-account-token`. Vous pouvez toujours créer un secret pour des raisons de compatibilité :

```bash
kubectl apply -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
  name: my-app-sa-token
  annotations:
    kubernetes.io/service-account.name: my-app-sa
type: kubernetes.io/service-account-token
EOF
```

Cependant, récupérer un jeton depuis un secret est un mécanisme hérité et n'est pas recommandé. L'approche actuelle consiste à demander directement un jeton à courte durée de vie :

```bash
kubectl create token my-app-sa
```

Cela affiche un jeton sur la sortie standard. Traitez ce jeton comme sensible ; ne le journalisez jamais et ne le committez pas dans un système de contrôle de version. Pour plus d'options de gestion des jetons, consultez la section Gestion des secrets et des jetons.

## Liste et inspection des comptes de service

Lister tous les comptes de service dans tous les espaces de noms :

```bash
kubectl get serviceaccounts --all-namespaces
```

Pour obtenir des informations détaillées sur un compte de service spécifique :

```bash
kubectl describe serviceaccount my-app-sa
```

Exemple de sortie :

```
Name:                my-app-sa
Namespace:           default
Labels:              <none>
Annotations:         <none>
Image pull secrets:  <none>
Mountable secrets:   my-app-sa-token
Tokens:              my-app-sa-token
Events:              <none>
```

Cela montre les secrets associés et les secrets d'extraction d'image attachés.

## Gestion des secrets et des jetons

Depuis Kubernetes 1.24, l'approche recommandée consiste à utiliser des jetons à courte durée de vie via l'API TokenRequest. Vous pouvez demander un jeton pour un compte de service à l'aide de kubectl :

```bash
kubectl create token my-app-sa
```

Cela affiche un jeton sur la sortie standard. Vous pouvez spécifier une durée (par défaut 1 heure) :

```bash
kubectl create token my-app-sa --duration=2h
```

Pour les jetons à longue durée de vie (non recommandés en production), créez un secret comme indiqué précédemment. Pour lister les secrets associés à un compte de service :

```bash
kubectl get secrets --field-selector type=kubernetes.io/service-account-token
```

Pour révoquer un jeton, supprimez le secret :

```bash
kubectl delete secret my-app-sa-token
```

Le compte de service ne disposera alors plus de ce jeton.

## Contrôle d'accès basé sur les rôles (RBAC)

Les comptes de service n'ont par eux-mêmes aucune autorisation, sauf s'ils sont liés à des rôles. Pour accorder l'accès, créez un Role ou un ClusterRole et liez-le au compte de service.

Exemple : Accorder un accès en lecture seule aux pods dans l'espace de noms par défaut.

Créez un Role :

```bash
kubectl create role pod-reader --verb=get,list,watch --resource=pods
```

Créez un RoleBinding :

```bash
kubectl create rolebinding pod-reader-binding --role=pod-reader --serviceaccount=default:my-app-sa
```

Désormais, le compte de service peut lister les pods dans l'espace de noms par défaut. Pour vérifier, vous pouvez emprunter l'identité du compte de service dans un test :

```bash
kubectl auth can-i list pods --as=system:serviceaccount:default:my-app-sa
```

Sortie attendue :

```
yes
```

Pour des autorisations à l'échelle du cluster, utilisez ClusterRole et ClusterRoleBinding :

```bash
kubectl create clusterrole secret-reader --verb=get,list --resource=secrets
kubectl create clusterrolebinding secret-reader-binding --clusterrole=secret-reader --serviceaccount=default:my-app-sa
```

Suivez toujours le principe du moindre privilège : n'accordez que les autorisations nécessaires au fonctionnement de l'application.

## Utilisation des comptes de service dans les pods

Pour utiliser un compte de service spécifique dans un pod, définissez `serviceAccountName` dans la spécification du pod :

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: my-app
spec:
  serviceAccountName: my-app-sa
  containers:
  - name: app
    image: nginx
```

Lorsque le pod s'exécute, le jeton du compte de service est monté dans `/var/run/secrets/kubernetes.io/serviceaccount`. Vous pouvez désactiver le montage automatique du jeton en définissant `automountServiceAccountToken: false` dans la spécification du pod, ce qui est recommandé si le pod n'a pas besoin de communiquer avec le serveur d'API.

Pour vérifier quel compte de service un pod en cours d'exécution utilise :

```bash
kubectl get pod my-app -o jsonpath='{.spec.serviceAccountName}'
```

## Dépannage des problèmes de compte de service

Les problèmes courants incluent les pods qui ne parviennent pas à s'authentifier, les autorisations manquantes et l'expiration des jetons. Voici les étapes de diagnostic.

### Le pod ne peut pas s'authentifier auprès du serveur d'API

- Vérifiez que le jeton du compte de service est monté :

```bash
kubectl exec my-app -- ls /var/run/secrets/kubernetes.io/serviceaccount
```

La sortie attendue comprend `token`, `ca.crt` et `namespace`.

- Si le jeton est manquant, vérifiez que `automountServiceAccountToken` n'est pas défini sur false, et que le compte de service existe et possède un secret de jeton (si vous utilisez des jetons hérités).

### Permission refusée lorsque le pod tente d'accéder aux ressources

- Vérifiez les rôles liés au compte de service :

```bash
kubectl get rolebindings,clusterrolebindings -o wide | grep my-app-sa
```

- Utilisez `kubectl auth can-i` pour tester les autorisations en tant que compte de service :

```bash
kubectl auth can-i get pods --as=system:serviceaccount:default:my-app-sa
```

Si cela renvoie `no`, vous devez ajuster le RoleBinding ou le ClusterRoleBinding.

### Jeton expiré ou invalide

Pour les jetons hérités à longue durée de vie, vérifiez l'expiration du secret si elle est définie. Pour les jetons à courte durée de vie, ils expirent après la durée demandée ; l'application doit donc demander un nouveau jeton via l'API TokenRequest. Envisagez d'utiliser des bibliothèques clientes qui gèrent automatiquement le renouvellement des jetons.

## Pièges courants et comment les éviter

1. **Utiliser le compte de service par défaut**
   - Pourquoi : Il est facile d'oublier de spécifier un compte de service, donc le compte par défaut est utilisé, qui a souvent des autorisations minimales ou, s'il est modifié, trop nombreuses.
   - Comment éviter : Définissez toujours `serviceAccountName` dans les spécifications de pod et auditez régulièrement les comptes de service utilisés par les pods.

2. **Rôles RBAC trop permissifs**
   - Pourquoi : Les développeurs peuvent demander des autorisations larges pour éviter des dépannages ultérieurs.
   - Comment éviter : Appliquez le moindre privilège, utilisez des rôles limités à l'espace de noms lorsque c'est possible et effectuez des revues d'accès régulières.

3. **Coder en dur les jetons dans le code applicatif**
   - Pourquoi : Au lieu de lire le fichier de jeton monté du compte de service, les développeurs peuvent copier le jeton dans le code pour les tests et oublier de le supprimer.
   - Comment éviter : Ne codez jamais en dur les jetons ; utilisez la configuration en cluster qui lit le fichier de jeton, et révoquez immédiatement tout jeton divulgué.

4. **Ne pas renouveler les jetons hérités**
   - Pourquoi : Les jetons à longue durée de vie peuvent rester valides indéfiniment s'ils ne sont pas gérés.
   - Comment éviter : Utilisez des jetons à courte durée de vie via TokenRequest, ou définissez une expiration sur les jetons de secret créés manuellement et renouvelez-les régulièrement.

## Liste de contrôle opérationnelle pour l'administration des comptes de service

- [ ] Vérifiez que la version du cluster prend en charge l'API de demande de jeton (1.20+).
- [ ] Listez les comptes de service existants et identifiez ceux qui ne sont pas utilisés pour le nettoyage.
- [ ] Créez des comptes de service dédiés pour chaque application ou charge de travail.
- [ ] Liez des rôles à moindre privilège aux comptes de service en utilisant des RoleBindings (espace de noms) ou des ClusterRoleBindings (à l'échelle du cluster).
- [ ] Testez les autorisations avec `kubectl auth can-i --as=system:serviceaccount:<ns>:<sa>`.
- [ ] Configurez les pods pour utiliser le bon compte de service et désactivez le montage automatique si ce n'est pas nécessaire.
- [ ] Préférez les jetons à courte durée de vie aux secrets à longue durée de vie.
- [ ] Auditez régulièrement l'utilisation des comptes de service et les liaisons RBAC (par exemple, mensuellement).
- [ ] Documentez le propriétaire et l'objectif de chaque compte de service dans les annotations ou la documentation externe. Par exemple : `kubectl annotate serviceaccount my-app-sa owner=team-a purpose=api-access`.
- [ ] Mettez en place une surveillance et des alertes pour la création de jetons de compte de service et les anomalies d'utilisation.

Attribuez un responsable unique de la gestion des comptes de service dans votre organisation, comme un ingénieur plateforme ou un administrateur de sécurité, et examinez l'ensemble de l'inventaire chaque trimestre.

## Conclusion

Gérer efficacement les comptes de service Kubernetes est essentiel pour sécuriser votre cluster et garantir que les applications ont le niveau d'accès approprié. Les commandes et flux de travail de ce guide couvrent l'ensemble du cycle de vie : création, inspection, liaison RBAC, intégration dans les pods et dépannage. En suivant les meilleures pratiques de moindre privilège, de jetons à courte durée de vie et d'audits réguliers, vous réduisez le risque d'utilisation abusive des identifiants et améliorez l'hygiène opérationnelle.

Commencez par auditer vos comptes de service actuels, puis mettez en œuvre la liste de contrôle progressivement. Avec une solide compréhension de ces commandes administratives, vous serez bien équipé pour gérer les tâches liées aux comptes de service dans n'importe quel environnement Kubernetes.