GNU/Linux >> Linux の 問題 >  >> Linux

Podmanを使用してpodをsystemdサービスとして実行する方法

Podmanは、最新のLinuxシステムへのシームレスな統合でよく知られており、systemdのサポートはこれらの取り組みの基礎です。 Linuxは通常、systemd initシステムを使用して、Webサーバー、コンテナーエンジン、ネットワークデーモン、およびそれらのすべての相互依存関係などのローカルサービスを管理します。これらのより伝統的なLinuxシステム管理手法を、現代のコンテナーの世界で拡張することは、自然な進化です。

systemdとcontainersを組み合わせる一般的なユースケースは2つあります。

  • コンテナ内でsystemdを実行する
  • systemdを使用してコンテナ化されたアプリケーションを実行する

最初のシナリオは、コンテナー内でsystemdを実行することです。 Dan Walshが説明しているように、コンテナー内でsystemdを実行することは、Podmanを使用する場合と同じくらい簡単です。 Podmanはコンテナにいくつかのマウントを自動的に設定し、systemdは問題ありません。これは比較的小さなPodman機能ですが、導入されたときは、コンテナー化されたワークロードを実行するための大きな飛躍でした。

歴史的に、他のコンテナツールはsystemdをサポートしていませんでした。ユーザーは、カスタムinitスクリプトを作成するという課題に直面しました。このスクリプトは、エラーが発生しやすく、ソフトウェアベンダーのサポートに負担がかかります。 Podmanを使用すると、これらの問題はすべて解消されます。ユーザーはsystemdを使用して、他の場所と同じようにアプリケーションをコンテナーにインストールして実行できます。ソフトウェアベンダーは、ユーザーが作成したカスタムinitスクリプトを処理するという課題に直面することはありません。

2番目のシナリオは、systemdを使用してコンテナー化されたアプリケーションを実行および管理することです。つまり、systemdはコンテナ化されたアプリケーションを開始し、そのライフサイクル全体を管理します。 Podmanは、podman generate systemdを使用してこれを簡素化します。 コマンド。指定されたコンテナまたはポッドのsystemdユニットファイルを生成します。 Podman v1.7以降は、このようなユニットの生成をサポートしています。時間の経過とともに、私たちのチームはこの機能を改善し、Kubernetes YAMLまたはComposeファイルを使用するのと同様に、他のマシンで実行できるsystemdユニットファイルを生成しました。さらに、systemdとの緊密な統合により、Podmanv3.4以降でサポートされている自動更新と単純なロールバックの基盤が築かれました。

コンテナ用のsystemdユニットの生成に関する以前のブログや記事はたくさんありますが、ポッド用にこれらのユニットを生成するためのブログや記事はありません。ただし、これらの詳細に入る前に、ポッドとは何かを確認したいと思います。

[コンテナを使い始めますか?この無料コースをチェックしてください。コンテナ化されたアプリケーションのデプロイ:技術的な概要。 ]

ポッドとは何ですか?

ポッドにはいくつかの異なる部分があり、ブレント・ボーデは以下の素晴らしい図でそれを最もよく説明していると思います:

最初に気付くのは、ポッドが1つ以上のコンテナで構成されていることです。このグループは、制御グループ(cgroups)と、PID、ネットワーク、IPC名前空間などの特定の名前空間を共有します。共有cgroupは、すべてのコンテナーが同じリソース制約を持つことを保証します。共有名前空間を使用すると、コンテナーは相互に簡単に通信できます(localhostやプロセス間通信など)。

特別なインフラコンテナも見ることができます。その主な目的は、ポート、名前空間、cgroupなど、ポッドに関連付けられた特定のリソースを開いたままにすることです。インフラコンテナはポッドの最上位コンテナであり、他のコンテナの前に作成され、最後に破棄されます。ポッドのsystemdユニットを生成するときにインフラコンテナを使用するため、このコンテナはポッドの存続期間全体にわたって実行されることに注意してください。また、インフラコンテナ(--infra=falseなど)がないと、ポッドのsystemdユニットを生成できないことも意味します。 。

最後になりましたが、複数のconmonが表示されます 実行中のプロセス、コンテナごとに1つ。 「Common」はコンテナモニターの略で、主な機能をまとめたものです。また、ログの転送と、コンテナーが終了した後のクリーンアップアクションの実行も処理します。 conmon プロセスはコンテナの前に開始され、基になるコンテナランタイム(runcなど)に指示します またはcrun )コンテナを作成して開始します。また、コンテナーの終了コードで終了し、systemdサービスのメインプロセスとして使用できるようにします。

ポッド用のsystemdユニットの生成

Podmanは、コンテナに対して1つのシステムユニットを生成します。インストールしたら、systemctlを使用します サービスを開始、停止、および検査します。各ユニットのメインPIDは、コンテナの共通プロセスです。このようにして、systemdはコンテナーの終了コードを読み取り、構成された再始動ポリシーに従って動作することができます。ユニットの詳細については、Podmanとsystemd共有可能サービスを使用したコンテナの実行およびPodman2.0を使用したsystemdPodmanの改善を参照してください。

ポッドのユニットの生成は、コンテナの開始と非常によく似ています。ポッド内の各コンテナには専用のsystemdユニットがあり、各ユニットはポッドのメインのsystemdユニットに依存します。このようにして、systemctlを引き続き使用できます。 ポッドのメインサービスを開始、停止、および検査します。 systemdは、メインサービスとともにコンテナのサービスの(再)開始と停止を処理します。

この例では、2つのコンテナでポッドを作成し、ポッドのユニットファイルを生成してから、現在のユーザーのファイルをインストールします。

$ 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

予想どおり、Podmanは3つの.serviceを生成しました ファイル、コンテナごとに1つ、ポッド用の最上位ファイル。ユニットファイルの内容全体を確認するには、記事の最後にある付録を参照してください。 2つのコンテナー用に生成されたユニットは、標準のコンテナーユニットに加えて、次のsystemd依存関係のように見えます。

  • BindsTo=pod-my-pod.service :コンテナユニットはポッドのユニットに「バインド」されています。ポッドのユニットが停止すると、このユニットも停止します。
  • After=pod-my-pod.service :コンテナユニットは、ポッドのユニットの後に起動します。

ポッドのメインサービスの依存関係により、コンテナユニットが正常に起動しない場合、メインポッドのメインユニットも失敗することがさらに確実になります。

Podmanを使用してポッド用のsystemdユニットを生成する方法について知っておく必要があるのはこれだけです。 systemctl --user daemon-reloadを介してsystemdをリロードしたら 、pod.serviceを開始および停止します 意のままに。ご覧ください:

# 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

素晴らしい、すべてが期待どおりに機能しています。 systemctlを使用できます サービスを開始するために、Podmanはポッドとそのコンテナを正しくリストします。一貫性を保つために、ポッドサービスを停止する方法を最終的に確認してください。

# 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

持ち帰りのメッセージは、Podmanがコンテナの場合と同じようにポッドのsystemdユニットを生成することです。これらのユニット間の依存関係は、ポッドのメインユニットと対話するだけでよいように設定され、systemdがコンテナのユニットの開始と停止を処理します。

付録

Podmanは、ポッドと2つの関連するコンテナ用に次のユニットファイルを生成します。

pod-my-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. コンテナ内でのPodmanの使用方法

  2. Linux –シャットダウン直前にsystemdでスクリプトを実行する方法は?

  3. 実行中のSystemdコンテナ内でコマンドを実行する方法は?

  1. LinuxでSystemctlを使用してSystemdサービスを管理する方法

  2. DockerコンテナでMySQLを実行する方法

  3. シャットダウン直前にsystemdでスクリプトを実行する方法は?

  1. 例を使用してDockerRunコマンドを使用する方法

  2. systemd サービスを削除する方法

  3. systemd でのシャットダウン時に、他のすべての前にスクリプトを実行するにはどうすればよいですか?