Multi container pods

Multi containers

Dans un pod avec un environnement multi-container, chaque container lance un process tout au long de son cycle de vie.
Un exemple peut être le besoin d’avoir une application et un agent de logs, si un des deux containers crash, le pod sera recréé.

Exemple

Manifest avec 2 containers, le second fini avant le premier et force le restart du pod:

apiVersion: v1
kind: Pod
metadata:
  name: multicontainer-cas1-pod
  labels:
    app: myapp
spec:
  containers:
  - name: sleep3600
    image: busybox
    command: ['sleep', '3600']
  - name: sleep30
    image: busybox
    command: ['sleep', '30']

initContainers

Parfois il peut être necessaire qu’un des containers ait fini son traitement pour démarrer le second, exemple, un process qui récupère du code ou un binaire dans un repos que l’application va ensuite utiliser.
Cette tâche s’exécute seulement une fois au démarrage du pod, pour cela il faut utiliser initContainers.

Il est possible de mettre plusieurs containers dans l’initContainers, dans ce cas, les containers seront exécutés les un après les autres dans l’ordre de déclaration.
Si un des containers, crash, Kubernetes redémarrera le pod jusqu’à ce que l’initContainers soit démarré avec succès.

apiVersion: v1
kind: Pod
metadata:
  name: multicontainer-cas2-pod
  labels:
    app: myapp
spec:
  containers:
  - name: sleep3600
    image: busybox
    command: ['sleep', '3600']
  initContainers:
  - name: sleep30
    image: busybox
    command: ['sleep', '30']

Quelques logs:

k get pods -n multicontainers
NAME                      READY   STATUS     RESTARTS   AGE
multicontainer-cas2-pod   0/1     Init:0/1   0          11s
k get pods -n multicontainers
NAME                      READY   STATUS    RESTARTS   AGE
multicontainer-cas2-pod   1/1     Running   0          36s
k logs -n multicontainers pods/multicontainer-cas2-pod
Defaulted container "sleep3600" out of: sleep3600, sleep30 (init)

Exemple avec 2 containers dans un initContainers

apiVersion: v1
kind: Pod
metadata:
  name: multicontainer-cas3-pod
  labels:
    app: myapp
spec:
  containers:
  - name: sleep3600
    image: busybox
    command: ['sleep', '3600']
  initContainers:
  - name: sleep30
    image: busybox
    command: ['sleep', '30']
  - name: sleep30-2
    image: busybox
    command: ['sleep', '30']

Logs avec un container en erreur (modifier le 30 d’un sleep avec une chaîne de caractère):

k get pods -n multicontainers
NAME                      READY   STATUS     RESTARTS   AGE
multicontainer-cas3-pod   0/1     Init:0/2   0          32s
k get pods -n multicontainers
NAME                      READY   STATUS     RESTARTS   AGE
multicontainer-cas3-pod   0/1     Init:1/2   0          34s
k get pods -n multicontainers
NAME                      READY   STATUS       RESTARTS   AGE
multicontainer-cas3-pod   0/1     Init:Error   0          37s
k get pods -n multicontainers
NAME                      READY   STATUS                  RESTARTS      AGE
multicontainer-cas3-pod   0/1     Init:CrashLoopBackOff   2 (18s ago)   70s
k get pods -n multicontainers
NAME                      READY   STATUS       RESTARTS      AGE
multicontainer-cas3-pod   0/1     Init:Error   5 (89s ago)   3m39s

Cas Sidecar

Cas comme par exemple pour un logger.
Il est possible d’utiliser le initContainer et restartPolicy à Always.

apiVersion: v1
kind: Pod
metadata:
  name: multicontainer-cas4-pod
  labels:
    app: myapp
spec:
  containers:
  - name: myapp
    image: alpine:latest
    command: ['sh', '-c', 'while true; do echo "logging" >> /opt/logs.txt; sleep 1; done']
    volumeMounts:
      - name: data
        mountPath: /opt
  initContainers:
  - name: logshipper
    image: alpine:latest
    restartPolicy: Always
    command: ['sh', '-c', 'tail -F /opt/logs.txt']
    volumeMounts:
      - name: data
        mountPath: /opt
  volumes:
    - name: data
      emptyDir: {}