Red Hatでソリューションアーキテクトをしている田中司恩(@tnk4on)です。 前回記事の続きになります。前回記事ではRed Hat build of Keycloak(RHBK)のサポート構成やPodmanを使ったテスト実行について紹介しました。 今回はPodmanで実行したコンテナレジストリのユーザー認証基盤としてRed Hat build of Keycloakを使う方法を紹介します。
(前回記事はこちら) rheb.hatenablog.com
-目次-
- Distribution Registryとは
- Red Hat build of KeycloakをDistribution Registryの認証基盤として利用する
- Red Hat build of Keycloakの実行
- コンテナレジストリ向けの認証設定
- Distribution Registryの実行
- PodmanからDistribution Registryを利用する
- まとめ
Distribution Registryとは
かつてPythonで書かれた「Docker Registry」*1というOSSプロジェクトがありました。 Docker Hubやその他のコンテナレジストリの基礎となるOSSプロジェクトでしたが、その後のコンテナエコシステムの標準化の流れでCNCFに寄贈されました。
詳細はDocker社のブログ記事を参照ください。
このプロジェクトはCNCFに寄贈された以降は「Distribution」に名称が変更されました。このDistributionプロジェクトの中のコンポーネントの1つが「Distribution Registry」で、現在はGoで書き直されています。このDistribution RegistryはOCI Distribution spec*2に基づいて実装が行われています。
DistributionプロジェクトのWebサイトとGitHubリポジトリ
ネットのさまざまなところではDocker Registryという名前を見ることが多いですが、その情報はすでに古く、Distribution Registryまたは単にRegistryと呼ぶのが正しいです。この際に覚えておきましょう。
Distribution Registryのコンテナイメージ
このDistribution Registryはコンテナイメージが公開されていますので、すぐにコンテナ環境で実行できます。 なお、Docker HubにあるRegistryのDocker公式イメージはDistribution Registryのコンテナイメージです。 これは「Docker HubにホストされているDistribution Registry」であり「Docker Registry」ではありませんのでお間違えないように。
registry - Official Image | Docker Hub
podman run
コマンドで実行する場合はこんな感じです。これだけでローカル環境にシンプルなコンテナレジストリが立ち上がります。
% podman run -d -p 5000:5000 --name registry docker.io/library/registry:2
registry:2
の2となっているのは現在のDistribution Registryのメジャーバージョンのv2をタグとして指定しています。なお現時点のDistribution Registryの最新版はv2.8.3ですが、2、2.8、2.8.3はすべて同じイメージを指すようにタグ付けされています。
保管するコンテナイメージを永続化したい場合はコンテナ内の/var/lib/registry
にバインドマウントします。
% mkdir registry % podman run -d -p 5000:5000 --name registry -v ./registry:/var/lib/registry:Z docker.io/library/registry
ローカル環境でテスト的に使いたい場合ははこれくらいを覚えておけば基本的には十分です。もう少し高度に使いたい場合は環境変数を追加して実行できます。
Distribution Registryのドキュメントにいくつか例があるので参考にしてください
次のセクションではRed Hat build of Keycloakを認証基盤として利用する方法を紹介します。 Distribution Registryは別の手段で実行しますので、テストで起動したコンテナは削除しておいてください。
% podman rm -f -t 0 registry
Red Hat build of KeycloakをDistribution Registryの認証基盤として利用する
Distribution Registry自体にはユーザーを作成したり管理する機能はありません。その代わりにsilly、token、htpasswdの認証プロバイダをサポートしています。 今回はRed Hat build of Keycloakをtoken方式の認証基盤として利用します。
実行するコンテナと公開ポートの構成はこちらです。
Red Hat build of Keycloakの実行
ここから構築方法について解説します。製品ドキュメントは下記を元にしていますが、ドキュメントの内容だけでは情報が足りないので本記事の内容をしっかりと確認してください。
第4章 Red Hat build of Keycloak を使用するための Docker レジストリー設定 | Red Hat Product Documentation
作業の順番は下記の通りです
- 管理者ユーザーでログインする
- 新規のレルムを作成する
- 新規のクライアントを作成する
- Docker Compose YAMLをダウンロードする
- 新規ユーザーを作成する
- 不要な属性の必須設定をオフにする
まずは前回と同じくpodman run
コマンドでRed Hat build of Keycloakを起動します。今回の構築用に若干オプションを変更しています。
Red Hat build of Keycloakのコンテナイメージの取得にはregistry.redhat.ioへのログインが必要です。 Red Hat build of Keycloakが含まれる製品の有効なサブスクリプションをお持ちのRed Hatアカウント、または評価版を使用中のRed Hatアカウント、等が必要です
% podman login registry.redhat.io % podman run -d -p 8080:8080 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin --name keycloak -e KC_FEATURES=docker keycloak-rhel9:24-10 start-dev
-d
:デタッチモードでバックグラウンド実行する--name keyclaok
:コンテナにkeycloak
という名前をつける-e KC_FEATURES=docker
:コンテナ実行時に環境変数「KC_FEATURES
」を追加し、パラーメーターをdocker
にセットする
今回使用するDocker認証はデフォルトでは無効化されています。そのため、Red Hat build of Keycloakの起動時に有効化するオプションを追加します。
この環境変数KC_FEATURES
については製品ドキュメントにチラッとだけ出てきます。製品ドキュメントではほとんど解説がないのでご注意ください。
3.8. 関連するオプション | Red Hat Product Documentation
podman run
コマンドで実行した後にpodman logs
コマンドでコンテナ名を指定してRed Hat build of Keycloakが起動したかどうか確認します。
正常に起動すると下記のようなログが出力されます。
% podman run -d -p 8080:8080 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin --name keycloak -e KC_FEATURES=docker keycloak-rhel9:24-10 start-dev % podman logs -f keycloak ... 2024-06-14 01:35:44,461 INFO [io.quarkus] (main) Keycloak 24.0.5.redhat-00001 on JVM (powered by Quarkus 3.8.4.redhat-00002) started in 16.594s. Listening on: http://0.0.0.0:8080 2024-06-14 01:35:44,462 INFO [io.quarkus] (main) Profile dev activated. 2024-06-14 01:35:44,462 INFO [io.quarkus] (main) Installed features: [agroal, cdi, hibernate-orm, jdbc-h2, keycloak, narayana-jta, reactive-routes, resteasy-reactive, resteasy-reactive-jackson, smallrye-context-propagation, vertx] 2024-06-14 01:35:44,468 WARN [org.keycloak.quarkus.runtime.KeycloakMain] (main) Running the server in development mode. DO NOT use this configuration in production.
コンテナレジストリ向けの認証設定
ここからはRed Hat build of Keycloakの管理画面での操作になります。
まず、Red Hat build of Keycloakのコンテナ起動時に指定した管理者ユーザーのユーザー名とパスワードでログインします。ブラウザでlocalhost:8080
へアクセスします。
管理者ユーザーでログイン直後はmaster
レルムが表示されます。レルムとはKeycloakにおけるマルチテナント機能のようなものです。master
はサーバー自体の管理ができるレルムになります。
アプリケーション用途には別のレルムを作ってそちらを使います。
ここではServer infoのタブを開きDocker機能が有効化されているか確認します。Enable featuresにDockerが見つかれば正常に有効化できています。
次に新規でレルムを作成します。Red Hat build of Keycloakと書いてあるプルダウンメニューを選択しCreate realmを押します。
レルムの作成画面ではレルム名を入力してCreateを押します。ここではレルム名は「registry」にします。
レルムの作成が成功するとプルダウンメニューの表示が作成したレルム名(registry)に変更されます。 左のClientsメニューを選択します。
新規でクライアントを作成します。Client typeはプルダウンから「docker-v2」を選択します。Client IDには任意の名前を入力します。ここでは「docker-auth」とします。「Next」を押します。
クライアントとはユーザーの認証を要求できるエンティティーのことでKeycloakに接続するアプリケーションの管理単位です。コンテナレジストリにログインする際のユーザー(後ほど作成)とは別の管理単位になりますので混同しないようにご注意ください
次のページのCapability configは空白なのでそのまま「Save」を押します。
さらに次のLogin settingsもそのまま「Save」を押します。
クライアント「docker-auth」が作成されました。
クライアント「docker-auth」のActionプルダウンから「Download adapter config」を選択します。
Download adaptor configsの画面でFormat optionが「Docker Compose YAML」になっていることを確認し「Download」を押します。
ダウンロードしたファイルは「keycloak-docker-compose-yaml.zip」として保存されます。これは後でDistribution Registryの実行時に使用します。
次はコンテナレジストリへログインするときに使用するユーザーを作成します。 左のメニューからUsersを選択し、「Create new user」を押します。
ユーザー名を入力し「Create」を押します。ここではユーザー名「tnk4on」を指定します。
ユーザーのパスワードを作成します。User datailsの画面からCredentialsタブを選択し、「Set password」選択します。
パスワードを入力し、Temporaryのチェックを外し「Save」を押します。
もう一度確認画面が出てくるので「Save password」押します。これでユーザーのパスワードがセットされました。
コンテナレジストリの認証に不要なemail
,firstName
,lastName
要素の必須設定をオフにします。
左のメニューからRealm settingsを選択し、User Profileタブを選択します。ますはemailのリンクを選択します。
Required fieldをオフにし「Save」を押します。残りのfirstName
,lastName
も同様に行います。この設定がemail
,firstName
,lastName
すべてでオフになっていないとpodman login
を実行したときにエラーになります。ご注意ください。
Distribution Registryの実行
先ほどの手順でダウンロードしたファイル「keycloak-docker-compose-yaml.zip」を展開すると下記のファイル一覧が出てきます。
% tree . ├── README.md ├── certs │ ├── localhost.crt │ ├── localhost.key │ └── localhost_trust_chain.pem ├── data └── docker-compose.yaml 3 directories, 5 files
docker-compose.yamlを使ってDistribution Registryを起動するのですが、このままではComposeの実行時でエラーになります。
<ダウンロードしたdocker-compose.yaml>
registry: image: registry:2 ports: - 127.0.0.1:5000:5000 environment: REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data REGISTRY_HTTP_TLS_CERTIFICATE: /opt/certs/localhost.crt REGISTRY_HTTP_TLS_KEY: /opt/certs/localhost.key REGISTRY_AUTH_TOKEN_REALM: http://localhost:8080/realms/registry/protocol/docker-v2/auth REGISTRY_AUTH_TOKEN_SERVICE: docker-auth REGISTRY_AUTH_TOKEN_ISSUER: http://localhost:8080/realms/registry REGISTRY_AUTH_TOKEN_ROOTCERTBUNDLE: /opt/certs/localhost_trust_chain.pem volumes: - ./data:/data:z - ./certs:/opt/certs:z
正常に起動する修正を加えたのが下記です。
<修正を加えたdocker-compose.yaml>>
version: '3' services: registry: image: registry:2 ports: - 127.0.0.1:5000:5000 environment: REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data REGISTRY_HTTP_TLS_CERTIFICATE: /opt/certs/localhost.crt REGISTRY_HTTP_TLS_KEY: /opt/certs/localhost.key REGISTRY_AUTH_TOKEN_REALM: http://localhost:8080/realms/registry/protocol/docker-v2/auth REGISTRY_AUTH_TOKEN_SERVICE: docker-auth REGISTRY_AUTH_TOKEN_ISSUER: http://localhost:8080/realms/registry REGISTRY_AUTH_TOKEN_ROOTCERTBUNDLE: /opt/certs/localhost_trust_chain.pem volumes: - ./data:/data:z - ./certs:/opt/certs:z
ではこのdocker-compose.yamlファイルを使ってDistribution Registryのコンテナを実行します。
Podman v4.7.0以降は
podman compose
コマンドが実装されています。podman compose
コマンドは、ローカルホストにインストールされたdocker-compose
コマンドを参照実行するラッパーコマンドです。 本家のdocker-compose
コマンドをインストールし、docker.sock
からpodman.sock
へシンボリックリンクを作成するだけでPodmanでdocker-compose
がそのまま使えます。 詳細は拙作の著書「Podman Advanced Pod-01:DockerからPodmanへの移行」を参照ください。
podman compose
コマンドを-d
オプションをつけて実行します。
% cd keycloak-docker-compose-yaml % podman compose up -d >>>> Executing external compose provider "/usr/local/bin/docker-compose". Please refer to the documentation for details. <<<< [+] Running 1/1 ✔ Container keycloak-docker-compose-yaml-registry-1 Started
podman ps
コマンドを実行し、keycloak-docker-compose-yaml-registry-1
というコンテナが正常に起動していれば成功です。
% podman ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e3ed196f344b registry.redhat.io/rhbk/keycloak-rhel9:24-10 start-dev 15 minutes ago Up 15 minutes 0.0.0.0:8080->8080/tcp, 8080/tcp, 8443/tcp keycloak 54f837e4c325 docker.io/library/registry:2 /etc/docker/regis... 12 seconds ago Up 13 seconds 127.0.0.1:5000->5000/tcp, 5000/tcp keycloak-docker-compose-yaml-registry-1
PodmanからDistribution Registryを利用する
コンテナレジストリを利用する環境が整ったのでPodmanを使って各種操作を行います。
ログイン/ログアウト
コンテナレジストリにログインするにはpodman login
コマンドを使います。注意点としては、実稼働環境のコンテナレジストリではhttps://
でアクセスを行いますが今回はテスト環境なのでhttp://
でアクセスを行います。
http://
でアクセスする場合はpodman login
コマンドに--tls-verify=false
オプションを追加して実行します。
% podman login localhost:5000 --tls-verify=false
ユーザー名とパスワードを入力し、Login Succeeded!
が出ればログイン成功です。
% podman login localhost:5000 --tls-verify=false Username: tnk4on Password: Login Succeeded!
ログイン済みのコンテナレジストリからログアウトをする場合はpodman logout
コマンドを使います。ログアウトの場合--tls-verify=false
オプションは不要です。
Removed login credentials for
が表示されればログアウト成功です。ローカルに保存されていた認証情報は削除されます。
% podman logout localhost:5000 Removed login credentials for localhost:5000
コンテナイメージのPushとPull
コンテナレジストリにログインし、そのユーザー専用のリポジトリとしてコンテナをPushしてみます。
サンプルでビルドしたコンテナをコンテナレジストリにPushします。podman push
コマンドの実行の場合も--tls-verify=false
をつけて実行します。
% cat > Containerfile <<EOF FROM ubi9 RUN echo "hello" | tee hello.txt EOF % podman build -t registry-test . % podman login localhost:5000 --tls-verify=false Username: tnk4on Password: Login Succeeded! % podman push registry-test localhost:5000/tnk4on/registry-test --tls-verify=false Getting image source signatures Copying blob sha256:32c72c1609374470f063a4a8d190512eedd824b0aa644575c3a75d0e466a6426 Copying blob sha256:0abe35b0d2bf06d260396dfc129715dae9736b6c91f3d861492982a0f7daa5c2 Copying config sha256:d7d811c318f6237a9dbc97dc15fc31cc92605b0c2166a4b66b4bdfbde727ea1f Writing manifest to image destination
コンテナがコンテナレジストリに登録されたかを確認します。Skopeoを使ってコンテナレジストリ上のコンテナイメージの詳細を確認します。
skopeo inspect
コマンドを実行します。コンテナレジストリ上のコンテナを直接調べる場合はdocker://
(Dockerトランスポート)を指定します。またこの場合も--tls-verify=false
オプションを追加します。
Linux以外の環境で
skopeo inspect
を実行して対象のOSが見つからないエラーになる場合は--override-os=linux
を追加してください。 今回のローカル環境のテストの場合はmacOS版Skopeoを使ってもエラーにならなかったのでオプションは追加していません
% skopeo inspect docker://localhost:5000/tnk4on/registry-test --tls-verify=false { "Name": "localhost:5000/tnk4on/registry-test", "Digest": "sha256:cd56949fd637e728a6145d7fb45717baac5dabd52cf440b95b4afcd3b140540b", "RepoTags": [ "latest" ], "Created": "2024-06-14T02:05:17.827927425Z", ...
コンテナイメージが登録されているのが確認できました。今度はこのイメージをPullします。
ローカルのコンテナストレージ上のコンテナイメージを削除し、コンテナレジストリからPullします。Pullの際も--tls-verify=false
オプションを追加します。
% podman images REPOSITORY TAG IMAGE ID CREATED SIZE localhost/registry-test latest d7d811c318f6 13 minutes ago 238 MB registry.access.redhat.com/ubi9 latest a13af6f8eaac 8 days ago 238 MB registry.redhat.io/rhbk/keycloak-rhel9 24-10 559c3ef84129 2 weeks ago 461 MB docker.io/library/registry 2 27031dfcd859 8 months ago 25.5 MB % podman rmi registry-test:latest Untagged: localhost/registry-test:latest Deleted: d7d811c318f6237a9dbc97dc15fc31cc92605b0c2166a4b66b4bdfbde727ea1f % podman pull localhost:5000/tnk4on/registry-test --tls-verify=false Trying to pull localhost:5000/tnk4on/registry-test:latest... Getting image source signatures Copying blob sha256:e4c264f9fa3197924054e658c77b17936ecf85f6dec74962138da485d7d7b86b Copying blob sha256:e44751f30cbb5bdc2d04fc32e3df7b09765f21c1db7682159c33cc3398c0e583 Copying config sha256:d7d811c318f6237a9dbc97dc15fc31cc92605b0c2166a4b66b4bdfbde727ea1f Writing manifest to image destination 6a9eef918b31d10db8fdb774f23a6ef27f91c29cecacd79c227196000cfa481f % podman images REPOSITORY TAG IMAGE ID CREATED SIZE localhost:5000/tnk4on/registry-test latest 6a9eef918b31 14 minutes ago 238 MB registry.access.redhat.com/ubi9 latest a13af6f8eaac 8 days ago 238 MB registry.redhat.io/rhbk/keycloak-rhel9 24-10 559c3ef84129 2 weeks ago 461 MB docker.io/library/registry 2 27031dfcd859 8 months ago 25.5 MB
podman logout
でローカルの認証情報を削除し、再度コンテナレジストリ上のコンテナイメージをPullしてみます。
今度はコンテナレジストリの認証でエラーになりPullできません。パブリックなコンテナレジストリと同様に、認証の仕組みが機能していることが確認できます。
% podman rmi registry-test:latest Untagged: localhost:5000/tnk4on/registry-test:latest Deleted: 6a9eef918b31d10db8fdb774f23a6ef27f91c29cecacd79c227196000cfa481f % podman logout localhost:5000 Removed login credentials for localhost:5000 % podman pull localhost:5000/tnk4on/registry-test --tls-verify=false Trying to pull localhost:5000/tnk4on/registry-test:latest... Error: initializing source docker://localhost:5000/tnk4on/registry-test:latest: Requesting bearer token: invalid status code from registry 400 (Bad Request)
まとめ
Red Hat build of Keycloakを認証基盤として利用するケースの1つとして、コンテナレジストリの認証環境を構築してみました。 Red Hat build of KeycloakはGUIの管理コンソールがあるため簡単に認証の設定を行うことができます。また、ユーザーの追加なども管理コンソール上で行うことができます。
Distribution Registryはローカル環境で簡単に実行できるコンテナレジストリのソリューションですが、ユーザー認証基盤を持たないためRed Hat build of Keycloakと組み合わせることで簡単に認証の仕組みを追加できます。 Red Hat build of Keycloakの基本機能を確認する目的でもローカルのコンテナ環境でサクッとお試しできますので、まずはPodmanを使って手を動かして体験してみることをオススメします。