hana_shinのLinux技術ブログ

Linuxの技術情報を掲載しています。特にネットワークをメインに掲載していきます。

コンテナを自動更新する方法



1 はじめに

イメージは時間が経つとバグや脆弱性の修正が必要になることがあります。修正が必要な場合、リポジトリから最新のイメージをプルし、コンテナを再作成する必要があります。io.containers.autoupdate は、コンテナの自動更新に関する設定を行うためのラベルです。このラベルには、コンテナの更新方法を指定する値を設定できます。具体的な設定値は以下の2つです。

io.containers.autoupdateの値 意味
registry リモートレジストリのイメージが更新されると、コンテナが自動的に更新されます
local ローカルに保存されているイメージが更新されると、コンテナが自動的に更新されます

io.containers.autoupdate を使うことで、コンテナの自動更新を効率的に管理し、常に最新の状態を維持することができます。本記事では、io.containers.autoupdate に local を指定した際の動作について確認します。

参考記事:podman-auto-update — Podman documentation

2 検証環境

サーバのAlmaLinux版数は以下のとおりです。

[user1@server ~]$ cat /etc/redhat-release
AlmaLinux release 9.2 (Turquoise Kodkod)

カーネル版数は以下のとおりです。

[user1@server ~]$ uname -r
5.14.0-284.11.1.el9_2.x86_64

3 動作確認( io.containers.autoupdate=local )

タグは何を使ってもかまいませんが、ここでは、タグが2.4の httpd イメージをダウンロードします。

[user1@server ~]$ podman pull docker.io/library/httpd:2.4

ダウンロードしたイメージを確認します。httpd イメージのタグが2.4であることが確認できます。

[user1@server ~]$ podman images
REPOSITORY               TAG         IMAGE ID      CREATED      SIZE
docker.io/library/httpd  2.4         a49fd2c04c02  5 weeks ago  152 MB

podman create コマンドを使用して、my-httpd という名前のコンテナを作成し、自動更新の設定を行います。ラベルに "io.containers.autoupdate=local" を指定することで、このコンテナはローカルのイメージが更新された際に自動的に再作成されるようになります。

[user1@server ~]$ podman create --name my-httpd --label "io.containers.autoupdate=local" docker.io/library/httpd:2.4
8649fb16b03903842fb4ba2486c35375f6f5d8db1ec4733428d8161244f04a78

コンテナの状態を確認すると 「Created」 になっています。この状態は、コンテナが作成されたがまだ実行されていないことを示しています。コンテナは停止しており、実際に動作していません。

[user1@server ~]$ podman ps -a
CONTAINER ID  IMAGE                        COMMAND           CREATED        STATUS      PORTS       NAMES
8649fb16b039  docker.io/library/httpd:2.4  httpd-foreground  9 seconds ago  Created                 my-httpd

ユニットファイルを格納するディレクトリを作成します。

[user1@server ~]$ mkdir -p /home/user1/config/systemd/user

ユニットファイルを生成します。

[user1@server ~]$ podman generate systemd my-httpd --new  > /home/user1/.config/systemd/user/my-httpd.service

新しく作成したユニットファイルを systemd が認識できるようにします。

[user1@server ~]$ systemctl --user daemon-reload

サービスを有効化し、サービスを起動(--now)します。

[user1@server ~]$ systemctl --user enable --now my-httpd.service
Created symlink /home/user1/.config/systemd/user/default.target.wants/my-httpd.service → /home/user1/.config/systemd/user/my-httpd.service.

サービスの状態を確認すると、Active であることが確認できます。

[user1@server ~]$ systemctl --user status my-httpd.service
● my-httpd.service - Podman container-8649fb16b03903842fb4ba2486c35375f6f5d8db1ec4733428d8161244f04a78.service
     Loaded: loaded (/home/user1/.config/systemd/user/my-httpd.service; enabled; preset: disabled)
     Active: active (running) since Tue 2024-08-27 22:23:40 JST; 3s ago
       Docs: man:podman-generate-systemd(1)
   Main PID: 9891 (conmon)
      Tasks: 2 (limit: 22895)
     Memory: 1.6M
        CPU: 201ms
     CGroup: /user.slice/user-1001.slice/user@1001.service/app.slice/my-httpd.service
             tq9886 /usr/bin/slirp4netns --disable-host-loopback --mtu=65520 --enable-sandbox --enable-seccomp --enable-ipv6 -c -e 3 -r 4 --netns-type>
             mq9891 /usr/bin/conmon --api-version 1 -c b885329c56abf5f6ebc297b09df2eabb327023b81d6989dc9431a29da8a29ed2 -u b885329c56abf5f6ebc297b09df>
[user1@server ~]$

コンテナのラベルを確認します。

[user1@server ~]$ podman inspect my-httpd --format '{{json .Config.Labels}}' | jq
{
  "PODMAN_SYSTEMD_UNIT": "my-httpd.service",
  "io.containers.autoupdate": "local"
}

podman auto-update コマンドを実行してコンテナの更新をしてみます。この時点ではイメージが更新されていないため、UPDATED の値が 「false」 となっています。これにより、コンテナがまだ更新されていないことが確認できます。

[user1@server ~]$ podman auto-update
            UNIT              CONTAINER                IMAGE                        POLICY      UPDATED
            my-httpd.service  b885329c56ab (my-httpd)  docker.io/library/httpd:2.4  local       false

LABELディレクティブを使って、イメージにラベルをつける Containerfile を作成します。ラベルをつけることで、ローカルに保存されているイメージを更新することができます。Containerfile の作成方法は、コンテナイメージの作り方(Containerfile 編) - hana_shinのLinux技術ブログを参照してください。

[user1@server ~]$ vi Containerfile
[user1@server ~]$ cat Containerfile
FROM docker.io/library/httpd:2.4
LABEL maintainer="hana_shin@example.com"

イメージをビルドします。

[user1@server ~]$ podman build -t docker.io/library/httpd:2.4 .

ビルドしたイメージを確認します。

[user1@server ~]$ podman images
REPOSITORY               TAG         IMAGE ID      CREATED        SIZE
docker.io/library/httpd  2.4         dd47d65b4c2f  4 seconds ago  152 MB

podman auto-update コマンドを実行すると、今度は UPDATED の値が true となりました。これは、更新されたイメージを検知した結果、コンテナが自動的に更新されたことを示しています。つまり、自動更新が正常に動作していることが確認できました。

[user1@server ~]$ podman auto-update
            UNIT              CONTAINER                IMAGE                        POLICY      UPDATED
            my-httpd.service  b885329c56ab (my-httpd)  docker.io/library/httpd:2.4  local       true

コンテナのラベルを確認すると、Containerfile で指定したラベル("maintainer": "hana_shin@example.com")が付加されていることが確認できます。つまり更新したイメージでコンテナが動作していることがわかります。

[user1@server ~]$ podman inspect my-httpd --format '{{json .Config.Labels}}' | jq
{
  "PODMAN_SYSTEMD_UNIT": "my-httpd.service",
  "io.buildah.version": "1.29.0",
  "io.containers.autoupdate": "local",
  "maintainer": "hana_shin@example.com"
}

4 あと始末

サービスを停止します。

[user1@server ~]$ systemctl --user stop my-httpd.service

サービスを無効化します。

[user1@server ~]$ systemctl --user disable my-httpd.service
Removed "/home/user1/.config/systemd/user/default.target.wants/my-httpd.service".

ユニットファイルを削除します。

[user1@server ~]$ rm /home/user1/.config/systemd/user/my-httpd.service

ユニットファイルが削除されたことを systemd が認識できるようにします。

[user1@server ~]$ systemctl --user daemon-reload

イメージを削除します。

[user1@server ~]$ podman rmi a49fd2c04c02

5 メモ

Docker Hub の httpd イメージのタグを確認するには、次のコマンドを使用します。

[user1@server ~]$ curl -s https://registry.hub.docker.com/v2/repositories/library/httpd/tags/ | jq '.results[].name'
"latest"
"bookworm"
"2.4.62-bookworm"
"2.4.62"
"2.4-bookworm"
"2.4"
"2-bookworm"
"2"
"alpine3.20"
"alpine"

Y 参考図書

今回の記事執筆にあたり参考にした図書は以下のものです。

単行本


Docker実践ガイド 第3版 (impress top gear)

電子書籍



Software Design (ソフトウェアデザイン) 2023年11月号 [雑誌]


Docker実践ガイド 第3版 impress top gearシリーズ