ウェブサイト検索

Quadletを使用してSystemdの下でPodmanコンテナを実行する方法


Quadletは、C言語で書かれた無料でオープンソースのツールで、SystemdのもとでPodmanコンテナを作成および実行することができます。このツールを使用することで、専用のSystemdユニットを用いて、コンテナ、ボリューム、ネットワーク、およびそれらの関係を宣言することができます。

このチュートリアルでは、Quadletを使ってPodmanコンテナ、ネットワーク、ボリュームを作成する方法と、マルチコンテナスタックを作成する方法を学びます。

このチュートリアルではあなたが学ぶことになる:

  • 対応するSystemdユニットを使用してコンテナ、ボリューム、ネットワークを作成する方法
  • Quadletを使用してマルチコンテナスタックを作成する方法

基本的な例: MariaDB コンテナの作成

この最初の基本的な例では、MariaDBデータベースサーバーのユニットを定義します。これがその見た目です。

[Unit]
Description=MariaDB container

[Container]
Image=docker.io/mariadb:latest
Environment=MYSQL_ROOT_PASSWORD=rootpassword
Environment=MYSQL_USER=testuser
Environment=MYSQL_PASSWORD=testpassword
Environment=MYSQL_DATABASE=testdb

[Install]
WantedBy=multi-user.target

これらの少ない行で、Dockerhubで利用可能な最新の公式MariaDBイメージに基づいたコンテナを定義しました。ご覧の通り、「.container」は専用のSystemdユニットのタイプです。このタイプのユニットに特有なのは、「Container」セクションで、ここでPodmanコマンドラインに渡せるオプションを指定できます。「Container」セクションで必要な唯一のオプションは、コンテナのベースイメージを指定するためのImageです。

コンテナをルートとして実行したい場合、ファイルを/etc/containers/systemdディレクトリに保存します。代わりに、自分の特権のないユーザーとして実行する場合は、~/.config/containers/systemdに保存します。この例では、後者のアプローチを使用し、私たちの“.container”ユニットを~/.config/containers/systemd/mariadb-service.containerとして保存します。systemdにコンテナユニットに基づくサービスを生成させるために、次のコマンドを実行します:

systemctl --user daemon-reload

コマンドを実行した後、生成されたサービスを次のように実行して確認できます:

systemctl --user cat mariadb-service

コンテナを開始するには、他のサービスと同様に、次のように実行できます:

systemctl --user start mariadb-service

最初にそれを起動するとき、コンテナのベースイメージがシステムに存在しない場合、サービスの開始に時間がかかることがあります。コンテナの状態を確認するために、podman コマンドラインを使用できます:

podman ps

コマンドは以下の出力を返し、コンテナが稼働していることを確認します:

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
151226b10a1c docker.io/library/mariadb:latest mariadbd 59 seconds ago Up About a minute systemd-mariadb-service

お気付きかもしれませんが、デフォルトでは、コンテナは「.container」ユニットファイルに「systemd-」接頭辞(この場合は「systemd-mariadb-service」)を付けた名前になります。しかし、コンテナに明示的に名前を付けるには、「[Container]」セクション内のContainerNameオプションの値として指定することができます。

「ボリューム」単位を作成する

私たちはボリュームを使用してコンテナのデータを永続化します。この場合、systemd-mariadb-serviceコンテナを削除してもデータベースデータが永続化されるようにしたいと思います。対応する「.volume」ユニットに名前付きボリュームを定義します。以下の例では、ボリュームの説明を提供するだけです。ボリューム固有のオプションは[Volume]スタンザの下で指定できます。

[Unit]
Description=MariaDB Volume

[Volume]

単位を~/.config/containers/systemd/mariadb-volume.volumeとして保存します。MariaDBコンテナにボリュームを使用するよう指示するために、“.container”ユニットの[Container]セクション内でVolumeオプションを使用し、ボリュームをコンテナ内の/var/lib/mysqlディレクトリにマッピングします:

[Unit]
Description=MariaDB container

[Container]
Image=docker.io/mariadb:latest
Environment=MYSQL_ROOT_PASSWORD=rootpassword
Environment=MYSQL_USER=testuser
Environment=MYSQL_PASSWORD=testpassword
Environment=MYSQL_DATABASE=testdb
Volume=mariadb-volume.volume:/var/lib/mysql

[Install]
WantedBy=multi-user.target

名前付きボリュームを使用すると、Systemdはコンテナのために生成するサービスユニットに自動的に依存関係を割り当てます。必要なサービスを再生成できるようにするために、再びdaemon-reloadコマンドを使用します。MariaDBコンテナを(再)起動すると、ボリュームは自動的に作成されます。これは、podmanコマンドラインユーティリティを使用して確認できます:

podman volume ls

予想通り、私たちのボリュームは次のコマンドで生成されたリストに表示されます:

DRIVER        VOLUME NAME
local         systemd-mariadb-volume

コンテナ内の /var/lib/mysql にボリュームがマウントされているかどうかは、podman inspect コマンドを使用して確認することもでき、コンテナの名前を引数として渡し、「Mounts」セクションを見てみることができます。

podman inspect systemd-mariadb-service

ここに出力の関連セクションがあります。

"Mounts": [
     {
         "Type": "volume",
         "Name": "systemd-mariadb-volume",
         "Source": "/home/doc/.local/share/containers/storage/volumes/systemd-mariadb-volume/_data",
         "Destination": "/var/lib/mysql",
         "Driver": "local",
         "Mode": "",
         "Options": [
              "nosuid",
              "nodev",
              "rbind"
         ],
         "RW": true,
         "Propagation": "rprivate"
     }
],

バインドマウントを使用すること

名前付きボリュームの代わりにバインドマウントを使用したい場合はどうでしょうか?バインドマウントは、ホストファイルをコンテナ内にマウントできるため、開発中に便利です。バインドマウントを使用するデメリットは、コンテナがホストのファイルシステムに依存してしまうことです。“.container” ユニット内でバインドマウントを使用するには、マウントしたいホストファイルの相対パスまたは絶対パスを指定するだけです。例えば、コンテナ内の /var/lib/mysql ディレクトリをホストの ~/mysql ディレクトリにバインドマウントしたいとしましょう。“.container” ユニットに書くべき内容は次のようになります:

[Unit]
Description=MariaDB container

[Container]
Image=docker.io/mariadb:latest
Environment=MYSQL_ROOT_PASSWORD=rootpassword
Environment=MYSQL_USER=testuser
Environment=MYSQL_PASSWORD=testpassword
Environment=MYSQL_DATABASE=testdb
Volume=%h/mysql:/var/lib/mysql

[Install]
WantedBy=multi-user.target

上記の例では、%h プレースホルダーを使用していることがわかります。これは、Systemdによって自分のホームディレクトリの絶対パスに自動的に展開されます。また、ユニットファイルの位置に対して相対的に解決される相対パスを使用することも可能です。

ネットワークを作成する

docker-composeと同様に、複数のコンテナで構成されたスタックを作成するには、コンテナ同士が通信できるように同じネットワークに配置する必要があります。Quadletでネットワークを作成するには、“.network”拡張子を持つユニットを使用できます。

コンテナやボリュームと同様に、デフォルトではネットワークは、その定義されているユニットファイルの名前と「systemd-」プレフィックスを組み合わせた名前が付けられます。ファイルの [Network] セクションで、名前やその他のネットワーク特有のオプションを明示的に指定することができます。以下の例では、ネットワークのサブネットおよびゲートウェイアドレスを指定しています(これは、--subnet 192.168.30.0/24 および --gateway 192.168.30.1 オプションで podman を実行するのと同等です)。

[Unit]
Description=MariaDB Network

[Network]
Subnet=192.168.30.0/24
Gateway=192.168.30.1

ファイルを ~/.config/containers/systemd/mariadb.network として保存します。特定のネットワークにコンテナを「配置」するためには、そのコンテナユニットの「Container」セクション内の Network オプションを使用します。以前に定義したMariaDBコンテナは以下のようになります:

[Unit]
Description=MariaDB container

[Container]
Image=docker.io/mariadb:latest
Environment=MYSQL_ROOT_PASSWORD=rootpassword
Environment=MYSQL_USER=testuser
Environment=MYSQL_PASSWORD=testpassword
Environment=MYSQL_DATABASE=testdb
Volume=mariadb-volume.volume:/var/lib/mysql
Network=mariadb.network

マルチコンテナスタックの作成

私たちはMariaDBサーバーを実行しているコンテナを持っています。データベースをウェブインターフェースを介して管理する簡単な方法を追加するために、phpMyAdminに基づいたコンテナを作成できます。2つのコンテナが互いに通信できるようにするために、同じネットワークに配置する必要があります。

phpMyAdminコンテナは正しく動作するためにMariaDBサーバがアクティブかつ稼働している必要があるため、他のSystemdサービスと同様にこの依存関係を宣言することができます。これは、「[Unit]」セクションのRequiresおよびAfterオプションを使って行います。前者は、指定されたサービスへのハード依存関係を確立し、後者は私たちのサービスがその後に起動することを保証します。ところで、Systemdに不慣れな場合は、Systemdサービスの作成方法に関するチュートリアルを参照できます。以下はphpMyAdminのコンテナユニットの例です:

[Unit]
Description=phpMyAdmin container
Requires=mariadb-service.service
After=mariadb-service.service
 
[Container]
Image=docker.io/phpmyadmin:latest
Network=mariadb.network
Environment=PMA_HOST=systemd-mariadb-service
PublishPort=8080:80

[Install]
WantedBy=multi-user.target

上記の例では、PublishPortオプションも使用しました。これはpodmanの-p(--publish)に相当し、ホストポートをコンテナポートにマッピングするために使用されます。この場合、ホストシステムのポート8080をコンテナ内のポート80にマッピングしました。

私たちはまた、Environmentオプションを介してPMA_HOST環境変数の値を提供しました:これはデータベースサーバーのアドレスを指定するために使用されます(この場合、私たちはMariaDBコンテナ名を使用し、それが実際のアドレスに解決されます)。注意すべきは、環境変数の値としてMariaDBコンテナの名前を使用し、「.container」ユニットの名前は使用していないことです。新しいセットアップを開始するには、再度、次のように実行します。

systemd --user daemon-reload

次に、生成された「phpmyadmin-service」サービスを開始することができます。これは、phpMyAdminコンテナを実行します。MariaDBコンテナに堅牢な依存関係があるため、後者も自動的に開始されます。私たちは「localhost:8080」アドレスでphpMyAdminにアクセスできるはずです。ログインするには、MariaDBコンテナユニットに指定された資格情報を使用できます。

締めくくりの考え

このチュートリアルでは、Quadletを使用してSystemdの下でPodmanコンテナ、ボリューム、およびネットワークを作成して実行する方法を学びました。docker-composeを使用する場合のように単一のファイルでマルチコンテナスタックを定義する代わりに、Quadletを使用して専用のSystemdユニットを使ってコンテナ、ボリューム、ネットワークを定義します。

関連記事: