(O+P)ut

アウトプット



(O+P)ut

エンジニアのアウトプット

【Kubernetes】RBACにおけるget,list,watchの違いを実機で確認する

スポンサーリンク

はじめに

KubernetesではRoleとUser/ServiceAccountを紐付けることで権限管理ができますが、その中で

  • get
  • list
  • watch

という状況照会系の似たverbが存在し、それぞれに役割が異なります。

本記事ではgetのみを与えた場合、listのみを与えた場合、watchのみを与えた場合を比較しながらそれぞれの役割について確認しました。

環境情報
  • Kubernetes v1.23

Roleによる権限付与による確認

権限を持っているユーザにて以下のように確認できる環境で

$ kubectl get pod
NAME       READY   STATUS    RESTARTS   AGE
backend    1/1     Running   0          2d22h
frontend   1/1     Running   0          2d22h

何も権限を与えていないユーザでコマンドを押下すると以下のような結果となります。

$ kubectl get pod
Error from server (Forbidden): pods is forbidden: User "testuser" cannot list resource "pods" in API group "" in the namespace "default"
$ kubectl get pod frontend
Error from server (Forbidden): pods "frontend" is forbidden: User "testuser" cannot get resource "pods" in API group "" in the namespace "default"

つまり、具体的なPod名を与えずnamespace全体のPodを確認するためには"list"が必要であり、具体的なPodで絞る場合には"get"が必要であることが分かります。

この状態でgetのみの権限をtestuserに付与すると

# kubectl create role testrole --verb=get --resource=pods
role.rbac.authorization.k8s.io/testrole created
# kubectl create rolebinding testrb --role=testrole --user=testuser
rolebinding.rbac.authorization.k8s.io/testrb created

一覧表示はできませんが特定のPodの状態は確認できます。

$ kubectl get pod
Error from server (Forbidden): pods is forbidden: User "testuser" cannot list resource "pods" in API group "" in the namespace "default"
$ kubectl get pod frontend
NAME       READY   STATUS    RESTARTS   AGE
frontend   1/1     Running   0          2d22h

そしてwatchオプションは以下のようなエラーとなりました。

$ kubectl get pod frontend -w
NAME       READY   STATUS    RESTARTS   AGE
frontend   1/1     Running   0          2d22h
Error from server (Forbidden): unknown (get pods)

get, list, watchの違い

上記のテストを実施すると以下のことが分かります。

  • get単体であればリソース名が分かっていれば情報を取得できる
  • list単体であればリソース名が分かっていなくても情報を取得できる
  • watch単体であれば何も確認できない
  • get または list に watchも合わせて与えれば -wオプションが利用できる

この動きは具体的に言うとgetが以下

GET /apis/apps/v1/namespaces/{namespace}/pods/{name}

listが以下

GET /apis/apps/v1/namespaces/{namespace}/pods

watchが以下といったそれぞれのAPIに対して権限を付与している動きになっているからです。

GET /apis/apps/v1/watch/namespaces/{namespace}/pods?watch=true

終わりに

KubernetesではRoleやClusterRoleに属することで特定ユーザが利用できるAPIに制限をかけることができます。

その中でも参照系である get list watch はひとまとめに付与しがちですが、それぞれの違いが気になったので実機で確認しました。

以上、ご参考になれば幸いです。