kubestronautへの道 ~CKS編 その21 killer coda「RBAC」~

tech article

今日覚えて帰ること

RBAC

  • Role-Based Access Controlの略
  • ユーザー、グループ、サービスアカウントなどに対してきめ細やかな権限を付与することが出来る
  • クラスター単位での権限なのか、 namespace 単位での権限なのかを意識する必要がある

RBAC ServiceAccount Permissions

Control ServiceAccount permissions using RBAC

There are existing Namespaces ns1 and ns2 .

Create ServiceAccount pipeline in both Namespaces.

These SAs should be allowed to view almost everything in the whole cluster. You can use the default ClusterRole view for this.

These SAs should be allowed to create and delete Deployments in their Namespace.

Verify everything using kubectl auth can-i .

serviceaccount(以後SA) に対して権限を付与せよ、と言っています。

それぞれの namespace に SA を作成します。

controlplane $ k -n ns1 create sa pipeline
serviceaccount/pipeline created
controlplane $ k -n ns2 create sa pipeline
serviceaccount/pipeline created

問題で指定されている view という clusterrole が存在するかどうかを確認します。

controlplane $ k get clusterrole view                       
NAME   CREATED AT
view   2024-08-02T07:24:52Z

一つの clusterrolebinding で複数の SA にロールを紐づけることができます。(知りませんでした。)

controlplane $ k create clusterrolebinding pipeline-view --clusterrole view --serviceaccount ns1:pipeline --serviceaccount ns2:pipeline
clusterrolebinding.rbac.authorization.k8s.io/pipeline-view created

clusterrolebinding を確認します。

controlplane $ k get clusterrolebindings.rbac.authorization.k8s.io pipeline-view 
NAME            ROLE               AGE
pipeline-view   ClusterRole/view   2m15s

controlplane $ k describe clusterrolebindings.rbac.authorization.k8s.io pipeline-view 
Name:         pipeline-view
Labels:       <none>
Annotations:  <none>
Role:
  Kind:  ClusterRole
  Name:  view
Subjects:
  Kind            Name      Namespace
  ----            ----      ---------
  ServiceAccount  pipeline  ns1
  ServiceAccount  pipeline  ns2

先ほど作成した SA に対して紐づいていることがわかります。
これでview権限の付与は完了です。

続いて、それぞれの SA が所属する namespace に対して deployments を create, delete する権限を作成します。

さて、ここでRBACについて詳しい説明があったので引用します。

Let’s talk a little about RBAC resources:

ClusterRole|Role defines a set of permissions and where it is available, in the whole cluster or just a single Namespace.

ClusterRoleBinding|RoleBinding connects a set of permissions with an account and defines where it is applied, in the whole cluster or just a single Namespace.

Because of this there are 4 different RBAC combinations and 3 valid ones:

  1. Role + RoleBinding (available in single Namespace, applied in single Namespace)
  2. ClusterRole + ClusterRoleBinding (available cluster-wide, applied cluster-wide)
  3. ClusterRole + RoleBinding (available cluster-wide, applied in single Namespace)
  4. Role + ClusterRoleBinding (NOT POSSIBLE: available in single Namespace, applied cluster-wide)

一見 namespace 単位で挙動を制御する必要があるときは Role + RoleBinding 構成にする必要があるのかな、と思いがちですが、実は ClusterRole + RoleBindingでも同様の制御が可能です。
clusterroleのほうが汎用的に使えるので、namespace 単位で挙動を制御したい場合でも clusterrole を作成することをお勧めします。

と、いうわけでclusterrole を作成します。
作成の仕方に迷う場合は k create clusterrole -h でサンプルを確認します。

オプションで–resourceと–resource-nameが存在します。
–resourceではkindやapiGroupを指定するのに対して、–resource-nameでは実際に存在するリソースに与えた名前(api-podみたいなやつ)を指定します。
ちなみに、kubectl api-resourcesでどのようなapiGroupに属するのか確認することができます。

今回はkindに対して制御を行いたいので–resourceで指定します。 

controlplane $ k create clusterrole pipeline-deployment-manager --verb create,delete --resource deployments
clusterrole.rbac.authorization.k8s.io/pipeline-deployment-manager created

rolebinding を作成します。
clusterrolebinding と違って rolebinding は namespace 単位で適用されるリソースなので個別に作成する必要があります。

controlplane $ k -n ns1 create rolebinding pipeline-deployment-manager --clusterrole pipeline-deployment-manager --serviceaccount ns1:pipeline
rolebinding.rbac.authorization.k8s.io/pipeline-deployment-manager created

controlplane $ k -n ns2 create rolebinding pipeline-deployment-manager --clusterrole pipeline-deployment-manager --serviceaccount ns2:pipeline
rolebinding.rbac.authorization.k8s.io/pipeline-deployment-manager created

これで完了です。

RBAC User Permissions

Control User permissions using RBAC

There is existing Namespace applications .

  1. User smoke should be allowed to create and delete PodsDeployments and StatefulSets in Namespace applications.
  2. User smoke should have view permissions (like the permissions of the default ClusterRole named view ) in all Namespaces but not in kube-system .
  3. User smoke should be allowed to retrieve available Secret names in Namespace applications. Just the Secret names, no data.
  4. Verify everything using kubectl auth can-i .

今度はユーザーに権限を付与しろ、と言っています。

まずは smoke というユーザーに対し、 application という namespace において Pods, Deployments, StatefulSets を create, delete できる権限を付与します。

先ほどの例からわかるように、namespece に限定した権限を付与したい場合だとしても clusterroleで問題ないので clusterrole を作成します。

controlplane $ k create clusterrole smoke --verb=create,delete --resource=pods,deployments,sts   
clusterrole.rbac.authorization.k8s.io/smoke created

controlplane $ k -n applications create rolebinding smoke --clusterrole=smoke --user=smoke   
rolebinding.rbac.authorization.k8s.io/smoke created

これでOKです。

次に smoke というユーザーが kube-system 以外の namespace でview 権限を持つように設定します。
clusterrole でクラスター単位の権限を与え、role で kube-system の制御をするのかなと思いました。
しかし現在 RBAC で拒否ルールを設定することはできないので、地道に namespace ごとに設定していきます。

controlplane $ k get clusterrole view 
NAME   CREATED AT
view   2024-08-02T07:24:52Z
controlplane $ 

controlplane $ k -n applications create rolebinding smoke-view --clusterrole view --user smoke
rolebinding.rbac.authorization.k8s.io/smoke-view created

controlplane $ k -n default create rolebinding smoke-view --clusterrole view --user smoke
rolebinding.rbac.authorization.k8s.io/smoke-view created

controlplane $ k -n kube-node-lease create rolebinding smoke-view --clusterrole view --user smoke
rolebinding.rbac.authorization.k8s.io/smoke-view created

controlplane $ k -n kube-public create rolebinding smoke-view --clusterrole view --user smoke
rolebinding.rbac.authorization.k8s.io/smoke-view created

controlplane $ k -n local-path-storage create rolebinding smoke-view --clusterrole view --user smoke
rolebinding.rbac.authorization.k8s.io/smoke-view created

最後に、secretリソース の名前だけを取り出して、 data にはアクセスできないような権限を付与します。

…….と行きたいところですが、これ実はRBACでは実現不可能らしいです。
list 権限だけを付与すればよいのでは?と思うかもしれませんが、list 権限があると、 -o yaml で中身を全部見ることが出来てしまうらしいです。

ということで、こちらの問題は解なし、でした。
こんなパターンもあるんですね。

タイトルとURLをコピーしました