GNU/Linux >> Tutoriels Linux >  >> Linux

Comment exécuter des pods en tant que services systemd avec Podman

Podman est bien connu pour son intégration transparente dans les systèmes Linux modernes, et la prise en charge de systemd est la pierre angulaire de ces efforts. Linux utilise couramment le système systemd init pour gérer les services locaux tels que les serveurs Web, les moteurs de conteneurs, les démons réseau et toutes leurs interdépendances. L'extension de ces pratiques d'administration système Linux plus traditionnelles avec le monde moderne des conteneurs est une évolution naturelle.

Il existe deux cas d'utilisation courants pour combiner systemd et conteneurs :

  • Exécuter systemd dans un conteneur
  • Utiliser systemd pour exécuter des applications conteneurisées

Le premier scénario consiste à exécuter systemd à l'intérieur d'un conteneur. Comme l'explique Dan Walsh, exécuter systemd dans un conteneur est aussi simple que possible lors de l'utilisation de Podman. Podman configure automatiquement plusieurs montages dans le conteneur, et systemd est prêt à partir. Bien qu'il s'agisse d'une fonctionnalité Podman relativement petite, elle a constitué un énorme pas en avant pour l'exécution de charges de travail conteneurisées lors de son introduction.

Historiquement, d'autres outils de conteneur n'ont pas pris en charge systemd. Les utilisateurs ont été confrontés au défi d'écrire des scripts d'initialisation personnalisés, qui sont sujets à des erreurs et à une charge de support pour les éditeurs de logiciels. Avec Podman, tous ces problèmes disparaissent. Les utilisateurs peuvent utiliser systemd pour installer et exécuter leurs applications dans des conteneurs, comme partout ailleurs, et les éditeurs de logiciels ne seront pas confrontés aux défis liés à la gestion de scripts d'initialisation personnalisés écrits par leurs utilisateurs.

Le deuxième scénario utilise systemd pour exécuter et gérer des applications conteneurisées. Cela signifie que systemd démarre une application conteneurisée et gère l'intégralité de son cycle de vie. Podman simplifie cela avec le podman generate systemd commande, qui génère un fichier d'unité systemd pour un conteneur ou un pod spécifié. Podman v1.7 et versions ultérieures prennent en charge la génération de telles unités. Au fil du temps, notre équipe a amélioré cette fonctionnalité et généré des fichiers d'unité systemd qui peuvent s'exécuter sur d'autres machines, similaires à l'utilisation d'un fichier YAML Kubernetes ou d'un fichier Compose. De plus, l'intégration étroite avec systemd a jeté les bases des mises à jour automatiques et des restaurations simples, prises en charge depuis Podman v3.4.

Bien qu'il existe de nombreux blogs et articles antérieurs sur la génération d'unités systemd pour les conteneurs, il n'y en a aucun pour générer ces unités pour les pods. Mais avant d'entrer dans ces détails, je veux revoir ce qu'est un pod.

[ Vous débutez avec les conteneurs ? Découvrez ce cours gratuit. Déploiement d'applications conteneurisées :présentation technique. ]

Qu'est-ce qu'un module ?

Il y a plusieurs parties différentes dans un pod, et je pense que Brent Baude l'explique le mieux avec la superbe figure ci-dessous :

La première chose à remarquer est qu'un pod se compose d'un ou plusieurs conteneurs. Le groupe partage des groupes de contrôle (cgroups) et des espaces de noms spécifiques tels que le PID, le réseau et l'espace de noms IPC. Les cgroups partagés garantissent que tous les conteneurs ont les mêmes contraintes de ressources. Les espaces de noms partagés permettent aux conteneurs de communiquer plus facilement entre eux (par exemple via la communication localhost ou interprocessus).

Vous pouvez également voir un conteneur infra spécial. Son objectif principal est de maintenir ouvertes des ressources spécifiques associées au pod, telles que des ports, des espaces de noms ou des cgroups. Le conteneur infra est le conteneur de niveau supérieur du pod, et il est créé avant les autres conteneurs et détruit en dernier. Vous utilisez le conteneur infra lors de la génération d'unités systemd pour un pod, alors gardez à l'esprit que ce conteneur s'exécute pendant toute la durée de vie du pod. Cela implique également que vous ne pouvez pas générer d'unités systemd pour les pods sans conteneur infra (comme --infra=false ).

Enfin et surtout, vous voyez plusieurs conmon processus en cours d'exécution, un par conteneur. "Commun" est l'abréviation de moniteur de conteneur, qui résume sa fonctionnalité principale. Il s'occupe également de transférer les journaux et d'effectuer des actions de nettoyage une fois que le conteneur est sorti. Le conmon le processus démarre avant le conteneur et instruit le runtime du conteneur sous-jacent (tel que runc ou crun ) pour créer et démarrer le conteneur. Il se termine également avec le code de sortie du conteneur permettant de l'utiliser comme processus principal d'un service systemd.

Générer des unités systemd pour un pod

Podman génère exactement une unité système pour un conteneur. Une fois installé, utilisez systemctl pour démarrer, arrêter et inspecter le service. Le PID principal de chaque unité est le processus commun du conteneur. De cette façon, systemd peut lire le code de sortie du conteneur et agir conformément à la politique de redémarrage configurée. Pour plus de détails sur les unités, veuillez consulter Exécuter des conteneurs avec Podman et des services partageables systemd et Podman systemd amélioré avec Podman 2.0.

Générer des unités pour un pod est très similaire au démarrage d'un conteneur. Chaque conteneur du pod a une unité systemd dédiée, et chaque unité dépend de l'unité systemd principale du pod. De cette façon, vous pouvez continuer à utiliser systemctl pour démarrer, arrêter et inspecter le service principal du pod ; systemd se chargera de (re)démarrer et d'arrêter les services des conteneurs avec le service principal.

Cet exemple crée un pod avec deux conteneurs, génère des fichiers d'unité pour le pod, puis installe les fichiers pour l'utilisateur actuel :

$ podman pod create --name=my-pod
635bcc5bb5aa0a45af4c2f5a508ebd6a02b93e69324197a06d02a12873b6d1f7

$ podman create --pod=my-pod --name=container-a -t centos top
c04be9c4ac1c93473499571f3c2ad74deb3e0c14f4f00e89c7be3643368daf0e

$ podman create --pod=my-pod --name=container-b -t centos top
b42314b2deff99f5877e76058ac315b97cfb8dc40ed02f9b1b87f21a0cf2fbff

$ cd $HOME/.config/systemd/user

$ podman generate systemd --new --files --name my-pod
/home/vrothberg/.config/systemd/user/pod-my-pod.service
/home/vrothberg/.config/systemd/user/container-container-b.service
/home/vrothberg/.config/systemd/user/container-container-a.service

Comme prévu, Podman a généré trois .service fichiers, un pour chaque conteneur plus celui de niveau supérieur pour le pod. Veuillez vous référer à l'annexe à la fin de l'article pour voir l'intégralité du contenu des fichiers de l'unité. Les unités générées pour les deux conteneurs ressemblent à des unités de conteneur standard plus les dépendances systemd suivantes :

  • BindsTo=pod-my-pod.service :L'unité du conteneur est "liée" à l'unité du pod. Si l'unité du pod est arrêtée, cette unité sera également arrêtée.
  • After=pod-my-pod.service :L'unité du conteneur démarre après l'unité du pod.

Les dépendances du service principal du pod garantissent en outre que si une unité de conteneur ne démarre pas correctement, l'unité principale du pod principal échouera également.

C'est tout ce que vous devez savoir sur la génération d'unités systemd pour les pods avec Podman. Une fois que vous avez rechargé systemd via systemctl --user daemon-reload , démarrer et arrêter le pod.service à volonté. Jetez un œil :

# Reload the daemon
$ systemctl --user daemon-reload

# Start the pod service and make sure the service is running
$ systemctl --user start pod-my-pod.service

$ systemctl --user is-active pod-my-pod.service
active

# Make sure the pod and its containers are running
$ podman pod ps
POD ID    	NAME    	STATUS  	CREATED    	INFRA ID  	# OF CONTAINERS
6dd1090d4ca6  my-pod  	Running 	2 minutes ago  85f760a5cfe5  3
user $ podman container ps
CONTAINER ID  IMAGE                                	COMMAND 	CREATED    	STATUS        	PORTS   	NAMES
85f760a5cfe5  localhost/podman-pause:4.0.2-1646319369          	5 minutes ago  Up 5 minutes ago          	6dd1090d4ca6-infra
44a7e60b9563  quay.io/centos/centos:latest         	top     	5 minutes ago  Up 5 minutes ago          	container-b
31f24bdff747  quay.io/centos/centos:latest         	top     	5 minutes ago  Up 5 minutes ago          	container-a

Super, tout fonctionne comme prévu. Vous pouvez utiliser systemctl pour démarrer les services, et Podman répertorie correctement les pods et leurs conteneurs. Par souci de cohérence, jetez un dernier coup d'œil à la façon d'arrêter le service de pod.

# Stop the pod service
$ systemctl --user stop pod-my-pod.service

# Make sure the pod and its containers are removed
$ podman pod ps -q

$ podman container ps -q

# Make sure the services are inactive
$ systemctl --user is-active pod-my-pod.service container-container-a.service container-container-b.service
inactive
inactive
inactive

Le message à retenir est que Podman génère des unités systemd pour les pods comme il le fait pour les conteneurs. Les dépendances entre ces unités sont définies de manière à ce que vous n'ayez qu'à interagir avec l'unité principale du pod, et systemd se charge de démarrer et d'arrêter les unités des conteneurs.

Annexe

Podman génère les fichiers d'unité suivants pour un pod et les deux conteneurs associés.

pod-mon-pod.service

Description=Podman pod-my-pod.service
Documentation=man:podman-generate-systemd(1)
Wants=network-online.target
After=network-online.target
RequiresMountsFor=
Requires=container-container-a.service container-container-b.service
Before=container-container-a.service container-container-b.service

[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Restart=on-failure
TimeoutStopSec=70
ExecStartPre=/bin/rm -f %t/pod-my-pod.pid %t/pod-my-pod.pod-id
ExecStartPre=/usr/bin/podman pod create --infra-conmon-pidfile %t/pod-my-pod.pid --pod-id-file %t/pod-my-pod.pod-id --name=my-pod --replace
ExecStart=/usr/bin/podman pod start --pod-id-file %t/pod-my-pod.pod-id
ExecStop=/usr/bin/podman pod stop --ignore --pod-id-file %t/pod-my-pod.pod-id -t 10
ExecStopPost=/usr/bin/podman pod rm --ignore -f --pod-id-file %t/pod-my-pod.pod-id
PIDFile=%t/pod-my-pod.pid
Type=forking

[Install]
WantedBy=default.target

container-container-a.service

[Unit]
Description=Podman container-container-a.service
Documentation=man:podman-generate-systemd(1)
Wants=network-online.target
After=network-online.target
RequiresMountsFor=%t/containers
BindsTo=pod-my-pod.service
After=pod-my-pod.service

[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Restart=on-failure
TimeoutStopSec=70
ExecStartPre=/bin/rm -f %t/%n.ctr-id
ExecStart=/usr/bin/podman run --cidfile=%t/%n.ctr-id --cgroups=no-conmon --rm --pod-id-file %t/pod-my-pod.pod-id --sdnotify=conmon -d --replace --name=container-a -t centos top
ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id
ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id
Type=notify
NotifyAccess=all

[Install]
WantedBy=default.target

container-container-b.service

[Unit]
Description=Podman container-container-b.service
Documentation=man:podman-generate-systemd(1)
Wants=network-online.target
After=network-online.target
RequiresMountsFor=%t/containers
BindsTo=pod-my-pod.service
After=pod-my-pod.service

[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Restart=on-failure
TimeoutStopSec=70
ExecStartPre=/bin/rm -f %t/%n.ctr-id
ExecStart=/usr/bin/podman run --cidfile=%t/%n.ctr-id --cgroups=no-conmon --rm --pod-id-file %t/pod-my-pod.pod-id --sdnotify=conmon -d --replace --name=container-b -t centos top
ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id
ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id
Type=notify
NotifyAccess=all

[Install]
WantedBy=default.target


Linux
  1. Comment gérer les services Systemd avec Systemctl sous Linux

  2. Comment utiliser Podman à l'intérieur d'un conteneur

  3. Linux - Comment exécuter un script avec Systemd juste avant l'arrêt ?

  4. Comment exécuter MySQL dans un conteneur Docker

  5. Comment exécuter un script avant tout le reste à l'arrêt avec systemd ?

Comment exécuter Podman sous Windows

Exécutez le conteneur Almalinux ou Rocky Linux 8 Docker avec Systemd (systemctl)

Comment exécuter PHPMyAdmin dans un conteneur Docker

Comment exécuter Grafana dans un conteneur Docker

Comment exécuter des conteneurs Docker

Comment exécuter un alias avec Sudo sous Linux