このトピックでは、Container Service for Kubernetes (ACK) クラスターにKeycloakサービスをデプロイし、KeycloakをKubernetes OpenID Connect (OIDC) 認証サーバーとして使用してIDを検証する方法について説明します。
前提条件
ACKマネージドクラスターが作成され、Kubernetes 1.22以降が実行されます。
jwt-cliがインストールされています。 jwt-cliは、JSON Webトークン (JWT) の解析に使用されます。 このステップは省略可能です。
環境のセットアップSet up the environment
Keycloakサービスのドメイン名を準備します。
証明書
本番環境でKeycloakのセキュリティを確保するには、次のコマンドを実行してルート証明書とサーバー証明書を生成します。 サーバー証明書のサブジェクト代替名 (SAN) には、Keycloakサービス用に準備したドメイン名が含まれている必要があります。
openssl genrsa -out rootCA.key 2048 #Generate a Certificate Authority (CA) key. openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 3650 -out rootCA.crt #Generate a CA certificate. openssl genrsa -out server.key 2048 #Generate a server key. openssl req -new -key server.key -out server.csr openssl x509 -req -in server.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out server.crt -days 3650 -sha256 -extensions v3_req -extfile <(echo '[v3_req]'; echo 'subjectAltName = DNS:${Service domain name}')データベース
デフォルトでは、Keycloakデータはローカルファイルに保持されます。 本番環境では、データをデータベースに保持する必要があります。 次の表に、Keycloakでサポートされているデータベースエンジンとバージョンを示します。
データベースエンジン
オプション値
バージョン
MariaDBサーバー
mariadb
10.11
Microsoft SQL Server
mssql
2022
MySQL
mysql
8.0
Oracleデータベース
オラクル
19.3
PostgreSQL
postgres
有効期限の 15
この例では、ApsaraDB RDS for MySQLを使用してKeycloakデータを保持します。 Keycloakという名前のデータベースが作成されます。 ApsaraDB RDS For MySQLインスタンスを作成および使用する方法の詳細については、「ApsaraDB RDS for MySQLインスタンスの作成」をご参照ください。
手順1: ACK管理クラスターへのKeycloakのデプロイ
ACK管理クラスターにKeycloakサービスをデプロイします。
keycloak.yamlという名前のファイルを作成し、次の内容をファイルに追加します。
apiVersion: v1 kind: Service metadata: labels: app: keycloak name: keycloak namespace: default spec: ports: - name: http port: 80 protocol: TCP targetPort: 8080 selector: app: keycloak type: ClusterIP次のコマンドを実行して、ACK管理クラスターにKeycloakサービスをデプロイし、サービスを内部アクセスに公開します。
kubectl apply -f keycloak.yaml
関連する設定をデプロイします。
keycloak-secret.yamlという名前のファイルを作成し、次の内容をファイルに追加します。
次のデータベース構成を使用して、Keycloakという名前のデータベースに接続します。 管理者設定は、初めてKeycloakにログインするために使用されます。
apiVersion: v1 data: db_passwd: ${Database password encoded by Base64} db_username: ${Database username encoded by Base64} db_url: ${Database URL or host encoded by Base64} keycloak_admin: ${Keycloak administrator username encoded by Base64} keycloak_admin_password: ${Keycloak administrator password encoded by Base64} kind: Secret metadata: name: keycloak-secret namespace: default type: Opaque次のコマンドを実行して、構成をデプロイします。
kubectl apply -f keycloak-secret.yamlkeylock-pki.yamlという名前のファイルを作成し、次のコンテンツをファイルに追加します。
apiVersion: v1 data: tls.crt: ${Server certificate encoded by Base64} tls.key: ${Server key encoded by Base64} kind: Secret metadata: name: keycloak-pki namespace: default type: IngressTLS次のコマンドを実行して、サーバー証明書をデプロイします。
kubectl apply -f keycloak-pki.yaml
Ingressを作成します。
keycloak-ingress.yamlという名前のファイルを作成し、次の内容をファイルに追加します。
次のコードブロックのサービスドメイン名を、Keycloakサービス用に用意したドメイン名に置き換えます。
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: labels: ingress-controller: nginx name: keycloak namespace: default spec: ingressClassName: nginx rules: - host: ${Service domain name} http: paths: - backend: service: name: keycloak port: number: 80 path: / pathType: ImplementationSpecific tls: - hosts: - ${Service domain name} secretName: keycloak-pki次のコマンドを実行して、Ingressをデプロイします。
kubectl apply -f keycloak-ingress.yamlIngressがデプロイされると、パブリックアクセス可能なIPアドレスが生成されます。 サービスドメイン名がIPアドレスに解決されます。
Keycloakデプロイをデプロイします。
keycloak-deploy.yamlという名前のファイルを作成し、次のコンテンツをファイルに追加します。
次のコマンドを実行して、Keycloak Deploymentをデプロイします。
kubectl apply -f keycloak-deploy.yaml
ウェブブラウザのアドレスバーに
https://${Keycloak Service domain name}と入力し、Keycloakサービスにアクセスします。 次のページが表示される場合、サービスは正常に展開されます。
ステップ2: Keycloakのデプロイ
ユーザー設定
Keycloak Serviceページで、[管理コンソール] をクリックし、ユーザー名とパスワードを入力して管理コンソールにログインします。
ステップ2.aでkeycloak-secret.yamlファイルに指定された管理者ユーザー名とパスワードを入力する必要があります。
ページの左上にあるドロップダウンリストからmasterを選択し、[レルムの作成] をクリックします。
レルムの作成ページで、レルム名をmyrealmに設定し、[作成] をクリックしてmyrealmという名前のレルムを作成します。 レルムでKeycloakテナントを管理できます。
ページの左上で、ドロップダウンリストからmyrealmを選択します。 左側のナビゲーションウィンドウで、[ユーザー] をクリックし、表示されるページで [ユーザーの追加] をクリックします。
[ユーザーの作成] ページで、[ユーザー名] を [myuser] に設定し、[作成] をクリックしてmyuserという名前のユーザーを作成します。 その他のパラメータはオプションです。
myuserページで、[属性] をクリックして、myuserユーザーの属性を追加します。 Keyをnameに、Valueをackに設定し、[Save] をクリックします。 属性は、IDトークンに挿入することができる。
myuserページで、[資格情報] をクリックし、[パスワードの設定] をクリックします。
[一時] を [オン] に設定し、[保存] をクリックします。 Keycloakに初めてログインするときにパスワードを変更する必要があります。
Keycloakのアドレスは
https://${Keycloak Service domain name}/realms/${Your realm}/accountです。
クライアント設定
KeycloakはクライアントのIDを確認する必要があります。 次のクライアント設定を構成します。
myrealmページの左側のナビゲーションウィンドウで、[クライアント] をクリックします。 [クライアント] ページで、[クライアントの作成] をクリックします。
[クライアントの作成] ページで、[一般設定] 、[機能設定] 、および [ログイン設定] を設定します。
[一般設定] ページで、[クライアントID] と [名前] を指定し、[次へ] をクリックします。 この例では、両方のパラメータがackに設定される。
[機能設定] ページで、[クライアント認証] を [オン] に設定してクライアントのアクセスタイプを機密に設定し、他のパラメーターにデフォルト設定を使用して、[次へ] をクリックします。
[ログイン設定] ページで、有効なリダイレクトURIをhttp:// * に設定します。 このパラメーターは、正常にログオンした後に使用されるリダイレクトURIを指定します。 この例では、http:// * はすべてのHTTPリダイレクトURIを指定します。 [保存] をクリックします。
クライアントスコープの設定
クライアントスコープを使用して、レルム内の複数のクライアント間で共通のプロトコルおよび役割マッピングを共有できます。
myrealmページの左側のナビゲーションウィンドウで、[クライアントスコープ] をクリックします。 [クライアントスコープ] ページで、[クライアントの作成] [スコープ] をクリックします。
[クライアントの作成] [スコープ] ページで、[名前] を [ack-kubernetes] に設定し、他のパラメーターのデフォルト設定を維持し、[保存] をクリックします。
ack-kubernetesページで、[マップ] をクリックし、[新しいマップの設定] をクリックします。
[Configure a new mapper] ページで、ステップ6で追加した属性をIDトークンに挿入するユーザー属性を作成します。 この例では、キーと値がnameとackである属性が挿入されます。
[マッパーの追加] ページで、[名前] を [名前] に、[ユーザー属性] を [名前] (前の手順で追加した名前: ack属性) に、[トークンクレーム名] を [名前] (IDトークンの属性の名前) に設定します。 他のパラメータのデフォルト設定を維持します。 [保存] をクリックします。
左側のナビゲーションウィンドウで、[クライアント] をクリックして [クライアント] ページに戻り、ackという名前のクライアントを選択します。
ackクライアントのクライアントページで、[クライアントスコープ] をクリックし、[クライアントスコープの追加] をクリックします。 表示されるダイアログボックスで、追加するクライアントスコープを選択し、[追加] をクリックします。

手順3: Kube API Serverパラメーターの設定
KubernetesはOIDCプロトコルをサポートしており、外部IDプロバイダー (IdP) とインターフェイスしてIDを検証できます。 ID検証を有効にするには、ACK管理クラスターのKube API Serverコンポーネントに関連するOIDCパラメーターを設定する必要があります。
ACKコンソールにログインします。 左側のナビゲーションウィンドウで、[クラスター] をクリックします。
[クラスター] ページで、管理するクラスターの名前をクリックします。 左側のナビゲーションウィンドウで、 を選択します。
[アドオン] ページで、[コアコンポーネント] タブでKube API Serverコンポーネントを見つけ、カードの右下にある [設定] をクリックします。
[Kube API Serverパラメーター] ダイアログボックスで、次のパラメーターを設定し、他のパラメーターのデフォルト設定を維持して、[OK] をクリックします。
パラメーター
説明
oidcIssuerURLOIDC
OIDCプロバイダーのURL
https://${Keycloak Service domain name}/realms/myrealm/.well-known/openid-configurationにアクセスし、OIDCプロバイダーのURLを取得します。 この例では、https://${Keycloak Service domain name}/realms/myrealmを入力します。重要クラスターのAPIサーバーは、oidcIssuerURL設定で指定されたアドレスにアクセスします。 パブリックエンドポイントを使用する場合は、クラスターがインターネットにアクセスできることを確認してください。 詳細については、「既存のACKクラスターによるインターネットへのアクセスの有効化」をご参照ください。
クラスターがインターネットアクセスを有効にした後でも、APIサーバーがoidcIssuerURL設定で指定されたアドレスにアクセスできない場合は、
kubectl get endpointsコマンドを実行して、KubernetesのバックエンドIPアドレスの数を取得できます。IPアドレスの数が1を超える場合は、ワーカーノードにログインし、oidcIssuerURLにアクセスしてから、インターネットとセキュリティグループルールの設定を確認します。
IPアドレスが1つしかない場合は、
チケットを起票してサポートセンターにお問い合わせくださいしてサポートセンターにお問い合わせください。
oidcClientIdOIDCトークン
クライアントID
[クライアント設定] セクションのステップ2で指定したクライアントIDを入力します。 この例では、ackが入力されます。
oidcUsernameClaim
ユーザー名JWTクレーム
[クライアントスコープ設定] セクションのステップ5で指定した [トークンクレーム名] パラメーターの値を入力します。 この例では、ACK管理クラスター内のユーザーのIDである名前が入力されます。
oidcUsernamePrefix
ユーザー名プレフィックス
ハイフン (-) を入力します。これは、プレフィックスが指定されていないことを意味します。
oidcCAContent
OIDCプロバイダーのURLにリクエストを送信するために必要なBase64-encoded CA証明書
環境の設定セクションで、証明書で生成されたBase64-encodedルート証明書を入力します。
ステップ4: IDの確認
次のコマンドを実行してIDトークンを要求します。 次に、リクエストボディからIDトークンを取得します。
curl -ks -X POST https://${Keycloak Service domain name}/realms/myrealm/protocol/openid-connect/token \ -d grant_type=password -d client_id=ack \ -d username=myuser -d password=${Password used to log on to Keycloak} -d scope=openid \ -d client_secret=${client credential}次の変数を置き換える必要があります。
置き換える変数
説明
Keycloak Serviceドメイン名
Keycloakサービス用に用意したドメイン名に置き換えます。
password
手順2.aで指定したパスワードに置き換えます。
client_secret
Keycloakコンソールにログインします。 [クライアント] ページで、ackという名前のクライアントを選択し、[資格情報] をクリックし、[クライアントシークレット] パラメーターの値をコピーします。

必要に応じて、 jwt-cliを使用してトークンを解析します。 解析結果は、
issがAPIサーバーのoidcIssuerURLパラメーターの値に設定され、nameがクライアントスコープ設定セクションのステップ5で追加したuser属性に設定されていることを示しています。次のYAMLコンテンツを使用してClusterRoleを作成します。
kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: keycloak-example rules: - apiGroups: [""] resources: ["namespaces"] verbs: ["get","list"] # Allow the role to read namespace information. --- kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: ack-crb roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: keycloak-example subjects: - kind: User name: ack apiGroup: rbac.authorization.k8s.io次のコマンドを実行して、APIサーバーにリクエストを送信します。
curl -k https://${API server address}/api/v1/namespaces -H "Authorization: Bearer ${id token}"APIサーバーアドレス: クラスターが存在するネットワークに基づいてAPIサーバーアドレスを入力します。 ACKコンソールの [クラスター情報] ページで、[基本情報] タブの [ネットワーク] セクションを見つけます。 次に、[API server Public Endpoint] および [API server Internal Endpoint] を表示します。id token: ステップ1で取得したIDトークンを指定します。
リクエストの送信後、次の名前空間情報が返されます。
現在のユーザーがアクセスを許可されていないリソースを要求する別の要求を送信します。 出力は、Kubernetesがackユーザーを識別し、ユーザーの権限を検証することを示します。