注意
当記事は執筆者の独自研究によるもので、Red Hat社の公式見解ではないことに注意してください。
UBIとは
Red Hat Universal Base Image (UBI)は、Red Hat社が公開しているLinuxコンテナイメージです。UBIはRed Hat Enterprise Linux(RHEL)のサブセットと言うこともでき、バージョンもRHELに合わせて7,8,9と続けてリリースされています。
UBIを使う理由
(1) Red Hat社による公式リリース物である
野良イメージに比べて信頼できること、修正やバージョンアップが継続されることが挙げられます。以前の私はよくCent OSのイメージを使っていましたが、ご存じのとおりCent OSは昨年末で終了してしまったので、現在Docker Hubで公開されているものも更新が停止してしまいました。UBIは8系は更新継続していますし、最近9もリリースされました。
(2) 非Red Hat環境でも使用できる
UBIを使って作られたイメージはRed Hat環境、例えばRHELやOpenShift(OCP)以外で利用や再配布をしてもいいことになっています。ただしサポートは受けられません。
(3) 限られた条件だがサポートを受けられる
どうしてもサポートが必要であれば、正式なEntitlementがあるRHEL+PodmanやOCP環境を利用すればよいです。
(4) Yumで必要なパッケージを追加できる
RHELと同様、UBI内でyum(dnf)コマンドを使って必要なパッケージを追加することができます。ただしUBIが標準で対応しているYumリポジトリがRHELとは異なりUBI用のものになります。RHELに比べ利用可能なパッケージは限定されています。
# yum repolist
Updating Subscription Management repositories.
Unable to read consumer identity
Subscription Manager is operating in container mode.
This system is not registered with an entitlement server. You can use subscription-manager to register.
repo id repo name
ubi-9-appstream Red Hat Universal Base Image 9 (RPMs) - AppStream
ubi-9-baseos Red Hat Universal Base Image 9 (RPMs) - BaseOS
ubi-9-codeready-builder Red Hat Universal Base Image 9 (RPMs) - CodeReady Builder
RHELのリポジトリにはあるのにUBIにはないがどうしても欲しいものがあった場合、サポートがあればリクエストをすることはできます。
ちなみに、RHELの正規のEntitlementを持ち込んでRHELのリポジトリを使うことも可能なようですがおすすめしません。配布先でもEntilementを購入しないとライセンス違反になるためです。
UBIの入手方法
現在は大きく3種類の方法があります
(1) Red Hatコンテナレジストリ(要認証 registy.redhat.io)から入手する
この方法がおそらくはRed Hat社が最も想定している方法です。認証のためにRed Hatカスタマーポータルのアカウントが必要です。アカウントを使えるようにするためには、商用製品を購入するか開発者登録をする必要があります。
ちなみにですが、Red Hat OpenShift on IBM Cloud
とAWSのROSA
ではregistry.redhat.ioのイメージを認証なしでプルすることができます。
$ oc run ubi --image=registry.redhat.io/ubi9/ubi -- tail -f /dev/null
pod/ubi created
$ oc get pods
NAME READY STATUS RESTARTS AGE
ubi 1/1 Running 0 17s
AzureのARO
では残念ながら認証エラーとなりました。このあたりの違いはよくわかっていません。
$ oc run ubi --image=registry.redhat.io/ubi9/ubi -- tail -f /dev/null
pod/ubi created
$ oc get pods
NAME READY STATUS RESTARTS AGE
ubi 0/1 ImagePullBackOff 0 5s
$ oc describe pod ubi
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 8s default-scheduler Successfully assigned default/ubi to ********
Normal AddedInterface 6s multus Add eth0 [10.129.2.11/23] from openshift-sdn
Normal Pulling 6s kubelet Pulling image "registry.redhat.io/ubi9/ubi"
Warning Failed 6s kubelet Failed to pull image "registry.redhat.io/ubi9/ubi": rpc error: code = Unknown desc = unable to retrieve auth token: invalid username/password: unauthorized: Please login to the Red Hat Registry using your Customer Portal credentials. Further instructions can be found here: https://access.redhat.com/RegistryAuthentication
Warning Failed 6s kubelet Error: ErrImagePull
Normal BackOff 5s (x2 over 6s) kubelet Back-off pulling image "registry.redhat.io/ubi9/ubi"
Warning Failed 5s (x2 over 6s) kubelet Error: ImagePullBackOff
(2) Red Hatコンテナレジストリ(認証不要 registy.access.redhat.com)から入手する
イメージは(1)と同じものですが、イメージをプルする際に認証は不要です。では(2)だけでいいじゃないかと思うかもしれませんが、このレジストリは将来廃止になるとRed Hatはかつてアナウンスしていました。しかし今調べてみたところそのアナウンスを見つけることができませんでした。もしかしたら方針が変わったのかもしれません。詳しい方がいらっしゃいましたら教えてください。
(1)(2)のいいところは、UBIの他にUBIを利用したさまざまな認定コンテナを見つけることができる点です。これはRed Hat Ecosystem Catalogと呼ばれています。
ここで公開されているものは、Red Hat社やサードパーティ製を含め全てUBI上に作られており、公開にあたってRed Hat社の審査を受けた認定コンテナイメージです。
(3) Docker Hubから入手する
昨年からだったと記憶していますが、UBIのうち最も基礎となるイメージはDocker Hubでも公開されています。
ただしRed Hat Ecosystem Catalogで公開されているその他イメージはありません。
私見ですが、現時点では(2)の方法を利用するのがいいと思っています。
とりあえずUBIを試してみる
DockerやPodmanを使っている人は次のコマンドだけでUBI9のシェルを起動することができます。
$ docker run -it registry.access.redhat.com/ubi9/ubi bash
# cat /etc/redhat-release
Red Hat Enterprise Linux release 9.0 (Plow)
厳密にはRHEL9とは異なりますが、雰囲気を知ることはできます。昔ならDVDのisoイメージをダウンロードして仮想マシンを作ってインストールしなければならなかったことを考えるといい時代になったものです。
使い方のヒント
(1) yum(dnf)時にThis system is not registered with an entitlement server. You can use subscription-manager to registerと表示されるのを消したい
DockerfileのRUNやシェルで普通にyumやdnfコマンドを使うとこのようなメッセージが出力されます。
# dnf list | more
Updating Subscription Management repositories.
Unable to read consumer identity
Subscription Manager is operating in container mode.
This system is not registered with an entitlement server. You can use subscription-manager to register.
Last metadata expiration check: 0:00:19 ago on Wed Jun 22 17:08:33 2022.
Installed Packages
acl.x86_64 2.3.1-3.el9 @System
alternatives.x86_64 1.20-2.el9 @System
使用上問題はありませんが精神衛生上気になる人は、--disableplugin subscription-manager
を付けることで抑止できます。
# dnf --disableplugin subscription-manager list | more
Last metadata expiration check: 0:02:19 ago on Wed Jun 22 17:08:33 2022.
Installed Packages
acl.x86_64 2.3.1-3.el9 @System
alternatives.x86_64 1.20-2.el9 @System
(2) 任意のUIDで実行できるようにする
UBIに限った話ではないですが、OCPはデフォルトでイメージのUSER指定を無視してランダムなUIDでコンテナが実行されます。SCCと呼ばれるOCP独自の機能です。Red Hat Ecosystem Catalogで公開されているイメージは恐らくは多くのものでそれを考慮していると思いますが、自分でカスタムイメージを作る場合は気にした方がいいでしょう。
下記は私がsquidを実行するコンテナイメージを作成したときのものです。Red Hat Ecosystem Catalogにsquidのイメージがなかったので自作せざるを得ませんでした。
FROM registry.access.redhat.com/ubi9/ubi:9.0.0-1468.1655190709
RUN dnf -y --disableplugin subscription-manager install squid && \
dnf clean all
ADD squid /etc/squid
ADD https://github.com/boynux/squid-exporter/releases/download/v1.10.3/squid-exporter /usr/local/bin/
RUN chmod 755 /usr/local/bin/squid-exporter && \
chgrp -R 0 /etc/squid /run /usr/local/bin && \
chmod -R g=u /etc/squid /run /usr/local/bin
USER 1001
CMD ["/usr/sbin/squid", "-NC"]
EXPOSE 3128/tcp
肝となる部分ですが、USER 1001
はローカルのDockerやPodmanで実行するときは有効ですが、OCPでは無視されランダムなUIDで実行されます。一方、GIDは常に0(root)になる特性を利用し、コンテナ内で読み書きが必要なディレクトリをGID 0にchownし、元のユーザーと同じパーミッションにグループをchmodすることで、実行時にUIDが変わってもGIDで動くようにしています。この作法はOCPのコンテナ開発では一般的なやり方です。