Back
Featured image of post Specify the API Group of the resource with kubectl

Specify the API Group of the resource with kubectl

kubectlで同じKindのリソースについてAPI Groupを指定する方法がわかんなくて消耗したのでメモ

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

Prerequisites

  • 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         Event

But 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時点でEventAPI Groupevents.k8s.ioになっていて、
それまであったcore版のEventOLD 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 Groupcoreで指定されてしまう。

# "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 Groupkubectlで指定できた。

おわり

ちゃんとヘルプを読んでいればなんてことない話だったんだけど、
自分は数時間ムダにしてしまったのでメモにした。

やっぱり公式ドキュメントやヘルプを読むのは大事。

おまけ

ごろごろするねこ
ごろごろするねこ

Built with Hugo
Theme Stack designed by Jimmy