Si on parle de pod, on pense immédiatement à Kubernetes . Mais pour tous ceux qui viennent d'un environnement Docker, le concept de pod n'est pas forcément évident.

Dans cet article nous allons voir :

  • Un pod c'est quoi ?
  • Pourquoi s'en servir...
  • Et comment les créer et les gérer avec Podman.

Alors un Pod, c'est quoi ?

Un pod c'est tout simplement, une grappe - un groupe - de containers qui vont partager des informations entre eux.

Bien évidement, on peut créer un pod avec un seul container. D'ailleurs Podman ne possède aucune obligation dans l'utilisation des pods. Vous pouvez très bien ne pas les utiliser !

Ce schéma résume très bien le concept de pod présent dans Podman :

Pod schema
Crédits : https://developers.redhat.com/blog/2019/01/15/podman-managing-containers-pods/

Chaque pod possède un container infra, ce container qui est basé sur l'image k8s.gcr.io/pause n'exécute aucun programme. Son but est de conserver les noms associés au pod et de permettre à Podman de se connecter à chaque container du groupe.

Ceci afin de vous permettre de démarrer ou arrêter les containers présents dans le pod tout en le conservant actif. En gros, il permet de garder une indépendance entre l'état de vos conteneurs et celui de votre pod. De ce fait, c'est également lui qui va stocker les informations liées au groupe : Mappage de ports, kernel namespaces, valeurs cgroup-parent.

conmon n'est pas spécifique au pod en soit. C'est un processus qui monitore vos propres containers... Il vérifie l'état du procces principal de vos conteneurs et stocke le code de retour de ceux-ci en cas d'arrêt. Oui, il s'agit ici d'un des mécanismes permettant le daemonless. Vous pouvez retrouver plus d'informations sur conmon ici :

containers/conmon
An OCI container runtime monitor. Contribute to containers/conmon development by creating an account on GitHub.

Ok, un pod c'est un groupe de containers qui partagent des informations mais ça va me servir quand ?

Pourquoi ?

Pour tous ceux qui viennent de Docker, le principe du pod me fait - un peu - penser à l'utilisation de links.

L'option est maintenant dépréciée et doit disparaître de Docker prochainement, mais il est encore possible d'écrire un fichier docker-compose.yaml de cette façon :

version: '2'
services:
  db:
    image: mariadb
    ....

  app:
    links:
      - db
    command: mysql localhost

Cette notion permet de lier, par exemple au niveau réseau, deux conteneurs afin de partager le même localhost. Et bien, bonne nouvelle, avec les pods c'est pareil !

Vous allez pouvoir créer un container Mariadb ou MySQL qui pourra partager directement sur son interface localhost une connexion avec un - ou des - autre(s) container(s) qui sont dans le même pod. Car ils seront tous dans un namespace réseau partagé.

Cela évite d'attacher son service de base de données à une adresse réseau routable ( même privée ).

Alors comment créer son premier Pod ?

Action 🎬

En réalité c'est très simple. Toutes les actions liées au Pod se gèrent avec la commande ... :

lfache@Midgar:~$ podman pod --help
Manage pods

Description:
  Pods are a group of one or more containers sharing the same network, pid and ipc namespaces.

Usage:
  podman pod [command]

Available Commands:
  create      Create a new empty pod
  exists      Check if a pod exists in local storage
  inspect     Displays a pod configuration
  kill        Send the specified signal or SIGKILL to containers in pod
  pause       Pause one or more pods
  prune       Remove all stopped pods and their containers
  ps          List pods
  restart     Restart one or more pods
  rm          Remove one or more pods
  start       Start one or more pods
  stats       Display a live stream of resource usage statistics for the containers in one or more pods
  stop        Stop one or more pods
  top         Display the running processes of containers in a pod
  unpause     Unpause one or more pods

Vous pouvez créer votre premier pod avec la commande suivante :

podman pod create

Si vous ne passez aucun argument, il sera créé avec les options par défaut et un nom aléatoire. Vous pouvez retrouver toutes les options possibles avec la commande :

podman pod create --help
Create a new empty pod

Description:
  After creating the pod, the pod ID is printed to stdout.

  You can then start it at any time with the  podman pod start <pod_id> command. The pod will be created with the initial state 'created'.

Usage:
  podman pod create [flags]

Flags:
      --add-host strings       Add a custom host-to-IP mapping (host:ip) (default [])
      --cgroup-parent string   Set parent cgroup for the pod
      --dns strings            Set custom DNS servers
      --dns-opt strings        Set custom DNS options
      --dns-search strings     Set custom DNS search domains
      --hostname string        Set a hostname to the pod
      --infra                  Create an infra container associated with the pod to share namespaces with (default true)
      --infra-command string   The command to run on the infra container when the pod is started (default "/pause")
      --infra-image string     The image of the infra container to associate with the pod (default "k8s.gcr.io/pause:3.2")
      --ip string              Specify a static IPv4 address for the container
  -l, --label strings          Set metadata on pod (default [])
      --label-file strings     Read in a line delimited file of labels
      --mac-address string     Container MAC address (e.g. 92:d0:c6:0a:29:33)
  -n, --name string            Assign a name to the pod
      --network string         Connect a container to a network (default "slirp4netns")
      --no-hosts               Do not create /etc/hosts within the container, instead use the version from the image
      --pod-id-file string     Write the pod ID to the file
  -p, --publish strings        Publish a container's port, or a range of ports, to the host (default [])
      --share string           A comma delimited list of kernel namespaces the pod will share (default "cgroup,ipc,net,uts")

Il est également possible de générer votre pod directement à la création d'un container :

podman run --name mariadb --pod new:apps -e MYSQL_RANDOM_ROOT_PASSWORD=yes -d mariadb:10

--pod new : permet de créer un pod si celui-ci n'existe pas.

Pour lister les pods existants, tout aussi simple :

podman pod list

Enfin comme un pod est un ensemble de containers, il est possible de les arrêter, les démarrer, ou les redémarrer tous ensemble :

podman pod start : démarre votre pod et l'ensemble des containers associés à celui-ci.

podman pod stop : stoppe le pod et l'ensemble des containers associés.

podman pod restart : redémarrer le  pod et l'ensemble des containers associés.

Pour ajouter un container à un pod existant à la création d'un conteneur :

podman run --name nginx --pod apps -d nginx:alpine

Enfin vous pouvez arrêter le container mariadb ou nginx, l'état du pod sera toujours en cours d'exécution !

lfache@Midgar:~$ podman ps -a
CONTAINER ID  IMAGE                           COMMAND               CREATED         STATUS             PORTS                   NAMES
0e74dd8547cf  docker.io/library/nginx:alpine  nginx -g daemon off;  41 seconds ago  Up 41 seconds ago                          nginx
547425934a71  k8s.gcr.io/pause:3.2                                  42 seconds ago  Created                                    20c1ad7ab5a9-infra
6161d0568097  docker.io/library/mariadb:10    mysqld                5 seconds ago   Up 3 seconds ago   0.0.0.0:3306->3306/tcp  mariadb
lfache@Midgar:~$ podman pod list
POD ID        NAME    STATUS   CREATED         # OF CONTAINERS  INFRA ID
20c1ad7ab5a9  apps    Running  50 seconds ago  3                547425934a71

Et si j'arrête un de mes deux containers :

lfache@Midgar:~$ podman stop nginx
lfache@Midgar:~$ podman ps -a
CONTAINER ID  IMAGE                           COMMAND               CREATED        STATUS                         PORTS                   NAMES
0e74dd8547cf  docker.io/library/nginx:alpine  nginx -g daemon off;  2 minutes ago  Exited (0) About a minute ago                          nginx
547425934a71  k8s.gcr.io/pause:3.2                                  2 minutes ago  Created                                                20c1ad7ab5a9-infra
6161d0568097  docker.io/library/mariadb:10    mysqld                2 minutes ago  Up 25 seconds ago              0.0.0.0:3306->3306/tcp  mariadb

et :

podman pod list
POD ID        NAME    STATUS   CREATED        # OF CONTAINERS  INFRA ID
20c1ad7ab5a9  apps    Running  2 minutes ago  3                547425934a71

Au cours de cet article, nous avons pu voir ce que sont les Pods et comment créer ceux-ci dans Podman à l'aide de la CLI.

Ces notions vont nous permettre dans un prochain article de commencer notre première stack sous Podman en mode rootless.

J'ai d'ailleurs prévu dans le prochain article de vous expliquer pourquoi je prends du temps pour regarder les outils permettant de faire du conteneur rootless ! Est-ce nécessaire ? Docker, n'était déjà pas assez secure ?

J'essaierai de répondre à ces questions lors du prochain article !

En tout cas  n'hésitez pas à m'apporter des remarques ou des commentaires sur Twitter, ou ici 👇