Oracle Cloud Infrastructure IAMとOracle Kubernetes EngineのUser/Groupってどうなってるの?
はじめに
KubernetesにはAPI Serverにアクセスするユーザ自体の情報を管理する機能はないため、こういったユーザの情報はマネージドサービスであったり別の管理サービスで行います。
各種マネージドK8sでは、そのクラウドベンダが提供するIAM的サービスとKubernetesのRBACとを連携させて管理をすることが多いです。
例えばAWSのEKSであれば、下記のような形でConfigMap上でAWSのUserをKubernetesでのUserに紐づけ、AWSのIAMサービスとKubernetesとの連携を実装しています。
この記事は「Oracle Cloud Infrastructure IAMのUser/GroupとOracle Kubernetes EngineのUser/Groupってどうなってるの」というところを調査した際のメモになります。
※ドキュメント上から読み取れなかった仕様もあるので、ある程度想像の部分があります。
事前知識
次に進む前に、下記に目を通しておくのがお勧めです。
What is client-go credential plugins - gashirar's blog
今回見るのは主に4~5あたりのパラメータになります。
OCI IAM
検証する前に、まずはドキュメントをみてみます。
アクセス制御とContainer Engine for Kubernetesについて
Oracle Cloud Infrastructureテナンシ管理者にはすでに十分な権限があり、クラスタ管理者のクラスタ・ロールは必要ありません。
ここでいう「テナンシ管理者」はどういったユーザを指すのかはっきりしていないため、下記のポリシが付与されたグループに所属するユーザとします。
Allow group <Group> to manage all-resources in tenancy
上記以外のユーザにはOKE側で適切なRole/RoleBindings、ClusterRole/ClusterRoleBindingsを設定してあげる必要がありそうです。
後で検証する際のパターンとして下記はありそうですね。
- テナント管理者
Allow group <Group> to manage all-resources in tenancy
が付与されたグループに所属している
- コンパートメント管理者
Allow group <Group> to manage all-resources in compartment <Compartment>
が付与されたグループに所属している
- 通常の開発者
Allow group <Group> to use all-resources in compartment <Compartment>
が付与されたグループに所属している
- どのグループにも所属していない開発者
- どのグループにも所属していない
OKE
OKE側についてはKubernetesのAuthN Webhookで認証処理が行われているものとみてよさそうです。
The remote service is expected to fill the status field of the request to indicate the success of the login. The response body's spec field is ignored and may be omitted. A successful validation of the bearer token would return:
{ "apiVersion": "authentication.k8s.io/v1beta1", "kind": "TokenReview", "status": { "authenticated": true, "user": { "username": "janedoe@example.com", "uid": "42", "groups": [ "developers", "qa" ], "extra": { "extrafield1": [ "extravalue1", "extravalue2" ] } } } }
上記例のような形でOCI IAMから.status.user
が返ってくるはずなので、その値を見てみます。
検証
検証内容
やる内容としては
- テナント管理者
Allow group <Group> to manage all-resources in tenancy
が付与されたグループに所属している
- コンパートメント管理者
Allow group <Group> to manage all-resources in compartment <Compartment>
が付与されたグループに所属している
- 通常の開発者
Allow group <Group> to use all-resources in compartment <Compartment>
が付与されたグループに所属している
- どのグループにも所属していない開発者
- どのグループにも所属していない
に対して、どのようなUser/GroupがKubernetes側にわたってくるかを調べます。
検証方法
2020年6月現在、Master側のログ出力やAuditの確認はできないため、KubernetesのTokenReview
を使ってUser/Groupを取得してみます。
流れとしては下記の形です
oci ce cluster generate-token
でtokenを取得- tokenを使ってAPI Serverに対して
TokenReview
をリクエスト - TokenReviewの戻り値のUser/Groupを確認
コマンドだと下記。
USER_TOKEN=$(oci ce cluster generate-token --cluster-id <Cluster ID> --region <Region> | jq -r '.status.token') echo $USER_TOKEN curl --insecure \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${USER_TOKEN}" \ -d '{"apiVersion": "authentication.k8s.io/v1","kind": "TokenReview","spec": {"token": "'"${USER_TOKEN}"'"}}' \ https://<API Server>/apis/authentication.k8s.io/v1/tokenreviews
検証作業
テナント管理者
コマンド実行結果
{ "kind": "TokenReview", "apiVersion": "authentication.k8s.io/v1", "spec": { "token": <TOKEN> }, "status": { "authenticated": true, "user": { "username": "<User OCID>", "uid": "<User OCID>", "groups": [ "<Compartment OCID>", "system:masters", "system:authenticated" ], "extra": { "AuthType": [ "Native" ], "ContextType": [ "OCI" ], "TenancyID": [ "<Tenancy OCID>" ], "TokenV2": [ "true" ] } } } }
User | Group |
---|---|
User OCID | Compartment OCID / system:masters / system:authenticated |
コンパートメント管理者
コマンド実行結果
{ "kind": "TokenReview", "apiVersion": "authentication.k8s.io/v1", "spec": { "token": <TOKEN> }, "status": { "authenticated": true, "user": { "username": "<User OCID>", "uid": "<User OCID>", "groups": [ "<Compartment OCID>", "system:masters", "system:authenticated" ], "extra": { "AuthType": [ "Native" ], "ContextType": [ "OCI" ], "TenancyID": [ "<Tenancy OCID>" ], "TokenV2": [ "true" ] } } } }
User | Group |
---|---|
User OCID | Compartment OCID / system:masters / system:authenticated |
テナント管理者と同じですね。
通常の開発者
コマンド実行結果
{ "kind": "Status", "apiVersion": "v1", "metadata": { }, "status": "Failure", "message": "Unauthorized", "reason": "Unauthorized", "code": 401 }
TokenReview
を叩けないRBACになっているかもなので、一時的にsystem:authenticated
にもcluster-admin
を付与。
{ "kind": "TokenReview", "apiVersion": "authentication.k8s.io/v1", "spec": { "token": <TOKEN> }, "status": { "authenticated": true, "user": { "username": "<User OCID>", "uid": "<User OCID>", "groups": [ "<Compartment OCID>", "system:authenticated" ], "extra": { "AuthType": [ "Native" ], "ContextType": [ "OCI" ], "TenancyID": [ "<Tenancy OCID>" ], "TokenV2": [ "true" ] } } } }
User | Group |
---|---|
User OCID | Compartment OCID / system:authenticated |
system:masters
Groupがなくなりました。
どのグループにも所属していない開発者
{ "kind": "Status", "apiVersion": "v1", "metadata": { }, "status": "Failure", "message": "Unauthorized", "reason": "Unauthorized", "code": 401 }
system:authenticated
/system:unauthenticated
もcluster-admin
に入れてみましたがダメそうです。
動きとしては真っ当な気もします。
User | Group |
---|---|
- | - |
検証結果
OCI Policy | K8s User | K8s Group |
---|---|---|
to manage all-resources in tenancy | User OCID | Compartment OCID / system:masters / system:authenticated |
to manage all-resources in compartment | User OCID | Compartment OCID / system:masters / system:authenticated |
to use all-resources in compartment | User OCID | Compartment OCID / system:authenticated |
なし | - | - |
まとめ
- OCI IAMからOKEに渡される
- UserはOCI IAMのUser OCID
- GroupはCompartment OCID/
system:authenticated
でPolicyによってsystem:masters
も付与
- OCI IAMのどのグループにも属さないUserはOKEへのアクセス不可
疑問とTODO
OKEにkubectlでアクセスするための最低限のPolicyってなに?
管理者としては各開発者のOCI権限は最小限にしたいですが、みたところuse以上を渡さないとOKEにはアクセスできないように見えます。(readも試したけどNGっぽい)
all-resources
でなくてcluster-family
とかcluster
に絞っていけば最低限のところがわかる気はしますが、ちょっと組み合わせが多そうなのでどうしようか考え中。
GroupでRBACかけられない?
OCI IAM由来のGroupはCompartment OCIDのみなので、RBACでいろいろやりたいときにはUser OCIDに紐づけてやらないといけない感じでしょうか。
AWSだとauth-config
ConfigMapでGroupかけるっぽいので似たような仕組みは欲しい所。