Un Pod suit un cycle de vie défini. Il commence à l'état Pending
, traverse l'état Running
s'il démarre correctement, puis peut finir dans les états Succeeded
ou Failed
selon le résultat de son exécution. Il peut aussi être à l'état Unknown
si le nœud sur lequel il s'exécute devient injoignable.
Voici les phases principales du cycle de vie d'un Pod :
restartPolicy
).restartPolicy
est Never
ou OnFailure
et que les tentatives de redémarrage sont épuisées ou non applicables.On peut vérifier la phase d'un Pod avec kubectl get pod <nom-du-pod> -o wide
ou en examinant le champ status.phase
dans la sortie kubectl describe pod <nom-du-pod>
ou kubectl get pod <nom-du-pod> -o yaml
.
Lorsque l'on exécute une application sur Kubernetes on peut vouloir passer une configuration dynamique à notre pod (mot de passe BDD, token API etc...). Pour gérer celà il existe différents moyens de faire.
ConfigMaps peut stocker des données sous forme de clé/valeur. Les ConfigMaps peuvent être passées au container.
apiVersion: v1
kind: ConfigMap
metadata:
name: my-configmap
data:
key1: Hello, world!
key2: |
Test
multiple lines
more lines
key3: |
subkey:
morekey: data
encoreplus: plus de data
Les Secrets sont similaires aux ConfigMaps mais les Secrets ont été conçu pour recevoir des données sensibles (mot de passe, clé API...). Les Secrets sont créés et utilisés de la même façon qu'une ConfigMap.
apiVersion: v1
kind: Secret
metadata:
name: my-secret
type: Opaque # Il existe différents types de Secret : service-account-token, dockercfg, ssh-auth...
data:
username: <base64> # Les valeurs dans `data` DOIVENT être encodées en base64. Ex: echo -n 'user' | base64
password: <base64> # Ex: echo -n 'password' | base64
Kubernetes propose aussi le champ stringData
qui permet de fournir les secrets sans encodage base64 préalable dans le manifeste YAML. Kubernetes s'occupera de l'encodage pour vous lors de la création/mise à jour. Notez que stringData
est en écriture seule ; kubectl get secret my-secret -o yaml
affichera toujours les valeurs encodées dans le champ data
.
apiVersion: v1
kind: Secret
metadata:
name: my-secret-stringdata
type: Opaque
stringData:
# Pas besoin d'encoder en base64 ici
username: user
api_key: "maSuperCleAPI123"
Il est également possible de rendre les Secrets (et ConfigMaps) immuables en ajoutant le champ immutable: true
dans leur définition. Une fois créé, un Secret immuable ne peut plus être modifié ou supprimé tant qu'il est utilisé par un Pod ou explicitement marqué pour suppression. Cela protège contre les modifications accidentelles qui pourraient impacter les applications en cours d'exécution.
apiVersion: v1
kind: Secret
metadata:
name: my-immutable-secret
immutable: true # Ce secret ne pourra plus être modifié
type: Opaque
data:
token: <base64>
Si on teste d'éditer le secret :
$ k edit secrets my-immutable-secret
error: secrets "my-immutable-secret" is invalid
A copy of your changes has been stored to "/tmp/kubectl-edit-3489768689.yaml"
error: Edit cancelled, no valid changes were saved.
# Si on modifie le fichier et qu'on essaie d'apply
$ k apply -f sec.yaml
The Secret "my-immutable-secret" is invalid: data: Forbidden: field is immutable when `immutable` is set
Plus d'informations sur les types de secrets ici.
On peut passer les ConfigMaps ainsi que les Secrets comme des variables d'environnement. Les variables seront alors visibles lors de l'exécution du container.
spec:
containers:
- ...
env:
- name: ENVVAR
valueFrom:
configMapKeyRef:
name: my-configmap
key: mykey
Notre container aura ici une variable $ENVVAR contenant la valeur de la clé mykey.
On peut aussi passer notre configuration depuis un volume. La configuration sera donc disponible dans un fichier monté sur le container.
...
volumes:
- name: secret-vol
secret:
secretName: my-secret
En pratique :
configmap.yml :
apiVersion: v1
kind: ConfigMap
metadata:
name: my-configmap
data:
key1: Hello, world!
key2: |
Test
multiple lines
more lines
Si on décrit cette configmap (une fois appliquée) :
$ kubectl describe configmaps my-configmap
Name: my-configmap
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
key1:
----
Hello, world!
key2:
----
Test
multiple lines
more lines
Events: <none>
$ echo -n 'utilisateur' | base64
dXRpbGlzYXRldXI=
$ echo -n 'motdepasse' | base64
bW90ZGVwYXNzZQ==
secret.yml :
apiVersion: v1
kind: Secret
metadata:
name: my-secret
type: Opaque
data:
secretkey1: dXRpbGlzYXRldXI=
secretkey2: bW90ZGVwYXNzZQ==
Si on décrit le Secret :
$ kubectl describe secrets my-secret
Name: my-secret
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
secretkey1: 11 bytes
secretkey2: 10 bytes
apiVersion: v1
kind: Pod
metadata:
name: env-pod
spec:
containers:
- name: busybox
image: busybox
command: ['sh', '-c', 'echo "configmap: $CONFIGMAPVAR secret: $SECRETVAR"']
env:
- name: CONFIGMAPVAR
valueFrom:
configMapKeyRef:
name: my-configmap
key: key1
- name: SECRETVAR
valueFrom:
secretKeyRef:
name: my-secret
key: secretkey1
restartPolicy: Never
Si on regarde les logs, on devrait donc afficher key1 et secretkey1 :
$ kubectl logs env-pod
configmap: Hello, world! secret: utilisateur
apiVersion: v1
kind: Pod
metadata:
name: volume-pod
spec:
containers:
- name: busybox
image: busybox
command: ['sh', '-c', 'while true; do sleep 3600; done'] # Ne fait rien pendant 1h (3600s)
volumeMounts:
- name: configmap-volume
mountPath: /etc/config/configmap
- name: secret-volume
mountPath: /etc/config/secret
volumes:
- name: configmap-volume
configMap:
name: my-configmap
- name: secret-volume
secret:
secretName: my-secret
Ici, chaque clé sera un fichier différent :
$ kubectl exec volume-pod -- ls /etc/config/configmap
key1
key2
$ kubectl exec volume-pod -- cat /etc/config/configmap/key1
Hello, world!
$ kubectl exec volume-pod -- cat /etc/config/configmap/key2
Test
multiple lines
more lines
$ kubectl exec volume-pod -- ls /etc/config/secret
secretkey1
secretkey2
$ kubectl exec volume-pod -- cat /etc/config/secret/secretkey1
utilisateur
$ kubectl exec volume-pod -- cat /etc/config/secret/secretkey2
motdepasse
Nous pouvons limiter l'utilisation du CPU/RAM... De chaque container. Il est recommandé de mettre une limite par container afin d'éviter qu'un container prenne 90% des ressources, et ainsi, provoquant des OOM (Out Of Memory) sur les autres.
Il existe deux types de RessourceRequest :
Voici un pod avec une ResourceRequest :
apiVersion: v1
kind: Pod
metadata:
name: big-request-pod
spec:
containers:
- name: busybox
image: busybox
command: ['sh', '-c', 'while true; do sleep 3600; done']
resources:
requests:
cpu: "100m" # milliCPU soit 0,1 CPU
memory: "128Mi"
limits:
cpu: "250m" # milliCPU soit 0,25 CPU
memory: "256Mi"
Dans le cas on l'on demanderait plus de CPU/RAM que ce qu'il y a de disponible le pod resterait en pending le temps d'avoir un noeud avec la ressource nécessaire.
Kubernetes assigne une classe de QoS à chaque Pod en fonction des requests
et limits
définis pour les containers qu'il contient. Ces classes influencent la manière dont le scheduler de Kubernetes traite le Pod et comment le Kubelet gère les ressources sur le nœud (notamment en cas de manque de ressources). Il existe trois classes de QoS :
Guaranteed :
limits
et des requests
définis pour le CPU et la mémoire, et que les limits
sont égaux aux requests
.spec:
containers:
- name: guaranteed-container
image: busybox
resources:
requests:
memory: "200Mi"
cpu: "700m"
limits:
memory: "200Mi" # Égal à la request
cpu: "700m" # Égal à la request
Burstable :
requests
ou limits
définis pour le CPU ou la mémoire, mais que le Pod ne remplit pas les critères pour la classe Guaranteed
.requests
et limits
ne sont pas définis pour toutes les ressources (CPU/mémoire) ou qu'ils ne sont pas égaux.Guaranteed
en cas de pénurie.spec:
containers:
- name: burstable-container
image: busybox
resources:
requests:
memory: "100Mi"
cpu: "100m"
limits:
memory: "300Mi" # Différent de la request
# Pas de limit CPU
BestEffort :
requests
ou de limits
définis.spec:
containers:
- name: besteffort-container
image: busybox
# Aucune resources.requests ou resources.limits définies
Comprendre les classes de QoS est crucial pour la stabilité des applications, car cela détermine quels Pods seront prioritaires et lesquels seront sacrifiés lorsque les ressources viendront à manquer sur un nœud.
K8s permet de redémarrer les containers "unhealthy". Pour déterminer si un container est healthy/unhealthy il faut mettre en place une probe. Il existe trois types de probe principaux et trois mécanismes pour les exécuter :
Types de Probes :
restartPolicy
). Utile pour détecter les blocages (deadlocks) où l'application tourne mais ne répond plus.failureThreshold
), le Kubelet tue le container, qui est alors sujet à sa restartPolicy
. Utile pour les applications lentes au démarrage.Mécanismes de Probes :
Pour chaque type de probe, on peut utiliser l'un des mécanismes suivants pour vérifier l'état du container :
exec
: Exécute une commande spécifique à l'intérieur du container. La sonde est considérée comme réussie si la commande se termine avec un code de sortie 0.
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
httpGet
: Effectue une requête HTTP GET contre l'adresse IP du Pod sur un port et chemin spécifiés. La sonde est considérée comme réussie si le code de statut de la réponse est supérieur ou égal à 200 et inférieur à 400.
readinessProbe:
httpGet:
path: /healthz # Chemin de l'endpoint de santé
port: 8080 # Port où l'application écoute
initialDelaySeconds: 3
periodSeconds: 3
tcpSocket
: Tente d'ouvrir un socket TCP sur l'adresse IP du Pod au port spécifié. La sonde est considérée comme réussie si le port est ouvert et accessible.
livenessProbe:
tcpSocket:
port: 6379 # Port standard de Redis
initialDelaySeconds: 15
periodSeconds: 20
Paramètres communs des Probes :
Chaque probe a plusieurs champs pour contrôler son comportement :
initialDelaySeconds
: Nombre de secondes à attendre après le démarrage du container avant que la première sonde ne soit lancée. Défaut à 0.periodSeconds
: Fréquence (en secondes) à laquelle la sonde est exécutée. Défaut à 10.timeoutSeconds
: Nombre de secondes après lesquelles la sonde est considérée comme ayant échoué si elle n'a pas répondu. Défaut à 1.successThreshold
: Nombre minimum de succès consécutifs pour que la sonde soit considérée comme réussie après avoir échoué. Défaut à 1. Doit être 1 pour les liveness et startup probes.failureThreshold
: Nombre de tentatives échouées consécutives après lesquelles la sonde est considérée comme ayant échoué. Pour les liveness et startup probes, cela entraîne le redémarrage du container. Pour les readiness probes, le Pod est marqué comme non prêt. Défaut à 3.Exemples Pratiques :
apiVersion: v1
kind: Pod
metadata:
name: liveness-exec-pod
spec:
containers:
- name: busybox
image: busybox
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -f /tmp/healthy; sleep 600
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
failureThreshold: 1 # Redémarre dès le premier échec
Ici, le container crée un fichier /tmp/healthy
, attend 30s, le supprime, puis attend longtemps. La liveness probe vérifie l'existence du fichier toutes les 5s. Après 30s, le fichier est supprimé, la sonde échoue et le container est redémarré après failureThreshold
échecs.
apiVersion: v1
kind: Pod
metadata:
name: readiness-http-pod
spec:
containers:
- name: nginx
image: nginx:1.27.4
ports:
- containerPort: 80
readinessProbe:
httpGet:
path: / # Vérifie la page d'accueil Nginx
port: 80
initialDelaySeconds: 5 # Attend 5s que Nginx démarre
periodSeconds: 10
successThreshold: 1 # Considéré prêt dès le premier succès
Ce Pod ne recevra du trafic (via un Service par exemple) qu'une fois que la requête GET sur /
sur le port 80 réussit.
apiVersion: v1
kind: Pod
metadata:
name: startup-probe-pod
spec:
containers:
- name: slow-app
image: busybox # Simule une app lente
command: ['sh', '-c', 'echo "Starting up..."; sleep 60; echo "Ready!" > /tmp/ready; echo "Healthy!" > /tmp/healthy; while true; do sleep 1; done']
startupProbe:
exec:
command:
- cat
- /tmp/ready # Supposons que l'app crée ce fichier quand elle est prête
# Laisse jusqu'à 120s (12*10) pour démarrer
failureThreshold: 12
periodSeconds: 10
livenessProbe: # La liveness probe ne démarre qu'après succès de la startup probe
exec:
command:
- cat
- /tmp/healthy # Vérifie si le fichier /tmp/healthy existe
initialDelaySeconds: 5
periodSeconds: 5
Ici, la startupProbe
vérifie toutes les 10 secondes si /tmp/ready
existe, avec une tolérance de 12 échecs (120 secondes). La livenessProbe
ne commencera ses vérifications qu'une fois que la startupProbe
aura réussi.
Kubernetes peut redémarrer des containers quand ils se stoppent. Les politiques de redémarrages nous permettent de configurer quand est-ce que k8s doit redémarrer le container ou non.
Politique par défaut. Avec cette politique, les containers redémarreront s'ils se stoppent même s'il n'y a pas d'erreur. Utiliser cette politique si on veut qu'une app soit tout le temps UP.
apiVersion: v1
kind: Pod
metadata:
name: always-pod
spec:
restartPolicy: Always
containers:
- name: busybox
image: busybox
command: ['sh', '-c', 'sleep 10']
Toutes les 10s le container sera redémarré.
OnFailure comme son nom l'indique, redémarre si et uniquement si le container se stoppe avec un code erreur ou si la liveness probe indique qu'il est unhealthy. Utiliser cette politique pour des applications éphémères (start --> effectue une action --> stop).
apiVersion: v1
kind: Pod
metadata:
name: onfailure-pod
spec:
restartPolicy: OnFailure
containers:
- name: busybox
image: busybox
command: ['sh', '-c', 'sleep 10']
Ici, le container ne sera pas redémarré car le container stoppe avec un code 0. Il sera en statut "Completed".
apiVersion: v1
kind: Pod
metadata:
name: onfailure-pod
spec:
restartPolicy: OnFailure
containers:
- name: busybox
image: busybox
command: ['sh', '-c', 'sleep 10; Commande avec une erreur!']
La commande sortira une erreur (exit 1), le container sera donc redémarré.
Comme son nom l'indique, Never ne redémarre jamais le pod. Utiliser cette politique pour les applications qui doivent tourner qu'une seule fois.
apiVersion: v1
kind: Pod
metadata:
name: never-pod
spec:
restartPolicy: Never
containers:
- name: busybox
image: busybox
command: ['sh', '-c', 'sleep 10; Commande avec une erreur!']
Le container ne sera pas redémarré, il sera en statut "Error".
Pour vérifier les événements d'un pod (liveness, restart...) on peut décrire le pod :
$ kubectl describe pod my-busybox
...
Liveness: http-get http://:8080/ delay=5s timeout=1s period=5s #success=1 #failure=3
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning Unhealthy 39s (x3 over 49s) kubelet Liveness probe failed: HTTP probe failed with statuscode: 500
Normal Killing 39s kubelet Container shipping-data failed liveness probe, will be restarted
Normal Pulled 9s (x2 over 93s) kubelet Container image "linuxacademycontent/random-crashing-web-server:1" already present on machine
Comme on le sait, un pod peut contenir un ou plusieurs container. Les pod multi-container partagent le réseau et le stockage.
Best Practice : éviter autant que possible de faire des pods multi containers.
Les containers partageant le même pod peuvent intéragir entre eux en utilisant les ressources partagées :
Voici une définition d'un pod multi containers :
apiVersion: v1
kind: Pod
metadata:
name: multi-container-pod
spec:
containers:
- name: nginx
image: nginx
- name: redis
image: redis
- name: couchbase
image: couchbase
On voit donc que le pod possèdera 3 containers (nginx, redis, couchbase). Aucun intérêt mais c'est pour l'exemple.
On va maintenant créer un pod avec 2 containers. Un qui écrit dans un fichier de log, l'autre qui écrit ces logs directement dans la console :
apiVersion: v1
kind: Pod
metadata:
name: sidecar-pod
spec:
containers:
- name: busybox1
image: busybox
command: ['sh', '-c', 'while true; do echo logs data > /output/output.log; sleep 5; done']
volumeMounts:
- name: sharedvol
mountPath: /output
- name: sidecar
image: busybox
command: ['sh', '-c', 'tail -f /input/output.log']
volumeMounts:
- name: sharedvol
mountPath: /input
volumes:
- name: sharedvol
emptyDir: {}
On va ensuite afficher les logs du container sidecar :
$ kubectl logs sidecar-pod -c sidecar
logs data
Init containers sont des containers qui s'exécutent qu'une seule fois au démarrage d'un pod. Un pod peut avoir plusieurs init containers, ils tourneront chacun leur tour (dans l'ordre).
On peut utiliser les init containers afin de faire différentes tâches au démarrage du pod. Ils peuvent contenir des outils qui ne sont pas utilisés par l'application principale.
C'est une manière d'alléger l'application et être plus sécurisé.
Exemple d'utilisation :
apiVersion: v1
kind: Pod
metadata:
name: init-pod
spec:
containers:
- name: nginx
image: nginx:1.27.4
initContainers:
- name: delay
image: busybox
command: ['sleep', '30']
L'application principale (nginx) attendra donc 30s avant d'être démarrée.
Une fois lancé, on peut lister le pod :
$ kubectl get pod init-pod
NAME READY STATUS RESTARTS AGE
init-pod 0/1 Init:0/1 0 7s
Le DNS Kubernetes fonctionne de la manière suivante <nom-service>.<nom-namespace>.svc.cluster.local
La Downward API permet aux containers d'accéder à des informations sur eux-mêmes ou sur le cluster sans avoir besoin d'interagir directement avec l'API Kubernetes. Ces informations peuvent être passées via des variables d'environnement ou des fichiers montés dans un volume.
C'est utile pour que les applications puissent connaître leur propre contexte d'exécution (nom du Pod, namespace, IP, limites de ressources, labels, annotations, etc.).
Exposer des informations via des variables d'environnement :
apiVersion: v1
kind: Pod
metadata:
name: downward-api-env-pod
labels:
app: myapp
spec:
containers:
- name: main-container
image: busybox
command: ["sh", "-c", "while true; do echo Pod Name: $POD_NAME, IP: $POD_IP, Namespace: $POD_NAMESPACE, Node: $NODE_NAME, CPU Limit: $CPU_LIMIT; printenv | grep POD_; sleep 3600; done"]
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name # Nom du Pod
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace # Namespace du Pod
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP # IP du Pod
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName # Nom du noeud
- name: POD_SERVICE_ACCOUNT
valueFrom:
fieldRef:
fieldPath: spec.serviceAccountName # Nom du Service Account
- name: CPU_REQUEST
valueFrom:
resourceFieldRef:
containerName: main-container # Important si plusieurs containers
resource: requests.cpu
- name: CPU_LIMIT
valueFrom:
resourceFieldRef:
containerName: main-container
resource: limits.cpu
divisor: 1m # Optionnel: diviseur pour l'unité (ex: 500m -> 500)
- name: MEMORY_LIMIT
valueFrom:
resourceFieldRef:
containerName: main-container
resource: limits.memory
divisor: 1Mi # Ex: 128Mi -> 128
Dans cet exemple, le container main-container
aura accès à diverses informations via les variables d'environnement définies.
Exposer des informations via des fichiers dans un volume :
On peut aussi monter ces informations sous forme de fichiers dans un volume de type downwardAPI
.
apiVersion: v1
kind: Pod
metadata:
name: downward-api-volume-pod
labels:
zone: us-west
annotations:
build: "2.7.1"
spec:
containers:
- name: main-container
image: busybox
command: ["sh", "-c", "while true; do cat /etc/podinfo/labels; echo \"---\"; cat /etc/podinfo/annotations; sleep 3600; done"]
volumeMounts:
- name: podinfo
mountPath: /etc/podinfo
readOnly: false # Nécessaire pour downwardAPI volumes
volumes:
- name: podinfo
downwardAPI:
items:
- path: "labels" # Crée un fichier 'labels' dans /etc/podinfo
fieldRef:
fieldPath: metadata.labels
- path: "annotations"
fieldRef:
fieldPath: metadata.annotations
- path: "cpu_limit"
resourceFieldRef:
containerName: main-container
resource: limits.cpu
- path: "pod_name"
fieldRef:
fieldPath: metadata.name
Ici, le container aura accès aux labels du Pod dans le fichier /etc/podinfo/labels
, aux annotations dans /etc/podinfo/annotations
, etc. Chaque clé/valeur des labels et annotations sera sur une ligne séparée dans les fichiers respectifs.
Le securityContext
permet de définir des paramètres de sécurité et de privilèges spécifiques pour un Pod entier ou pour des containers individuels. C'est essentiel pour renforcer la sécurité de vos applications en limitant les permissions au strict nécessaire (principe du moindre privilège).
Security Context au niveau du Pod :
Les paramètres définis dans spec.securityContext
s'appliquent à tous les containers du Pod. Ils peuvent concerner l'utilisateur/groupe sous lequel les processus s'exécutent ou des paramètres liés au système de fichiers.
apiVersion: v1
kind: Pod
metadata:
name: pod-security-context-demo
spec:
securityContext:
runAsUser: 1000 # Tous les containers tourneront avec l'UID 1000
runAsGroup: 3000 # Tous les containers tourneront avec le GID 3000
fsGroup: 2000 # Le propriétaire des volumes montés sera le GID 2000
containers:
- name: sec-ctx-demo
image: busybox
command: ["sh", "-c", "sleep 1h"]
volumeMounts:
- name: data-volume
mountPath: /data/demo
volumes:
- name: data-volume
emptyDir: {}
Dans cet exemple, le processus principal du container sec-ctx-demo
s'exécutera avec l'UID 1000 et le GID 3000. De plus, le volume data-volume
monté dans /data/demo
appartiendra au groupe GID 2000, permettant ainsi aux processus du container (tournant avec le GID 3000 ou l'UID 1000, selon les permissions) d'y accéder si les permissions du système de fichiers le permettent.
Security Context au niveau du Container :
Les paramètres définis dans spec.containers[].securityContext
s'appliquent uniquement à ce container spécifique. Ils peuvent surcharger les paramètres définis au niveau du Pod ou définir des permissions plus granulaires, comme les capabilities Linux ou l'exécution en mode privilégié.
apiVersion: v1
kind: Pod
metadata:
name: container-security-context-demo
spec:
securityContext: # Niveau Pod
runAsUser: 1000
containers:
- name: container-1
image: busybox
command: ["sh", "-c", "sleep 1h"]
securityContext: # Niveau Container (surcharge/ajoute)
runAsUser: 2000 # Surcharge runAsUser du Pod
allowPrivilegeEscalation: false # Empêche l'escalade de privilèges
- name: container-2
image: busybox
command: ["sh", "-c", "id; sleep 1h"]
# Ce container utilise runAsUser: 1000 du Pod
Ici, container-1
tourne avec l'UID 2000 (surcharge du Pod) et a des capabilities Linux restreintes, tandis que container-2
tourne avec l'UID 1000 (défini au niveau du Pod).
Paramètres courants du Security Context :
runAsUser
/ runAsGroup
: Spécifie l'UID / GID sous lequel le processus principal du container doit s'exécuter.runAsNonRoot
: Booléen. Si true
, le Kubelet valide que le container ne s'exécute pas en tant que root (UID 0). Si ce n'est pas le cas, le démarrage du Pod échoue.fsGroup
: Spécifie un GID supplémentaire qui sera appliqué aux volumes montés. Le propriétaire de ces volumes sera ce GID, et tous les nouveaux fichiers/dossiers créés hériteront de ce GID.privileged
: Booléen. Si true
, le container s'exécute en mode privilégié, similaire à docker run --privileged
. À utiliser avec extrême prudence.allowPrivilegeEscalation
: Booléen. Contrôle si un processus peut obtenir plus de privilèges que son processus parent. Devrait généralement être false
.capabilities
: Permet d'ajouter (add
) ou de retirer (drop
) des capabilities Linux spécifiques, offrant un contrôle fin sur les permissions sans accorder un accès root complet.readOnlyRootFilesystem
: Booléen. Si true
, le système de fichiers racine du container est monté en lecture seule.seLinuxOptions
/ seccompProfile
/ appArmorProfile
: Permettent de configurer des mécanismes de sécurité Linux plus avancés (SELinux, seccomp, AppArmor).Configurer correctement les contextes de sécurité est une étape fondamentale pour sécuriser les workloads sur Kubernetes.
Les Ephemeral Containers sont des containers temporaires que l'on peut ajouter à un Pod déjà en cours d'exécution. Ils sont principalement utilisés pour le dépannage et l'inspection lorsque kubectl exec
ne suffit pas (par exemple, si le container principal n'a pas les outils nécessaires ou a crashé).
Contrairement aux containers normaux (et aux init containers), les Ephemeral Containers :
kubectl
(kubectl debug
) ou en modifiant directement la spec du Pod via l'API (moins courant).ports
, livenessProbe
, readinessProbe
).ephemeralContainers
de la spec du Pod (similaire à containers
et initContainers
).Cas d'usage typique :
Imaginez un Pod dont le container principal tourne mais ne répond plus correctement, et il manque des outils comme curl
ou netstat
. On peut ajouter un Ephemeral Container avec une image contenant ces outils pour investiguer.
Exemple (conceptuel avec kubectl debug
) :
# Attacher un container de debug (par exemple, basé sur busybox)
# au pod 'mon-pod-en-panne'
# Le nouveau container s'appellera 'debugger'
kubectl debug -it mon-pod-en-panne --image=busybox --target=container-principal -- sh
La commande kubectl debug
(qui a évolué dans les versions récentes de Kubernetes) est le moyen privilégié pour interagir avec les Ephemeral Containers. Elle permet d'attacher un container temporaire ou de créer une copie d'un Pod avec des modifications pour le débogage.
Les Ephemeral Containers sont une fonctionnalité relativement avancée, utile dans des scénarios de dépannage complexes.