Podmanのauto-update機能でコンテナの自動更新を試す

概要

Podmanのauto-update機能を利用するとレジストリ上のコンテナイメージが更新された場合に自動でコンテナを新しいコンテナイメージに差し替える自動更新が可能になる。 また、auto-update機能は更新後のコンテナイメージでコンテナ起動が失敗すると自動で以前起動していたコンテナイメージで起動し直すロールバック機能も備えているのでそれらの機能を試す。

auto-updateに対応したコンテナの起動手順

auto-update用のラベルを付けてコンテナを作成

io.containers.autoupdate=registry というラベルを付けてコンテナを作成する。

podman create --label "io.containers.autoupdate=registry" -p 8080:80 --name nginx docker.io/tsunokawa/nginx:release

作成したコンテナは起動状態ではないため、 podman ps コマンドでは表示されず podman ps -a コマンドで以下のように STATUSCreated となる。

$ podman ps -a
CONTAINER ID  IMAGE                              COMMAND               CREATED        STATUS      PORTS                 NAMES
c37a4190f51d  docker.io/tsunokawa/nginx:release  nginx -g daemon o...  8 seconds ago  Created     0.0.0.0:8080->80/tcp  nginx
$

起動するコンテナは以下のContainerfileでビルドしたNginxのコンテナを使用する。

Containerfile

FROM nginx:latest

COPY default.conf /etc/nginx/conf.d/
COPY index.html /usr/share/nginx/html/

Nginxの設定ファイルは以下を読み込ませるようにして SSI を有効化する。

default.conf

server {
    listen       80;
    server_name  localhost;
    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
    ssi on;
}

HTMLファイルは以下のようにしてコンテナにアクセスするとホスト名(コンテナ名)が表示されるようにする。

index.html

<!--#echo var="HOSTNAME" --> / Version: blue

表示例

xxxxx / Version: blue

systemdユニットファイルを作成

以下コマンドでsystemdユニットファイルを作成する。

podman generate systemd nginx --new > ~/.config/systemd/user/nginx.service

ディレクトリが存在しない場合は以下で事前に作成をおこなう。

mkdir -p ~/.config/systemd/user

systemdユニットファイルをsystemdへ反映

systemctl --user daemon-reload

systemdサービスを起動

systemctl --user start nginx

コンテナの起動状態を確認

podman ps では以下のように起動状態が確認出来る。

$ podman ps
CONTAINER ID  IMAGE                              COMMAND               CREATED        STATUS        PORTS                 NAMES
25beec1b9ef4  docker.io/tsunokawa/nginx:release  nginx -g daemon o...  6 seconds ago  Up 6 seconds  0.0.0.0:8080->80/tcp  nginx
$

curlでアクセスをおこなうと以下のような表示になることを確認する。

$ curl http://127.0.0.1:8080/
25beec1b9ef4 / Version: blue
$

ここまででauto-updateに対応したコンテナが起動した状態になる。

コンテナイメージとコンテナのイメージID一覧を確認すると以下のように出力される。

$ podman images
REPOSITORY                 TAG         IMAGE ID      CREATED             SIZE
docker.io/tsunokawa/nginx  release     c88b7e82b4fc  About a minute ago  192 MB
docker.io/library/nginx    latest      a72860cb95fd  6 weeks ago         192 MB

起動しているコンテナのコンテナイメージIDを確認すると c88b7e82b4fc で起動していることが分かる。

$ podman inspect --format='{{.Id}} {{.ImageName}} {{.Image}} {{.Name}}' 25beec1b9ef4
25beec1b9ef4ce7b071bc16887412b9e999c813e5ee9bd21602cfe8299ae0214 docker.io/tsunokawa/nginx:release c88b7e82b4fc5c24ae5133576c1d40d735f6a4bc732debe628e9cd5a1a4f0f21 nginx
$



自動更新のテスト

コンテナイメージを更新

curlでアクセスした際に、 Version: green となるようにしてコンテナイメージを更新する。 コンテナをビルドし、レジストリにpushする。※イメージ名とタグ名は同じものを指定する。

自動更新のdry-run

イメージの更新前は --dry-run オプションを付けてコマンドでauto-updateを実行した場合は以下の表示で UPDATED の箇所が false になっている。

$ podman auto-update --dry-run
            UNIT           CONTAINER             IMAGE                              POLICY      UPDATED
            nginx.service  25beec1b9ef4 (nginx)  docker.io/tsunokawa/nginx:release  registry    false
$

更新したイメージをレジストリにpushした後は、以下のように --dry-run オプションを付けてコマンドでauto-updateを実行すると UPDATED の箇所が pending となっており更新待ちの状態となっている。

$ podman auto-update --dry-run
            UNIT           CONTAINER             IMAGE                              POLICY      UPDATED
            nginx.service  25beec1b9ef4 (nginx)  docker.io/tsunokawa/nginx:release  registry    pending
$

自動更新を実行

$ podman auto-update
Trying to pull docker.io/tsunokawa/nginx:release...
Getting image source signatures
Copying blob 9e891cdb453b skipped: already exists
Copying blob 3dfc528a4df9 skipped: already exists
Copying blob 045037a63be8 skipped: already exists
Copying blob 8fe9a55eb80f skipped: already exists
Copying blob ba59045628c1 skipped: already exists
Copying blob efc2b5ad9eec skipped: already exists
Copying blob 0f11e17345c5 skipped: already exists
Copying blob be56a8a98726 skipped: already exists
Copying blob 7111b42b4bfa skipped: already exists
Copying config 54d7ad174e done
Writing manifest to image destination
Storing signatures
            UNIT           CONTAINER             IMAGE                              POLICY      UPDATED
            nginx.service  25beec1b9ef4 (nginx)  docker.io/tsunokawa/nginx:release  registry    true
$

再度 --dry-run オプションを付けてコマンドでauto-updateを実行すると UPDATED の箇所が false となっており更新がないことが分かる。

$ podman auto-update --dry-run
            UNIT           CONTAINER             IMAGE                              POLICY      UPDATED
            nginx.service  6973c850a56f (nginx)  docker.io/tsunokawa/nginx:release  registry    false
$

再度コンテナの起動状態を確認

再度 podman ps でコンテナの起動状態を確認するとコンテナIDが変更となりコンテナが起動し直されていることが分かる。

$ podman ps
CONTAINER ID  IMAGE                              COMMAND               CREATED         STATUS         PORTS                 NAMES
6973c850a56f  docker.io/tsunokawa/nginx:release  nginx -g daemon o...  31 seconds ago  Up 31 seconds  0.0.0.0:8080->80/tcp  nginx
$

curlでアクセスした際に、 Version: green となって最新のコンテナイメージが利用された状態でコンテナが起動していることが分かる。

$ curl http://127.0.0.1:8080/
6973c850a56f / Version: green
$

更新後のコンテナイメージとコンテナイメージID一覧を確認する。

$ podman images
REPOSITORY                 TAG         IMAGE ID      CREATED             SIZE
docker.io/tsunokawa/nginx  release     54d7ad174ea8  About a minute ago  192 MB
<none>                     <none>      c88b7e82b4fc  3 minutes ago       192 MB
docker.io/library/nginx    latest      a72860cb95fd  6 weeks ago         192 MB
$

コンテナイメージ更新後のコンテナイメージIDを確認すると 54d7ad174ea8 で起動していることが分かる。

$ podman inspect --format='{{.Id}} {{.ImageName}} {{.Image}} {{.Name}}' 6973c850a56f
6973c850a56fd2a760ce1ed5b82714b3cf4d34c7605cdbcaa3bf43bdf83954ff docker.io/tsunokawa/nginx:release 54d7ad174ea8f6b07fbb6250efcb13512d0c0d0416eeb1121154d80e5b15fe98 nginx
$



ロールバック機能

ロールバック機能を試すため、わざと起動に失敗するコンテナイメージに更新してロールバックして正常に起動するコンテナで起動し直すのか確認する。

まずは、正常に動作しているコンテナが起動中の状態を確認する。

$ podman ps
CONTAINER ID  IMAGE                              COMMAND               CREATED        STATUS        PORTS                 NAMES
6f33577d282b  docker.io/tsunokawa/nginx:release  nginx -g daemon o...  8 seconds ago  Up 8 seconds  0.0.0.0:8080->80/tcp  nginx
$

curlでアクセスすると blue と応答が返ってくることが確認出来る。

$ curl http://127.0.0.1:8080/
6f33577d282b / Version: blue
$

コンテナイメージの更新がないことを確認する。

$ podman auto-update --dry-run
            UNIT           CONTAINER             IMAGE                              POLICY      UPDATED
            nginx.service  6f33577d282b (nginx)  docker.io/tsunokawa/nginx:release  registry    false
$

コンテナイメージ、イメージID一覧と起動中のコンテナイメージIDを確認する。

$ podman images
REPOSITORY                 TAG         IMAGE ID      CREATED        SIZE
docker.io/tsunokawa/nginx  release     2cc2e3d8fb09  2 minutes ago  192 MB
docker.io/library/nginx    latest      a72860cb95fd  6 weeks ago    192 MB

現在のコンテナは 2cc2e3d8fb09 のコンテナイメージIDで起動していることが分かる。

$ podman inspect --format='{{.Id}} {{.ImageName}} {{.Image}} {{.Name}}' 6f33577d282b
6f33577d282b7d5e3d95ccf3c5fa25425bef050adb6e824964902a3732464d8d docker.io/tsunokawa/nginx:release 2cc2e3d8fb098002d9349e0d0c2e27c15a0ccd126fe5f9fb7d1e45d85f000833 nginx
$

curlでアクセスすると green と応答が返ってくるよう変更をおこない、コンテナ起動が失敗するように以下のようにContainerfileの最終行に終了コードの 1 を返すよう変更してビルドしてレジストリにpushする。

FROM nginx:latest

COPY default.conf /etc/nginx/conf.d/
COPY index.html /usr/share/nginx/html/

ENTRYPOINT ["exit", "1"]

ビルドしてレジストリにpush後、 podman auto-update --dry-run コマンドを実行すると pending状態に変わっていることが分かる。

$ podman auto-update --dry-run
            UNIT           CONTAINER             IMAGE                              POLICY      UPDATED
            nginx.service  6f33577d282b (nginx)  docker.io/tsunokawa/nginx:release  registry    pending
$

コンテナ起動が失敗するコンテナイメージで更新しようと podman auto-update を実行すると以下のように UPDATEDrolled back になっていることが分かる。

$ podman auto-update
Trying to pull docker.io/tsunokawa/nginx:release...
Getting image source signatures
Copying blob 9e891cdb453b skipped: already exists
Copying blob 8fe9a55eb80f skipped: already exists
Copying blob 3dfc528a4df9 skipped: already exists
Copying blob 7111b42b4bfa skipped: already exists
Copying blob 045037a63be8 skipped: already exists
Copying blob efc2b5ad9eec skipped: already exists
Copying blob 0f11e17345c5 skipped: already exists
Copying blob 8b3954e4d45e skipped: already exists
Copying blob cd5399ba9716 skipped: already exists
Copying config e99e6a0fbb done
Writing manifest to image destination
Storing signatures
            UNIT           CONTAINER             IMAGE                              POLICY      UPDATED
            nginx.service  6f33577d282b (nginx)  docker.io/tsunokawa/nginx:release  registry    rolled back
$

コンテナIDが変わりコンテナが起動し直していることが分かる。

$ podman ps
CONTAINER ID  IMAGE                              COMMAND               CREATED         STATUS         PORTS                 NAMES
23639d9bcb0f  docker.io/tsunokawa/nginx:release  nginx -g daemon o...  19 seconds ago  Up 20 seconds  0.0.0.0:8080->80/tcp  nginx
$

curlでアクセスをおこなうと bluepodman auto-update 前のイメージでコンテナが起動していることが確認出来る。

$ curl http://127.0.0.1:8080/
23639d9bcb0f / Version: blue

再度コンテナイメージとコンテナイメージID一覧を確認する。

$ podman images
REPOSITORY                 TAG         IMAGE ID      CREATED             SIZE
<none>                     <none>      e99e6a0fbbd2  About a minute ago  192 MB
docker.io/tsunokawa/nginx  release     2cc2e3d8fb09  4 minutes ago       192 MB
docker.io/library/nginx    latest      a72860cb95fd  6 weeks ago         192 MB

起動し直されたコンテナイメージIDを確認すると以前のコンテナイメージ( 2cc2e3d8fb09 )を使ってコンテナが起動していることが分かる。

$ podman inspect --format='{{.Id}} {{.ImageName}} {{.Image}} {{.Name}}' 23639d9bcb0f
23639d9bcb0f4bcd167f26ea4300924bc46cc796c68b74450ff1e334b8250bef docker.io/tsunokawa/nginx:release 2cc2e3d8fb098002d9349e0d0c2e27c15a0ccd126fe5f9fb7d1e45d85f000833 nginx
$

更新後のコンテナイメージでコンテナ起動が失敗すると自動で以前起動していたコンテナイメージで起動し直すロールバック機能の確認が出来た。

参考