Introduction
Un conteneur d'initialisation (init container) s'exécute avant les conteneurs d'application principaux dans un Pod. Chaque conteneur d'initialisation doit se terminer avec succès avant que Kubernetes ne démarre le conteneur d'initialisation suivant ou tout conteneur régulier. Cela rend les conteneurs d'initialisation utiles pour préparer des fichiers, vérifier des dépendances ou effectuer de petites tâches de configuration qui n'ont pas besoin de rester actives parallèlement à l'application.
Dans ce laboratoire, vous allez ajouter un conteneur d'initialisation qui écrit un fichier de démarrage dans un volume partagé emptyDir, confirmer que le conteneur d'application peut lire ce fichier, inspecter le statut et les journaux du conteneur d'initialisation, puis appliquer ce même modèle dans un modèle de déploiement (Deployment).
Préparer un espace de noms pour les conteneurs d'initialisation
Dans cette étape, vous allez préparer un espace de noms (namespace) propre pour pratiquer les conteneurs d'initialisation.
Commencez dans /home/labex/project. Vous rédigerez les manifestes de Pod et de Deployment dans ce répertoire.
mkdir -p /home/labex/project
cd /home/labex/project
Vérifiez que le serveur API Kubernetes est accessible. Si la machine virtuelle vient de démarrer et que le nœud n'est pas encore prêt, attendez quelques secondes et relancez la commande.
kubectl get nodes --request-timeout=5s
La sortie attendue inclut :
NAME STATUS ROLES AGE VERSION
labex-v135 Ready control-plane ... v1.35...
Les conteneurs d'initialisation s'exécutent à l'intérieur des Pods ; attendez donc que le Pod réseau du cluster soit prêt avant de créer des charges de travail.
kubectl wait --namespace kube-system --for=condition=Ready pod -l k8s-app=calico-node --timeout=120s
Sortie attendue :
pod/calico-node-... condition met
Créez un espace de noms nommé ckad-prep-init :
kubectl create namespace ckad-prep-init
Définissez cet espace de noms comme contexte actuel :
kubectl config set-context --current --namespace=ckad-prep-init
Confirmez l'espace de noms actuel :
kubectl config view --minify --output 'jsonpath={..namespace}'; echo
Sortie attendue :
ckad-prep-init
Préparer des données partagées avant le démarrage de l'application
Dans cette étape, vous allez créer un Pod où un conteneur d'initialisation prépare un fichier avant le démarrage du conteneur d'application.
Le volume emptyDir est créé lorsque le Pod est assigné à un nœud et est partagé par les conteneurs au sein du même Pod. Le conteneur d'initialisation et le conteneur d'application montent tous deux ce volume sur /work. Le conteneur d'initialisation écrit /work/startup.txt, puis se termine. Ce n'est qu'après sa réussite que Kubernetes démarre le conteneur d'application.
Créez init-file-pod.yaml :
cat > init-file-pod.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata:
name: init-file-demo
labels:
app: init-file-demo
spec:
terminationGracePeriodSeconds: 0
volumes:
- name: shared-work
emptyDir: {}
initContainers:
- name: prepare-startup-file
image: busybox:1.36
command:
- /bin/sh
- -c
- 'echo init-started; echo prepared-by-init > /work/startup.txt; echo init-finished'
volumeMounts:
- name: shared-work
mountPath: /work
containers:
- name: app
image: busybox:1.36
command:
- /bin/sh
- -c
- 'echo app-started; cat /work/startup.txt; sleep 3600'
volumeMounts:
- name: shared-work
mountPath: /work
EOF
Appliquez le manifeste :
kubectl apply -f init-file-pod.yaml
Sortie attendue :
pod/init-file-demo created
Attendez que le Pod soit prêt :
kubectl wait --for=condition=Ready pod/init-file-demo --timeout=120s
Sortie attendue :
pod/init-file-demo condition met
Lisez le fichier depuis l'intérieur du conteneur d'application. Cela prouve que le conteneur d'initialisation a bien préparé les données sur le volume partagé avant le démarrage de l'application.
kubectl exec init-file-demo -c app -- cat /work/startup.txt
Sortie attendue :
prepared-by-init
Inspecter le statut et les journaux du conteneur d'initialisation
Dans cette étape, vous allez vérifier que le conteneur d'initialisation s'est bien terminé avant que le conteneur d'application ne continue de s'exécuter.
Les conteneurs d'initialisation apparaissent sous .status.initContainerStatuses, tandis que les conteneurs réguliers apparaissent sous .status.containerStatuses. Le conteneur d'initialisation doit avoir une raison Completed car il s'est terminé avec succès.
kubectl get pod init-file-demo -o 'jsonpath={.status.initContainerStatuses[0].name}{" "}{.status.initContainerStatuses[0].state.terminated.reason}{"\n"}'
Sortie attendue :
prepare-startup-file Completed
Inspectez maintenant le statut du conteneur d'application régulier. Il doit être prêt et en cours d'exécution.
kubectl get pod init-file-demo -o 'jsonpath={.status.containerStatuses[0].name}{" "}{.status.containerStatuses[0].ready}{" "}{.status.containerStatuses[0].state.running.startedAt}{"\n"}'
La sortie attendue inclut :
app true ...
Lisez les journaux du conteneur d'initialisation. Même si le conteneur d'initialisation est terminé, ses journaux restent disponibles via kubectl logs -c.
kubectl logs init-file-demo -c prepare-startup-file
Sortie attendue :
init-started
init-finished
Lisez les journaux du conteneur d'application. L'application démarre après que le conteneur d'initialisation a écrit le fichier, ses journaux incluent donc la valeur préparée.
kubectl logs init-file-demo -c app
La sortie attendue inclut :
app-started
prepared-by-init
Ajouter un conteneur d'initialisation à un Deployment
Dans cette étape, vous allez utiliser le même modèle de conteneur d'initialisation au sein d'un modèle de déploiement (Deployment).
Pour les charges de travail applicatives, vous placez généralement les conteneurs d'initialisation dans le modèle de Pod d'un contrôleur plutôt que de créer des Pods isolés. Lorsque le Deployment crée un Pod, Kubernetes exécute d'abord le conteneur d'initialisation pour chaque Pod créé à partir de ce modèle.
Créez init-deployment.yaml :
cat > init-deployment.yaml <<'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: init-web
spec:
replicas: 1
selector:
matchLabels:
app: init-web
template:
metadata:
labels:
app: init-web
spec:
terminationGracePeriodSeconds: 0
volumes:
- name: web-content
emptyDir: {}
initContainers:
- name: render-index
image: busybox:1.36
command:
- /bin/sh
- -c
- 'echo deployment-init > /site/index.txt'
volumeMounts:
- name: web-content
mountPath: /site
containers:
- name: web
image: busybox:1.36
command:
- /bin/sh
- -c
- 'cat /site/index.txt; sleep 3600'
volumeMounts:
- name: web-content
mountPath: /site
EOF
Appliquez le Deployment :
kubectl apply -f init-deployment.yaml
Sortie attendue :
deployment.apps/init-web created
Attendez que le Deployment soit disponible :
kubectl wait --for=condition=Available deployment/init-web --timeout=120s
Sortie attendue :
deployment.apps/init-web condition met
Trouvez le Pod créé par le Deployment :
web_pod="$(kubectl get pods -l app=init-web -o 'jsonpath={.items[0].metadata.name}')"
echo "$web_pod"
La sortie attendue affiche un nom de Pod généré :
init-web-...
Lisez les journaux du conteneur d'application depuis ce Pod :
kubectl logs "$web_pod" -c web
Sortie attendue :
deployment-init
Inspectez le statut de fin du conteneur d'initialisation à l'intérieur du Pod créé par le Deployment :
kubectl get pod "$web_pod" -o 'jsonpath={.status.initContainerStatuses[0].name}{" "}{.status.initContainerStatuses[0].state.terminated.reason}{"\n"}'
Sortie attendue :
render-index Completed
Résumé
Vous avez ajouté des conteneurs d'initialisation à un Pod et à un modèle de déploiement. Vous avez utilisé un volume emptyDir pour partager des fichiers préparés avec le conteneur d'application, inspecté le statut des conteneurs d'initialisation terminés, lu les journaux d'initialisation et d'application, et confirmé que ce même modèle fonctionne pour les Pods d'application gérés par un contrôleur.


