Armadilloフォーラム

swupdate作成用にエクスポートしたコンテナイメージのサイズを小さくしたい

hisanori

2024年7月23日 3時40分

現在、製造した製品のアップデートのために
①開発用マシン上でコンテナの内容を更新して上書きし、podman saveでエクスポートする

②ATDE環境にてswupate用のファイル「updater_v10x.swu」を生成し、USBメモリ(ルート直下)にコピーする

③USBメモリを起動前にG4にセットし電源ONし起動
という流れでアプリケーションをアップデートしております。
アップデート自体は問題なく動作しているのですが、新しい改造を加えるたびに「podman save」でエクスポートされるコンテナイメージのサイズが
どんどん肥大化していっているため、困っております。
作成したアプリケーションやapache2が出力しているログ(/var/log)は削除しているはずなのですが、エクスポートのたびに結構なサイズで肥大化して
いっているので、/var/log配下のログファイルを削除する以外にもコンテナイメージを小さくするための施策がありましたら、教えてください。

コメント

アットマークテクノの古賀です。

hisanoriさん:
>現在、製造した製品のアップデートのために
>①開発用マシン上でコンテナの内容を更新して上書きし、podman saveでエクスポートする
>↓
>②ATDE環境にてswupate用のファイル「updater_v10x.swu」を生成し、USBメモリ(ルート直下)にコピーする
>↓
>③USBメモリを起動前にG4にセットし電源ONし起動
>という流れでアプリケーションをアップデートしております。
>アップデート自体は問題なく動作しているのですが、新しい改造を加えるたびに「podman save」でエクスポートされるコンテナイメージのサイズが
>どんどん肥大化していっているため、困っております。
>作成したアプリケーションやapache2が出力しているログ(/var/log)は削除しているはずなのですが、エクスポートのたびに結構なサイズで肥大化して
>いっているので、/var/log配下のログファイルを削除する以外にもコンテナイメージを小さくするための施策がありましたら、教えてください。

コンテナ内でファイル内容の更新を行った場合、更新されたファイルの内容がコンテナ内で上書きされるのではなく、更新後のファイルが入ったレイヤーが作られて更新前の内容のファイルが入ったレイヤーを「マスク」することで、更新後の方のファイルを見せる、という仕組みなのです。ファイルを削除した場合も同様で、削除されたファイルがレイヤーによって「マスク」されるだけであり、ファイル実体は削除されません。
そのため、コンテナ内容をイメージに保存する操作を繰り返すと、イメージサイズが肥大化していく、というわけです。

レイヤーの積み重ねによって肥大化したコンテナイメージのサイズを縮小するには、レイヤーを一つにまとめる必要があります。
この対策について、弊社の FAQ にある「swupdateが失敗した時のよくある原因とその対処方法は?」というページの、「No space left on device: ファイルシステムの容量が足りない場合」で説明しています:
 https://armadillo.atmark-techno.com/faq/swupdate-troubleshooting-abos#f…
 https://armadillo.atmark-techno.com/faq/swupdate-troubleshooting-abos

この FAQ 項目の「対処方法」の中で、
 podman build コマンドの --squash-all オプションで中間レイヤーを削除してみてください。
と記載しています。つまり、保存したコンテナイメージをソースとして、レイヤーを一つに縮退させた新しいコンテナイメージを podman build コマンドで生成するというわけです。podman build コマンドに --squash-all オプションを指定すると、生成するコンテナイメージのレイヤーを一つだけにしてくれます。
 https://docs.podman.io/en/latest/markdown/podman-build.1.html#squash-all

手順については、このフォーラムの過去の質問スレッドの、以下のコメントを参考にしてみてください:
 https://armadillo.atmark-techno.com/forum/armadillo/16139#comment-13720

以上、参考になりましたら幸いです。

ご回答ありがとうございます。
コンテナ更新時に行っているpodman commitのときに--squashオプションを追加して更新するようにいたしました。
オプションを追加したコマンドでエクスポートしたコンテナイメージのサイズを小さくなること確認できました。ありがとうございます!

アットマークテクノの古賀です。

hisanoriさん:
>ご回答ありがとうございます。
>コンテナ更新時に行っているpodman commitのときに--squashオプションを追加して更新するようにいたしました。
>オプションを追加したコマンドでエクスポートしたコンテナイメージのサイズを小さくなること確認できました。ありがとうございます!

目的を果たせて良かったです。

ところで、最初に頂いた質問で「アップデート自体は問題なく動作しているのですが、新しい改造を加えるたびに…」と書いていらっしゃいましたが、「新しい改造」というのは、アプリケーションの実行ファイル(あるいはスクリプト)や設定ファイルだけを変更していらっしゃるのでしょうか?
もしそうであれば、アプリケーションの実行ファイルや設定ファイルをコンテナイメージに収録せず、ABOS のディレクトリに配置する、という方策をとることで、アプリケーションを更新する際の SWU イメージを小さくできると思います。
つまり、次のようにするわけです:

1.) ABOS の /var/app/volumes/ に、アプリケーション用のディレクトリを作り、そこにアプリケーションの実行ファイルや設定ファイルを配置する。
2.) (1) のディレクトリをコンテナにマウントする設定を、コンテナの .conf ファイルに記述する。
3.) コンテナの .conf ファイルに記述する set_command で、(2) の設定でマウントしたディレクトリ下の実行ファイルのパスを指定する。

このようにすれば、アプリケーションだけを更新した場合、ABOS の /var/app/volumes/ 配下に配置した実行ファイルを更新する SWU イメージを作ればよく、SWU イメージにはコンテナイメージを収録せずに済むため、SWU イメージのサイズを小さくできます。
コンテナイメージのベースにしているディストリビューション/ユーザーランドにセキュリティパッチ適用の更新が必要になった場合は、別途コンテナイメージを更新する SWU イメージを作って更新すればよいですよね。

つまり、アプリケーション実行環境としてのルートファイルシステム/コンテナと、アプリケーション本体とを分離することで、アプリケーション本体だけを更新できるようにする、という方策です。
コンテナイメージから分離して ABOS 上に配置するアプリケーション本体には、もし ABOS 上で直接実行された場合は動作しないようにする仕組みを入れておけば、アプリケーションの実行をコンテナ内に封じ込められますので、より安全でしょう。

以上、もし参考になりましたら幸いです。