Pods - ii02735/learn-k8 GitHub Wiki
Les pods
Qu'est-ce qu'un Pod ?
Un Pod est la plus petite unité déployable de Kubernetes. Ce n'est pas un container, mais un groupe d'un ou plusieurs containers qui partagent :
- le réseau : une seule adresse IP, un seul espace de ports, une communication via
localhost - les volumes : un même stockage monté dans plusieurs containers
- l'espace de nommage IPC et le cycle de vie
[!IMPORTANT] Un Pod est éphémère : il est conçu pour être remplacé, pas pour durer. Si un noeud tombe, ses Pods disparaissent.
Un ou plusieurs containers ?
Dans la grande majorité des cas, un Pod contient un seul container : on parle de Pod mono-container.
On ajoute un second container uniquement quand les containers sont fortement couplés (ils doivent partager le réseau ou les données). On parle alors de Pod multi-container et de modèles (patterns) :
- sidecar : un container auxiliaire qui assiste le container principal (collecte de logs, proxy…)
- init container : s'exécute et se termine avant le démarrage des containers principaux
- ambassador : un proxy qui expose le container principal vers l'extérieur
- adapter : un adaptateur qui normalise la sortie du container principal (métriques, logs…)
:warning: Multiplier les containers dans un Pod rend le débogage plus complexe. En cas de doute, garder un container par Pod.
Pods et contrôleurs
Un Pod ne se répare pas tout seul : s'il meurt, il n'est pas recréé. C'est pour cela qu'on ne déploie presque jamais des Pods directement, mais via un contrôleur qui les gère (nombre de réplicas, redémarrage, remplacement…) :
- Deployment : applications sans état (stateless), gère les réplicas et les mises à jour
- ReplicaSet : maintient un nombre de Pods identiques (généralement géré par un Deployment)
- StatefulSet : applications avec état (stateful), identité réseau et stockage stables
- DaemonSet : un Pod sur chaque noeud (agents de logs, monitoring…)
- Job / CronJob : tâches ponctuelles ou planifiées
Le cycle de vie d'un Pod
Un Pod est éphémère : il passe par des phases (Pending, Running, Succeeded, Failed, Unknown), expose des conditions (PodScheduled, Initialized, ContainersReady, Ready) et redémarre ses containers selon sa restartPolicy (Always, OnFailure, Never).
Pour le détail — les phases et conditions, les états des containers, les init containers, les sondes (liveness, readiness, startup) et l'arrêt gracieux — voir la page dédiée : Les sondes et le cycle de vie d'un Pod.
Les spécifications d'un Pod
Un Pod se décrit dans un manifeste YAML, principalement sous la clé spec. Voici les champs les plus utiles au niveau d'un container.
Les ports
spec:
containers:
- name: app
image: nginx:1.27
ports:
- name: http
containerPort: 80
protocol: TCP
containerPort: le port sur lequel écoute le container. C'est une information de documentation : cela ne publie rien à l'extérieur du cluster.name: nomme le port pour pouvoir le référencer (utilisé par les Services et les sondes).protocol:TCP(par défaut),UDPouSCTP.hostPort: publie le port directement sur le noeud. À éviter : cela entre en conflit avec le scheduler et empêche de faire tourner plusieurs réplicas sur le même noeud.
:warning: containerPort ne suffit pas à exposer une application : c'est un Service (ou un Ingress) qui rend un Pod joignable.
La gestion des ressources
On déclare pour chaque container les ressources qu'il demande (requests) et qu'il ne peut pas dépasser (limits) :
resources:
requests:
cpu: "250m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "256Mi"
requests: la quantité garantie à la planification. Le scheduler s'en sert pour choisir un noeud qui a assez de ressources libres.limits: le plafond. En cas de dépassement, le CPU est bridé (throttled) et la mémoire déclenche unOOMKilled.
Les unités :
- CPU : en coeurs (
1) ou en millicoeurs (250m= 0,25 coeur). - Mémoire : en octets avec le suffixe binaire
Mi/Gi(recommandé) ou décimalM/G.
Ces valeurs déterminent la classe de QoS du Pod :
Guaranteed:requests=limitspour tous les containers (la plus prioritaire)Burstable:requests<limitsBestEffort: aucunerequestnilimit(la première sacrifiée en cas de pression mémoire)
[!NOTE] Si tu définis une
limitsansrequest, Kubernetes recopie lalimitdans larequest.
:warning: Sans limit, un container peut épuiser la mémoire du noeud et déstabiliser les autres Pods.
Les security contexts
On peut durcir la sécurité à deux niveaux : le Pod (spec.securityContext) et chaque container (spec.containers[].securityContext).
spec:
securityContext:
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
containers:
- name: app
image: nginx:1.27
securityContext:
runAsNonRoot: true
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
Les champs les plus courants :
runAsUser/runAsGroup: l'UID / GID avec lequel le container s'exécute.runAsNonRoot: refuse de démarrer si l'image tourne enroot. Une des protections les plus efficaces.fsGroup: le groupe propriétaire des volumes montés (utile pour les volumes partagés).readOnlyRootFilesystem: monte le système de fichiers du container en lecture seule.allowPrivilegeEscalation: empêche l'escalade de privilèges (falserecommandé).capabilities: ajoute ou retire des capacités Linux ;drop: ["ALL"]retire tout.privileged: donne tous les droits du noeud au container — à proscrire sauf cas très particulier.
:warning: Par défaut, un container peut tourner en root. Il est recommandé de combiner runAsNonRoot: true, readOnlyRootFilesystem: true et capabilities.drop: ["ALL"].
Les sondes (probes)
Les sondes (livenessProbe, readinessProbe, startupProbe) permettent au kubelet de vérifier régulièrement l'état d'un container : en cas d'échec, il le redémarre (vitalité) ou le retire des endpoints d'un Service (disponibilité). Elles se définissent au niveau de chaque container (spec.containers[]), et non au niveau du Pod.
Pour le détail des trois types, des modes de sonde (httpGet, tcpSocket, exec, grpc), des paramètres et des bonnes pratiques : Les sondes et le cycle de vie d'un Pod.
Autres champs utiles
env/envFrom: variables d'environnement (directement ou depuis unConfigMap/Secret).volumeMounts: points de montage des volumes déclarés dansspec.volumes.command/args: remplacent l'ENTRYPOINT/CMDde l'image.imagePullPolicy:Always,IfNotPresentouNever.
Un manifeste complet
apiVersion: v1
kind: Pod
metadata:
name: web
labels:
app: web
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 2000
containers:
- name: app
image: nginx:1.27
ports:
- name: http
containerPort: 80
protocol: TCP
env:
- name: LOG_LEVEL
value: info
resources:
requests:
cpu: "250m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "256Mi"
securityContext:
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
startupProbe:
httpGet:
path: /
port: http
failureThreshold: 30
periodSeconds: 5
livenessProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 10
readinessProbe:
httpGet:
path: /
port: http
Les commandes principales
- Lister les Pods d'un namespace :
kubectl get pods - Voir sur quel noeud tourne chaque Pod :
kubectl get pods -o wide - Obtenir les détails d'un Pod :
kubectl describe pod web - Consulter les logs d'un container :
kubectl logs web -c app - Ouvrir un shell dans un container :
kubectl exec -it web -c app -- sh - Suivre l'état des Pods en direct :
kubectl get pods --watch - Supprimer un Pod :
kubectl delete pod web