メインコンテンツまでスキップ

SSO でクラスターにログインする

Kubernetes にはユーザーデータベースがありません。User という object も、ユーザーを作成するコマンドもありません。API server が知っているのは、Identity Provider(IdP)がすでに保証している identity を検証する方法だけです。

認証フロー: あなた(kubectl + kubelogin)がログイン → IdP(Keycloak/Azure AD/Okta)が ID token を返す → その token を API server に直接送信 → API server が IdP の JWKS で署名を検証 → Kubernetes RBAC が権限を決定します。

注記

token はあなたから API server へ直接送られます — IdP はリクエストの経路には含まれません。IdP が一時的に停止しても、キャッシュ済みの token は有効期限まで使え、クラスターは通常どおり動作します。

警告

ログインに成功しても、何かをする権限があるとは限りません。認証されたが RoleBinding を持たないユーザーは、kubectl get pods のようなコマンドで 403 Forbidden を受け取ります。これは設計どおりの動作であり、構成ミスではありません。

区別すべき 3 つの層​

チームで GPU workload を動かすには、3 つの層があります — この層を混同することが、最もよくある混乱の原因です。

層答える問い構成手段
認証(Authentication)あなたは誰かOIDC(Issuer URL、Client ID)— Cluster Admin が一度だけ構成
認可(Authorization)何ができるかKubernetes RBAC(RoleBinding / ClusterRoleBinding)— このページ
クォータ(Quota)どれだけ使えるかResourceQuota / LimitRange(CPU、RAM、requests.nvidia.com/gpu)— このページ

認証を通過しても、残り 2 つの層のどちらかでブロックされることがあります。namespace への権限はあってもクォータが尽きていれば、権限エラーではなくスケジューリングエラーになります。

開始する前に​

項目要件
クラスター管理者が OIDC 認証をすでに有効化していること — Configure OIDC authentication for the cluster を参照。
ツール自分の端末に kubectl と kubelogin がインストールされていること。
ネットワーク自分の端末からクラスターの API server と IdP の両方に到達できること。
HTTPSIdP が有効な証明書を使用していること — 社内 CA を使用している場合は、その CA を端末に取り込む必要があります。
アカウントIdP 上のユーザー名/パスワードがあり、適切な group に追加されていること。

さらに、クラスター管理者から次の 4 つの情報を受け取る必要があります。これらがすべて揃わないと kubeconfig を作成できません。

情報用途
API server URLkubeconfig の server フィールド。
クラスターの CA certificatecertificate-authority-data フィールド。
Issuer URL(IdP)管理者が Portal で OIDC を構成したときに入力した Issuer URL と同じ値。
Client ID管理者が Portal で OIDC を構成したときに入力した Client ID と同じ値。

kubelogin をインストールする​

krew(kubectl のプラグインマネージャー)をインストールする​

公式の krew インストールガイド(krew.sigs.k8s.io)を参照してください。

PATH に追加する​

echo 'export PATH="${KREW_ROOT:-$HOME/.krew}/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
# Using zsh: replace ~/.bashrc with ~/.zshrc

# Confirm
kubectl krew version
警告

~/.bashrc に設定した PATH は、対話的なシェルにのみ適用されます。ssh host 'kubectl ...' のような実行方法やスクリプト内では、このファイルは読み込まれません。そのような場合は、次のように明示的に追加してください: export PATH="$HOME/.krew/bin:$PATH"; kubectl get nodes。

oidc-login プラグインをインストールする​

kubectl krew install oidc-login

# Upgrade later
kubectl krew upgrade oidc-login

# See installed version
kubectl krew list

インストールを確認する​

# 1. Does the binary run?
kubectl oidc-login --version
# kubelogin version v1.36.4

# 2. Does kubectl recognize the plugin?
kubectl plugin list
# /root/.krew/bin/kubectl-oidc_login

# 3. Can you reach the IdP? (replace with your real issuer URL)
curl -sI https://sso.example.com/realms/kubernetes/.well-known/openid-configuration | head -1
# HTTP/2 200
インストール時のエラー原因対処方法
unknown command "krew"ステップ 1 を実行していない、またはステップ 2 を省略した~/.krew/bin を PATH に追加し、source ~/.bashrc を実行する
unknown command "oidc-login"プラグインが未インストール、または PATH に ~/.krew/bin がないkubectl krew list で確認し、ステップ 2 を見直す
手動実行はできるが SSH 経由だとできない非対話的シェルでは ~/.bashrc が読み込まれないコマンドの先頭に export PATH="$HOME/.krew/bin:$PATH" を追加する
kubelogin のバージョンが古すぎる長期間更新していないkubectl krew upgrade oidc-login

ユーザー用の kubeconfig を作成する​

OIDC の kubeconfig にはパスワードや token は含まれません。kubelogin をどう呼び出して token を取得するかを記述しているだけです。そのため、1 つのファイルをチーム全員に配布でき、それぞれが自分のアカウントでログインして、自分に対応する権限を得られます。

サンプルファイル(全体)​

apiVersion: v1
kind: Config
current-context: my-gpu-cluster-sso

clusters:
- name: my-gpu-cluster
cluster:
server: https://api.my-gpu-cluster.example.com
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0t...

contexts:
- name: my-gpu-cluster-sso
context:
cluster: my-gpu-cluster
user: sso-user
namespace: ml-training

users:
- name: sso-user
user:
exec:
apiVersion: client.authentication.k8s.io/v1beta1
command: kubectl
args:
- oidc-login
- get-token
- --oidc-issuer-url=https://sso.example.com/realms/kubernetes
- --oidc-client-id=kubernetes
- --oidc-extra-scope=email
- --oidc-extra-scope=profile
# Machine with no browser: add the 2 lines below
# - --grant-type=device-code
# - --skip-open-browser
interactiveMode: IfAvailable
installHint: |
kubelogin isn't installed. Install it with:
kubectl krew install oidc-login
ヒント

--oidc-issuer-url と --oidc-client-id は、クラスター管理者が Portal で OIDC を構成したときに設定した Issuer URL と Client ID(Configure OIDC authentication for the cluster を参照)と同じ値です — この 2 つの値を、クラスター管理者に確認してください。

ファイル構造 — 3 つのブロックとその関係​

clusters ──┐ which cluster (address + CA)
├── contexts ── links a cluster to a user, plus a default namespace
users ──┘ how to log in

current-context が、現在使用する context を指定します。1 つのファイルに複数のクラスターと複数の context を含めることができ、kubectl config use-context で切り替えられます。

clusters ブロック:

フィールド意味
serverAPI server の HTTPS アドレス。管理者に確認してください。
certificate-authority-dataクラスターの CA(base64 形式)。API server の証明書を検証するために使用します — 機密情報ではありません。
certificate-authority上記フィールドの代わりに、.crt ファイルのパスを指定します。どちらか一方のみ使用します。
insecure-skip-tls-verify使用は避けてください。証明書の検証をスキップします — 使い捨ての lab 環境でのみ使用します。

contexts ブロック:

フィールド意味
clusterクラスター名。clusters 内のエントリと一致させる必要があります。
userユーザー名。users 内のエントリと一致させる必要があります。
namespace-n を指定しない場合に使われる既定の namespace。

exec ブロックの各パラメーターの説明​

この部分が、ログイン方法を決定します。kubectl は command を args 付きで実行し、その出力から token を読み取ります。

exec のフィールド​

フィールド値意味
apiVersionclient.authentication.k8s.io/v1beta1exec credential プロトコルのバージョン
commandkubectl呼び出されるコマンド(kubelogin はプラグインのため)
argsリストコマンドに渡す引数
interactiveModeIfAvailableterminal を占有してよいタイミング
installHintテキストkubelogin が未インストールの場合に表示されるメッセージ

必須の 2 つの引数​

引数意味
oidc-login get-tokenプラグイン名 + サブコマンド。先頭に、この順序で指定する必要があります
--oidc-issuer-urlIdP のアドレス — クラスターの構成と 1 文字も違わず 一致する必要があります
--oidc-client-idIdP に登録したアプリケーションの識別子。API server が検証する aud にもなります

よく使う任意の引数​

引数必要になる場合
--oidc-client-secretclient が confidential の場合のみ
--oidc-extra-scope追加の scope をリクエストする場合。通常は email と profile
--grant-typeauto(既定)、authcode、device-code、password
--skip-open-browserブラウザがない端末の場合
--certificate-authorityIdP 用の CA(クラスターの CA とは異なります)
--force-refreshキャッシュを無視して新しい token を取得する — group 変更直後に便利
-v=1 … -v=5ログレベル。トラブルシューティングには -v=5 を使用
警告

--oidc-extra-scope=groups は追加しないでください。group の情報は IdP 管理者が構成する protocol mapper から来るもので、scope から来るものではありません。IdP が定義していない groups scope をリクエストすると invalid_scope エラーになります。

token キャッシュの仕組み​

初回実行時、kubelogin は token を ~/.kube/cache/oidc-login に保存します。以降の実行ではキャッシュを読み取り、自動的に refresh し、refresh token の有効期限が切れたときのみ再ログインを求めます。

# Clear the cache when you need to force a re-login (required after a group change)
rm -rf ~/.kube/cache/oidc-login # Linux/macOS
Remove-Item -Recurse -Force "$env:USERPROFILE\.kube\cache\oidc-login" # Windows

ログイン成功を確認する​

kubectl auth whoami
ATTRIBUTE VALUE
Username oidc:nguyenvana
Groups [oidc:ml-team system:authenticated]

正しい名前と group が表示されれば、認証は正しく機能しています。その後 403 が発生する場合は authorization の問題です。Kubernetes 権限を割り当てる を参照してください。

ブラウザがない端末の場合​

jump host、server、container など、ブラウザを開けない環境です。既定の kubeconfig をそのまま使うと、処理が止まり最終的に context deadline exceeded になります。

  • Device code(推奨): args に次の 2 行を追加します。

    - --grant-type=device-code
    - --skip-open-browser

    terminal に、コードが入力済みのリンクが表示されます。それをスマートフォンや別の端末で開いてログインし、terminal に戻って数秒待てば完了します。コードの有効期限は 10 分です。

  • SSH port forwarding: kubeconfig は既定のままにし、ssh -L 8000:localhost:8000 -L 18000:localhost:18000 user@jumphost で接続してから、jump host 上で通常どおり kubectl を実行します。

  • Authcode keyboard: --grant-type=authcode-keyboard — URL を開いてログインし、返されたコードを terminal に貼り付けます。

  • Password grant: --grant-type=password --username=... — アカウントで MFA が有効な場合は使用できません。非推奨であり、簡易なテスト時のみ使用してください。

注記

CI/CD には OIDC ログインを使わず、ServiceAccount token を使用してください(use case 7 を参照)。

Kubernetes 権限を割り当てる​

マッピングルール​

クラスター管理者が構成した prefix(Portal で OIDC を構成する際に Advanced で入力した Username Prefix / Groups Prefix)が、IdP から来るすべての identity に付加されます。

IdP 上token 内の claimRBAC で使う名前
ユーザー nguyenvanapreferred_usernameoidc:nguyenvana
Group ml-teamgroups[]oidc:ml-team

prefix が何か分からない場合は kubectl auth whoami を実行してください — 表示される値が、RBAC で使うべき名前そのものです。

ヒント

権限は必ず User ではなく Group に割り当ててください。kind: User に割り当てると、チームへの加入・離脱があるたびに各クラスターの RBAC を修正する必要があります。kind: Group に割り当てれば、IdP 上でメンバーを追加・削除するだけで済みます。唯一の例外は break-glass アカウントです。

組み込みの 4 つの ClusterRole​

ClusterRole権限用途
cluster-adminすべての namespace に対する full accessインフラ管理者
admin1 つの namespace 内での full access(RoleBinding の作成を含む)MLOps チームリーダー
editリソースの編集は可能だが RBAC 自体は編集不可training/inference を実行する data scientist、ML engineer
view読み取り専用。Secret は除外レビュー担当、監視担当者

ClusterRoleBinding はクラスター全体への権限を付与し、RoleBinding は 1 つの namespace に権限を限定します(ClusterRole を参照することもできます)。

よくある 8 つのユースケース​

クラスター全体の管理者​

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: sso-cluster-admins
subjects:
- kind: Group
name: "oidc:gpu-admins"
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io

クラスター全体の読み取り専用アクセス​

use case 1 と同様ですが、roleRef.name: view を使用します。view ClusterRole は Secret の読み取りを意図的に除外しています。

チームが自分の namespace を所有する​

ML チームリーダーには admin、data scientist / ML engineer には edit を割り当てます。

# ML team lead
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: ml-training-leads
namespace: ml-training
subjects:
- kind: Group
name: "oidc:ml-team-lead"
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: admin
apiGroup: rbac.authorization.k8s.io
---
# Data scientists / ML engineers
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: ml-training-users
namespace: ml-training
subjects:
- kind: Group
name: "oidc:ml-team"
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: edit
apiGroup: rbac.authorization.k8s.io

namespace 一覧の表示を許可する​

Namespace はクラスタースコープのリソースのため、RoleBinding だけでは不十分です。

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: namespace-lister
rules:
- apiGroups: [""]
resources: ["namespaces"]
verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: all-users-list-namespaces
subjects:
- kind: Group
name: "system:authenticated"
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: namespace-lister
apiGroup: rbac.authorization.k8s.io
警告

これにより、ログイン済みの全ユーザーにすべての namespace 名が公開されます。

複数チームでクラスターを共有し、GPU クォータを設ける​

RBAC だけでは「どれだけ使えるか」は制限できません — GPU を含む ResourceQuota を組み合わせます。

apiVersion: v1
kind: ResourceQuota
metadata:
name: ml-team-quota
namespace: ml-training
spec:
hard:
requests.cpu: "40"
requests.memory: 160Gi
requests.nvidia.com/gpu: "8"
persistentvolumeclaims: "20"
count/deployments.apps: "50"
警告

複数チームがクラスターを共有する場合、GPU quota は必須です — 設定しないと、1 つの Deployment だけで 1 チームがすべての GPU を占有できてしまいます。

1 種類のリソースに対する狭い権限​

例: on-call 担当者が training pod の log 確認や再起動はできるが、Deployment の編集や Secret の読み取りはできない場合。

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: oncall-responder
rules:
- apiGroups: [""]
resources: ["pods", "pods/log", "events"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["delete"] # restart = delete the pod, the ReplicaSet recreates it
- apiGroups: ["apps"]
resources: ["deployments", "statefulsets"]
verbs: ["get", "list"]

CI/CD では SSO ではなく ServiceAccount を使う​

学習/デプロイの pipeline を定期実行する場合:

kubectl -n ml-training create serviceaccount ci-deployer
kubectl -n ml-training create rolebinding ci-deployer \
--clusterrole=edit --serviceaccount=ml-training:ci-deployer
kubectl -n ml-training create token ci-deployer --duration=24h

Kubernetes 1.24 以降、ServiceAccount は永続的な token を含む Secret を自動生成しなくなりました — create token で生成する token には有効期限があり、より安全です。

人事異動があった場合のアクセス取り消し​

状況対応反映されるタイミング
チームの異動IdP 上の group を変更する次回の token refresh 時
退職IdP 上のアカウントを無効化するtoken の lifetime を上限として
即時に遮断する必要がある場合アカウントを無効化し、かつ session を削除する新しい session からは即時に反映
危険

発行済みの token は取り消せません — bearer token の本質的な制約です。リスクの発生し得る期間は、token の有効期間と同じです。機密性の高いシステムでは、5〜10 分程度に設定することを推奨します。

トラブルシューティング​

401 と 403 の違い — 最初に必ず確認すること​

コード意味問題のある層対応者
401Unauthorized認証 — token が受け付けられないクラスター管理者 / IdP
403Forbidden権限 — token は有効だが権限が不足クラスター管理者(RBAC)
警告

401 が発生している間は RBAC を修正しないでください。401 は、API server がそもそもあなたの identity を認識していないことを意味します — RoleBinding をいくつ追加しても解決しません。

よくあるエラーの一覧​

症状原因対処方法
ログインは成功するのに 401 になるkubeconfig の Issuer URL がクラスターの構成と一致していない、またはクラスターで OIDC が有効になっていないissuer URL を 1 文字ずつ比較する。クラスター管理者に連絡する
403 になるが、whoami の名前は正しいRoleBinding がまだない、または RBAC 上の group 名が一致していないkubectl auth whoami の出力をクラスター管理者に送る
whoami で Groups が空になるIdP が group を token に含める mapper を構成していないIdP 管理者に連絡する
context deadline exceededkubelogin が非対話的な実行でブラウザを待っている--grant-type=device-code を使用する
invalid_scopeIdP が定義していない scope をリクエストしている--oidc-extra-scope=groups を削除する
whoami で想定外の identity が表示されるKUBECONFIG 変数が切り替わっていない$env:KUBECONFIG を使う、または --kubeconfig を渡す
group を変更しても権限が変わらない古い token がまだキャッシュに残っている~/.kube/cache/oidc-login を削除する
invalid_grantパスワードが間違っている、またはアカウントが無効化されているIdP 上のアカウントを確認する
x509: certificate signed by unknown authorityIdP が信頼されていない社内 CA を使用している--certificate-authority=/path/to/ca.crt を追加する
address already in useポート 8000 がすでに使用されている--listen-address=127.0.0.1:8100 を追加し、新しい redirect URI を登録する
Missing parameter: code_challenge_methodIdP が device endpoint で PKCE を必須にしている管理者に PKCE の要件を緩めてもらう、または SSH port forwarding を使用する
could not open the browser: exit status 3エラーではありません — 端末にブラウザがないだけです下に表示される "Please visit..." の行を探し、そのリンクを開いてください

3 つの診断コマンド(順番どおりに)​

# 1. Who does the API server think I am?
kubectl auth whoami

# 2. Can I do this specific thing?
kubectl auth can-i create deployments -n ml-training

# 3. See everything I can do in one namespace
kubectl auth can-i --list -n ml-training

ログイン処理の詳細を確認する​

kubectl oidc-login get-token -v=5 \
--oidc-issuer-url=https://sso.example.com/realms/kubernetes \
--oidc-client-id=kubernetes

token を取得できれば IdP 側は問題なく、問題はクラスター側にあります。取得できない場合は、IdP 側またはそこまでのネットワークに問題があります。

セキュリティチェックリスト​

  • token を含む kubeconfig を共有しない。 OIDC の kubeconfig は機密情報を含まないため、チーム全体に配布しても安全です — ただし、token: や client-key-data: フィールドがすでに含まれているファイルは絶対に配布しないでください。
  • insecure-skip-tls-verify を使わない。 使い捨ての lab 環境以外では使用しないでください。
  • クラスター管理権限を持つアカウントには MFA を有効化する。
  • 共有端末から離れる際は token キャッシュを削除する: rm -rf ~/.kube/cache/oidc-login。
  • 誤った namespace での操作を防ぐため、context に 既定の namespace を設定する。
  • view から始める。 具体的な必要がある場合にのみ権限を上げてください。利便性のために cluster-admin を要求しないでください。
  • 権限は group 単位で割り当て、user 単位では割り当てない。 唯一の例外は break-glass アカウントです。
  • 複数チームでクラスターを共有する場合は、必ず requests.nvidia.com/gpu に ResourceQuota を設定する。 設定しないと、RBAC だけでは 1 チームがすべての GPU を占有することを防げません。
  • break-glass 用の kubeconfig を保管する。 IdP が停止していても、対応のためにクラスターへアクセスできる手段が必要です。安全な場所に保管してください。
  • 定期的に見直す。 四半期ごとに、IdP 上の group メンバーと実際のチーム名簿を照合してください。

このガイドは、Portal を通じて OIDC 認証がすでに有効化されているクラスター(Configure OIDC authentication for the cluster を参照)、および Linux 上で krew 経由で kubelogin をインストールしている環境を前提としています。Identity Provider 自体の構成やクラスターでの OIDC 有効化は、クラスター管理者の責任範囲です — 開始する前に に記載した 4 つの情報については、管理者に問い合わせてください。