KubernetesのRBAC(Role-based access control)の設定用にAPIリソースについてまとめました。Kubernetes v1.4時点での情報になります。
KubernetesのAPI
KubernetesのAPIは、API ResourceとNon-Resource URLの2つに分けられます。
API Resource
Kubernetes上で扱われる情報(Pod, Service等)はapiserver
上ではAPI Resourceとして定義されています。kube-scheduler
やkubelet
、kubectl
などKubernetesのコンポーネントはこのAPIリソースをHTTPで操作することでPodの配置などの実際の操作を行います。(参考: Kubernetes: コンテナが起動するまでの各コンポーネントの流れ
パスの形式例(requestinfo.goより):
# Resource paths
/apis/{api-group}/{version}/namespaces
/api/{version}/namespaces
/api/{version}/namespaces/{namespace}
/api/{version}/namespaces/{namespace}/{resource}
/api/{version}/namespaces/{namespace}/{resource}/{resourceName}
/api/{version}/{resource}
/api/{version}/{resource}/{resourceName}
# Special verbs without subresources:
/api/{version}/proxy/{resource}/{resourceName}
/api/{version}/proxy/namespaces/{namespace}/{resource}/{resourceName}
/api/{version}/redirect/namespaces/{namespace}/{resource}/{resourceName}
/api/{version}/redirect/{resource}/{resourceName}
# Special verbs with subresources:
/api/{version}/watch/{resource}
/api/{version}/watch/namespaces/{namespace}/{resource}
API Resourceの具体例
例えばdefault
ネームスペースに配置されたnginx-526438288-n5fn9
という名前のpods
リソースのパスは下記のようになります。
/api/v1/namespaces/default/pods/nginx-526438288-n5fn9
サブリソース
いくつかのリソースはサブリソースを持ちます。例えばpods
リソースはlog
というサブリソースを持つため、上記例のPodのログは下記のようなパスになります。
/api/v1/namespaces/default/pods/nginx-526438288-n5fn9/log
RBACでは{Resource}/{SubResource}
という形式でサブリソースを表記します。上記の例ではpods/log
という表記になります。
Non-Resource URL
バージョン情報やヘルスチェックなどの一部のURLはNon-Resource URLとして定義されており、リソースとは別に扱われています。
パスの形式例(requestinfo.goより):
# NonResource paths
/apis/{api-group}/{version}
/apis/{api-group}
/apis
/api/{version}
/api
/healthz
/
RBACでの権限設定
RBACではClusterRole / Roleで権限定義し、ClusterRoleBinding / RoleBindingでユーザとの紐付けを行います。なおClusterRoleとRoleの違いはクラスタ全体に対してのロール(ClusterRole)か、ネームスペース内に対してのロール(Role)かの違いになります。
ClusterRoleでは下記のように権限の指定を行います。rules
で複数のルールを指定し、APIリソースの場合、verbs
、apiGroups
, resources
、Non-Resource URLの場合verbs
(小文字のHTTPメソッド)、nonResourceURLs
を指定します。どの項目も複数指定でき、*
によってワイルドカードを表すことができます。多くの場合はワイルドカードの指定で充分だと思いますが、厳密に権限を管理したい場合にはリソース名を把握しておく必要があります。
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1alpha1
metadata:
name: foo # ロールの名前
rules:
- verbs: ["get", "list", "watch"] # 操作の定義
apiGroups: [""] # APIグループの指定(空はcore groupを表す
resources: ["pods", "pods/exec"] # リソースの指定
- verbs: ["*"] # 全てのHTTPメソッドを許可する
nonResourceURLs: ["/version", "/api", "/api/*", "/apis", "/apis/*"] # Non-Resource URL
# ruleは複数指定できる
サブリソースについて少し注意が必要です。この例では"リソースにpods
とサブリソースのpods/exec
を指定しています。しかしログを見るためのpods/log
は指定していないのでPodのログを見る権限はありません。Kubernetes 1.4.4時点ではpods/*
のようにサブリソースにワイルドカードを指定することはできないようです。
ClusterRoleBinding / RoleBindingで下記のように権限をユーザに紐付けます。
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1alpha1
metadata:
name: foo
subjects:
# 複数のユーザを指定できる
- kind: User # Userの他にGroup、ServiceAccountが選択できる
name: alice
- kind: User
name: bob
roleRef:
kind: ClusterRole
name: foo # 紐付ける対象のロールの名前
権限のブートストラップ
ClusterRole等RBACのリソース自体もRBACの管理するリソースになります。そのため、現時点ではAPIサーバーの--authorization-rbac-super-user
オプションでRBACの制限を受けないスーパーユーザーを指定して、そのユーザの権限でRBACの初期設定を行う必要があります。
操作(verb)
Kubernetesのリソースへの操作はverb
という形で表現されています。
API Resourceへの操作
verb | HTTPメソッド | 備考 |
---|---|---|
get |
GET , HEAD
|
リソースの取得 |
list |
GET |
リソースのリスト取得(GET かつリソース名が空のとき) |
create |
POST |
リソースの作成 |
update |
PUT |
リソースの置き換え(kubectl replace 等) |
patch |
PATCH |
リソースの部分更新(kubectl patch 等) |
delete |
DELETE |
リソースの削除 |
deletecollection |
DELETE |
リソースの一括削除(DELETE かつリソース名が空のとき) |
watch |
リソースの変更監視 | |
proxy |
リソースへのproxy |
この内get
, list
, watch
がreadonlyの操作になります(参考: policy.go)。
HTTPのリクエスト情報からverbへの変換は下記のコードで行われています。
Non-Resource URLへの操作
verbはHTTPメソッド(get
, post
等)をそのまま小文字にしたものになります。
API Group
KubernetesのAPIはAPI Groupというグループに分かれて管理されています。またThirdPartyResourceという仕組みを使って独自にAPI Group及びリソースを作ることもできます。
グループ | 内容 |
---|---|
core groupやKubernetes APIと呼ばれる、Kubernetesの基本となるリソース(Pod , Service 等)のグループ。RBACで指定する場合グループ名は空文字列("" )を指定する。 |
|
extensions |
拡張機能に関するグループ。Deployment , Ingress などが含まれている。 |
apps |
ステートフルなアプリケーションを扱うためのグループ。現状はPetSets のみ(StatefulSets に改名予定) |
authentication.k8s.io |
認証に関するグループ |
authorization.k8s.io |
認可に関するグループ |
autoscaling |
オートスケールに関するグループ |
batch |
バッチ処理、ジョブに関するグループ |
certificates.k8s.io |
TLS証明書に関するグループ |
componentconfig |
Kubernetesコンポーネントの設定情報に関するグループ |
imagepolicy.k8s.io |
コンテナイメージのポリシー制御に関するグループ |
rbac.authorization.k8s.io |
RBACに関するグループ |
storage.k8s.io |
ストレージに関するグループ。現状はStorageClass のみ |
core groupを除くAPI Groupは下記のように/apis
で始まるリソースパスになります。
/apis/{api-group}/{version}/
例えばextensions
グループに含まれる、default
ネームスペースに配置されたnginx
という名前のdeployemnts
リソースのパスは下記のようになります。
/apis/extensions/v1beta1/namespaces/default/deployments/nginx
なお有効なAPI Groupの一覧はAPIサーバーから下記の様に取得できます。一覧を返す/apis
はNon-Resource URLになります。
curl http://localhost:8080/apis | jq -r '.groups[].name'
ThirdPartyResource
ThirdPartyResourceというリソースを使うと独自にAPI Groupとリソースの定義を行うことができます。これによりKubernetesのリソースの仕組みをフレームワークのように扱うことができます。CoreOSのOperatorsなどThirdPartyResourceの活用も進んできています。
設定例:
kind: ThirdPartyResource
apiVersion: extensions/v1beta1 # ThirdPartyResource自体のAPIバージョン
metadata:
name: awesome-resource.tpr.example.com
versions:
- name: v1
ThirdPatyResourceを上記のように定義した場合、metadata.nameのawesome-resource.tpr.example.com
の内、tpr.example.com
がAPI Groupになり、awesome-resource
がAwesomeResource
と変換されリソースのKindになります。(リソース名はawesomeresources
)
定義したThirdPartyResourceはスキーマが無く自由にリソースの中身を定義できます。
kind: AwesomeResource
apiVersion: tpr.example.com/v1
metadata:
name: foo
# データは好きに定義できる
mydata:
hello: world
このリソースをdefault
ネームスペースに定義した場合、リソースのパスは以下のようになります。
/apis/tpr.example.com/v1/namespaces/default/awesomeresources/foo
ThirdPartyResourceも通常のAPIリソースと同様にRBACの権限の対象となり、下記のようにロールを設定することができます。ThirdPartyResource自体はextensions
グループに属していますが、ここではThirdPartyResourceのmetadata.nameで定義した独自のAPIグループを使います。
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1alpha1
metadata:
name: awesomerole
rules:
- verbs: ["*"]
apiGroups: ["tpr.example.com"] # 独自のAPIグループ
resources: ["awesomeresources"]
ThirdPartyResourceについては下記のデザインドキュメントが参考になります。
リソースの一覧
Core Group
Kubernetesの基本的なリソースが含まれているグループです。Kubernetesのソースコード上の扱いもCore Groupのみが、pkg/api以下で扱われており、それ以外はpkg/apisで扱われています。
core groupの場合は下記のように/api
で始まるリソースパスになります。
/api/{version}
リソースの一覧
bindings
componentstatuses
configmaps
endpoints
events
limitranges
namespaces
namespaces/finalize
namespaces/status
nodes
nodes/proxy
nodes/status
persistentvolumeclaims
persistentvolumeclaims/status
persistentvolumes
persistentvolumes/status
pods
pods/attach
pods/binding
pods/eviction
pods/exec
pods/log
pods/portforward
pods/proxy
pods/status
podtemplates
replicationcontrollers
replicationcontrollers/scale
replicationcontrollers/status
resourcequotas
resourcequotas/status
secrets
serviceaccounts
services
services/proxy
services/status
なお、リソースの一覧はAPIサーバーから下記の様に取得できます。
kubectl get --raw /api/v1/ | jq -r .resources[].name
各リソースの詳細はマニュアルにまとまっています。
extensions
daemonsets
daemonsets/status
deployments
deployments/rollback
deployments/scale
deployments/status
horizontalpodautoscalers
horizontalpodautoscalers/status
ingresses
ingresses/status
jobs
jobs/status
networkpolicies
replicasets
replicasets/scale
replicasets/status
replicationcontrollers
replicationcontrollers/scale
thirdpartyresources
各リソースの詳細はマニュアルにまとまっています。
apps
petsets
petsets/status
authentication.k8s.io
tokenreviews
authorization.k8s.io
subjectaccessreviews
autoscaling
horizontalpodautoscalers
horizontalpodautoscalers/status
各リソースの詳細はマニュアルにまとまっています。
batch
jobs
jobs/status
scheduledjobs
scheduledjobs/status
各リソースの詳細はマニュアルにまとまっています。(v1のjobsのみ)
certificates.k8s.io
certificatesigningrequests
certificatesigningrequests/approval
certificatesigningrequests/status
rbac.authorization.k8s.io
clusterrolebindings
clusterroles
rolebindings
roles
storage.k8s.io
storageclasses