## Introduction

Les commandes de contexte de sécurité Kubernetes sont fondamentales pour exécuter des charges de travail avec le moindre privilège. Un contexte de sécurité définit les paramètres de privilèges et de contrôle d'accès pour un Pod ou un conteneur, notamment les identifiants d'utilisateur et de groupe, les capacités Linux, les profils seccomp et les options SELinux. Ce guide fournit des commandes et des exemples pratiques pour aider les opérateurs, les développeurs et les ingénieurs DevOps à configurer et vérifier les contextes de sécurité de manière sûre et efficace.

L'objectif est la sécurité opérationnelle : 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. À la fin de cet article, vous serez en mesure d'inspecter les contextes de sécurité actuels, d'appliquer les paramètres appropriés et de résoudre les problèmes courants en toute confiance.

## Inventaire de la version et de l'environnement

Avant de modifier un contexte de sécurité, vous devez comprendre votre environnement et son état actuel. Cette section explique comment inventorier votre cluster, identifier les composants pertinents et vérifier la version de Kubernetes.

### Étape 1 : Vérifier la version de Kubernetes et la prise en charge de l'API

Les champs de contexte de sécurité ont évolué au fil des versions de Kubernetes. Confirmez toujours la version de votre cluster et la disponibilité de l'API avant d'appliquer des manifestes.

kubectl version --short 
 Exemple de sortie :

Client Version: v1.28.2
Server Version: v1.28.3 
 Notes de compatibilité clés :

- runAsUser , runAsGroup , fsGroup et supplementalGroups sont stables et disponibles dans toutes les versions prises en charge.

- seccompProfile est devenu GA en v1.19 ; utilisez securityContext.seccompProfile.type plutôt que des annotations.

- allowPrivilegeEscalation est stable ; définissez-le à false chaque fois que possible.

- Le champ capabilities est stable ; préférez la liste drop à add .

- windowsOptions concerne les conteneurs Windows (par exemple, runAsUserName ).

### Étape 2 : Inventorier les contextes de sécurité existants

Avant de modifier quoi que ce soit, observez les Pods existants et leurs paramètres de sécurité. Cette étape en lecture seule vous aide à comprendre la posture de risque actuelle.

Listez tous les Pods avec une sortie large pour voir le placement des nœuds et l'état :

kubectl get pods -A -o wide 
 Pour inspecter le contexte de sécurité complet d'un Pod spécifique, utilisez kubectl get avec une sortie YAML ou JSON. Par exemple, pour afficher le contexte de sécurité d'un Pod nommé nginx-secure dans l'espace de noms default :

kubectl get pod nginx-secure -n default -o yaml 
 Recherchez la section securityContext au niveau du Pod et du conteneur. Voici un extrait d'un Pod avec un contexte restrictif :

spec:
 securityContext:
 runAsNonRoot: true
 runAsUser: 1000
 runAsGroup: 3000
 fsGroup: 2000
 seccompProfile:
 type: RuntimeDefault
 containers:
 - name: nginx
 image: nginx:1.25
 securityContext:
 allowPrivilegeEscalation: false
 capabilities:
 drop:
 - ALL
 runAsNonRoot: true
 runAsUser: 1000 
 Vous pouvez également utiliser kubectl describe pour voir les événements et repérer rapidement les problèmes liés à la sécurité, comme un Pod qui ne démarre pas à cause d'un utilisateur non root ou de capacités manquantes.

### Étape 3 : Vérifier les prérequis

Les contextes de sécurité dépendent du runtime de conteneur et des fonctionnalités du système d'exploitation. Assurez-vous que :

- Le runtime de conteneur (containerd, CRI-O) prend en charge les champs que vous comptez utiliser.

- Si vous utilisez des profils seccomp, le fichier de profil est présent sur le nœud ou chargé en tant que ressource personnalisée.

- Les politiques SELinux ou AppArmor sont alignées avec vos paramètres.

- Le compte de service du Pod a la permission pour toutes les ressources supplémentaires, bien que les modifications du contexte de sécurité ne nécessitent pas de RBAC supplémentaire.

Une vérification rapide du support seccomp :

kubectl get nodes -o jsonpath='{.items[*].metadata.name}' | xargs -I {} kubectl get node {} -o jsonpath='{.status.nodeInfo.containerRuntimeVersion}' && echo 
 Exemple de sortie : containerd://1.7.2

<style>
.eno-quiz-widget{margin:2rem 0;padding:1.5rem;border-radius:12px;background:var(--eno-surface-lowest,#f7f7f8);border:1px solid var(--eno-border-soft,#e2e2e6);font-family:var(--eno-font-body,Inter,sans-serif)}
.eno-quiz-widget .eno-quiz-kicker{font-family:var(--eno-font-label,"JetBrains Mono",monospace);font-size:.75rem;letter-spacing:.05em;text-transform:uppercase;color:var(--eno-text-muted,#5f5f68);margin:0 0 .5rem}
.eno-quiz-widget .eno-quiz-question{font-family:var(--eno-font-heading,"Hanken Grotesk",sans-serif);font-size:1.0625rem;font-weight:600;margin:0 0 1rem;color:var(--eno-text-strong,#1a1a1f)}
.eno-quiz-widget .eno-quiz-options{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.5rem}
.eno-quiz-widget .eno-quiz-option{display:block;width:100%;min-height:44px;text-align:left;padding:.625rem .875rem;border-radius:8px;border:1.5px solid var(--eno-border-soft,#e2e2e6);background:#fff;font-size:.9375rem;cursor:pointer;transition:border-color var(--eno-motion-base,180ms ease-out),background var(--eno-motion-base,180ms ease-out)}
.eno-quiz-widget .eno-quiz-option:hover{border-color:var(--eno-primary,#0059bb)}
.eno-quiz-widget .eno-quiz-option:focus-visible{outline:none;box-shadow:0 0 0 3px rgb(0 89 187 / 0.15)}
.eno-quiz-widget .eno-quiz-option[aria-pressed="true"]{border-color:var(--eno-primary,#0059bb);background:rgb(0 89 187 / 0.06)}
.eno-quiz-widget .eno-quiz-option[data-correct="true"].eno-quiz-revealed{border-color:var(--eno-success,#17803a);background:rgb(23 128 58 / 0.08)}
.eno-quiz-widget .eno-quiz-option[data-correct="false"].eno-quiz-revealed.eno-quiz-was-selected{border-color:var(--eno-error,#ba1a1a);background:var(--eno-error-soft,#ffdad6)}
.eno-quiz-widget .eno-quiz-option-icon{display:inline-block;width:1.1em;margin-right:.4em;font-weight:700}
.eno-quiz-widget .eno-quiz-submit{margin-top:1rem;min-height:44px;padding:.5rem 1.25rem;border-radius:8px;border:none;background:var(--eno-primary,#0059bb);color:#fff;font-weight:600;font-size:.9375rem;cursor:pointer;transition:opacity var(--eno-motion-base,180ms ease-out)}
.eno-quiz-widget .eno-quiz-submit:disabled{opacity:.5;cursor:not-allowed}
.eno-quiz-widget .eno-quiz-submit:focus-visible{outline:none;box-shadow:0 0 0 3px rgb(0 89 187 / 0.15)}
.eno-quiz-widget .eno-quiz-explanation{margin-top:1rem;padding:.875rem 1rem;border-radius:8px;font-size:.9375rem;line-height:1.5;display:none}
.eno-quiz-widget .eno-quiz-explanation.eno-quiz-visible{display:block}
.eno-quiz-widget .eno-quiz-explanation.eno-quiz-correct{background:rgb(23 128 58 / 0.08);color:var(--eno-success,#17803a)}
.eno-quiz-widget .eno-quiz-explanation.eno-quiz-incorrect{background:var(--eno-error-soft,#ffdad6);color:var(--eno-error,#ba1a1a)}
@media (prefers-reduced-motion: reduce){.eno-quiz-widget *{transition:none!important}}
</style><div class="eno-quiz-widget" role="group" aria-label="Question rapide">
Question rapide 1 sur 2

Lequel des champs suivants de securityContext est utilisé pour spécifier l'ID de groupe principal pour tous les processus à l'intérieur des conteneurs d'un Pod ?

- runAsUser
- runAsGroup
- fsGroup
- supplementalGroups

<button type="button" class="eno-quiz-submit" disabled>Valider</button>
<div class="eno-quiz-explanation">Le passage indique : « Le champ runAsGroup spécifie l&#39;ID de groupe principal 3000 pour tous les processus dans tous les conteneurs du Pod. »</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function () {
  document.querySelectorAll('.eno-quiz-widget:not([data-eno-quiz-bound])').forEach(function (widget) {
    widget.setAttribute('data-eno-quiz-bound', '1');
    var options = Array.prototype.slice.call(widget.querySelectorAll('.eno-quiz-option'));
    var submitBtn = widget.querySelector('.eno-quiz-submit');
    var explanation = widget.querySelector('.eno-quiz-explanation');
    var selected = null;
    options.forEach(function (opt) {
      opt.addEventListener('click', function () {
        if (widget.hasAttribute('data-eno-quiz-answered')) return;
        options.forEach(function (o) { o.setAttribute('aria-pressed', 'false'); });
        opt.setAttribute('aria-pressed', 'true');
        selected = opt;
        submitBtn.disabled = false;
      });
    });
    submitBtn.addEventListener('click', function () {
      if (!selected || widget.hasAttribute('data-eno-quiz-answered')) return;
      widget.setAttribute('data-eno-quiz-answered', '1');
      submitBtn.disabled = true;
      var correct = selected.getAttribute('data-correct') === 'true';
      options.forEach(function (o) {
        o.classList.add('eno-quiz-revealed');
        if (o === selected) o.classList.add('eno-quiz-was-selected');
        var icon = o.querySelector('.eno-quiz-option-icon');
        if (o.getAttribute('data-correct') === 'true') icon.textContent = '\u2713';
        else if (o === selected) icon.textContent = '\u2717';
      });
      explanation.classList.add('eno-quiz-visible', correct ? 'eno-quiz-correct' : 'eno-quiz-incorrect');
    });
  });
});
</script>

## Chemin de configuration sûr

Maintenant que vous avez observé l'environnement, vous pouvez effectuer des modifications minimes et justifiées. Cette section fournit des exemples concrets pour les configurations de contexte de sécurité courantes, en mettant l'accent sur une approche de moindre privilège.

### Principes généraux

- Appliquez un changement à la fois.

- Définissez toujours runAsNonRoot: true sauf si le conteneur a réellement besoin de root.

- Utilisez des identifiants runAsUser et runAsGroup spécifiques pour éviter de dépendre des valeurs par défaut de l'image.

- Supprimez toutes les capacités et n'ajoutez que celles qui sont nécessaires.

- Définissez allowPrivilegeEscalation: false .

- Utilisez un profil seccomp par défaut du runtime ( RuntimeDefault ) comme base ; envisagez un profil personnalisé pour un contrôle plus strict.

- Évitez les conteneurs privilégiés ; si c'est inévitable, définissez privileged: false partout ailleurs.

### Exemple 1 : Exécuter en tant qu'utilisateur non root

Une exigence stricte courante : le conteneur ne doit pas s'exécuter en tant que root. Créez un manifeste de Pod avec un contexte de sécurité qui définit un utilisateur non root.

Enregistrez le fichier suivant sous nonroot-pod.yaml :

apiVersion: v1
kind: Pod
metadata:
 name: nonroot-demo
spec:
 securityContext:
 runAsNonRoot: true
 runAsUser: 1000
 runAsGroup: 3000
 fsGroup: 2000
 containers:
 - name: app
 image: alpine:3.19
 command: ["sleep", "3600"]
 securityContext:
 allowPrivilegeEscalation: false 
 Appliquez-le :

kubectl apply -f nonroot-pod.yaml 
 Sortie attendue :

pod/nonroot-demo created 
 Vérifiez que le Pod est en cours d'exécution et que les processus du conteneur ne sont pas root :

kubectl exec nonroot-demo -- id 
 Sortie attendue (si l'utilisateur 1000 existe dans le conteneur) :

uid=1000 gid=3000 groups=3000,2000 
 Si l'image ne définit pas l'utilisateur 1000, le conteneur peut échouer avec container has runAsNonRoot and image will run as root , ce qui indique que vous devez choisir une image de base différente ou créer l'utilisateur dans l'image.

### Exemple 2 : Supprimer toutes les capacités et n'ajouter que celles nécessaires

Les capacités Linux accordent des privilèges fins. Supprimer toutes les capacités et n'ajouter que celles nécessaires réduit les risques.

Créez capabilities-pod.yaml :

apiVersion: v1
kind: Pod
metadata:
 name: capabilities-demo
spec:
 containers:
 - name: net-admin
 image: alpine:3.19
 command: ["sleep", "3600"]
 securityContext:
 allowPrivilegeEscalation: false
 capabilities:
 drop:
 - ALL
 add:
 - NET_BIND_SERVICE 
 Appliquez et vérifiez :

kubectl apply -f capabilities-pod.yaml
kubectl exec capabilities-demo -- capsh --print | grep Current 
 La sortie attendue montre uniquement les capacités autorisées, y compris net_bind_service .

### Exemple 3 : Appliquer un profil seccomp

Seccomp restreint les appels système. Commencez par le défaut du runtime, puis envisagez un profil personnalisé.

Seccomp au niveau du Pod (s'applique à tous les conteneurs) :

apiVersion: v1
kind: Pod
metadata:
 name: seccomp-demo
spec:
 securityContext:
 seccompProfile:
 type: RuntimeDefault
 containers:
 - name: app
 image: alpine:3.19
 command: ["sleep", "3600"] 
 Pour un profil personnalisé plus strict, créez un profil Localhost sur le nœud. Exemple de profil refusant chmod :

{
 "defaultAction": "SCMP_ACT_ERRNO",
 "architectures": ["SCMP_ARCH_X86_64"],
 "syscalls": [
 {
 "names": ["chmod", "fchmod", "fchmodat"],
 "action": "SCMP_ACT_ERRNO"
 }
 ]
} 
 Enregistrez-le sous custom-seccomp.json sur le nœud, puis référencez-le :

securityContext:
 seccompProfile:
 type: Localhost
 localhostProfile: custom-seccomp.json 
 Appliquez et testez en tentant chmod à l'intérieur du conteneur ; cela devrait échouer avec Operation not permitted .

### Étape 4 : Vérifier après application

Après chaque modification, vérifiez que le Pod démarre et se comporte comme prévu. Utilisez kubectl get pods pour vérifier l'état, kubectl describe pour les événements et kubectl logs pour les erreurs d'application. Pour un test fonctionnel rapide, utilisez kubectl exec pour exécuter des commandes à l'intérieur du conteneur.

Pour les déploiements, utilisez kubectl rollout status pour vous assurer que le déploiement se termine :

kubectl rollout status deployment/nginx-secure -n default 
 Sortie attendue : deployment "nginx-secure" successfully rolled out

## Vérification et diagnostics

Cette section explique comment vérifier que les contextes de sécurité fonctionnent comme prévu et comment diagnostiquer les problèmes lorsqu'ils ne le font pas.

### Vérifier les paramètres de sécurité réels au moment de l'exécution

Vous pouvez inspecter le contexte de sécurité effectif d'un conteneur en cours d'exécution en regardant les attributs de processus ou en utilisant kubectl exec pour interroger l'environnement.

Par exemple, pour vérifier l'utilisateur et les groupes :

kubectl exec -it nonroot-demo -- id 
 Sortie attendue : uid=1000 gid=3000 groups=2000 (ou similaire, selon l'image).

Pour vérifier les capacités à l'intérieur du conteneur, utilisez capsh (peut nécessiter une installation) :

kubectl exec capabilities-demo -- capsh --print 
 Recherchez la ligne de capacités Current: .

Pour vérifier le mode seccomp, utilisez kubectl get pod avec JSONPath ou inspectez le runtime de conteneur. Par exemple :

kubectl get pod seccomp-demo -o jsonpath='{.spec.securityContext.seccompProfile.type}' 
 Sortie attendue : RuntimeDefault

### Diagnostiquer les échecs courants

1. Le conteneur échoue avec CreateContainerConfigError

Souvent causé par des champs de contexte de sécurité invalides. Utilisez kubectl describe pod <nom> pour voir l'événement. Erreur courante : invalid value: 0: must be greater than or equal to 1 pour runAsUser . Corrigez en définissant un UID valide.

2. Pod bloqué dans ContainerCreating ou CrashLoopBackOff

Peut être dû à un profil seccomp introuvable. Vérifiez les événements :

kubectl describe pod seccomp-demo 
 Recherchez : cannot load seccomp profile . Corrigez en vous assurant que le fichier de profil existe sur le nœud et a les bonnes permissions.

3. Permission refusée à l'intérieur du conteneur malgré le non-root

Si le conteneur ne peut pas écrire sur un volume, assurez-vous que fsGroup est défini sur le groupe propriétaire du volume, ou utilisez un groupe supplémentaire. Par exemple :

securityContext:
 fsGroup: 2000
 runAsUser: 1000
 runAsGroup: 3000
 supplementalGroups: [2000] 
 4. La liaison réseau échoue

Si l'application doit se lier à un port inférieur à 1024, ajoutez la capacité NET_BIND_SERVICE comme montré précédemment. Alternativement, configurez l'application pour utiliser un port plus élevé.

5. Le conteneur ne peut pas utiliser setuid ou effectuer des opérations privilégiées

C'est attendu lorsque allowPrivilegeEscalation: false et que les capacités sont supprimées. Si c'est vraiment nécessaire, ajoutez la capacité spécifique, mais préférez modifier l'application pour l'éviter.

### Journalisation et surveillance

Les échecs de contexte de sécurité apparaissent souvent dans les journaux du conteneur ou les événements. Utilisez kubectl logs --previous pour voir les derniers journaux d'un conteneur planté :

kubectl logs nonroot-demo --previous 
 Pour une surveillance continue, envisagez de mettre en place une journalisation d'audit ou un moteur de politique comme OPA Gatekeeper ou Kyverno pour appliquer les contextes de sécurité.

<style>
.eno-quiz-widget{margin:2rem 0;padding:1.5rem;border-radius:12px;background:var(--eno-surface-lowest,#f7f7f8);border:1px solid var(--eno-border-soft,#e2e2e6);font-family:var(--eno-font-body,Inter,sans-serif)}
.eno-quiz-widget .eno-quiz-kicker{font-family:var(--eno-font-label,"JetBrains Mono",monospace);font-size:.75rem;letter-spacing:.05em;text-transform:uppercase;color:var(--eno-text-muted,#5f5f68);margin:0 0 .5rem}
.eno-quiz-widget .eno-quiz-question{font-family:var(--eno-font-heading,"Hanken Grotesk",sans-serif);font-size:1.0625rem;font-weight:600;margin:0 0 1rem;color:var(--eno-text-strong,#1a1a1f)}
.eno-quiz-widget .eno-quiz-options{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.5rem}
.eno-quiz-widget .eno-quiz-option{display:block;width:100%;min-height:44px;text-align:left;padding:.625rem .875rem;border-radius:8px;border:1.5px solid var(--eno-border-soft,#e2e2e6);background:#fff;font-size:.9375rem;cursor:pointer;transition:border-color var(--eno-motion-base,180ms ease-out),background var(--eno-motion-base,180ms ease-out)}
.eno-quiz-widget .eno-quiz-option:hover{border-color:var(--eno-primary,#0059bb)}
.eno-quiz-widget .eno-quiz-option:focus-visible{outline:none;box-shadow:0 0 0 3px rgb(0 89 187 / 0.15)}
.eno-quiz-widget .eno-quiz-option[aria-pressed="true"]{border-color:var(--eno-primary,#0059bb);background:rgb(0 89 187 / 0.06)}
.eno-quiz-widget .eno-quiz-option[data-correct="true"].eno-quiz-revealed{border-color:var(--eno-success,#17803a);background:rgb(23 128 58 / 0.08)}
.eno-quiz-widget .eno-quiz-option[data-correct="false"].eno-quiz-revealed.eno-quiz-was-selected{border-color:var(--eno-error,#ba1a1a);background:var(--eno-error-soft,#ffdad6)}
.eno-quiz-widget .eno-quiz-option-icon{display:inline-block;width:1.1em;margin-right:.4em;font-weight:700}
.eno-quiz-widget .eno-quiz-submit{margin-top:1rem;min-height:44px;padding:.5rem 1.25rem;border-radius:8px;border:none;background:var(--eno-primary,#0059bb);color:#fff;font-weight:600;font-size:.9375rem;cursor:pointer;transition:opacity var(--eno-motion-base,180ms ease-out)}
.eno-quiz-widget .eno-quiz-submit:disabled{opacity:.5;cursor:not-allowed}
.eno-quiz-widget .eno-quiz-submit:focus-visible{outline:none;box-shadow:0 0 0 3px rgb(0 89 187 / 0.15)}
.eno-quiz-widget .eno-quiz-explanation{margin-top:1rem;padding:.875rem 1rem;border-radius:8px;font-size:.9375rem;line-height:1.5;display:none}
.eno-quiz-widget .eno-quiz-explanation.eno-quiz-visible{display:block}
.eno-quiz-widget .eno-quiz-explanation.eno-quiz-correct{background:rgb(23 128 58 / 0.08);color:var(--eno-success,#17803a)}
.eno-quiz-widget .eno-quiz-explanation.eno-quiz-incorrect{background:var(--eno-error-soft,#ffdad6);color:var(--eno-error,#ba1a1a)}
@media (prefers-reduced-motion: reduce){.eno-quiz-widget *{transition:none!important}}
</style><div class="eno-quiz-widget" role="group" aria-label="Question rapide">
Question rapide 2 sur 2

Selon l'article, quel type de profil seccomp est devenu GA dans Kubernetes v1.19 et doit être utilisé à la place des annotations ?

- RuntimeDefault
- Localhost
- Unconfined
- Personnalisé

<button type="button" class="eno-quiz-submit" disabled>Valider</button>
<div class="eno-quiz-explanation">L&#39;article indique : « seccompProfile est devenu GA dans la v1.19 ; utilisez securityContext.seccompProfile.type plutôt que les annotations. »</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function () {
  document.querySelectorAll('.eno-quiz-widget:not([data-eno-quiz-bound])').forEach(function (widget) {
    widget.setAttribute('data-eno-quiz-bound', '1');
    var options = Array.prototype.slice.call(widget.querySelectorAll('.eno-quiz-option'));
    var submitBtn = widget.querySelector('.eno-quiz-submit');
    var explanation = widget.querySelector('.eno-quiz-explanation');
    var selected = null;
    options.forEach(function (opt) {
      opt.addEventListener('click', function () {
        if (widget.hasAttribute('data-eno-quiz-answered')) return;
        options.forEach(function (o) { o.setAttribute('aria-pressed', 'false'); });
        opt.setAttribute('aria-pressed', 'true');
        selected = opt;
        submitBtn.disabled = false;
      });
    });
    submitBtn.addEventListener('click', function () {
      if (!selected || widget.hasAttribute('data-eno-quiz-answered')) return;
      widget.setAttribute('data-eno-quiz-answered', '1');
      submitBtn.disabled = true;
      var correct = selected.getAttribute('data-correct') === 'true';
      options.forEach(function (o) {
        o.classList.add('eno-quiz-revealed');
        if (o === selected) o.classList.add('eno-quiz-was-selected');
        var icon = o.querySelector('.eno-quiz-option-icon');
        if (o.getAttribute('data-correct') === 'true') icon.textContent = '\u2713';
        else if (o === selected) icon.textContent = '\u2717';
      });
      explanation.classList.add('eno-quiz-visible', correct ? 'eno-quiz-correct' : 'eno-quiz-incorrect');
    });
  });
});
</script>

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

Même avec une planification minutieuse, les choses peuvent mal tourner. Cette section décrit les scénarios de défaillance courants, leurs symptômes et les étapes de récupération.

### Scénario 1 : Le Pod refuse de démarrer en raison du contexte de sécurité

Symptôme : L'état du Pod est CreateContainerConfigError ou Error .

Diagnostic : Exécutez kubectl describe pod <nom> et recherchez les événements indiquant des valeurs de champs invalides, un profil seccomp manquant ou des options non prises en charge.

Récupération : Modifiez le Pod ou le déploiement pour corriger le contexte de sécurité. Par exemple, si runAsUser: 0 avec runAsNonRoot: true , changez runAsUser pour un UID non nul ou supprimez runAsNonRoot . Ensuite, supprimez et recréez le Pod (ou déployez le déploiement).

### Scénario 2 : L'application échoue à l'exécution en raison de permissions manquantes

Symptôme : Le conteneur démarre mais l'application se termine avec des erreurs de permission ou plante.

Diagnostic : Vérifiez les journaux du conteneur avec kubectl logs <pod> . Recherchez des messages comme « permission denied » ou « operation not permitted ».

Récupération : Déterminez quel changement de capacité ou d'utilisateur est nécessaire. Accordez le privilège supplémentaire minimal. Par exemple, si l'application a besoin de modifier l'heure système, ajoutez la capacité SYS_TIME . Mettez à jour le manifeste et appliquez.

### Scénario 3 : Le déploiement d'un changement de contexte de sécurité provoque une interruption

Symptôme : Après la mise à jour d'un déploiement avec un nouveau contexte de sécurité, les nouveaux Pods échouent et les anciens Pods sont terminés, laissant aucune réplique disponible.

Diagnostic : Vérifiez kubectl rollout status deployment/<nom> pour le message d'échec. Inspectez les nouveaux Pods avec kubectl describe et kubectl logs .

Récupération : Revenez immédiatement à la révision précédente :

kubectl rollout undo deployment/nginx-secure 
 Ensuite, déboguez le problème dans un espace de noms séparé ou avec un seul Pod avant de réappliquer.

### Scénario 4 : Le profil seccomp bloque les appels système requis

Symptôme : Le conteneur échoue avec une erreur (souvent EPERM ou EACCES ) sur une opération spécifique.

Diagnostic : Vérifiez les journaux de l'application ou utilisez strace si disponible. Vérifiez également le profil seccomp appliqué : kubectl get pod <nom> -o jsonpath='{.spec.securityContext.seccompProfile}' .

Récupération : Modifiez le profil seccomp personnalisé pour autoriser l'appel système nécessaire, ou passez temporairement à RuntimeDefault pour les tests. Rechargez le profil et redémarrez le Pod.

### Bonnes pratiques générales de récupération

- Ayez toujours un plan de retour en arrière : utilisez des manifestes versionnés, GitOps, ou au moins kubectl rollout undo .

- Testez les changements dans un environnement de préproduction d'abord.

- Gardez une sauvegarde de la spécification du Pod d'origine : kubectl get pod <nom> -o yaml > pod-backup.yaml avant de le modifier.

- Documentez la défaillance et la récupération dans votre manuel d'exploitation.

## Liste de contrôle des opérations

Utilisez la liste de contrôle suivante avant et après avoir modifié les contextes de sécurité en production.

### Avant d'appliquer les changements

- [ ] Confirmez que la version de Kubernetes prend en charge les champs de contexte de sécurité que vous prévoyez d'utiliser.

- [ ] Vérifiez le contexte de sécurité actuel : kubectl get pod <nom> -o yaml .

- [ ] Identifiez l'utilisateur et le groupe d'exécution du conteneur : kubectl exec -- id (s'il est en cours d'exécution).

- [ ] Listez les capacités actuelles : kubectl exec -- capsh --print (si disponible).

- [ ] Vérifiez l'état du profil seccomp : kubectl get pod -o jsonpath='{.spec.securityContext.seccompProfile}' .

- [ ] Sauvegardez le YAML du Pod/Déploiement : kubectl get -o yaml > backup.yaml .

- [ ] Déterminez les privilèges minimaux requis (utilisateur, capacités, etc.) en consultant la documentation de l'application ou en testant localement.

- [ ] Préparez une commande de retour en arrière : kubectl rollout undo deployment/ ou gardez le YAML d'origine prêt.

- [ ] Informez les membres de l'équipe concernés de la fenêtre de changement.

### Après avoir appliqué les changements

- [ ] Vérifiez l'état du Pod : kubectl get pods -n -o wide .

- [ ] Vérifiez que le contexte de sécurité est correctement défini : kubectl get pod -o yaml | grep -A10 securityContext .

- [ ] Confirmez que le conteneur s'exécute avec l'utilisateur attendu : kubectl exec -- id .

- [ ] Validez les capacités : kubectl exec -- capsh --print (si disponible).

- [ ] Vérifiez les journaux de l'application pour les erreurs : kubectl logs .

- [ ] Testez les fonctionnalités critiques (par exemple, un contrôle de santé HTTP).

- [ ] Surveillez pendant quelques minutes : kubectl get pods -w .

- [ ] Mettez à jour la documentation et les manuels d'exploitation avec la nouvelle configuration.

- [ ] Supprimez tous les outils de diagnostic ou permissions temporaires.

### Exemple de liste de contrôle remplie pour une charge de travail réelle

 Supposons que vous sécurisez un déploiement Nginx dans l'espace de noms web .

- État actuel : Pod nginx-6d4b7c9f8-abcde s'exécutant en tant que root, pas de seccomp, toutes les capacités.

- État souhaité : S'exécuter en tant qu'UID 1000, supprimer toutes les capacités, seccomp RuntimeDefault.

- Sauvegarde : kubectl get deployment nginx -n web -o yaml > nginx-deployment-backup.yaml .

- Appliquer le changement : Modifiez le déploiement pour ajouter le contexte de sécurité.

- Déploiement : kubectl rollout status deployment/nginx -n web .

- Vérifier : kubectl exec -n web <nouveau-pod> -- id renvoie uid=1000 .

- Tester : curl le service ; attendez un HTTP 200.

- Retour en arrière si nécessaire : kubectl rollout undo deployment/nginx -n web .

Gardez cette liste de contrôle comme modèle et adaptez-la à votre flux de travail.

## Conclusion

Les commandes de contexte de sécurité Kubernetes sont essentielles pour durcir vos charges de travail. En suivant une approche structurée—inventorier l'environnement, apporter des modifications minimes, vérifier les résultats et planifier la récupération—vous pouvez réduire la surface d'attaque sans sacrifier la fonctionnalité.

Commencez par les bases : exécutez les conteneurs en tant que non-root, supprimez les capacités inutiles et appliquez un profil seccomp. Utilisez les commandes et les exemples de ce guide pour inspecter et ajuster vos contextes de sécurité en toute sécurité. Rappelez-vous que la sécurité est un processus continu ; examinez régulièrement vos configurations et restez à jour avec les versions de Kubernetes.

Pour en savoir plus, explorez la documentation Kubernetes sur les normes de sécurité des Pods, l'admission de sécurité des Pods et des outils comme kube-bench pour auditer la posture de sécurité de votre cluster.