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
| Characteristic | Description |
|---|---|
| Unique IP | Each Pod has its own IP address |
| Shared network | Containers share localhost |
| Shared storage | Volumes accessible by all containers |
| Ephemeral | Pods are mortal and replaceable |
| Co-location | Containers 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
2.2 Declarative method (recommended)
# 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
| Phase | Description |
|---|---|
| Pending | Pod accepted but not yet scheduled |
| Running | At least one container running |
| Succeeded | All containers finished successfully |
| Failed | At least one container failed |
| Unknown | Unknown state (communication issue) |
3.2 Pod conditions
# Voir les conditions
kubectl describe pod mon-pod | grep Conditions -A 10
| Condition | Description |
|---|---|
| PodScheduled | Pod assigned to a node |
| ContainersReady | All containers are ready |
| Initialized | All init containers finished |
| Ready | Pod 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
| Probe | Question | Action on failure |
|---|---|---|
| Liveness | Is the container running? | Restart |
| Readiness | Can the container receive traffic? | Removed from the Service |
| Startup | Has 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
| Parameter | Description | Default |
|---|---|---|
| initialDelaySeconds | Delay before the first probe | 0 |
| periodSeconds | Interval between probes | 10 |
| timeoutSeconds | Probe timeout | 1 |
| successThreshold | Consecutive successes required | 1 |
| failureThreshold | Failures before action | 3 |
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
| Class | Condition | Priority |
|---|---|---|
| Guaranteed | requests = limits for all containers | High |
| Burstable | At least one request defined | Medium |
| BestEffort | No request or limit | Low (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