※ この記事は Red Hat Advent Calendar 2023 の19日目の記事です。
Red Hatのソリューションアーキテクトのおおみぞです。
Red Hat Build of Keycloak(以降、Keycloak)を Red Hat OpenShift Container Platform(以降、OpenShift)の Identity Provider として利用するための設定をご紹介します。今回は Keycloak も OpenShift にデプロイするので、
2つの OpenShift 環境を用意します。1つは Keycloak をデプロイする環境でクラウド上に作成、もう一つは Keycloak によって保護される環境でローカルに作成します。
全体の流れとしては、以下のようになります。
- (クラウド) Postgresql をデプロイ
- (クラウド) Keycloak Operator インストール
- (クラウド) Keycloak インスタンス作成
- (クラウド) KeycloakにRealm/Client/User 作成
- (ローカル) OpenShift のアイデンティティプロバイダー設定
Keycloakのデプロイ
keycloak
という名前の OpenShift のプロジェクトに、DB や Keycloak をデプロイしていきます。
データベースの準備
まずは、Keycloakのバックエンドのデータベースを準備します。
様々なDBサーバがサポート対象となっていますが、今回はPostgreSQLを利用します。
PostgresqlのStatefulsetとServiceをYAMLを使ってデプロイします。
以下の内容を kc-pgsql.yaml
というファイルに保存し、oc apply -f kc-pgsql.yaml
コマンドで PostgreSQL をデプロイします。
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgresql-db
spec:
serviceName: postgresql-db-service
selector:
matchLabels:
app: postgresql-db
replicas: 1
template:
metadata:
labels:
app: postgresql-db
spec:
containers:
- name: postgresql-db
image: postgres:latest
volumeMounts:
- mountPath: /data
name: cache-volume
env:
- name: POSTGRES_PASSWORD
value: testpassword
- name: PGDATA
value: /data/pgdata
- name: POSTGRES_DB
value: keycloak
volumes:
- name: cache-volume
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
name: postgres-db
spec:
selector:
app: postgresql-db
type: LoadBalancer
ports:
- port: 5432
targetPort: 5432
KeycloakがDBにアクセスするときに利用する DB のユーザとパスワードを Secret keycloak-db-secret
として登録します。
oc create secret generic keycloak-db-secret \
--from-literal=username=postgres \
--from-literal=password=testpassword
Keycloak の TLS 証明書と鍵の作成
自己証明書を作成します。OpenShift の Identity Provider を登録する際に SAN(Subject Alternative Name)がない証明書を利用すると、証明書が不正となって Identity Provider の登録ができないので、SANに対応した証明書を作成します。
私は Red Hat Build of Keycloak - Operator Guideに記載の通りに設定していき、いざ、OpenShift の設定をするときに「証明書が登録できない!?」となってあたふたしてしまいました。
証明書に関する細かな説明は割愛しますが、以下の手順で作成した証明書を利用しました。
ルートCAの秘密鍵作成 => rootCA1.key
ルートCAの証明書作成 => rootCA1.pem
openssl genrsa -out rootCA1.key -des3 2048
openssl req -new -x509 -key rootCA1.key -sha256 -days 3650 -extensions v3_ca -out rootCA1.pem -subj "/C=JP/ST=Tokyo/O=rootCA1/CN=rooCA1"
中間CAの秘密鍵作成 => inCA1.key
中間CAの証明書要求作成(CSR) => inCA1.csr
中間CAの証明書作成(PEM) => inCA1.pem
openssl genrsa -out inCA1.key -des3 2048
openssl req -new -key inCA1.key -sha256 -outform PEM -keyform PEM -out inCA1.csr -subj "/C=JP/ST=Tokyo/O=inCA1/CN=inCA1"
openssl x509 -extfile openssl_sign_inca.cnf -req -in inCA1.csr -sha256 -CA rootCA1.pem -CAkey rootCA1.key -set_serial 01 -extensions v3_ca -days 3650 -out inCA1.pem
秘密鍵と証明書要求の作成 => server.csr
サーバ証明書作成 => server.pem
openssl req -new -newkey rsa:2048 -nodes -out server.csr -keyout server.key -sha256 -config openssl_sign_server.cnf -subj "/C=JP/ST=Tokyo/O=Keycloak/CN=test.keycloak.org"
openssl x509 -req -in server.csr -sha256 -CA inCA1.pem -CAkey inCA1.key -set_serial 01 -days 3650 -extfile san.txt -out server.pem
最後に内容確認します。
openssl x509 -in server.pem -text -noout
証明書を Secret として登録します。
oc create secret tls example-tls-secret --cert server.pem --key server.key
Keycloak Operator のインストール
Operator Hub で rhbk
というキーワードで Keycloak Operator を検索しインストールします。
Keycloak のインスタンス作成
インストール済みの Operator の中から Keycloak Operator を選択し、 Keycloak インスタンスを作成します。
Keycloak の作成画面で、YAML ビューを選択し以下の内容を貼りつけて作成をクリックします。
apiVersion: k8s.keycloak.org/v2alpha1
kind: Keycloak
metadata:
name: example-kc
spec:
instances: 1
db:
vendor: postgres
host: postgres-db
usernameSecret:
name: keycloak-db-secret
key: username
passwordSecret:
name: keycloak-db-secret
key: password
http:
tlsSecret: example-tls-secret
hostname:
hostname: test.keycloak.org
Keycloak の Pod が正常に動いていることを確認するために oc get pods
を実行します。Operator, Postgresql, Keycloak の3つが Running となっていれば OK です。
oc get pods
NAME READY STATUS RESTARTS AGE
example-kc-0 1/1 Running 0 2m12s
postgresql-db-0 1/1 Running 0 80m
rhbk-operator-7975df488-9gx22 1/1 Running 0 57m
Keycloak の管理ポータルにアクセスするときに利用するユーザとパスワードを確認します。
oc get secret example-kc-initial-admin -o jsonpath='{.data.username}' | base64 --decode
oc get secret example-kc-initial-admin -o jsonpath='{.data.password}' | base64 --decode
Keycloak へアクセス
Keycloak の Hostname に設定した test.keycloak.org
の名前解決ができるようにする必要があります。
oc get ingress
コマンドで、Ingress Controller のアドレスを確認し、ADDRESS 列に出力された FQDN の IP アドレスを確認し、hosts (MacやLinuxの場合は /etc/hosts) にエントリを追加します。
% oc get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
example-kc-ingress <none> test.keycloak.org router-default.apps.cluster-000000.dynamic.redhatworkshops.io 80 13m
% dig router-default.apps.cluster-000000.dynamic.redhatworkshops.io
これで、ブラウザで http://test.keycloak.org
アクセスできるようになりました。
Keycloak を利用した OpenShift の認証の設定
Keycloak の Realm の登録
Keycloak のポータルにアクセスして、OpenShift の認証に利用する Realm を demo
という名前で作成し、openshift
という名前の Client を作成します。その後、 User を追加します。
OpenShift の Identity Provider の設定
OpenShift のポータルの管理メニューでクラスター設定を選択し、設定タブで oauth
というキーワードで検索し oAuth
を選択します。
oAuth の詳細画面の下の方のアイデンティティプロバイダーの追加リストで OpenID Connect
を選択し、Keycloak での認証の設定をします。
アイデンティティプロバイダの追加画面で、名前、クライアントID、クライアントシークレット、発行者のURL (Issuer URL)とTSLの証明書をアップロードして保存すれば設定は完了です。
反映時にエラーなどがある場合は、ClusterOperators の authentication
の詳細でエラーなどが確認できます。
動作確認
ローカルで起動中の OpenShift の URL にアクセスすると、ID Provider の選択ができるのでここで demo
を選択します。
Keycloak のユーザ認証画面にリダイレクトされるのでそこで、ユーザ/パスワードを入力して認証が OK ならば、OpenShift の画面に遷移します。
まとめ
Keycloak を OpenShift の Identity Provider として利用するための設定方法を説明しました。 OpenShift では、様々な Identity Provider と連携することができますので使い方に合わせて最適な方式を選択してみてください。