RHEL上のUBIから、RHELのリポジトリを利用できる仕組み

Red Hatの森若です。 今日はRHEL上でコンテナを使うときにちょっと不思議なアレについておはなしします。

Red Hat Universal Base Image

1年とすこし前、Red Hat Universal Base Images (以下UBI) というコンテナイメージが公開されました。 これはRHEL 7および RHEL 8の基本的なコンテナイメージと、さらにRHELの約1/3のrpmパッケージをEULA契約のみで無償で入手でき、さらに自由に利用・再配布できるというものです。

単に入手再配布が簡単というだけでなく、これをベースにアプリケーションのコンテナイメージを作成すると、Red Hatのコンテナ環境上(RHELまたはOpenShift)であればUBI部分もRed Hatからのサポート対象になります。 この仕組みが登場したことで「通常の契約ではRHELは再配布できない」という制約を部分的にゆるめ、OSSプロジェクトを含むISVがRHEL対応ソフトウェアのコンテナイメージを作成しやすくなりました。

UBIについて詳しくは、以下のページをごらんください。 developers.redhat.com

Red Hatのテクノロジーパートナーによる認定コンテナイメージについては、2020年2月にさらに制約をゆるめるアナウンスが行われ、kernel以外の全てのrpmパッケージを配布できるようになっています。こちらについては以下の記事をごらんください。 developers.redhat.com

RHELのベースイメージとしてのUBI

さて、UBI自体はRHELを契約していなくても利用できますが、UBIはRHELのベースイメージを兼任しています。ついさっきUBIで「RHELの約1/3のrpmパッケージ」が利用できると書いていたのに、UBIに含まれないRHEL一般のrpmパッケージはどうやって使うのでしょうか?

実は、RHEL上でUBIを利用すると 自動的に RHELのリポジトリを利用できるようになります。今回はその仕組みをちょっと見てみましょう。

RHELのサブスクリプション情報はどこにある?

RHELのユーザであれば、多くの方が subscription-manager を利用してシステムを登録し、システムとサブスクリプションとを対応づけたことがあるかと思います。この作業をすることで、 yumコマンドによるパッケージの導入などが利用できるようになります。(パブリッククラウド上のものに一部例外があります。)

普段あまり意識することはありませんが、これらのコマンドの裏側では複数の証明書を利用して個別のシステムを識別し、製品の種類や、いつからいつまで利用可能かなどを管理しています。

$ ls -l /etc/pki/product-default/  # 製品の種類
total 4
-rw-r--r--. 1 root root 2171 Mar 31 20:15 479.pem

$ ls -l /etc/pki/entitlement/ # サブスクリプションの情報
total 144
-rw-r--r--. 1 root root   3247 Jun  8 15:24 5747300626421762999-key.pem
-rw-r--r--. 1 root root 141049 Jun  8 15:24 5747300626421762999.pem

$ ls -l /etc/pki/consumer/ # システムの識別情報
total 8
-rw-r-----. 1 root root 2228 Mar  9 17:35 cert.pem
-rw-r-----. 1 root root 3247 Mar  9 17:35 key.pem

UBIへホストRHELのサブスクリプション情報を共有する

コンテナ内からRHELのリポジトリを利用できるよう、コンテナ実行時にホスト側のサブスクリプション情報を自動的にコンテナ内の(揮発する)ディレクトリへコピーしています。

具体的には、containers-common パッケージで提供される /usr/share/containers/mounts.conf が起点となります。このファイルにはホストの特定ディレクトリからコンテナの特定ディレクトリにファイルをコピーする設定を記述します。(ファイル名がまぎらわしいのですがbind mountではなく再帰的なコピーが行われます。)

$ cat /usr/share/containers/mounts.conf 
/usr/share/rhel/secrets:/run/secrets

ホストの/usr/share/rhel/secrets には、あらかじめサブスクリプション情報が含まれるディレクトリへのシンボリックリンクが作成されています。

$ ls -l /usr/share/rhel/secrets
total 0
lrwxrwxrwx. 1 root root 20 Apr 21 03:17 etc-pki-entitlement -> /etc/pki/entitlement
lrwxrwxrwx. 1 root root 28 Apr 21 03:17 redhat.repo -> /etc/yum.repos.d/redhat.repo
lrwxrwxrwx. 1 root root  9 Apr 21 03:17 rhsm -> /etc/rhsm

コンテナ内のyumでは、これらの情報を参照することでRHELのリポジトリを使うことができます。

UBIでRHELリポジトリを利用する

サブスクリプションを登録したRHEL上で podman run -it bash ubi8 のようにして起動したコンテナの中で、利用できるリポジトリを確認してみましょう。RHELのリポジトリが利用できることがわかります。

# yum repolist
Updating Subscription Management repositories.
Unable to read consumer identity
Subscription Manager is operating in container mode.
repo id                                        repo name
rhel-8-for-x86_64-appstream-rpms               Red Hat Enterprise Linux 8 for x86_64 - AppStream (RPMs)
rhel-8-for-x86_64-baseos-rpms                  Red Hat Enterprise Linux 8 for x86_64 - BaseOS (RPMs)
ubi-8-appstream                                Red Hat Universal Base Image 8 (RPMs) - AppStream
ubi-8-baseos                                   Red Hat Universal Base Image 8 (RPMs) - BaseOS
ubi-8-codeready-builder                        Red Hat Universal Base Image 8 (RPMs) - CodeReady Builder

コンテナイメージの中に製品証明書が含まれていて適切なリポジトリが選択されるので、ホストのRHELとコンテナUBIのバージョンが異なっていても問題なく利用できます。

ためしてみよう

Red Hat Enterprise Linux 8を試せるラボを公開しています。以下リンクのラボではRHEL8のコンテナの基本的な利用をためせるほか、シナリオの中にないコマンドも自由に入力できます。以下のようなコマンドを試すとこの記事の理解が深まるかと思います。

ホスト側で
# podman pull ubi8
# podman run -it ubi8 bash
コンテナ内で
# yum repolist
# yum list coreutils
# yum list postgresql
# ls /run/secrets/

https://lab.redhat.com/podman-deploylab.redhat.com

* 各記事は著者の見解によるものでありその所属組織を代表する公式なものではありません。その内容については非公式見解を含みます。