Cette page fournit une vue d’ensemble des conteneurs d’initialisation (init containers) : des conteneurs spécialisés qui s’exécutent avant les conteneurs d’application dans un PodLe plus petit et le plus simple des objets Kubernetes. Un Pod est un ensemble de conteneurs fonctionnant sur votre cluster. . Les init containers peuvent contenir des utilitaires ou des scripts d’installation qui ne sont pas présents dans une image d’application.
Vous pouvez spécifier des init containers dans la spécification du Pod à côté du tableau containers
(qui décrit les conteneurs d’application)
Un PodLe plus petit et le plus simple des objets Kubernetes. Un Pod est un ensemble de conteneurs fonctionnant sur votre cluster. peut avoir plusieurs conteneurs exécutant des applications mais peut aussi avoir un ou plusieurs init containers, qui sont exécutés avant que les conteneurs d’application ne démarrent.
Les init containers se comportent comme les conteneurs réguliers, avec quelques différences :
Si le init container d’un Pod échoue, Kubernetes redémarre le Pod à répétition jusqu’à ce que le init container se termine avec succès.
Cependant, si le Pod a une restartPolicy
à “Never”, Kubernetes ne redémarre pas le Pod.
Afin de spécifier un init container pour un Pod, il faut ajouter le champ initContainers
dans la spécification du Pod, comme un
tableau d’objets de type Container, au même niveau que le tableau d’applications containers
.
Le statut des init containers est retourné dans le champ .status.initContainerStatuses
comme un tableau des statuts du conteneur (comparable au champ .status.containerStatuses
).
Les init containers supportent tous les champs et fonctionnalités des conteneurs d’application incluant les limites de ressources, les volumes et les paramètres de sécurité. Cependant, les demandes de ressources pour un init container sont gérées différemment des limites de ressources, tel que documenté dans Ressources.
De plus, les init containers ne supportent pas les readiness probes parce que ces conteneurs s’exécutent jusqu’au bout avant que le Pod soit prêt.
Si l’on spécifie plusieurs init containers pour un Pod, Kubelet exécute chaque init container de manière séquentielle. Chaque init container doit se terminer avec succès avant que le prochain ne puisse s’exécuter. Lorsque tous les init containers se sont exécutés jusqu’au bout, Kubelet initialise les conteneurs d’application pour le Pod et les exécute comme d’habitude.
Puisque les init containers ont des images séparées des conteneurs d’application, ils apportent certains avantages pour du code de mise en route :
FROM
) seulement pour utiliser
un outil comme sed
, awk
, python
, ou dig
pendant l’installation.Voici plusieurs idées pour utiliser les init containers :
Attendre qu’un ServiceUn moyen d’exposer une application s’exécutant sur un ensemble de pods en tant que service réseau. soit créé, en utilisant une commande shell d’une ligne telle que :
for i in {1..100}; do sleep 1; if dig myservice; then exit 0; fi; done; exit 1
Enregistrer ce Pod à un serveur distant depuis l’API downward avec une commande telle que :
curl -X POST http://$MANAGEMENT_SERVICE_HOST:$MANAGEMENT_SERVICE_PORT/register -d 'instance=$(<POD_NAME>)&ip=$(<POD_IP>)'
Attendre un certain temps avant de démarrer le conteneur d’application avec une commande telle que :
sleep 60
Cloner un dépôt Git dans un VolumeA directory containing data, accessible to the containers in a pod.
Placer des valeurs dans un fichier de configuration et exécuter un outil de templating pour générer
dynamiquement un fichier de configuration pour le conteneur d’application principal.
Par exemple, placer la valeur POD_IP
dans une configuration et générer le fichier de configuration de l’application principale
en utilisant Jinja.
Cet exemple définit un simple Pod possédant deux init containers.
Le premier attend myservice
et le second attend mydb
. Une fois que les deux
init containers terminent leur exécution, le Pod exécute le conteneur d’application décrit dans sa section spec
.
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: busybox:1.28
command: ['sh', '-c', 'echo "L''app s''exécute!" && sleep 3600']
initContainers:
- name: init-myservice
image: busybox:1.28
command: ['sh', '-c', "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo en attente de myservice; sleep 2; done"]
- name: init-mydb
image: busybox:1.28
command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo en attente de mydb; sleep 2; done"]
Les fichiers YAML suivants résument les services mydb
et myservice
:
apiVersion: v1
kind: Service
metadata:
name: myservice
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9376
---
apiVersion: v1
kind: Service
metadata:
name: mydb
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9377
Vous pouvez démarrer ce Pod en exécutant :
kubectl apply -f myapp.yaml
pod/myapp-pod created
Et vérifier son statut avec :
kubectl get -f myapp.yaml
NAME READY STATUS RESTARTS AGE
myapp-pod 0/1 Init:0/2 0 6m
ou pour plus de détails :
kubectl describe -f myapp.yaml
Name: myapp-pod
Namespace: default
[...]
Labels: app=myapp
Status: Pending
[...]
Init Containers:
init-myservice:
[...]
State: Running
[...]
init-mydb:
[...]
State: Waiting
Reason: PodInitializing
Ready: False
[...]
Containers:
myapp-container:
[...]
State: Waiting
Reason: PodInitializing
Ready: False
[...]
Events:
FirstSeen LastSeen Count From SubObjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
16s 16s 1 {default-scheduler } Normal Scheduled Successfully assigned myapp-pod to 172.17.4.201
16s 16s 1 {kubelet 172.17.4.201} spec.initContainers{init-myservice} Normal Pulling pulling image "busybox"
13s 13s 1 {kubelet 172.17.4.201} spec.initContainers{init-myservice} Normal Pulled Successfully pulled image "busybox"
13s 13s 1 {kubelet 172.17.4.201} spec.initContainers{init-myservice} Normal Created Created container with docker id 5ced34a04634; Security:[seccomp=unconfined]
13s 13s 1 {kubelet 172.17.4.201} spec.initContainers{init-myservice} Normal Started Started container with docker id 5ced34a04634
Pour voir les logs des init containers dans ce Pod, exécuter :
kubectl logs myapp-pod -c init-myservice # Inspecter le premier init container
kubectl logs myapp-pod -c init-mydb # Inspecter le second init container
À ce stade, ces init containers attendent de découvrir les services nommés
mydb
et myservice
.
Voici une configuration que vous pouvez utiliser pour faire apparaître ces Services :
---
apiVersion: v1
kind: Service
metadata:
name: myservice
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9376
---
apiVersion: v1
kind: Service
metadata:
name: mydb
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9377
Pour créer les services mydb
et myservice
:
kubectl apply -f services.yaml
service/myservice created
service/mydb created
Vous verrez ensuite que ces init containers se terminent et que le Pod myapp-pod
évolue vers l’état “Running” (en exécution) :
kubectl get -f myapp.yaml
NAME READY STATUS RESTARTS AGE
myapp-pod 1/1 Running 0 9m
Cet exemple simple devrait suffire à vous inspirer pour créer vos propres init containers. A suivre contient un lien vers un exemple plus détaillé.
Pendant le démarrage d’un Pod, chaque init container démarre en ordre, après que le réseau
et les volumes ont été initialisés. Chaque conteneur doit se terminer avec succès avant que le prochain
ne démarre. Si un conteneur n’arrive pas à démarrer à cause d’un problème d’exécution ou
se termine avec un échec, il est redémarré selon la restartPolicy
du Pod.
Toutefois, si la restartPolicy
du Pod est configurée à “Always”, les init containers utilisent la restartPolicy
“OnFailure”.
Un Pod ne peut pas être Ready
tant que tous les init containers ne se sont pas exécutés avec succès.
Les ports d’un init container ne sont pas agrégés sous un Service. Un Pod qui s’initialise
est dans l’état Pending
mais devrait avoir une condition Initialized
configurée à “true”.
Si le Pod redémarre ou est redémarré, tous les init containers doivent s’exécuter à nouveau.
Les changements aux spec d’un init containers sont limités au champ image du conteneur. Changer le champ image d’un init container équivaut à redémarrer le Pod.
Puisque les init containers peuvent être redémarrés, réessayés ou ré-exécutés,
leur code doit être idempotent. En particulier, le code qui écrit dans des fichiers sur EmptyDirs
devrait être préparé à la possibilité qu’un fichier de sortie existe déjà.
Les init containers ont tous les champs d’un conteneur d’application.
Cependant, Kubernetes interdit l’utilisation de readinessProbe
parce que les init containers
ne peuvent pas définir une “readiness” distincte de la complétion. Ceci est appliqué lors de la validation.
L’utilisation de activeDeadlineSeconds
sur le Pod et livenessProbe
sur le conteneur
permet d’empêcher les init containers d’échouer tout le temps.
La deadline active inclut les init containers.
Le nom de chaque application et init container dans un Pod doit être unique; une erreur de validation est générée pour tout conteneur partageant un nom avec un autre.
Étant donné l’ordonnancement et l’exécution des init containers, les règles suivantes s’appliquent pour l’utilisation des ressources :
Les quotas et limites sont appliqués sur la base de la requête/limite effective d’un Pod.
Les groupes de contrôle au niveau du Pod (cgroupsUn groupe de processus Linux avec des options d’isolation, de suivi, et de limites des ressources. ) sont basés sur la requête/limite effective de Pod, la même que celle du scheduler.
Un Pod peut redémarrer, ce qui cause la ré-exécution des init containers, pour les raisons suivantes :
restartPolicy
est configurée à “Always”, ce qui force le redémarrage, et l’enregistrement de complétion du init container a été perdu à cause d’une opération de garbage collection (récupération de mémoire).Cette page est elle utile ?
Thanks for the feedback. If you have a specific, answerable question about how to use Kubernetes, ask it on Stack Overflow. Open an issue in the GitHub repo if you want to report a problem or suggest an improvement.