Skip to main content

Pods and Containers


1 - What is a Pod?

A Pod is the smallest deployable unit in Kubernetes. It represents one or more containers that share the same execution context.

Characteristics of a Pod

CharacteristicDescription
Unique IPEach Pod has its own IP address
Shared networkContainers share localhost
Shared storageVolumes accessible by all containers
EphemeralPods are mortal and replaceable
Co-locationContainers on the same node

2 - Create a Pod

2.1 Imperative method

# Créer un Pod simple
kubectl run mon-pod --image=nginx

# Avec des options
kubectl run mon-pod --image=nginx --port=80 --labels="app=web,env=dev"

# Vérifier
kubectl get pods
kubectl describe pod mon-pod
# pod-simple.yaml
apiVersion: v1
kind: Pod
metadata:
name: mon-pod
labels:
app: web
env: dev
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
# Appliquer le manifest
kubectl apply -f pod-simple.yaml

# Vérifier
kubectl get pod mon-pod -o wide

2.3 Structure of a Pod manifest


3 - Pod lifecycle

3.1 Pod phases

PhaseDescription
PendingPod accepted but not yet scheduled
RunningAt least one container running
SucceededAll containers finished successfully
FailedAt least one container failed
UnknownUnknown state (communication issue)

3.2 Pod conditions

# Voir les conditions
kubectl describe pod mon-pod | grep Conditions -A 10
ConditionDescription
PodScheduledPod assigned to a node
ContainersReadyAll containers are ready
InitializedAll init containers finished
ReadyPod ready to receive traffic

4 - Multi-container Pods

4.1 Multi-container Pod patterns

4.2 Example: Sidecar pattern

# pod-sidecar.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-avec-sidecar
spec:
containers:
# Conteneur principal
- name: app
image: nginx
volumeMounts:
- name: logs
mountPath: /var/log/nginx

# Sidecar - collecte les logs
- name: log-collector
image: busybox
command: ['sh', '-c', 'tail -f /var/log/nginx/access.log']
volumeMounts:
- name: logs
mountPath: /var/log/nginx

volumes:
- name: logs
emptyDir: {}

4.3 Example: Ambassador pattern

# pod-ambassador.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-avec-ambassador
spec:
containers:
# Application principale
- name: app
image: mon-app
env:
- name: DATABASE_HOST
value: "localhost" # Le proxy local
- name: DATABASE_PORT
value: "5432"

# Ambassador - proxy vers la base de données
- name: db-proxy
image: cloudnativelabs/kube-ambassador
ports:
- containerPort: 5432

5 - Init Containers

Init Containers run before the main containers and must complete successfully.

Init Container example

# pod-init.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-avec-init
spec:
initContainers:
# Attendre que la DB soit disponible
- name: wait-for-db
image: busybox
command: ['sh', '-c', 'until nc -z database 5432; do echo waiting...; sleep 2; done']

# Télécharger la configuration
- name: download-config
image: busybox
command: ['wget', '-O', '/config/app.conf', 'http://config-server/app.conf']
volumeMounts:
- name: config
mountPath: /config

containers:
- name: app
image: mon-app
volumeMounts:
- name: config
mountPath: /etc/app

volumes:
- name: config
emptyDir: {}

6 - Probes (Health checks)

6.1 Probe types

ProbeQuestionAction on failure
LivenessIs the container running?Restart
ReadinessCan the container receive traffic?Removed from the Service
StartupHas the container started?Restart

6.2 Probe methods

# pod-probes.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-avec-probes
spec:
containers:
- name: app
image: mon-app
ports:
- containerPort: 8080

# HTTP GET
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 15
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3

# TCP Socket
readinessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 5
periodSeconds: 5

# Exec command
startupProbe:
exec:
command:
- cat
- /tmp/healthy
failureThreshold: 30
periodSeconds: 10

6.3 Probe configuration

ParameterDescriptionDefault
initialDelaySecondsDelay before the first probe0
periodSecondsInterval between probes10
timeoutSecondsProbe timeout1
successThresholdConsecutive successes required1
failureThresholdFailures before action3

7 - Resources and limits

7.1 Requests and Limits

# pod-resources.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-ressources
spec:
containers:
- name: app
image: nginx
resources:
requests:
memory: "128Mi"
cpu: "250m"
limits:
memory: "256Mi"
cpu: "500m"

7.2 QoS Classes

ClassConditionPriority
Guaranteedrequests = limits for all containersHigh
BurstableAt least one request definedMedium
BestEffortNo request or limitLow (killed first)
# Guaranteed QoS
resources:
requests:
memory: "256Mi"
cpu: "500m"
limits:
memory: "256Mi"
cpu: "500m"

8 - kubectl commands for Pods

8.1 Basic management

# Lister les pods
kubectl get pods
kubectl get pods -o wide # Plus de détails
kubectl get pods -A # Tous les namespaces

# Détails d'un pod
kubectl describe pod mon-pod

# Logs
kubectl logs mon-pod
kubectl logs mon-pod -c nom-conteneur # Multi-conteneur
kubectl logs mon-pod -f # Follow
kubectl logs mon-pod --previous # Conteneur précédent (après restart)

# Exécuter une commande
kubectl exec mon-pod -- ls /
kubectl exec -it mon-pod -- /bin/bash # Shell interactif

# Copier des fichiers
kubectl cp mon-pod:/var/log/app.log ./app.log
kubectl cp ./config.yaml mon-pod:/etc/app/

# Supprimer
kubectl delete pod mon-pod
kubectl delete pod mon-pod --grace-period=0 --force # Force

8.2 Debugging

# Voir les événements
kubectl get events --sort-by='.lastTimestamp'

# Debug avec un pod éphémère
kubectl debug mon-pod -it --image=busybox

# Port-forward
kubectl port-forward pod/mon-pod 8080:80

# Voir le YAML complet
kubectl get pod mon-pod -o yaml

9 - Best practices

9.1 Labels and annotations

apiVersion: v1
kind: Pod
metadata:
name: mon-app
labels:
app: frontend
version: v1.2.0
environment: production
team: platform
annotations:
description: "Application frontend principale"
prometheus.io/scrape: "true"
prometheus.io/port: "9090"
spec:
containers:
- name: app
image: mon-app:v1.2.0

9.2 Production Pod checklist

  • Define resource requests and limits
  • Configure probes (liveness, readiness)
  • Use consistent labels
  • Avoid using the :latest tag
  • Define an appropriate securityContext
  • Never use standalone Pods in production (use Deployments)
# Exemple complet
apiVersion: v1
kind: Pod
metadata:
name: app-production
labels:
app: mon-app
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
containers:
- name: app
image: mon-app:v1.2.0
ports:
- containerPort: 8080
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true

Summary

In this chapter, we learned:

  • The anatomy of a Pod and its characteristics
  • The multi-container patterns (Sidecar, Ambassador, Adapter)
  • Init Containers for initialization
  • Probes for container health
  • Managing resources (requests/limits)
  • The essential kubectl commands

Next step

In the next chapter, we will discover Deployments and ReplicaSets to manage the lifecycle of applications.

→ Next chapter: Deployments and ReplicaSets


← Back to the table of contents