IK.AM

@making's tech note


Kubernetesハンズオン - 10. RBACによるKubernetes APIアクセス制御

🗃 {Dev/CaaS/Kubernetes}
🏷 Kubernetes 🏷 Kubernetes Handson 🏷 PKS 
🗓 Updated at 2022-11-08T07:28:22Z  🗓 Created at 2020-01-13T13:43:16Z {✒️️ Edit  ⏰ History  🗑 Delete}  🌎 Translation by Google

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   <none>        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を作成して次の内容を記述してください。

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を作成して次の内容を記述してください。

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

出力結果

{
  "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を作成し、次の内容を記述してください。

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を次のように修正してください。

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

出力結果

{
  "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

出力結果

{
  "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リソースに対する読み取り権限を追加してください。

# ...
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

出力結果

{
  "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

それぞれの説明はドキュメントを確認してください。

ここでは多くのリソースの読み取り権限をもつview ClusterRoleをdemo-sa ServiceAccountにバインドします。

demo-sa-edit-binding.ymlを作成して、次の内容を記述してください。

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

出力結果

{
  "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

出力結果

{
  "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を作成して、次の内容を記述してください。

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

出力結果

{
  "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を作成して、次の内容を記述してください。

#!/bin/bash
set -e

NAMESPACE=$1
SERVICE_ACCOUNT=$2
SECRET_NAME=${SERVICE_ACCOUNT}-token
cat <<EOF | kubectl apply -n ${NAMESPACE} -f - > /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

出力結果(例)

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ファイルも同様に作成可能です。