gashirar's blog

ウイスキーがすき/美味しいものがすき/k8sがすき

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との連携を実装しています。

docs.aws.amazon.com

この記事は「Oracle Cloud Infrastructure IAMのUser/GroupとOracle Kubernetes EngineのUser/Groupってどうなってるの」というところを調査した際のメモになります。

※ドキュメント上から読み取れなかった仕様もあるので、ある程度想像の部分があります。

事前知識

次に進む前に、下記に目を通しておくのがお勧めです。

Authenticating - Kubernetes

What is client-go credential plugins - gashirar's blog

今回見るのは主に4~5あたりのパラメータになります。

f:id:gashirar:20200616085111p:plain

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で認証処理が行われているものとみてよさそうです。

Authenticating | Kubernetes

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の確認はできないため、KubernetesTokenReviewを使って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:unauthenticatedcluster-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かけるっぽいので似たような仕組みは欲しい所。