--- title: Kubernetesハンズオン - 10. RBACによるKubernetes APIアクセス制御 tags: ["Kubernetes Handson", "Kubernetes", "PKS"] categories: ["Dev", "CaaS", "Kubernetes"] date: 2020-01-13T13:43:16Z updated: 1970-01-01T00:00:00Z --- Kubernetesに対する操作はMaster NodeのAPI Serverに対して行われます。 このAPIアクセスを制限するためにRBAC(Roll Based Access Control)の仕組みが備わっています。 KubernetesのRBACでは、どのリソース(Pod, ReplicaSet, Deployment, Serviceなど)にどの操作(get, list, create, deleteなど)を許可するかを表現する * Role * ClusterRole というリソースが用意されています。 Roleは特定の名前空間配下に適用されます。一方ClusterRoleは名前空間に関係なくKuberntesクラスタ全体に適用されます。 ClusterRoleはリソース以外に、ノードなどのクラスタスコープのリソースや`/healthz`などの非リソースへのアクセスも制御対象とできます。 Role/ClusterRoleをバインドするSubject(対象)としては次の3種類があります。 * User * Group * ServiceAccount UserはKubernetes APIにアクセスする人間を指します。GroupはUserをグルーピング化したものです。 一方、ServiceAccountはKubernetes APIにアクセスするコンテナ上のプロセスを想定します。ServiceAccountは名前空間に対して作成されます。 Kubernetesにはユーザーやグループの作成機能はありません。ユーザー/グループの管理は外部システムに移譲し、OpenID Connect等で連携されます。 本ドキュメントではServiceAccountのみ扱います。 RoleをSubjectにバインドするために * RoleBinding * ClusterRoleBinding というリソースが用意されています。 RoleBindingは、特定の名前空間のリソースに対するRoleまたはClusterRoleをSubjectにバインドします。 ClusterRoleBindingは、任意の名前空間のリソースやクラスタスコープのリソース、`/healthz`などの非リソースに対するClusterRoleをSubjectにバインドします。 RBACは許可するルールを追加するホワイトリスト方式です。アクセスを拒否するルールは指定できません。 **目次** ### curlコマンドでKubernetes APIにアクセス RBACを説明するために、Kubernetes APIにアクセスする最もシンプルなクライアントとして、`curl`コマンドを利用します。 Kubernetes APIは`kubernetes`と名前のServiceとして`default`名前空間に公開されています。 ``` kubectl get svc kubernetes -n default ``` 出力結果 ``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.11.240.1 443/TCP 170d ``` 内部DNS(KubeDNS)を使うことでHost名`kubernetes.default.svc.cluster.local`でPodのコンテナ内から次のようにアクセス可能です。 ``` curl --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \ -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \ https://kubernetes.default.svc.cluster.local ``` `/var/run/secrets/kubernetes.io/serviceaccount/ca.crt`にはKubernetes APIのCA証明書、 `/var/run/secrets/kubernetes.io/serviceaccount/token`にはPodにアサインされたServiceAccountのトークン(JWT)がマウントされます。 まず始めに、作業する名前空間として`demo-pks`を作成します。 `demo-pks-ns.yml`を作成して次の内容を記述してください。 ```yaml apiVersion: v1 kind: Namespace metadata: name: demo-pks ``` 次のコマンドで`demo-pks`名前空間を作成してください。 ``` kubectl apply -f demo-pks-ns.yml ``` 出力結果 ``` namespace "demo-pks" created ``` 次に`curl`コマンドが含まれるPodを`demo-pks`名前空間にデプロイします。 `curl.yml`を作成して次の内容を記述してください。 ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: curl namespace: demo-pks spec: replicas: 1 selector: matchLabels: app: curl template: metadata: labels: app: curl spec: containers: - image: tutum/curl name: sleep command: - sh - -c - | while true;do sleep 1;done ``` プロセスが終了しないように無限に`sleep`させています。 次のコマンドでデプロイしてください。 ``` kubectl apply -f curl.yml ``` 出力結果 ``` deployment "curl" created ``` 次のコマンドで`demo-pks`名前空間のPod一覧を確認してください。 ``` kubectl get pod -n demo-pks ``` 出力結果 ``` NAME READY STATUS RESTARTS AGE curl-997d489df-8lvqp 1/1 Running 0 7s ``` 次のコマンドでコンテナ上のbashを実行してください。 ``` kubectl exec -n demo-pks -ti $(kubectl get pod -n demo-pks -l app=curl -o jsonpath='{.items[?(@.status.phase=="Running")].metadata.name}') /bin/bash ``` コンテナ上のbashから、次のコマンドを実行し、`demo-pks`名前空間のPod一覧を取得するAPIにアクセスてください。 ``` curl --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \ -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \ https://kubernetes.default.svc.cluster.local/api/v1/namespaces/demo-pks/pods ``` 出力結果 ```json { "kind": "Status", "apiVersion": "v1", "metadata": { }, "status": "Failure", "message": "pods is forbidden: User \"system:serviceaccount:demo-pks:default\" cannot list pods in the namespace \"demo-pks\"", "reason": "Forbidden", "details": { "kind": "pods" }, "code": 403 } ``` `exit`を実行してコンテナ上のbashを終了してください。 デフォルトでは`default`という名前のServiceAccountが使用されます。 次のコマンドで`demo-pks`名前空間のServiceAccountを確認出来ます。 ``` kubectl get serviceaccount -n demo-pks ``` 出力結果 ``` NAME SECRETS AGE default 1 4m ``` `default` ServiceAccountは**Kubernetes APIにアクセスする権限がありません**。そのため、403エラーが返りました。 ### ServiceAccount、Role、RoleBindingの作成 `demo-pks`名前空間のPod一覧を取得できるように`demo-sa`という名前のServiceAccountを作成し、`demo-reader`という名前のRoleをバインドします。 `demo-rbac.yml`を作成し、次の内容を記述してください。 ```yaml apiVersion: v1 kind: ServiceAccount metadata: name: demo-sa namespace: demo-pks --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: demo-reader namespace: demo-pks rules: - apiGroups: - "" # "" indicates the core API group resources: - pods verbs: - get - watch - list --- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: RoleBinding metadata: name: demo-sa-binding namespace: demo-pks roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: demo-reader subjects: - kind: ServiceAccount name: demo-sa namespace: demo-pks ``` 次のコマンドを実行し、ServiceAccount、RoleそしてRoleBindingを作成してください。 ``` kubectl apply -f demo-rbac.yml ``` 出力結果 ``` serviceaccount "demo-sa" created role "demo-reader" created rolebinding "demo-sa-binding" created ``` Podがこの`demo-sa` ServiceAccountを使うように`curl.yml`を次のように修正してください。 ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: curl namespace: demo-pks spec: replicas: 1 selector: matchLabels: app: curl template: metadata: labels: app: curl spec: serviceAccountName: demo-sa # 追加 containers: - image: tutum/curl name: sleep command: - sh - -c - | while true;do sleep 1;done ``` 次のコマンドを実行し、Podを更新してください。 ``` kubectl apply -f curl.yml ``` 出力結果 ``` deployment "curl" configured ``` 次のコマンドでコンテナ上の再度bashを実行してください。 ``` kubectl exec -n demo-pks -ti $(kubectl get pod -n demo-pks -l app=curl -o jsonpath='{.items[?(@.status.phase=="Running")].metadata.name}') /bin/bash ``` コンテナ上のbashから、次のコマンドを実行し、`demo-pks`名前空間のPod一覧を取得するAPIにアクセスてください。 ``` curl --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \ -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \ https://kubernetes.default.svc.cluster.local/api/v1/namespaces/demo-pks/pods ``` 出力結果 ```json { "kind": "PodList", "apiVersion": "v1", "metadata": { "selfLink": "/api/v1/namespaces/demo-pks/pods", "resourceVersion": "139492" }, "items": [ { ... } ] } ``` `demo-reader` RoleにはPodの読み取り権限しかないため、例えばService一覧取得APIにはアクセスできません。 コンテナ上のbashから、次のコマンドを実行し、`demo-pks`名前空間のService一覧を取得するAPIにアクセスてください。 ``` curl --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \ -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \ https://kubernetes.default.svc.cluster.local/api/v1/namespaces/demo-pks/services ``` 出力結果 ```json { "kind": "Status", "apiVersion": "v1", "metadata": { }, "status": "Failure", "message": "services is forbidden: User \"system:serviceaccount:demo-pks:demo-sa\" cannot list services in the namespace \"demo-pks\"", "reason": "Forbidden", "details": { "kind": "services" }, "code": 403 } ``` `exit`を実行してコンテナ上のbashを終了してください。 `demo-rbac.yml`を次のように修正して、Serviceリソースに対する読み取り権限を追加してください。 ```yaml # ... apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: demo-reader rules: - apiGroups: - "" # "" indicates the core API group resources: - pods - services # 追加 verbs: # ... ``` 次のコマンドを実行し、Roleを更新してください。 ``` kubectl apply -f demo-rbac.yml ``` 出力結果 ``` serviceaccount "demo-sa" unchanged role "demo-reader" configured rolebinding "demo-sa-binding" unchanged ``` 次のコマンドでコンテナ上の再度bashを実行してください。 ``` kubectl exec -n demo-pks -ti $(kubectl get pod -n demo-pks -l app=curl -o jsonpath='{.items[?(@.status.phase=="Running")].metadata.name}') /bin/bash ``` コンテナ上のbashから、次のコマンドを実行し、`demo-pks`名前空間のService一覧を取得するAPIにアクセスてください。 ``` curl --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \ -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \ https://kubernetes.default.svc.cluster.local/api/v1/namespaces/demo-pks/services ``` 出力結果 ```json { "kind": "ServiceList", "apiVersion": "v1", "metadata": { "selfLink": "/api/v1/namespaces/demo-pks/services", "resourceVersion": "140006" }, "items": [] } ``` Roleが拡張されたことを確認できました。 ### ClusterRoleの利用 Roleは名前空間毎に作成する必要があります。各リソースに対するアクセス制御を名前空間毎に作成するのは手間がかかります。 同一クラスタ内であればどの名前空間でも利用できるRoleがClusterRoleです。 ClusterRoleはRole同様に自分で作成しても良いですし、予め用意されているものを使用しても良いです。 次のコマンドを実行して、作成ずみのClusterRole一覧を確認してください。 ``` kubectl get clusterrole ``` 出力結果 ``` NAME AGE admin 2d cluster-admin 2d edit 2d kubo:internal:kubelet-drain 2d kubo:route-sync 2d nginx-ingress-clusterrole 22h system:aggregate-to-admin 2d system:aggregate-to-edit 2d system:aggregate-to-view 2d system:auth-delegator 2d system:aws-cloud-provider 2d system:basic-user 2d system:certificates.k8s.io:certificatesigningrequests:nodeclient 2d system:certificates.k8s.io:certificatesigningrequests:selfnodeclient 2d system:controller:attachdetach-controller 2d system:controller:certificate-controller 2d system:controller:clusterrole-aggregation-controller 2d system:controller:cronjob-controller 2d system:controller:daemon-set-controller 2d system:controller:deployment-controller 2d system:controller:disruption-controller 2d system:controller:endpoint-controller 2d system:controller:generic-garbage-collector 2d system:controller:horizontal-pod-autoscaler 2d system:controller:job-controller 2d system:controller:namespace-controller 2d system:controller:node-controller 2d system:controller:persistent-volume-binder 2d system:controller:pod-garbage-collector 2d system:controller:pv-protection-controller 2d system:controller:pvc-protection-controller 2d system:controller:replicaset-controller 2d system:controller:replication-controller 2d system:controller:resourcequota-controller 2d system:controller:route-controller 2d system:controller:service-account-controller 2d system:controller:service-controller 2d system:controller:statefulset-controller 2d system:controller:ttl-controller 2d system:discovery 2d system:heapster 2d system:kube-aggregator 2d system:kube-controller-manager 2d system:kube-dns 2d system:kube-scheduler 2d system:node 2d system:node-bootstrapper 2d system:node-problem-detector 2d system:node-proxier 2d system:persistent-volume-provisioner 2d view ``` `system:`から始まるものは特定のコンポーネントで利用されるClusterRoleです。 次の4つが汎用的に利用可能なClusterRoleです。 * `cluster-admin` * `admin` * `edit` * `view` それぞれの説明は[ドキュメント](https://kubernetes.io/docs/admin/authorization/rbac/#user-facing-roles)を確認してください。 ここでは多くのリソースの読み取り権限をもつ`view` ClusterRoleを`demo-sa` ServiceAccountにバインドします。 `demo-sa-edit-binding.yml`を作成して、次の内容を記述してください。 ```yaml apiVersion: rbac.authorization.k8s.io/v1beta1 kind: RoleBinding metadata: name: demo-sa-edit-binding namespace: demo-pks roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: view subjects: - kind: ServiceAccount name: demo-sa namespace: demo-pks ``` 次のコマンドでRoleBindingを作成してください。 ``` kubectl apply -f demo-sa-edit-binding.yml ``` 出力結果 ``` rolebinding "demo-sa-edit-binding" created ``` 次のコマンドでコンテナ上の再度bashを実行してください。 ``` kubectl exec -n demo-pks -ti $(kubectl get pod -n demo-pks -l app=curl -o jsonpath='{.items[?(@.status.phase=="Running")].metadata.name}') /bin/bash ``` コンテナ上のbashから、次のコマンドを実行し、`demo-pks`名前空間のDeployment一覧を取得するAPIにアクセスてください。 ``` curl --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \ -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \ https://kubernetes.default.svc.cluster.local/apis/extensions/v1beta1/namespaces/demo-pks/deployments ``` 出力結果 ```json { "kind": "DeploymentList", "apiVersion": "extensions/v1beta1", "metadata": { "selfLink": "/apis/extensions/v1beta1/namespaces/demo-pks/deployments", "resourceVersion": "142427" }, "items": [ { ... } ] } ``` アクセスできるAPIが増えたことが分かります。 ただし、ClusterRoleを使っても、RoleBindingの範囲は依然として特定の名前空間に限られます。 例えば同じPod一覧取得でも名前空間が異なる場合はアクセスできません。次のコマンドで`kube-system`名前空間のPod一覧を取得するAPIにアクセスてください。 ``` curl --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \ -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \ https://kubernetes.default.svc.cluster.local/api/v1/namespaces/kube-system/pods ``` 出力結果 ```json { "kind": "Status", "apiVersion": "v1", "metadata": { }, "status": "Failure", "message": "pods is forbidden: User \"system:serviceaccount:demo-pks:demo-sa\" cannot list pods in the namespace \"kube-system\"", "reason": "Forbidden", "details": { "kind": "pods" }, "code": 403 } ``` `demo-sa-edit-binding`は削除してください。 ``` kubectl delete -f demo-sa-edit-binding.yml ``` 出力 ``` rolebinding "demo-sa-edit-binding" deleted ``` ### ClusterRoleBindingの作成 名前空間に限定せずにAPIアクセスを許可するにはRoleBindingではなく、ClusterRoleBindingを作成する必要があります。 `demo-sa-clusterrole-binding.yml`を作成して、次の内容を記述してください。 ```yaml apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: name: demo-sa-clusterrole-binding roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: view subjects: - kind: ServiceAccount name: demo-sa namespace: demo-pks ``` 次のコマンドでClusterRoleBindingを作成してください。 ``` kubectl apply -f demo-sa-clusterrole-binding.yml ``` 出力結果 ``` clusterrolebinding "demo-sa-clusterrole-binding" created ``` 次のコマンドでコンテナ上の再度bashを実行してください。 ``` kubectl exec -n demo-pks -ti $(kubectl get pod -n demo-pks -l app=curl -o jsonpath='{.items[?(@.status.phase=="Running")].metadata.name}') /bin/bash ``` コンテナ上のbashから、次のコマンドを実行し、`kube-system`名前空間のPod一覧を取得するAPIにアクセスてください。 ``` curl --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \ -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \ https://kubernetes.default.svc.cluster.local/apis/extensions/v1beta1/namespaces/demo-pks/deployments ``` 出力結果 ```json { "kind": "PodList", "apiVersion": "v1", "metadata": { "selfLink": "/api/v1/namespaces/kube-system/pods", "resourceVersion": "143487" }, "items": [ { ... } ] } ``` ClusterRoleBindingを使うことで、外の名前空間に対してもアクセスできました。 ClusterRoleBindingは影響範囲が大きいため、基本的にはシステムコンポーネントに対してのみ利用してください。 `demo-sa-clusterrole-binding`は削除してください。 ``` kubectl delete -f demo-sa-clusterrole-binding.yml ``` 出力結果 ``` clusterrolebinding "demo-sa-clusterrole-binding" deleted ``` ### kubectlコマンドのRBAC `kubectl`コマンド自体もAPI Serverに対するアクセスであるため、 ServiceAccountを使って`kubectl`コマンドのRBACを行えます。 ServiceAccountを作成するとSecretにTokenが作成されます。 このTokenを使うことで`kubectl`がアクセスできるAPIを、ServiceAccountにバインドされているClusterRoleおよびRoleが許可されているもののみに制限できます。 PKS 1.0ではOpenID Connectによるユーザー認証がサポートされておらず、`pks get-credentials`で取得した認証情報を使うと 管理者権限が与えられます。 一つのKubernetesクラスタを複数のプロジェクトで共有する場合で、**名前空間毎にユーザーのアクセスを制限したい**場合は、 `pks get-credentials`で取得した認証情報を共有するのではなく、ServiceAccountのTokenを使ってください。 特定のServiceAccountに対するKubernetesのConfigファイルは次のスクリプトで作成できます。 `create-sa-kubeconfig.sh`を作成して、次の内容を記述してください。 ```bash #!/bin/bash set -e NAMESPACE=$1 SERVICE_ACCOUNT=$2 SECRET_NAME=${SERVICE_ACCOUNT}-token cat < /dev/null apiVersion: v1 kind: Secret metadata: name: ${SECRET_NAME} annotations: kubernetes.io/service-account.name: "${SERVICE_ACCOUNT}" type: kubernetes.io/service-account-token EOF TOKEN=`kubectl get secret ${SECRET_NAME} -n ${NAMESPACE} -o 'jsonpath={.data.token}' | base64 --decode` CREDENTIALS_NAME="${NAMESPACE}:${SERVICE_ACCOUNT}" kubectl config set-credentials ${CREDENTIALS_NAME} --token=${TOKEN} > /dev/null CURRENT_CLUSTER=`kubectl config view --minify=true -o jsonpath='{.clusters[0].name}'` CONTEXT_NAME="${CURRENT_CLUSTER}:${CREDENTIALS_NAME}" kubectl config set-context ${CONTEXT_NAME} \ --cluster=${CURRENT_CLUSTER} \ --namespace=${NAMESPACE} \ --user=${CREDENTIALS_NAME} > /dev/null CURRENT_CONTEXT=`kubectl config current-context` kubectl config use-context ${CONTEXT_NAME} > /dev/null kubectl config view --minify=true --raw=true kubectl config use-context ${CURRENT_CONTEXT} > /dev/null if [ "$3" != "--keep" ];then kubectl config delete-context ${CONTEXT_NAME} > /dev/null kubectl config unset "users.${CREDENTIALS_NAME}" > /dev/null fi ``` `demo-pks`名前空間の`demo-sa` ServiceAccountでログインするConfigファイルは次のコマンドで作成できます。 ``` chmod +x create-sa-kubeconfig.sh ./create-sa-kubeconfig.sh demo-pks demo-sa ``` 出力結果(例) ```yaml apiVersion: v1 clusters: - cluster: certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKRENDQWd5Z0F3SUJBZ0lVSVEwb1hTMllLanpBZVJqU0RHUVZ5NU4xSEEwd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0RURUxNQWtHQTFVRUF4TUNZMkV3SGhjTk1UZ3dOVEV5TURZMU5UUTNXaGNOTVRrd05URXlNRFkxTlRRMwpXakFOTVFzd0NRWURWUVFERXdKallUQ0NBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCCkFNRGRvczI1ZjBSMVVtVGttQ0hQYXhKdFlFUXc4Tjhia1IwRVVNcktPUkQ3U0Q3bzFxbnh3NmM1Ujg3VURmLzgKc1Q3RFZsMzkxL1c2T0IySlgyUFU1YzY0Ymt1Mll6Zmt4Yk1qdGxCeTRQd1VVODlia1JQUnluTjFNTU9icFc2cQpWTTgrUGZDV1Z1OWNaUEV3K3dSL0dGQjc3Rzg4RXlKQnVmYjJmT0p6Z1hCemllaTB3Tk5ydTR1T21QaE5CZ2VQCkhONVBReDlsaE5HZ1BhcGV1UGthalR4cUd6NzBEN0pQRDRKSUljdkFSdWs0cnhZbDVGbHZNN05GRU9ZR3dFb2wKeDdxeDMrWUJsZnB2STFNSVdtcHFyZGR0SUd3aDhJK0UrOElkM2ZOUWNyZHpRUU5JdlVDT1d4MWVHRStEUndqQwpCbHRPTnp3dEh2dXNHNDZ2TWFDNDUwOENBd0VBQWFOOE1Ib3dIUVlEVlIwT0JCWUVGTlVTOWhuU0ZLZWtoZmcwClZKYVMyUnpwd0xBSU1FZ0dBMVVkSXdSQk1EK0FGTlVTOWhuU0ZLZWtoZmcwVkphUzJSenB3TEFJb1JHa0R6QU4KTVFzd0NRWURWUVFERXdKallZSVVJUTBvWFMyWUtqekFlUmpTREdRVnk1TjFIQTB3RHdZRFZSMFRBUUgvQkFVdwpBd0VCL3pBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQVFFQVY4dnhOS2xxQUp4SThBYmt3aitWVWpQaGh6RCt1a0dwCm80Z2k3T2VzL3BwKytjOEV3UXJpVkswRDZhQU9UNlFzZlRsRi9PQ0tEd3Z6QnNRN3Z6N3hob2t1KzNDRk12TnAKbzZWYjlWVDk4c3ZBYTNsOXI4bEtBT3ZqVjh5U1E3MnlJMDI3c0xjb0kwb3V6VkVaVk1RdlJQa0M5R3VZZTRhZApTVC8wK1R5OWtFQ0psajlxRkNaNlFsdHpkcmV1emMyc3cwYzZHTFNucXJaTk1pZzRkL2RPQU5YTjBGZGVWc2FzCjVvMjg4R2VmUk1oTFVSTnNQK1MrSkw5MnhndTc3NjRDWU1FZkltai9FdCthRUpHU0RkQm1QQXNneWM5YVhtQ2YKTGRZWE5wYTVKQ1pqeWhieHl3OVVMZ2Z1RU1maWFKdkoyYTAvek16N01pc04rVkRtY3lpRFNRPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQoK server: https://10.244.1.92:8443 name: cfcr contexts: - context: cluster: cfcr namespace: demo-pks user: demo-pks:demo-sa name: cfcr:demo-pks:demo-sa current-context: cfcr:demo-pks:demo-sa kind: Config preferences: {} users: - name: demo-pks:demo-sa user: token: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZW1vLXBrcyIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkZW1vLXNhLXRva2VuLWZoem5nIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImRlbW8tc2EiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiI0ZjU2ZjAyMy01ODU2LTExZTgtODNhYy05YTc3OWNjODlkNGUiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6ZGVtby1wa3M6ZGVtby1zYSJ9.dEBjSabWlIda27uIEUd8YWYdaDA6azuHYke5tDkEL0Hoin0vNu32TWzy0-3PBt8qNvNzQgbd-dVhkAojtpCjnqlcYz0RyAWVgTTnoJ6lLThajZEK-MI--yG9DUNiD1cbFCLca52g7BNriXbV3RKnHTvrvf8Y_jAx35heESXZLmI7cEkZ7BUTPwLGiHCKmY287orVep2Z0-JvNnUartxOHvf6WgG_POru-66uoo3uKXEcrAX7rKzTVJDRidAaNv2mmIJJezJbV6kgH2bgY5xXIzN9La6bmDOuWYdI6jsw2fWmlzsx-SuxVLZCD475oJjKxugcCv9Qo1mNimwNOxwj2w ``` このファイルを`~/.kube/config`にコピーするか、別のパスに保存し、環境変数`KUBECONFIG`にそのパスを設定した上で`kubectl`コマンドを使用すれば、 ServiceAccountのTokenで認証されます。 `demo-sa` ServiceAccountには`demo-pks`名前空間のPod読み取り権限は与えられているので、次のようにPod一覧は確認できます。 ``` ./create-sa-kubeconfig.sh demo-pks demo-sa > /tmp/demo-sa.yml KUBECONFIG=/tmp/demo-sa.yml kubectl get pod ``` 出力結果 ``` NAME READY STATUS RESTARTS AGE curl-5b5b789f7f-dgjbx 1/1 Running 0 3m ``` ただし、削除はできません。 ``` KUBECONFIG=/tmp/demo-sa.yml kubectl delete pod --all ``` 出力結果 ``` Error from server (Forbidden): pods "curl-5b5b789f7f-dgjbx" is forbidden: User "system:serviceaccount:demo-pks:demo-sa" cannot delete pods in the namespace "demo-pks" ``` その他、`kubectl get node`等も制限されています。 ``` KUBECONFIG=/tmp/demo-sa.yml kubectl get node ``` 出力結果 ``` Error from server (Forbidden): nodes is forbidden: User "system:serviceaccount:demo-pks:demo-sa" cannot list nodes at the cluster scope ``` プロジェクト毎に名前空間を作る場合は、例えばServiceAccountに`edit` ClusterRoleをバインドし、 Configファイルを作成してプロジェクト内の開発者に配布すればプロジェクト毎のアクセスを制限できます。 また、CIツールでKubernetesにアプリケーションをデプロイしたい場合に、CIツールに設定するConfigファイルも同様に作成可能です。