KeycloakのOpenID ConnectでKubernetesにアクセスする
TL;DR
- Kubernetesの認証はクライアント証明書やID/パスワードだけでなく、OpenID Connectに対応している。
- RBACを設定することで、ユーザやグループによるアクセス制御ができる。
- 以下の設定が必要になる。
- Keycloak(OpenID Connect IdP)
- kube-apiserver(Kubernetes APIサーバ)
- kubectl(Kubernetesクライアント)
Getting Started
Keycloak
OpenID Connectで認証できるようにKeycloakを設定します。ここではKeycloakに以下のレルムとユーザが存在しており、ユーザはグループに入っているものとします。
- レルム名:
hello
- ユーザ名:
foo
- グループ名:
admin
まず、新しいクライアントを作成します。Settingsタブで下表の内容を設定します。
項目 | 設定値 |
---|---|
Client ID | kubernetes |
Client Prorocol | openid-connect |
Access Type | confidential |
Valid Redirect URIs | urn:ietf:wg:oauth:2.0:oob |
Credentialsタブを開くとSecretが表示されるのでメモしておきます。後述するkubectlの設定で必要になります。
Mappersタブで新しいマッパーを作成します。ここではグループによるアクセス制御を行いたいので groups
クレームを返すように下表の内容を設定します。
項目 | 設定値 |
---|---|
Name | groups |
Mapper Type | Group Membership |
Token Claim Name | groups |
kube-apiserver
kube-apiserverに下表の引数を渡すように設定します。
引数名 | 設定値 |
---|---|
--oidc-issuer-url |
https://keycloak.example.com/auth/realms/hello |
--oidc-client-id |
kubernetes |
--oidc-groups-claim |
groups |
kopsの場合は kops edit cluster
で以下を設定します。設定したら kops update cluster
と kops rolling-update cluster
でmastersを再作成しておきます。
spec: kubeAPIServer: oidcClientID: kubernetes oidcGroupsClaim: groups oidcIssuerURL: https://keycloak.example.com/auth/realms/hello
kubectl
OpenID ConnectのIDトークンを使用してKubernetesにアクセスするようにkubectlを設定します。kubectlはログイン処理は行ってくれないため、あらかじめIDトークンを取得しておく必要があります。ここではcurlコマンドでIDトークンを取得します。 ブラウザで以下のURLにアクセスします。
https://keycloak.example.com/auth/realms/hello/protocol/openid-connect/auth ?client_id=kubernetes &client_secret=YOUR_CLIENT_SECRET &response_type=code &scope=openid &scope=email &scope=profile &redirect_uri=urn:ietf:wg:oauth:2.0:oob
以下のコマンドを実行します。YOUR_CODE
はブラウザに表示されたコードに置き換えてください。
curl -d grant_type=authorization_code \ -d client_id=kubernetes \ -d client_secret=YOUR_CLIENT_SECRET \ -d redirect_uri=urn:ietf:wg:oauth:2.0:oob \ -d code=YOUR_CODE \ https://keycloak.example.com/auth/realms/hello/protocol/openid-connect/token
以下のようなJSONが返ってきたら成功です。
{"access_token":"...", "expires_in":300, "refresh_expires_in":1800, "refresh_token":"...リフレッシュトークン...", "token_type":"bearer", "id_token":"...IDトークン...", "not-before-policy":0, "session_state":"...", "scope":"..."}
新しいコンテキストでIDトークン認証を設定します。
kubectl config set-credentials hello.k8s.local-oidc \ --auth-provider oidc \ --auth-provider-arg idp-issuer-url=https://keycloak.example.com/auth/realms/hello \ --auth-provider-arg client-id=kubernetes \ --auth-provider-arg client-secret=YOUR_CLIENT_SECRET \ --auth-provider-arg id-token=IDトークン \ --auth-provider-arg refresh-token=リフレッシュトークン kubectl config set-context hello.k8s.local-oidc --cluster hello.k8s.local --user hello.k8s.local-oidc
IDトークン認証のコンテキストでkubectlを実行してみましょう。
% kubectl --context hello.k8s.local-oidc get po Error from server (Forbidden): pods is forbidden: User "https://keycloak.example.com/auth/realms/hello#874c4a74-faf3-45a0-bcfe-9ddf4fb802ea" cannot list pods in the namespace "default"
現在のユーザにはまだ何も権限を付与していないためForbiddenエラーが返ってくるはずです。もしUnauthorizedエラーが返ってきた場合は認証に失敗しているので、設定を再確認してください。トラブルシューティングでは kubectl --v=10
でデバッグログを出力するようにすると便利です。
現在のユーザに管理者権限を付与します。
# rbac-oidc.yaml kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: keycloak-admin-group roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - kind: User name: https://keycloak.example.com/auth/realms/hello#874c4a74-faf3-45a0-bcfe-9ddf4fb802ea
kubectl apply -f rbac-oidc.yaml
以下のようにPodsが表示されたら成功です。
% kubectl get po NAME READY STATUS RESTARTS AGE echoserver-7f76cc58-w8v4d 1/1 Running 0 2d
グループ単位で管理者権限を付与することも可能です。以下のように subjects
で Group
を指定します。
kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: keycloak-admin-group roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - kind: Group name: /admin
Keycloakが返すIDトークンの内容は https://jwt.io などでデコードして確認できます。ユーザ名やグループ名を調べる時に便利です。
まとめ
KeycloakがOpenID Connect IdPになり、IDトークンを使用してKubernetesにアクセスする方法を紹介しました。
現状、kubectlはOpenID Connectの認可コードフローに対応していないので、IDトークンの取得は自力で行う必要があります。コマンドラインツールの登場が待ち望まれます。
追記:OpenID Connectの認証フローとkubeconfigの更新を行うツールを公開しました.
参考文献
- Kubernetes の認証と dex - Qiita
- kubectl で OpenID Connect ID トークンをリフレッシュする - Qiita
- Using RBAC Authorization - Kubernetes
- 作者: Kelsey Hightower,Brendan Burns,Joe Beda,松浦隼人
- 出版社/メーカー: オライリージャパン
- 発売日: 2018/03/22
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る