おうち Kubernetesをはじめて一週間が経ちましたが、やはり手元に3ノードある Kubernetesは便利ですね。早くマスターの HA 構成もしたいところです。
今回は、そんなおうち Kubernetesの認証を OpenID Connect で行うコトハジメをしてみたいと思います。
kubelogin を使ったログイン
kubectl を使ったクラスタへのログインに kubeloginというプラグインを導入します。
これは OpenID Connect プロバイダから認証のリクエストを送り、プロバイダからもらった結果をプラグインに戻したのち、トークンを元に kube-apiserver へのリクエストを行います。その結果元に、クラスタの操作を行います。(そのためには権限を付与する必要がありますが)
いわゆる GKE などでいう gcloud 認証情報ヘルパーのようなモノです。kube-apiserver 自体は OpenID Connect に対応しているものの、 Authorization Code Flow を実現するためには kubelogin のようなプラグインが必要です。さまざまな方が自作されていて、 k8s-oidc-helperというものもあるのでそちらでも良いと思います。
Auth0 を IdP とした設定手順
Google Workspace も持っているのですが、グループやロールを柔軟に設定したいと思ったので Auth0 を使用することにしました。
Auth0 でテナントを作成したら、ダッシュボードから APIを選択して APIを作成します。 Enable RBAC と Add Permissions in the Access Token を有効にします。 offline_accessを要求する場合はAllow Offline Accessも入れておくと良いでしょう。(これは自分で必要なら、入れてください)



User と Role を適当に作成します。今回は Role に adminというものを追加しました。

Auth0 の認証プロセスをカスタマイズできる Rules 機能を使って、ロールをカスタムクレームとして含ませます。Rules を以下のように作成します。
function (user, context, callback) {const namespace = '<custom_claim_prefix>'; const assignedRoles = (context.authorization || {}).roles; let idTokenClaims = context.idToken || {}; let accessTokenClaims = context.accessToken || {}; idTokenClaims[`${namespace}/roles`] = assignedRoles; accessTokenClaims[`${namespace}/roles`] = assignedRoles; context.idToken = idTokenClaims; context.accessToken = accessTokenClaims; callback(null, user, context); }
あとは kubelogin をします。
kubectl oidc-login setup --oidc-issuer-url=https://<tenant>.us.auth0.com/ --oidc-client-id=<api_client_id> --oidc-client-secret=<api_client_secret>- --oidc-extra-scope=offline_access
{
"<custom_claim_prefix>/roles": [
"admin"
],
"iss": ...
}表示に従って、 kubectl config set-credentialsを行います。
その後、API Serverへの設定を行います。Set up the Kubernetes API serverの表示される通りに設定すると、Userをバインドする形になります。今回はグループでバインドしたいので、手動で設定します。まず kube-apiserver の引数に以下を足します。
kubeadm で構築した場合は sudo vim /etc/kubernetes/manifests/kube-apiserver.yaml等で開いて、以下を足します。
- --oidc-issuer-url=https://<tenant>.us.auth0.com/
- --oidc-client-id=<client_id>
- --oidc-groups-claim=<custom_claim_prefix>/roles
- '--oidc-groups-prefix=auth0:'oidc-groups-claim と oidc-groups-prefix を使うことで、独自のグループクレームを使うことができます。
作成した admin ロールを cluster-admin にバインドする ClusterRoleBinding の例は以下の通りです。
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata:name: auth0-admin-group roleRef:apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects:- apiGroup: rbac.authorization.k8s.io kind: Group name: auth0:admin
これを既存の cluster-admin で適用した後、kubectl oidc-login setupを行ったクライアントでkubectl --user=oidc cluster-infoなどを行って動作確認してください。
終わりに
これで Kubernetesクラスタと OpenID Connect による IdP との連携が可能になりました。また、グループによる権限制御もできるようになり便利になりました。この内容自体は他の IdP でも利用できるので、ぜひ試してみてください。
参考
- Sample Use Cases: Rules with Authorization
- kubeloginコマンドを利用してOpenID ConnectでKubernetesにアクセスする - GeekFactory
- GitHub - micahhausler/k8s-oidc-helper: Helper tool for authenticating to Kubernetes using Google's OpenID Connect
- GitHub - auth0/k8s-pixy-auth: k8s plugin to authenticate against an OIDC compatible issuer using PKCE (pixy) flow