Red Hatでソリューションアーキテクトをしている田中司恩(@tnk4on)です。今回はRed Hatの新しい最軽量なコンテナーイメージについて紹介します。
UBI Microのリリース
2021年5月18日にRed Hat Enterprise Linux(以下、RHEL) 8.4がリリースされたのと同時に新しいRed Hat Universal Base Image (以下、UBI)、UBI Microがリリースされました。
RHEL 8.4のリリースに先立って投稿されたRed Hat公式ブログ記事にもUBI Microについての記載があります。
上記ブログ記事より抜粋
With RHEL 8.4, we're announcing the Red Hat Universal Base Image (UBI) Micro to help reduce the attack surface, and deliver smaller footprint images of your containerized applications. UBI Micro joins the Standard, Minimal, and Multi-service images to provide the right options for you to build your applications on.
(翻訳)RHEL 8.4 では、Red Hat Universal Base Image (UBI) Micro が発表され、攻撃対象を減らし、コンテナ化されたアプリケーションのより小さなフットプリントのイメージを提供します。UBI Micro は Standard、Minimal、Multi-service の各イメージに加えて、アプリケーションを構築するための適切なオプションを提供します。
UBI Microはすでに公開済みのUBI(Standard)、UBI Minimal、UBI Init(Multi-service)に加えて、4つ目の種類のUBIコンテナーイメージとなります。
リリース版イメージのバグ
以前からこのUBI Microの紹介をしようと思っていたのですが、実はリリース版のubi8-micro:8.4-72
イメージにバグがあり、修正が完了するまで保留にしていました。
このバグは、/etc/yum.repos.d
ディレクトリにRed Hat社内向けのURLが含まれた*.repo
ファイルが含まれており、それらのファイルを取り除かないとdnf
コマンドが使えないという内容でした。詳細な内容については下記Bugzilla IDのコメントで確認することができます。
これからUBI Microを使う場合はubi-micro:8.4-84
以降をお使いください。
(参考)UBIについて
UBIについては詳細がまとまった電子書籍 Red Hat's Universal Base Image ebookがあります。下記の記事では電子書籍についての紹介と翻訳した目次を掲載しています。
UBI Microとは
UBI Microはこれまでに公開されているUBIの中で最軽量サイズのコンテナイメージになります。UBI Microの詳細はRed Hatの認定コンテナーカタログページから確認できます。
上記カタログページより抜粋
Universal Base Image Micro (UBI Micro) is a stripped down image that uses the package manager on the underlying host to install packages, typically using Buildah, or Multi-stage builds with Podman.
(翻訳)Universal Base Image Micro (UBI Micro)は、基盤となるホスト上のパッケージマネージャーを使用してパッケージをインストールするストリップダウンされたイメージで、通常はBuildah、またはPodmanを使用したマルチステージビルドを使用します。
UBIにはRHEL 7をベースにしたUBI 7とRHEL 8をベースにしたUBI 8がありますが、UBI MicroはUBI 8のみになります。
UBI 8のイメージ一覧
公開済みのUBI 8と並べてみるとUBI Microのサイズの小ささが小ささがよくわかります。
UBI 8の種類 | イメージ名 | サイズ |
---|---|---|
Red Hat Universal Base Image 8 | ubi8/ubi | 79.5 MB (215.2 MB uncompressed) |
Red Hat Universal Base Image 8 Minimal | ubi8/ubi-minimal | 37.7 MB (98.2 MB uncompressed) |
Red Hat Universal Base Image 8 Init | ubi8/ubi-init | 85.3 MB (235.2 MB uncompressed) |
Red Hat Universal Base Image 8 Micro ←🆕 | ubi8/ubi-micro | 12.9 MB (35.0 MB uncompressed) |
UBI Microをコンテナのベースイメージ使用することでUBI Minimalよりさらにサイズを抑えたコンテナイメージの作成が可能です。
DistrolessなUBI Microの特徴
UBI MicroにはUBI/UBI Minimal/Initにあるようなパッケージマネージャー(dnf/microdnf)がありません。パッケージマネージャーと関連する依存関係を除外することでサイズを抑えることができています。このようにディストリビューションのパッケージ管理ツールを使用せずにコンテナイメージを構築するのはDistrolessとも呼ばれます*1。UBI MicroはホストOSのdnf
コマンドを使ってパッケージの追加を行います(詳細は後述)。UBI Microは他のUBIイメージと同様の品質を保ちながらサイズを最小化したい場合に有効です。コンテナのサイズが小さくなるといことは悪意のある攻撃者から攻撃範囲を減らすことにもなりセキュリティ面でも有利です。
UBI Microを使ってみる
UBI MicroはこれまでのUBIと同様の方法でコンテナの操作が可能です。UBI Microのイメージ取得はRed HatのサイトだけでなくDocker Hubからも可能です。
# podman pull registry.access.redhat.com/ubi8/ubi-micro # podman images --filter label=name=ubi8/ubi-micro REPOSITORY TAG IMAGE ID CREATED SIZE registry.access.redhat.com/ubi8/ubi-micro latest c5ba898d3645 2 weeks ago 38.9 MB # podman run --rm -it ubi-micro sh-4.4# sh-4.4# dnf;microdnf sh: dnf: command not found sh: microdnf: command not found
UBI Micro上のシェルに入ることはできますが、dnf
やmicrodnf
などのパッケージマネージャーは存在しないことが確認できます
UBI Microにパッケージを追加する
UBI Microにパッケージを追加するにはBuildahを使用します。事前にBuildahまたはContainer Toolsモジュールをインストールしておいてください。 手順についてはRHEL 8のドキュメントに記載があります。下記も参考にしてください。
下記の例ではUBI Microにpython39
を追加します。なお下記例で実行はrootモードで行っていますが、ルートレスモードで実行する場合は事前にbuildah unshare
を実行して名前空間に入ってから作業してください。
また、ホストOSにRHEL(またはCentOS Stream)が必要です*2。
# containername=ubi-micro-python # microcontainer=$(buildah from --name ${containername} registry.access.redhat.com/ubi8/ubi-micro) # micromount=$(buildah mount ${microcontainer}) # dnf install \ > --installroot ${micromount} \ > --releasever 8 \ > --setopt install_weak_deps=false \ > --nodocs -y \ > python39 # dnf clean all \ --installroot ${micromount} # buildah umount ${microcontainer} # buildah commit ${microcontainer} ${containername} # buildah rm ${containername}
ビルド後のイメージの確認
# podman images --filter label=name="ubi8/ubi-micro" REPOSITORY TAG IMAGE ID CREATED SIZE localhost/ubi-micro-python latest 82921a06b57c 9 minutes ago 104 MB registry.access.redhat.com/ubi8/ubi-micro latest c5ba898d3645 2 weeks ago 38.9 MB # podman run --rm ubi-micro-python python --version Python 3.9.2
これまでのUBIイメージと同様にベースイメージ上にパッケージの追加を行うことができました。ただし、最小限のパッケージ追加にも関わらずパッケージ自体の依存関係により多数のパッケージが追加されるのでどうしても出来上がったイメージのサイズは元のサイズに比べると膨らんでしまいます*3。 UBI Microのサイズの小ささを生かす場合は極力パッケージの追加を行わないようなシングルバイナリを実行するような用途に向いていると考えられます。 次のマルチステージビルドの例ではGoのシンプルなバイナリを追加してコンテナイメージを作成してみます。
UBI Microを使ったマルチステージビルド
マルチステージビルドを用いてビルド済みのシングルバイナリをUBI Microにコピーすることでサイズの増加を抑えたコンテナイメージの作成が可能です。マルチステージビルドではContainerfileやDockerfile(以下、Containerfile)を使用した通常手順でのビルドが可能です。
今回はGoで書いた実行すると「Hello,World!」返すシンプルなアプリを使います。なお、Podmanを使ったGoのサンプルバイナリのビルド方法については下記の記事を参照ください。 zenn.dev
Containerfileは下記を使用します
FROM docker.io/library/golang as go-build ENV APP_ROOT /go/src WORKDIR ${APP_ROOT} COPY ./hello.go . RUN go mod init hello && go build FROM registry.access.redhat.com/ubi8/ubi-micro COPY --from=go-build /go/src/hello /usr/local/bin/ CMD ["hello"]
Buildah(またはPodman)を使用してビルドします
# ls Containerfile hello.go Containerfile hello.go # buildah bud -t ubi-micro-hello-world . # podman run --rm ubi-micro-hello-world Hello, World! # podman images --filter label=name=ubi8/ubi-micro REPOSITORY TAG IMAGE ID CREATED SIZE localhost/ubi-micro-hello-world latest 56fcfe57af0e 6 minutes ago 40.7 MB localhost/ubi-micro-python latest 3bb4998a2f2c 29 minutes ago 104 MB registry.access.redhat.com/ubi8/ubi-micro latest c5ba898d3645 2 weeks ago 38.9 MB
このように出来上がったubi-micro-hello-world
という名前のコンテナイメージは元のイメージとほぼ変わらないサイズに抑えられています。
まとめ
Red Hatの新しい軽量なコンテナベースイメージであるUBI Microについて紹介しました。パッケージマネージャが搭載されていないDistrolessなイメージでサイズが小さいだけでなくセキュリティ面でも有利なイメージとなっています。パッケージを追加する場合はホストOSのdnf
コマンドを使用するなどこれまでのUBIとは若干使い方が異なる点が注意です。また従来通りのContainerfileを使ったマルチステージビルドも可能で、シングルバイナリを配置するようなイメージであれば十分に元のサイズを保った小さなコンテナイメージを作成することが可能です。
UBI/UBI Minimal/UBI Init/UBI Microと多彩な種類のイメージが揃ったことでUBIを使ったコンテナイメージ作成の幅が広がりました。UBIは無料で使用、配布可能(一部制限あり)が可能となっていますので是非UBIを活用したコンテナイメージの作成に取り組んでみてください。
リンク
- RHEL 8.4 brings continuous stability plus innovation
- RHBA-2021:1999 - Bug Fix Advisory - Red Hat カスタマーポータル
- Universal Base Images (UBI): イメージ、リポジトリー、パッケージ、およびソースコード - Red Hat Customer Portal
- 1966837 – ubi8-micro image includes internal compose repo configurations
ubi-micro:8.4-84
- Red Hat's Universal Base Image ebook
- (電子書籍)Red Hat's Universal Base Image ebookの紹介【UBI】 - 赤帽エンジニアブログ
- Introduction to Red Hat's UBI Micro
- Red Hat Brings Red Hat Universal Base Image to Docker Hub
- 2.8. UBI マイクロイメージの使用 Red Hat Enterprise Linux 8 | Red Hat Customer Portal
- 【Podman】Goのビルドをコンテナ内で実行する
*1:UBI Microを紹介したRed Hatのブログ記事でも同様の記載あり → https://www.redhat.com/ja/blog/introduction-ubi-micro
*2:Fedoraのdnfでは /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release が取得できずエラー
*3:UBI Minimalに同様に追加した場合は151MBほどなので十分に小さいサイズとも言える