## Introduction

Les demandes de signature de certificat (CSR, Certificate Signing Requests) sont un élément essentiel de la sécurité de Kubernetes, permettant aux nœuds, services et utilisateurs d'obtenir des certificats signés par l'autorité de certification du cluster. Lorsqu'une CSR n'est pas approuvée ou qu'un certificat ne peut pas être émis, la cause racine se situe souvent au niveau du réseau : le serveur d'API peut être injoignable, la résolution DNS peut échouer, ou un port requis peut être bloqué. Ce guide propose une approche pratique et étape par étape pour dépanner les problèmes réseau liés aux CSR Kubernetes. Vous apprendrez à recueillir des informations sur votre cluster, vérifier la connectivité, diagnostiquer les modes de défaillance courants et vous en remettre.

Cet article s'adresse aux administrateurs Kubernetes, aux ingénieurs DevOps et aux développeurs qui gèrent des clusters et doivent résoudre rapidement les problèmes liés aux CSR. Nous nous concentrons sur les aspects réseau : DNS, ports, connectivité et les outils pour les diagnostiquer. En suivant le flux de travail structuré présenté ici, vous pouvez passer d'un symptôme observé à une résolution vérifiée, minimisant les temps d'arrêt et assurant la sécurité de votre cluster.

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 les résultats et documenter les procédures de récupération.

## Inventaire de la version et de l'environnement

Avant de dépanner tout problème réseau lié aux CSR, vous devez comprendre la version et l'environnement de votre cluster. Les différentes versions de Kubernetes peuvent avoir des API CSR et des comportements réseau différents. Par exemple, l'API `certificates.k8s.io/v1` est stable depuis la version 1.19, tandis que les versions plus anciennes peuvent utiliser `v1beta1`. Connaître votre version vous aide à choisir les bonnes commandes et à interpréter les sorties.

Commencez par identifier la version de votre cluster Kubernetes et des composants impliqués.

### Recueillir des informations sur le cluster

Exécutez les commandes suivantes pour obtenir un aperçu de votre cluster :

```bash
kubectl version --short
kubectl cluster-info
```

Exemple de sortie :

```
Client Version: v1.27.3
Kustomize Version: v5.0.1
Server Version: v1.27.3
```

Notez la version du serveur ; si elle est antérieure à la v1.19, vous devrez peut-être utiliser `certificates.k8s.io/v1beta1` pour les objets CSR.

Vérifiez les nœuds et leur statut :

```bash
kubectl get nodes -o wide
```

Cela affiche les noms des nœuds, leur statut, leurs rôles, leurs versions et leurs adresses IP internes/externes. Si un nœud est `NotReady`, l'approbation de la CSR peut être retardée car le kubelet ne peut pas joindre le serveur d'API.

### Vérifier la disponibilité de l'API CSR

Assurez-vous que l'API CSR est activée et accessible. Vous pouvez lister les CSR existantes :

```bash
kubectl get csr
```

Si vous obtenez une erreur comme `the server doesn't have a resource type "csr"`, l'API peut être désactivée ou vous n'avez pas les permissions nécessaires.

### Vérifier les prérequis

Assurez-vous d'avoir les permissions nécessaires pour gérer les CSR. Par exemple, pour approuver une CSR, vous avez besoin des permissions sur `certificates.k8s.io`. Vérifiez votre accès :

```bash
kubectl auth can-i create certificatesigningrequests/approval
kubectl auth can-i get certificatesigningrequests
```

Si vous obtenez `no`, demandez à votre administrateur de cluster de vous accorder les rôles appropriés.

### Comprendre la topologie

Déterminez où s'exécutent les composants signataires de CSR. Dans un cluster typique, le gestionnaire de contrôleurs (`kube-controller-manager`) inclut l'approbateur et le signataire de CSR. Vérifiez s'il est en cours d'exécution :

```bash
kubectl get pods -n kube-system | grep controller-manager
```

Si le pod du gestionnaire de contrôleurs est manquant ou en erreur, les CSR ne seront pas traitées. Utilisez `kubectl describe pod` et `kubectl logs` pour diagnostiquer.

### Exemple : Problème de CSR lors du bootstrap d'un nœud

Imaginons qu'un nouveau nœud ne parvienne pas à rejoindre le cluster et que le journal de son kubelet affiche :

```
Failed to create CSR: Post "https://api.example.com:6443/apis/certificates.k8s.io/v1/certificatesigningrequests": dial tcp 10.0.0.10:6443: connect: no route to host
```

Cela indique un problème réseau : le nœud ne peut pas joindre le serveur d'API. Nous aborderons ces problèmes dans les sections suivantes.

## Chemin de configuration sûr

Lors de la modification de la configuration pour résoudre les problèmes réseau liés aux CSR, suivez un chemin sûr : effectuez des modifications petites et réversibles, et vérifiez toujours avant et après. Cette section décrit les principaux domaines de configuration qui affectent le réseau des CSR.

### Configuration du point de terminaison du serveur d'API

Les nœuds et les clients doivent connaître l'adresse correcte du serveur d'API. Celle-ci est souvent spécifiée dans les fichiers kubeconfig ou la configuration du kubelet.

Vérifiez la configuration du kubelet sur un nœud :

```bash
cat /var/lib/kubelet/config.yaml
```

Recherchez le champ `server` sous `cluster` dans le kubeconfig ou le drapeau `--kubeconfig`. Assurez-vous que l'adresse est correcte et joignable depuis le nœud.

Si le serveur d'API est derrière un équilibreur de charge, vérifiez que celui-ci transfère le trafic vers le port du serveur d'API (par défaut 6443) et que les contrôles de santé passent.

### Configuration DNS

Les nœuds doivent résoudre le nom d'hôte du serveur d'API. Vérifiez les paramètres DNS dans `/etc/resolv.conf` sur chaque nœud. Pour les clusters utilisant CoreDNS, assurez-vous que le service DNS est en cours d'exécution et correctement configuré.

Testez la résolution DNS depuis un nœud :

```bash
nslookup api.example.com
```

Exemple de sortie attendue :

```
Server:         10.96.0.10
Address:        10.96.0.10#53

Name:   api.example.com
Address: 10.0.0.10
```

Si la résolution échoue, vérifiez les pods CoreDNS :

```bash
kubectl get pods -n kube-system -l k8s-app=kube-dns
kubectl logs -n kube-system -l k8s-app=kube-dns
```

### Politiques réseau et pare-feu

Les politiques réseau peuvent bloquer par inadvertance le trafic vers le serveur d'API ou entre les composants. Passez en revue toutes les NetworkPolicies qui peuvent affecter le kubelet ou le gestionnaire de contrôleurs.

Listez les politiques réseau :

```bash
kubectl get networkpolicies --all-namespaces
```

Si vous soupçonnez qu'une politique bloque le trafic, vous pouvez la supprimer temporairement (après l'avoir sauvegardée) pour tester. Mais d'abord, examinez ses règles :

```bash
kubectl describe networkpolicy <name> -n <namespace>
```

Vérifiez également les groupes de sécurité du fournisseur de cloud ou les règles de pare-feu. Assurez-vous que le port 6443 est ouvert pour les nœuds et les clients, et que le trafic interne entre les composants du plan de contrôle est autorisé.

### Configuration du signataire de demandes de signature de certificat

Le gestionnaire de contrôleurs doit être configuré avec les bons drapeaux de signataire. Vérifiez la spécification du pod du gestionnaire de contrôleurs ou le fichier de configuration.

Par exemple, dans un cluster kubeadm, le gestionnaire de contrôleurs peut avoir ces drapeaux :

```
--cluster-signing-cert-file=/etc/kubernetes/pki/ca.crt
--cluster-signing-key-file=/etc/kubernetes/pki/ca.key
```

Si ces fichiers sont manquants ou corrompus, les CSR ne peuvent pas être signées. Vérifiez que les fichiers existent et sont lisibles.

### Appliquer les modifications en toute sécurité

Lorsque vous modifiez la configuration, suivez ces étapes :

1. Sauvegardez le fichier de configuration ou la ressource actuelle.
2. Appliquez la modification à un seul composant ou nœud.
3. Vérifiez l'effet à l'aide du contrôle approprié.
4. Si cela fonctionne, déployez sur d'autres composants si nécessaire.
5. Si cela échoue, revenez immédiatement à la sauvegarde.

Par exemple, pour mettre à jour le kubeconfig du kubelet, vous pouvez modifier le fichier et redémarrer le kubelet :

```bash
sudo systemctl restart kubelet
```

Puis vérifiez son état :

```bash
sudo systemctl status kubelet
```

## Vérification et diagnostics

Après avoir configuré ou observé un problème, vous devez vérifier systématiquement la connectivité et diagnostiquer les problèmes. Cette section fournit un ensemble de commandes et de procédures.

### Contrôles de connectivité de base depuis les nœuds

Depuis un nœud, testez la connectivité vers le serveur d'API à l'aide de `curl` ou `nc`.

```bash
curl -k https://api.example.com:6443/healthz
```

Sortie attendue : `ok` si le serveur est sain.

Si `curl` n'est pas disponible, utilisez `nc` :

```bash
nc -zv api.example.com 6443
```

Une connexion réussie affiche :

```
Connection to api.example.com 6443 port [tcp/*] succeeded!
```

Si la connexion échoue, vérifiez le routage :

```bash
ip route
```

Assurez-vous qu'il existe une route vers le réseau du serveur d'API. Vérifiez également si le port est ouvert localement avec `ss` :

```bash
ss -tuln | grep 6443
```

### Vérification du DNS Kubernetes

Si les pods ont des difficultés à résoudre les noms de service, vérifiez les journaux de CoreDNS pour les erreurs.

Obtenez les noms des pods CoreDNS :

```bash
kubectl get pods -n kube-system -l k8s-app=kube-dns -o name
```

Affichez les journaux :

```bash
kubectl logs -n kube-system <coredns-pod>
```

Recherchez des erreurs comme `SERVFAIL` ou `i/o timeout`. Testez également la résolution DNS depuis un pod :

```bash
kubectl run -it --rm debug --image=busybox --restart=Never -- nslookup kubernetes.default
```

La sortie attendue inclut l'adresse IP du service.

### Inspection des CSR

Listez les CSR et examinez leur état :

```bash
kubectl get csr
kubectl describe csr <csr-name>
```

Dans la sortie de `describe`, vérifiez le champ `Conditions`. Si la CSR est en attente, elle attend peut-être une approbation. Si elle est approuvée mais non délivrée, le signataire peut être en échec.

Vérifiez les détails de la CSR, y compris les usages demandés et le nom du signataire :

```bash
kubectl get csr <csr-name> -o yaml
```

### Vérification des journaux du gestionnaire de contrôleurs

Les journaux du gestionnaire de contrôleurs contiennent souvent des erreurs liées à la signature des CSR. Récupérez les journaux :

```bash
kubectl logs -n kube-system <controller-manager-pod> | grep -i csr
```

Recherchez des messages comme `failed to sign CSR` ou `certificate signing error`.

### Utilisation d'outils de traçage réseau

Pour un diagnostic plus approfondi, vous pouvez utiliser `tcpdump` sur les nœuds pour capturer le trafic vers le serveur d'API.

```bash
sudo tcpdump -i any port 6443 -w /tmp/api-traffic.pcap
```

Analysez ensuite avec Wireshark si nécessaire.

### Exemple : Diagnostic d'un retard d'approbation de CSR

Supposons qu'une CSR reste à l'état `Pending` même après approbation. Vérifiez les journaux du gestionnaire de contrôleurs et observez :

```
E0120 10:00:00.123456       1 certificate_manager.go:562] kubernetes.io/kube-apiserver-client-kubelet: Failed while requesting a signed certificate from the cluster: cannot create certificate signing request: Post "https://api.example.com:6443/apis/certificates.k8s.io/v1/certificatesigningrequests": dial tcp: i/o timeout
```

Cela indique que le gestionnaire de contrôleurs ne peut pas joindre le serveur d'API. Procédez à la vérification de la connectivité depuis le nœud du pod du gestionnaire de contrôleurs vers le serveur d'API, comme décrit précédemment.

## Modes de défaillance et récupération

Le réseau des CSR peut échouer de plusieurs manières. Cette section décrit les modes de défaillance courants et comment s'en remettre.

### Mode de défaillance 1 : Serveur d'API injoignable

**Symptômes :** Les nœuds ne peuvent pas créer de CSR, les clients reçoivent des erreurs `connection refused` ou `timeout`, et les commandes `kubectl` se bloquent.

**Causes possibles :**
- Le pod du serveur d'API ne s'exécute pas.
- Mauvaise configuration réseau, règles de pare-feu ou politiques réseau bloquant le port 6443.
- Mauvaise configuration de l'équilibreur de charge.

**Étapes de récupération :**
1. Vérifiez si le pod du serveur d'API s'exécute :
   ```bash
   kubectl get pods -n kube-system | grep kube-apiserver
   ```
2. S'il ne s'exécute pas, inspectez pourquoi (describe, logs).
3. Vérifiez les règles de pare-feu : assurez-vous que le port 6443 est ouvert.
4. Testez la connectivité depuis un nœud avec `curl -k https://<api-server>:6443/healthz`.
5. Si vous utilisez un équilibreur de charge, vérifiez sa configuration et la santé des backends.

### Mode de défaillance 2 : Échec de la résolution DNS

**Symptômes :** Les nœuds ne peuvent pas résoudre `api.example.com`, la création de CSR échoue avec `no such host`.

**Causes possibles :**
- CoreDNS ne s'exécute pas ou est mal configuré.
- Le `/etc/resolv.conf` du nœud pointe vers un serveur DNS incorrect.
- Une politique réseau bloque le trafic DNS (port UDP/TCP 53).

**Étapes de récupération :**
1. Vérifiez les pods CoreDNS :
   ```bash
   kubectl get pods -n kube-system -l k8s-app=kube-dns
   ```
2. Testez le DNS depuis un nœud : `nslookup api.example.com`.
3. Vérifiez `/etc/resolv.conf` ; assurez-vous qu'il inclut l'adresse IP DNS du cluster (généralement 10.96.0.10).
4. Passez en revue les politiques réseau pour le DNS.

### Mode de défaillance 3 : CSR bloquée en attente

**Symptômes :** La CSR existe mais n'est jamais approuvée ni signée.

**Causes possibles :**
- Aucun approbateur configuré (par exemple, pas d'approbateur CSR dans le gestionnaire de contrôleurs).
- Signataire non configuré ou fichiers CA manquants.
- Permissions insuffisantes.

**Étapes de récupération :**
1. Vérifiez les drapeaux du gestionnaire de contrôleurs pour `--cluster-signing-cert-file` et `--cluster-signing-key-file`.
2. Assurez-vous que l'approbateur CSR s'exécute et ne plante pas.
3. Approuvez manuellement si approprié :
   ```bash
   kubectl certificate approve <csr-name>
   ```
4. Si la CSR est signée mais que le certificat n'est pas délivré, vérifiez les journaux du gestionnaire de contrôleurs pour les erreurs.

### Mode de défaillance 4 : Certificat non approuvé

**Symptômes :** Après l'approbation et la signature de la CSR, les clients rejettent le certificat.

**Causes possibles :**
- Mauvaise autorité de certification (CA) utilisée pour signer.
- Le certificat ne contient pas les usages requis ou les SAN (Subject Alternative Names).

**Étapes de récupération :**
1. Vérifiez les détails du certificat :
   ```bash
   kubectl get csr <csr-name> -o jsonpath='{.status.certificate}' | base64 -d | openssl x509 -text -noout
   ```
2. Vérifiez que le signataire est bien la CA du cluster.
3. Si nécessaire, recréez la CSR avec les usages et SAN corrects.

### Documentation de récupération

Documentez toujours le mode de défaillance, les étapes effectuées et la vérification. Cela aide lors des incidents futurs et pour la conformité aux audits.

## Liste de contrôle opérationnelle

Cette liste de contrôle résume les étapes pour dépanner les problèmes réseau liés aux CSR. Utilisez-la comme référence rapide pendant les incidents.

| Étape | Action | Commande/Signal | Résultat attendu |
|------|--------|----------------|-----------------|
| 1 | Vérifier la version du cluster | `kubectl version --short` | Version du serveur >=1.19 pour l'API CSR v1 |
| 2 | Vérifier la disponibilité de l'API CSR | `kubectl get csr` | Pas d'erreur, une liste apparaît |
| 3 | Vérifier le statut des nœuds | `kubectl get nodes` | Tous les nœuds sont `Ready` |
| 4 | Tester la connectivité au serveur d'API | `curl -k https://<api-server>:6443/healthz` | `ok` |
| 5 | Tester la résolution DNS | `nslookup api.example.com` | Adresse IP correcte retournée |
| 6 | Vérifier les journaux de CoreDNS | `kubectl logs -n kube-system -l k8s-app=kube-dns` | Pas d'erreurs `SERVFAIL` |
| 7 | Inspecter les CSR en attente | `kubectl describe csr <csr-name>` | Les conditions indiquent `Pending` |
| 8 | Vérifier les journaux du gestionnaire de contrôleurs | `kubectl logs -n kube-system <controller-manager-pod> \| grep -i csr` | Pas d'erreurs de signature |
| 9 | Vérifier la configuration du signataire | Vérifier les drapeaux du gestionnaire de contrôleurs pour les fichiers CA | Les drapeaux sont présents et les fichiers existent |
| 10 | Test d'approbation manuelle | `kubectl certificate approve <csr-name>` | La CSR devient `Approved,Issued` |

## Conclusion

Le dépannage des problèmes réseau liés aux CSR Kubernetes nécessite une approche systématique : comprendre votre environnement, vérifier la connectivité, diagnostiquer les défaillances et appliquer des correctifs sûrs. En suivant les étapes de ce guide, avec des commandes et des exemples concrets, vous pouvez résoudre les problèmes efficacement. N'oubliez pas de toujours observer avant de modifier, de limiter le rayon d'impact, de protéger les données sensibles et de documenter vos procédures de récupération. Avec ces pratiques, vous pouvez maintenir un cluster Kubernetes sécurisé et fiable. Continuez à développer vos compétences en dépannage en vous exerçant dans un environnement de test et en vous tenant à jour avec les versions de Kubernetes.