こちらの本で紹介されているRBACについてkubernetes-dashboardの例を交えながら紹介します。
RBACとは
Role Based Access Controlの略で最近流行ってきてる権限周りの単語です。
誰に何を許可するのか?という意味です。
この図のように、それぞれのユーザー(人)と役割を紐づけて管理するのがRBACです。(一番右の社長っぽい人には全ての役割が紐づいていますね)
KubernetesにおけるRBAC
Kubernetesには様々なリソースが存在します。これらに対してユーザごとに権限を与えたり、お互いのリソース間でやりとりをさせるためにRBACは利用されています。
ちなみにKubernetesではユーザーと役割を紐づけるためにRoleBinding
というものを使って管理しています。
kubernetesのユーザーについて
kuberneteには2種類のUserAccount
とServiceAccount
が存在します。
それぞれの違いは以下の通り
UserAccount
→ 外部のアカウントからkuberneteクラスタを制御する場合のユーザー(AWSのIAMなど)ServiceAccount
→ kubernetesの中で利用するユーザー
そのため基本的にはServiceAccount
を知っておく必要があります。
ServiceAccountのデフォルト値を確認する
httpdのpodを起動して見ましょう。
[root@master k8s-role]# kubectl run httpd-test -o yaml --image httpd apiVersion: v1 kind: Pod metadata: creationTimestamp: "2020-04-13T16:11:11Z" labels: run: httpd-test managedFields: - apiVersion: v1 fieldsType: FieldsV1 fieldsV1: f:metadata: f:labels: .: {} f:run: {} f:spec: f:containers: k:{"name":"httpd-test"}: .: {} f:image: {} f:imagePullPolicy: {} f:name: {} f:resources: {} f:terminationMessagePath: {} f:terminationMessagePolicy: {} f:dnsPolicy: {} f:enableServiceLinks: {} f:restartPolicy: {} f:schedulerName: {} f:securityContext: {} f:terminationGracePeriodSeconds: {} manager: kubectl operation: Update time: "2020-04-13T16:11:11Z" name: httpd-test namespace: default resourceVersion: "139719" selfLink: /api/v1/namespaces/default/pods/httpd-test uid: 176c17d6-d73c-46f4-8db2-e936ff4dfac3 spec: containers: - image: httpd imagePullPolicy: Always name: httpd-test resources: {} terminationMessagePath: /dev/termination-log terminationMessagePolicy: File volumeMounts: - mountPath: /var/run/secrets/kubernetes.io/serviceaccount name: default-token-8b6g2 readOnly: true dnsPolicy: ClusterFirst enableServiceLinks: true priority: 0 restartPolicy: Always schedulerName: default-scheduler securityContext: {} **serviceAccount: default** serviceAccountName: default terminationGracePeriodSeconds: 30 tolerations: - effect: NoExecute key: node.kubernetes.io/not-ready operator: Exists tolerationSeconds: 300 - effect: NoExecute key: node.kubernetes.io/unreachable operator: Exists tolerationSeconds: 300 volumes: - name: default-token-8b6g2 secret: defaultMode: 420 secretName: default-token-8b6g2 status: phase: Pending qosClass: BestEffort
するとserviceAccount: default
とかかれています。これはnamespaceに初めから存在するdefaultのユーザです。
実際にServiceAccountを作ってみる
root@master k8s-role]# kubectl create serviceaccount sample-account serviceaccount/sample-account created [root@master k8s-role]# kubectl get serviceaccount sample-account NAME SECRETS AGE sample-account 1 10s
このように作成できます。そして作成したアカウントを見てみるとsecrets
というものが増えています。
[root@master k8s-role]# kubectl get serviceaccount sample-account -o yaml apiVersion: v1 kind: ServiceAccount metadata: creationTimestamp: "2020-04-13T15:48:52Z" name: test namespace: default resourceVersion: "136799" selfLink: /api/v1/namespaces/default/serviceaccounts/sample-account uid: f62a0897-e232-4989-ba16-28bf245dd7bf **secrets:** **- name: sample-account-token-lhbsd**
これはkubernetesが勝手に作成したものでトークンと証明書です。
[root@master k8s-role]# kubectl get secrets sample-account-token-lhbsd -o yaml apiVersion: v1 data: ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN5RENDQWJDZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJd01EUXhNakV3TXpRME4xb1hEVE13TURReE1ERXdNelEwTjFvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBT214CmdaL0JFY0dWellQaGRuSTBwZlJyamRxdkVoU2c3S0RtTEFNMzc3SXpoT2Jvb1VMU2p2TEZLQU5oOEJGMDJYREEKZ3NaMFBXSmIyTmk1bUI0cXBCYXROWjNkeGdSNjlhbVJ1N3Zibi9USFg0T3lhcHVqNG1KcWFqc0tRQjRQQ3FxYgpYVXladFRKU1cwNXpQWjVrdWNISk93TkF5M1EwdGtJRlkraFRLeTBnL01OS3NHN1RmcDZDNHV4ZG9TRmZ3YmQ1CitmN1J0OHFRVUcwNkJsYmVzcUYvQk5zL2pobTY2SmZLU0Q3c2dDS215VWEvSkhBV09JM09xMURpUS8ybktJMXYKV1VZdjJ3QWE5bTRYVlpMY212dGpBRE4va3FCTlo4R2kyYXhSOTF4cDlkd3l5VkZ5LzdieFZhUUNwcVFqSkFkOApKT3RTaEtvaUNzZ0Vld3pMdTRNQ0F3RUFBYU1qTUNFd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFMaHF0VnVtYkpTOGthYWlCMW5oZGtHWXZNQkIKWWVPUFdRdW95b2w0NkppWUM5b3Q4V0p4S0tmNGU0UVFOUzlPVkI2Umc1M0RWSm9SVXp4NTlqdytOMm84bjJKTwoxQmxZdjd1SlhMWFBrM3FMUnRxaEtDV3g3RHFiU0t5SVJxZ0M4b0JUNnN4eUVManFySGpOL0J4eTE5b0RvYkhMCitBWnZ4NDBwUFB5WHU5b1QyTEFxSE0wZHorM0lBU2E4d1p5bVUrZ0xKQnVPQlZNY2lCc3FvYldUTTVEd1dOeFAKV3kzTHFPdVR4T0ZvTG5RWDg3Rm0vQjhXSVV0bkEwSUxVTWsrc0RoUjRhMDVranFvdWx2Ujd5Rk5EM2ZPdzM2Twp4eGpsNVZxNHpFTVhnam5MUTNmc2pVSnY5bjNqNllDSFlLdjFVQWo2OVI3UlFoMmE3NzNQRWhqRUxhVT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= namespace: ZGVmYXVsdA== token: ZXlKaGJHY2lPaUpTVXpJMU5pSXNJbXRwWkNJNklrc3diVE5KUmpGSFgxSkljbUZRV2tkMFJrVmlZV3hUTVMxdmNUaGFhM0JIWVVObloxUmFjM2xvVFVraWZRLmV5SnBjM01pT2lKcmRXSmxjbTVsZEdWekwzTmxjblpwWTJWaFkyTnZkVzUwSWl3aWEzVmlaWEp1WlhSbGN5NXBieTl6WlhKMmFXTmxZV05qYjNWdWRDOXVZVzFsYzNCaFkyVWlPaUprWldaaGRXeDBJaXdpYTNWaVpYSnVaWFJsY3k1cGJ5OXpaWEoyYVdObFlXTmpiM1Z1ZEM5elpXTnlaWFF1Ym1GdFpTSTZJblJsYzNRdGRHOXJaVzR0YkdoaWMyUWlMQ0pyZFdKbGNtNWxkR1Z6TG1sdkwzTmxjblpwWTJWaFkyTnZkVzUwTDNObGNuWnBZMlV0WVdOamIzVnVkQzV1WVcxbElqb2lkR1Z6ZENJc0ltdDFZbVZ5Ym1WMFpYTXVhVzh2YzJWeWRtbGpaV0ZqWTI5MWJuUXZjMlZ5ZG1salpTMWhZMk52ZFc1MExuVnBaQ0k2SW1ZMk1tRXdPRGszTFdVeU16SXRORGs0T1MxaVlURTJMVEk0WW1ZeU5EVmtaRGRpWmlJc0luTjFZaUk2SW5ONWMzUmxiVHB6WlhKMmFXTmxZV05qYjNWdWREcGtaV1poZFd4ME9uUmxjM1FpZlEuTWZGUERYaXMxZFpjVWtmRV9fczI1NkpKLTNuN3Rfd21qVUdueHY1dHdKTEc5UF9LQVJtTjMyZmRFXzM1QTJRaUh1YUFSRjhfMktzTXhqSXdWbk9KZHlrOXFnblRxbjdfd0xZVFVGNHlNNlNNbUFCLUVKVmdpRWV3YmtqZW1BT3VBUzlfZFY4amxWTzV1ZzN5NkJmY003QTBLT2ZhN3lBdElhTF9GbVhxMkpOaTVDa0NNRUFKbDAxakZkTFJaQ25BNjVjTkFIMjlXZmNaUXpWTkx3ZnVnbVoySXhfQVhjWHVyTHJHNzNKVU5WNE9DdUItOFFfcVozeUNTZldOQ0taUGJJczRxbjMxQmkwb21IdGFMX0c3ZmU3S05qWEZMb18yd2pJZkxxTXFPdWtzYlNLVDRiLWRHaUxqNU1LVk9UbVlBWENPMmh5SzQ5Z1RNZERNVFc1ZXlR kind: Secret metadata: annotations: kubernetes.io/service-account.name: sample-account kubernetes.io/service-account.uid: f62a0897-e232-4989-ba16-28bf245dd7bf creationTimestamp: "2020-04-13T15:48:52Z" managedFields: - apiVersion: v1 fieldsType: FieldsV1 fieldsV1: f:data: .: {} f:ca.crt: {} f:namespace: {} f:token: {} f:metadata: f:annotations: .: {} f:kubernetes.io/service-account.name: {} f:kubernetes.io/service-account.uid: {} f:type: {} manager: kube-controller-manager operation: Update time: "2020-04-13T15:48:52Z" name: sample-account-token-lhbsd namespace: default resourceVersion: "136798" selfLink: /api/v1/namespaces/default/secrets/sample-account-token-lhbsd uid: 757becf9-c427-4b2f-bab8-e2b039348ee8 type: kubernetes.io/service-account-token
ServiceAccount
が割り当てられたリソース(podなど)はこの権限を使ってAPIを叩いたりしています。
つづいて作ったユーザのtokenを見てみましょう。
[root@master k8s-role]# kubectl get secret | grep sample-account sample-account-token-lhbsd kubernetes.io/service-account-token 3 35m [root@master k8s-role]# kubectl describe secret sample-account-token-lhbsd Name: sample-account-token-lhbsd Namespace: default Labels: <none> Annotations: kubernetes.io/service-account.name: sample-account kubernetes.io/service-account.uid: f62a0897-e232-4989-ba16-28bf245dd7bf Type: kubernetes.io/service-account-token Data ==== ca.crt: 1025 bytes namespace: 7 bytes token: eyJhbGciOiJSUzI1NiIsImtpZCI6IkswbTNJRjFHX1JIcmFQWkd0RkViYWxTMS1vcThaa3BHYUNnZ1Rac3loTUkifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6InRlc3QtdG9rZW4tbGhic2QiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoidGVzdCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6ImY2MmEwODk3LWUyMzItNDk4OS1iYTE2LTI4YmYyNDVkZDdiZiIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OnRlc3QifQ.MfFPDXis1dZcUkfE__s256JJ-3n7t_wmjUGnxv5twJLG9P_KARmN32fdE_35A2QiHuaARF8_2KsMxjIwVnOJdyk9qgnTqn7_wLYTUF4yM6SMmAB-EJVgiEewbkjemAOuAS9_dV8jlVO5ug3y6BfcM7A0KOfa7yAtIaL_FmXq2JNi5CkCMEAJl01jFdLRZCnA65cNAH29WfcZQzVNLwfugmZ2Ix_AXcXurLrG73JUNV4OCuB-8Q_qZ3yCSfWNCKZPbIs4qn31Bi0omHtaL_G7fe7KNjXFLo_2wjIfLqMqOuksbSKT4b-dGiLj5MKVOTmYAXCO2hyK49gTMdDMTW5eyQ
この長いのがtokenです。
kubernetes-dashboardでためしてみよう
こちらの記事を参考にkubernetes-dashboardを入れてみましょう。
そして先ほどのtokenでログインしてみます。すると何も表示されないことがわかります。
なぜでしょうか?
これはServiceAccount
に各種リソースをみる権限がないからです。では権限をつけるにはどうすれば良いのか?そこで大事なのがRole
となります。
kubernetesのroleとRoleBindingについて
kubernetesには2種類のRole
とRoleBinding
が存在します。
それぞれの違いは範囲です。
Role
・RoleBinding
→ NameSpace単位で存在Cluster Role
・Cluster RoleBinding
→ クラスター単位で存在
Roleの確認方法
[root@master ~]# kubectl get role -n kube-system NAME CREATED AT extension-apiserver-authentication-reader 2020-04-12T10:35:10Z kube-proxy 2020-04-12T10:35:12Z kubeadm:kubelet-config-1.18 2020-04-12T10:35:10Z kubeadm:nodes-kubeadm-config 2020-04-12T10:35:10Z system::leader-locking-kube-controller-manager 2020-04-12T10:35:10Z system::leader-locking-kube-scheduler 2020-04-12T10:35:10Z system:controller:bootstrap-signer 2020-04-12T10:35:10Z system:controller:cloud-provider 2020-04-12T10:35:10Z system:controller:token-cleaner 2020-04-12T10:35:10Z
ClusterRoleの確認方法
[root@master ~]# kubectl get clusterrole NAME CREATED AT admin 2020-04-12T10:35:09Z calico-kube-controllers 2020-04-12T10:51:45Z calico-node 2020-04-12T10:51:46Z cluster-admin 2020-04-12T10:35:09Z edit 2020-04-12T10:35:09Z kubeadm:get-nodes 2020-04-12T10:35:11Z kubernetes-dashboard 2020-04-13T08:47:51Z system:aggregate-to-admin 2020-04-12T10:35:09Z system:aggregate-to-edit 2020-04-12T10:35:09Z system:aggregate-to-view 2020-04-12T10:35:09Z
RoleやClusterRoleの作成について
ClusterRoleには初めからプリセットと呼ばれるものが存在します
名前 | 内容 |
---|---|
cluster-admin | 全てのリソース操作可能 |
admin | ClusterRoleの編集とNameSpaceレベルのRBAC |
view | Clusterに対するRead/Write権限 |
edit | Clusterに対するReadOnly権限 |
Roleを作ってみる
# ServiceAccount apiVersion: v1 kind: ServiceAccount metadata: name: sample-account namespace: default --- # Role apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: sample-role namespace: default rules: - apiGroups: ["*"] resources: ["*"] verbs: - get - list - watch - create - delete - update --- # RoleBinding apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: sample-rolebinding namespace: default roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: sample-role subjects: - kind: ServiceAccount name: sample-account namespace: default --- # Pod apiVersion: v1 kind: Pod metadata: name: sample-kubectl spec: serviceAccount: sample-account containers: - name: kubectl-container image: lachlanevenson/k8s-kubectl:latest command: ["sleep", "86400"]
kubernetes-dashboardでためしてみよう
こちらの記事を参考にkubernetes-dashboardを入れてみましょう。
そして先ほどのtokenでログインしてみます。すると今度はdefault namespaceの情報が表示されていることがわかります。
割り当てたroleがきちんと効いていることがわかりますね。
つづいてroleをpods
のみ許可するようにかえてみます。
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: sample-role namespace: default rules: - apiGroups: ["*"] resources: - pods verbs: - get - list - watch - create - delete - update
変更したらkubectl apply -f
してあげてください。
すると、このようにpod
しか表示されなくなります。
これは先ほど見えていたリソースには権限がないからですね。
ということで「何を誰に許可するのか?」がRBACということでした。