Kuber-adm 安装的 k8s 集群默认启用 RBAC,Kubernetes 的授权操作由第三方插件来完成,当有一个插件完成授权后其他插件不再检查,在众多授权插件中常用的有四个
- Node: 有节点的认证
- ABAC: 基于属性的访问控制,RBAC 启用前的算法
- RBAC: Role-based access control,基于角色的访问控制
- Webhook: 基于 HTTP 的回调机制来实现
RBAC
基于角色分配的访问控制,角色决定权限
- 角色 (role)
- 许可 (permission)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7S3jaEhh-1624628602280)(https://raw.githubusercontent.com/ma823956028/image/master/picgo/20200915224359.png)]
K8s 有三种资源,对象、对象列表和非对象资源或非资源 URL,那么在 k8s 当中所有对对象的 operation 都是一种 action, 在一个对象上可以进行的 operation 的集合就是 permission,而后在 role 之上可以授予 permission,Subject 可以分配权限的有两个账号:human user 和 pod service account
RBAC 工作逻辑
在 namespace 中需要以下方式控制权限
-
role
- operation: 许可授权
- object: 对象
-
rolbebinding
- user account OR service account
- role
在集群中需要以下方式控制权限
- cluster role
- cluster rolebinding
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5mI88PKN-1624628602282)(https://raw.githubusercontent.com/ma823956028/image/master/picgo/20200915231835.png)]
可以通过 rolbebinding 绑定 cluster role 这样节省了创建重复 role 和授权 role 的操作,而权限依然根据 rolbebinding 来判定
UserAccount
创建 role
kubectl create role NAME --verb=verb --resource=resource.group/subresource [--resource-name=resourcename]
[root@master-0 ~]# kubectl create role pod-read --verb=get,list,watch --resource=pods --dry-run -oyaml
W0916 09:24:03.897276 3806 helpers.go:535] --dry-run is deprecated and can be replaced with --dry-run=client.
role.rbac.authorization.k8s.io/pod-read created (dry run)
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
creationTimestamp: null
name: pod-read
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- list
- watch
[root@master-0 ~]# cat role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-read
namespace: default
rules:
- apiGroups: # 对 apiGroups 里那些资源组做操作
- ""
resources:
- pods
verbs: # 值可以用 * 来代表所有权限
- get
- list
- watch
[root@master-0 ~]# kubectl apply -f role.yaml
role.rbac.authorization.k8s.io/pod-read created
[root@master-0 ~]# kubectl describe role pod-read
Name: pod-read
Labels: <none>
Annotations: PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
pods [] [] [get list watch]
- Resource Names 指 Resources 下的资源细分
- Non-Resource URLs 既 非对象资源
创建 rolebinding
kubectl create rolebinding NAME --clusterrole=NAME|--role=NAME [--user=username] [--group=groupname]
[root@master-0 ~]# kubectl create rolebinding test-pod-read --role=pod-read --user=testadmin --dry-run -o yaml
W0916 20:26:18.350655 27929 helpers.go:535] --dry-run is deprecated and can be replaced with --dry-run=client.
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
creationTimestamp: null
name: test-pod-read
roleRef: # 引用的 role
apiGroup: rbac.authorization.k8s.io
kind: Role
name: pod-read
subjects: # 动作的执行主体,引用谁
- apiGroup: rbac.authorization.k8s.io
kind: User
name: testadmin
[root@master-0 ~]# kubectl explain rolebinding.subjects
KIND: RoleBinding
VERSION: rbac.authorization.k8s.io/v1
RESOURCE: subjects <[]Object>
DESCRIPTION:
Subjects holds references to the objects the role applies to.
Subject contains a reference to the object or user identities a role
binding applies to. This can either hold a direct API object reference, or
a value for non-objects such as user and group names.
FIELDS:
apiGroup <string>
APIGroup holds the API group of the referenced subject. Defaults to "" for
ServiceAccount subjects. Defaults to "rbac.authorization.k8s.io" for User
and Group subjects.
kind <string> -required- # 指定那个 user 或者 Group 或者 SA
Kind of object being referenced. Values defined by this API group are
"User", "Group", and "ServiceAccount". If the Authorizer does not
recognized the kind value, the Authorizer should report an error.
name <string> -required- # kind 资源的名字
Name of the object being referenced.
namespace <string> # 如果是 SA 则必须指定 namespace
Namespace of the referenced object. If the object kind is non-namespace,
such as "User" or "Group", and this value is not empty the Authorizer
should report an error.
[root@master-0 ~]# kubectl create rolebinding test-pod-read --role=pod-read --user=testadmin
rolebinding.rbac.authorization.k8s.io/testadmin-pod-read created
[root@master-0 ~]# kubectl config use-context testadmin@kubernetes
Switched to context "testadmin@kubernetes".
[root@master-0 ~]# kubectl get po
NAME READY STATUS RESTARTS AGE
myapp-deploy-5d645d645-2dsjq 1/1 Running 5 17d
myapp-deploy-5d645d645-65ftw 1/1 Running 3 17d
myapp-deploy-5d645d645-hfxqf 1/1 Running 5 17d
pod-cm-3 1/1 Running 1 5d15h
pod-sa-demo 1/1 Running 1 5d6h
pod-vol-hostpath 1/1 Running 1 6d2h
创建 clusterrole
Usage:
kubectl create clusterrole NAME --verb=verb --resource=resource.group [--resource-name=resourcename]
[--dry-run=server|client|none] [options]
[root@master-0 ~]# kubectl create clusterrole cluster-read --verb=* --resource=pod -oyaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
creationTimestamp: "2020-09-17T12:02:21Z"
managedFields:
- apiVersion: rbac.authorization.k8s.io/v1
fieldsType: FieldsV1
fieldsV1:
f:rules: {}
manager: kubectl
operation: Update
time: "2020-09-17T12:02:21Z"
name: cluster-read
resourceVersion: "3058226"
selfLink: /apis/rbac.authorization.k8s.io/v1/clusterroles/cluster-read
uid: fee331a3-f386-4c0c-a204-82fd50bf0a5c
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- '*'
[root@master-0 ~]# kubectl delete rolebinding test-pod-read
rolebinding.rbac.authorization.k8s.io "test-pod-read" deleted
创建 clusterrolebinding
注意 clusterrolebinding 只能绑定 clusterrole
Usage:
kubectl create clusterrolebinding NAME --clusterrole=NAME [--user=username] [--group=groupname]
[--serviceaccount=namespace:serviceaccountname] [--dry-run=server|client|none] [options]
[root@master-0 ~]# kubectl create clusterrolebinding cluster-test-pod-read --clusterrole=cluster-read --user=testadmin
clusterrolebinding.rbac.authorization.k8s.io/cluster-test-pod-read created
clusterrole 绑定 rolebinding
[root@master-0 ~]# kubectl create clusterrole cluster-rolebinding-read --verb=get,list --resource=pod
[root@master-0 ~]# kubectl create rolebinding clusterrole-rolebinding --clusterrole=cluster-rolebinding-read --user=testadmin
- 系统默认的 clusterrole 拥有一个 admin,用户可以直接用 rolebinding 绑定这个 clusterrole 来生成特定名称空间的管理员
[root@master-0 ~]# kubectl get clusterrole admin -oyaml
aggregationRule:
clusterRoleSelectors:
- matchLabels:
rbac.authorization.k8s.io/aggregate-to-admin: "true"
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
creationTimestamp: "2020-03-30T07:32:03Z"
labels:
kubernetes.io/bootstrapping: rbac-defaults
managedFields:
- apiVersion: rbac.authorization.k8s.io/v1
fieldsType: FieldsV1
fieldsV1:
f:aggregationRule:
.: {}
f:clusterRoleSelectors: {}
f:metadata:
f:annotations:
.: {}
f:rbac.authorization.kubernetes.io/autoupdate: {}
f:labels:
.: {}
f:kubernetes.io/bootstrapping: {}
manager: kube-apiserver
operation: Update
time: "2020-03-30T07:32:03Z"
- apiVersion: rbac.authorization.k8s.io/v1
fieldsType: FieldsV1
fieldsV1:
f:rules: {}
manager: kube-controller-manager
operation: Update
time: "2020-03-30T07:32:24Z"
name: admin
resourceVersion: "353"
selfLink: /apis/rbac.authorization.k8s.io/v1/clusterroles/admin
uid: a9254f8a-4914-4c63-8945-d66d4a679d23
rules:
- apiGroups:
- ""
resources:
- pods/attach
- pods/exec
- pods/portforward
- pods/proxy
- secrets
- services/proxy
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- serviceaccounts
verbs:
- impersonate
- apiGroups:
- ""
resources:
- pods
- pods/attach
- pods/exec
- pods/portforward
- pods/proxy
verbs:
- create
- delete
- deletecollection
- patch
- update
- apiGroups:
- ""
resources:
- configmaps
- endpoints
- persistentvolumeclaims
- replicationcontrollers
- replicationcontrollers/scale
- secrets
- serviceaccounts
- services
- services/proxy
verbs:
- create
- delete
- deletecollection
- patch
- update
- apiGroups:
- apps
resources:
- daemonsets
- deployments
- deployments/rollback
- deployments/scale
- replicasets
- replicasets/scale
- statefulsets
- statefulsets/scale
verbs:
- create
- delete
- deletecollection
- patch
- update
- apiGroups:
- autoscaling
resources:
- horizontalpodautoscalers
verbs:
- create
- delete
- deletecollection
- patch
- update
- apiGroups:
- batch
resources:
- cronjobs
- jobs
verbs:
- create
- delete
- deletecollection
- patch
- update
- apiGroups:
- extensions
resources:
- daemonsets
- deployments
- deployments/rollback
- deployments/scale
- ingresses
- networkpolicies
- replicasets
- replicasets/scale
- replicationcontrollers/scale
verbs:
- create
- delete
- deletecollection
- patch
- update
- apiGroups:
- policy
resources:
- poddisruptionbudgets
verbs:
- create
- delete
- deletecollection
- patch
- update
- apiGroups:
- networking.k8s.io
resources:
- ingresses
- networkpolicies
verbs:
- create
- delete
- deletecollection
- patch
- update
- apiGroups:
- ""
resources:
- configmaps
- endpoints
- persistentvolumeclaims
- persistentvolumeclaims/status
- pods
- replicationcontrollers
- replicationcontrollers/scale
- serviceaccounts
- services
- services/status
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- bindings
- events
- limitranges
- namespaces/status
- pods/log
- pods/status
- replicationcontrollers/status
- resourcequotas
- resourcequotas/status
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- namespaces
verbs:
- get
- list
- watch
- apiGroups:
- apps
resources:
- controllerrevisions
- daemonsets
- daemonsets/status
- deployments
- deployments/scale
- deployments/status
- replicasets
- replicasets/scale
- replicasets/status
- statefulsets
- statefulsets/scale
- statefulsets/status
verbs:
- get
- list
- watch
- apiGroups:
- autoscaling
resources:
- horizontalpodautoscalers
- horizontalpodautoscalers/status
verbs:
- get
- list
- watch
- apiGroups:
- batch
resources:
- cronjobs
- cronjobs/status
- jobs
- jobs/status
verbs:
- get
- list
- watch
- apiGroups:
- extensions
resources:
- daemonsets
- daemonsets/status
- deployments
- deployments/scale
- deployments/status
- ingresses
- ingresses/status
- networkpolicies
- replicasets
- replicasets/scale
- replicasets/status
- replicationcontrollers/scale
verbs:
- get
- list
- watch
- apiGroups:
- policy
resources:
- poddisruptionbudgets
- poddisruptionbudgets/status
verbs:
- get
- list
- watch
- apiGroups:
- networking.k8s.io
resources:
- ingresses
- ingresses/status
- networkpolicies
verbs:
- get
- list
- watch
- apiGroups:
- authorization.k8s.io
resources:
- localsubjectaccessreviews
verbs:
- create
- apiGroups:
- rbac.authorization.k8s.io
resources:
- rolebindings
- roles
verbs:
- create
- delete
- deletecollection
- get
- list
- patch
- update
- watch
cluster-admin
系统默认定义的 cluster-admin
中包含定义了一个 masters 组,在创建账号时 O 指定这个组,则默认归类到 cluster-admin
中,并拥有最高管理权限,在授权多个用户时也可以以这种组方式授权
[root@master-0 ~]# cd /etc/kubernetes/pki/
[root@master-0 pki]# openssl x509 -in apiserver-kubelet-client.crt -text -noout
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 7592427137245817586 (0x695db8414292aaf2)
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=kubernetes
Validity
Not Before: Mar 30 07:31:42 2020 GMT
Not After : Mar 30 07:31:42 2021 GMT
Subject: O=system:masters, CN=kube-apiserver-kubelet-client # O 代表隶属于什么组织
... ...
[root@master-0 pki]# kubectl get clusterrolebinding cluster-admin -oyaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
creationTimestamp: "2020-03-30T07:32:04Z"
labels:
kubernetes.io/bootstrapping: rbac-defaults
managedFields:
- apiVersion: rbac.authorization.k8s.io/v1
fieldsType: FieldsV1
fieldsV1:
f:metadata:
f:annotations:
.: {}
f:rbac.authorization.kubernetes.io/autoupdate: {}
f:labels:
.: {}
f:kubernetes.io/bootstrapping: {}
f:roleRef:
f:apiGroup: {}
f:kind: {}
f:name : {}
f:subjects: {}
manager: kube-apiserver
operation: Update
time: "2020-03-30T07:32:04Z"
name: cluster-admin
resourceVersion: "101"
selfLink: /apis/rbac.authorization.k8s.io/v1/clusterrolebindings/cluster-admin
uid: 8ff1eba1-2543-445c-be36-4a4d9cc31102
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:masters # 代表这个组都拥有这种权限,即在创建用户是 O 指定的组
ServiceAccount
一个 pod 以指定的 spec.serviceAccountName 身份运行时, serviceAccountName 授予特定权限以后,这个 pod 就拥有了 serviceAccountName 之上对 apiserver 的访问权限
https://kubernetes.io/zh/docs/tasks/configure-pod-container/configure-service-account/
https://kubernetes.io/zh/docs/tasks/access-application-cluster/access-cluster/#accessing-the-api-from-a-pod