Summary
We can use the expression <Resource>.<API Group> to specify the API Group with kubectl.
# Example: the expressions of "Event v1 core" and "Event v1 events.k8s.io"
kubectl auth can-i get events
kubectl auth can-i get events.events.k8s.ioPrerequisites
- Kubernetes API v1.21.1
- kubectl v1.21.5
Same resource, different API Groups
In Kubernetes API 1.21, there are some different API Groups for the same kind of resource.
For example:
# in Kubernetes 1.21, there are two different API Groups for Events resource
$ kubectl api-resources | grep event
events ev v1 true Event
events ev events.k8s.io/v1 true EventBut if we specify “events” resource with kubectl 1.21, it will be treated as “Event v1 core”.
# create a serviceaccount with permissions to view only "Event v1 core"
$ kubectl -n default create serviceaccount user01
$ kubectl -n default create role event-corev1-reader --verb="get,list" --resource="events"
$ kubectl -n default create rolebinding event-corev1-reader --role=event-corev1-reader --serviceaccount=default:user01
# Check the permissions of the serviceaccount
# https://kubernetes.io/docs/tasks/run-application/access-api-from-pod/#without-using-a-proxy
$ kubectl -n default run nginx --image=nginx --restart=Never --rm -it --overrides='{ "spec": { "serviceAccountName" : "user01" } }' -- /bin/bash
# The serviceaccount can list "Event v1 core"
(root@nginx)$ curl -I -X GET -k https://kubernetes.default.svc/api/v1/namespaces/default/events -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)"
HTTP/2 200
...
# The serviceaccount is not allowed to list "Event v1 events.k8s.io"
(root@nginx)$ curl -I -X GET -k https://kubernetes.default.svc/apis/events.k8s.io/v1/namespaces/default/events -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)"
HTTP/2 403
...So, how can we specify the API Group “events.k8s.io” with kubectl?
According to the help, we can use the expression <Resource>.<API Group>.
$ kubectl create role --help
...
Usage:
kubectl create role NAME --verb=verb --resource=resource.group/subresource
[--resource-name=resourcename] [--dry-run=server|client|none] [options]
...This expression can be used with other kubectl subcommands such as kubectl auth can-i.
# create a serviceaccount with permissions to view only "Event v1 events.k8s.io"
$ kubectl -n default create serviceaccount user02
$ kubectl -n default create role event-eventsk8siov1-reader --verb="get,list" --resource="events.events.k8s.io"
$ kubectl -n default create rolebinding event-eventsk8siov1-reader --role=event-eventsk8siov1-reader --serviceaccount=default:user02
# user01 can view only "Event v1 core"
$ kubectl -n default auth can-i get events --as system:serviceaccount:default:user01
yes
$ kubectl -n default auth can-i get events.events.k8s.io --as system:serviceaccount:default:user01
no
# user02 can view only "Event v1 events.k8s.io"
$ kubectl -n default auth can-i get events --as system:serviceaccount:default:user02
no
$ kubectl -n default auth can-i get events.events.k8s.io --as system:serviceaccount:default:user02
yes(The following is the same content in Japanese.)
まとめ
リソースが同じでもAPI Groupが異なるものをkubectlで指定したいときは<Resource>.<API Group>とすれば良い。
# "Event v1 core"と"Event v1 events.k8s.io"をそれぞれ指定して権限を確認する例
kubectl auth can-i get events
kubectl auth can-i get events.events.k8s.io環境
- Kubernetes API v1.21.1
- kubectl v1.21.5
同じリソース名でAPI versionが複数あるとき
Kubernetes APIではv1.21時点でEventのAPI Groupがevents.k8s.ioになっていて、
それまであったcore版のEventはOLD API VERSIONSという扱い。
# 1.22時点では2種類のAPI Groupが存在する
$ kubectl api-resources | grep event
events ev v1 true Event
events ev events.k8s.io/v1 true Eventしかし、v1.22のkubectlで普通にeventsに対するRoleを作成するとAPI Groupがcoreで指定されてしまう。
# "event"を指定してRoleを作成する
$ kubectl -n default create serviceaccount user01
$ kubectl -n default create role event-corev1-reader --verb="get,list" --resource="events"
$ kubectl -n default create rolebinding event-corev1-reader --role=event-corev1-reader --serviceaccount=default:user01
# Podを立てて確認してみる
# https://kubernetes.io/docs/tasks/run-application/access-api-from-pod/#without-using-a-proxy
$ kubectl -n default run nginx --image=nginx --restart=Never --rm -it --overrides='{ "spec": { "serviceAccountName" : "user01" } }' -- /bin/bash
# coreのAPIは利用可能
(root@nginx)$ curl -I -X GET -k https://kubernetes.default.svc/api/v1/namespaces/default/events -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)"
HTTP/2 200
...
# events.k8s.ioのAPIは認可エラーで利用不可
(root@nginx)$ curl -I -X GET -k https://kubernetes.default.svc/apis/events.k8s.io/v1/namespaces/default/events -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)"
HTTP/2 403
...じゃあk8s.events.io版への権限はどうやって付与するんだろう?と試行錯誤していたら、helpにちゃんと書いてあった…
$ kubectl create role --help
...
Usage:
kubectl create role NAME --verb=verb --resource=resource.group/subresource
[--resource-name=resourcename] [--dry-run=server|client|none] [options]
...リソースの後に続いて.<API Group>を指定すればいいらしい。
(何も指定しない場合はcoreになるっぽい?)
この方法で再度Roleを指定しなおす。
$ kubectl -n default create serviceaccount user02
$ kubectl -n default create role event-eventsk8siov1-reader --verb="get,list" --resource="events.events.k8s.io"
$ kubectl -n default create rolebinding event-eventsk8siov1-reader --role=event-eventsk8siov1-reader --serviceaccount=default:user02他のコマンドでリソースを指定するときも同様にできるらしいので、今度はPodを建てずにkubectl authで確認してみる。
# user01: core版のみの閲覧権限
$ kubectl -n default auth can-i get events --as system:serviceaccount:default:user01
yes
$ kubectl -n default auth can-i get events.events.k8s.io --as system:serviceaccount:default:user01
no
# user02: events.k8s.io版のみの閲覧権限
$ kubectl -n default auth can-i get events --as system:serviceaccount:default:user02
no
$ kubectl -n default auth can-i get events.events.k8s.io --as system:serviceaccount:default:user02
yesやったぜ。
異なるAPI Groupをkubectlで指定できた。
おわり
ちゃんとヘルプを読んでいればなんてことない話だったんだけど、
自分は数時間ムダにしてしまったのでメモにした。
やっぱり公式ドキュメントやヘルプを読むのは大事。
おまけ

