RBAC
RBAC
查看当前用户和所属组
root@master01:~# kubectl auth whoami ATTRIBUTE VALUE Username kubernetes-admin Groups [system:masters system:authenticated]
用于验证该sa 是否有指定权限。举例:
kubectl auth can-i list endpointslices --as=system:serviceaccount:kube-system:coredns
RBAC (role base access control),基于角色的访问控制。如果希望使用RBAC功能,需要在api-server启动命令中增加如下配置:
--authorization-mode=RBAC
- 用户分为 user 和serviceAccount 和group
- 角色分为 Role和 ClusterRole
- 角色和用户的绑定分为 rolebinding 和 clusterrolebinding
三者关系:
用户/角色 | Role | ClusterRole |
---|---|---|
user | rolebinding |
rolebinding/clusterrolebinding |
serviceAccount | rolebinding |
rolebinding/clusterrolebinding |
group | rolebinding |
rolebinding/clusterrolebinding |
user
user 不是真正意义上k8s资源,常用于从集群外部连接kube-apiserver。 可以通过openssl创建证书,通过CluserRoleBinding/RoleBinding 绑定权限。
例如 kubectl 连接k8s 集群的权限就是其中应用
openssl genrsa -out user01.key 1024
# CN (common name) 是用户名 -subj /CN=user01,user01用于rolebinding
# O (organization) 是所属组 -sub /CN=user01/O=system:masters
# openssl req -new -key user01.key -out user01.csr -subj /CN=user01/O=system:masters 此时用户user01 已经加入到了system:masters组中,cluser-admin 默认属于system:matster ,因此user01默认有集群管理员权限
openssl req -new -key user01.key -out user01.csr -subj /CN=user01
openssl x509 -req -CA ca.pem -CAkey ca-key.pem -in user01.csr -out user01.crt -days 3650 -CAcreateserial
openssl x509 -in user01.crt -text
kubectl create rolebinding user01-binding --clusterrole=cluster-admin --user=user01 -n default
创建认证文件
# 设置集群信息
kubectl config set-cluster test01 \
--certificate-authority=./ca.pem \
--embed-certs=true \
--server=https://10.4.7.250:6443 \
--kubeconfig=kubelet.kubeconfig
# 设置用户信息
kubectl config set-credentials user01 \
--client-certificate=./user01.crt \
--client-key=./user01.key \
--embed-certs=true \
--kubeconfig=kubelet.kubeconfig
# 把集权和用户信息绑定
kubectl config set-context user01-context \
--cluster=test01 \
--user=user01 \
--kubeconfig=kubelet.kubeconfig
# current-context
kubectl config use-context user01-context \
--kubeconfig=kubelet.kubeconfig
测试权限
# 1.使用kubectl 测试创建的认证文件
kubectl --kubeconfig ./kubelet.kubeconfig get pod
# 2.使用dashboard测试,提示如下错误
# Internal error (500): Not enough data to create auth info structure.
# https://dl.k8s.io/release/v1.22.2/bin/windows/amd64/kubectl.exe
serviceAccount
serviceAccount 是k8s资源,常用于内部pod 连接kube-apiServer。dashboard的授权管理就是其中应用
kubectl create serviceaccount test-dashboard \
--dry-run=client -o yaml
kubectl create rolebinding test-dashboard \
--clusterrole=cluster-admin \
--serviceaccount=default:test-dashboard \
-n default \
--dry-run=client -o yaml
#此时我们把token 登录
token=kubectl describe secret test-dashboard-token-jnrzl |awk '/^token/{print $NF}'
# 设置集群信息
kubectl config set-cluster test01 \
--certificate-authority=./ca.pem \
--embed-certs=true \
--server=https://10.4.7.250:6443 \
--kubeconfig=kubelet.kubeconfig
# 设置用户信息
kubectl config set-credentials user02 \
--token=${token} \
--kubeconfig=kubelet.kubeconfig
# 把集权和用户信息绑定
kubectl config set-context user02-context \
--cluster=test01 \
--user=user02 \
--kubeconfig=kubelet.kubeconfig
# current-context
kubectl config use-context user02-context \
--kubeconfig=kubelet.kubeconfig
测试权限
# 1.使用kubectl 测试创建的认证文件
kubectl --kubeconfig ./kubelet.kubeconfig get pod
# 2.使用dashboard测试成功
Role
- Role 总是用来在某个名称空间内设置访问权限;在你创建 Role 时,你必须指定该 Role 所属的名字空间。
ClusterRole 则是集群资源,如果你希望定义集群范围的角色,应该使用 ClusterRole。- "get", "post","list", "watch", "create", "update", "patch", "delete"
示例:
#kubectl create role pod-reader --verb=get,watch,list --resource=pods --dry-run=client -oyaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""] # "" 标明 core API 组
resources: ["pods"]
verbs: ["get", "watch", "list"]
对子资源的授权
kubectl get --raw /api/v1/namespaces/default/pods/web-server/log
# pods资源的资源log
#kubectl create role pod-reader --verb=get,watch,list --resource=pods,pods/log --dry-run=client -oyaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader
rules:
- apiGroups:
- ""
resources:
- pods
- pods/log
verbs:
- get
- watch
- list
指定资源名称
[info]
你不能使用资源名字来限制
create
或者deletecollection
请求。 对于create
请求而言,这是因为在鉴权时可能还不知道新对象的名字
# kubectl create role test --verb=list --resource=ingress --resource-name=http-80 --dry-run=client -oyaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: test
rules:
- apiGroups:
- networking.k8s.io
resourceNames:
- http-80 # 只允许对http-80 的ingress资源访问
resources:
- ingresses
verbs:
- list
也可以使用 *
号模糊匹配
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: example.com-superuser # 此角色仅作示范,请勿使用
rules:
- apiGroups: ["example.com"]
resources: ["*"]
verbs: ["*"]
ClusterRole
clusterrole 在授权时支持role 所有的操作,同时增加了一下资源的控制:
- 集群范围资源(比如 节点(Node))
- 非资源端点(比如
/healthz
)- 支持权限聚合(可以将若干clusterrole 聚合起来),Role不支持
示例:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
# "namespace" 被忽略,因为 ClusterRoles 不受名字空间限制
name: secret-reader
rules:
- apiGroups: [""]
# 在 HTTP 层面,用来访问 Secret 资源的名称为 "secrets"
resources: ["secrets"]
verbs: ["get", "watch", "list"]
#查询cluserrole
kubectl get clusterrole
#查询system:node 绑定的权限,在kubelet中使用了改权限
kubectl get clusterrole system:node -o yaml
clusterRole权限聚合
[info]
如果你想更改或添加规则,请在被
aggregationRule
所选中的ClusterRole
对象上执行变更。如果你创建一个与某个已存在的聚合 ClusterRole 的标签选择算符匹配的 ClusterRole, 这一变化会触发新的规则被添加到聚合 ClusterRole 的操作。
# 聚合拥有标签为 rbac.example.com/aggregate-to-monitoring=true 的clusterrole
# kubectl create clusterrole test --aggregation-rule="rbac.example.com/aggregate-to-monitoring=true" --dry-run=client -oyaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: test
aggregationRule:
clusterRoleSelectors:
- matchLabels:
rbac.example.com/aggregate-to-monitoring: "true"
rules: [] # 控制面自动填充这里的规则
RoleBinding
- rolebinding 在名称空间级别中授权,clusterrolebinding 在集群级别授权
示例:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: user01-binding
namespace: default
# 如果你想要改变现有绑定对象中 roleRef 字段的内容,必须删除重新创建绑定对象。
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
# 你可以指定不止一个“subject(主体)”
- apiGroup: rbac.authorization.k8s.io
kind: User
name: user01 # openssl 创建时-subject \CN=user01,CN时commont name的缩写
RoleBinding 也可以引用 ClusterRole,这种引用使得你可以跨整个集群定义一组通用的角色, 之后在多个名字空间中复用。
apiVersion: rbac.authorization.k8s.io/v1
# 此角色绑定使得用户 "dave" 能够读取 "default" 名字空间中的 Secrets
# 你需要一个名为 "secret-reader" 的 ClusterRole
kind: RoleBinding
metadata:
name: read-secrets
# RoleBinding 的名字空间决定了访问权限的授予范围。
# 这里仅授权在 "development" 名字空间内的访问权限。
namespace: development
subjects:
# 你可以指定不止一个“subject(主体)”
- kind: User
name: dave # 'name' 是不区分大小写的
apiGroup: rbac.authorization.k8s.io
# 如果你想要改变现有绑定对象中 roleRef 字段的内容,必须删除重新创建绑定对象。
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io
Clusterrolebinding
apiVersion: rbac.authorization.k8s.io/v1
# 此集群角色绑定允许 “manager” 组中的任何人访问任何名字空间中的 secrets
kind: ClusterRoleBinding
metadata:
name: read-secrets-global
subjects:
- kind: Group
name: manager # 'name' 是不区分大小写的,绑定cluserrole 到组
apiGroup: rbac.authorization.k8s.io
- kind: User
name: jane # "name" 是不区分大小写的,绑定cluserrole 到用户
apiGroup: rbac.authorization.k8s.io
# 如果你想要改变现有绑定对象中 roleRef 字段的内容,必须删除重新创建绑定对象。
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io
root@master01:~# kubectl get clusterrolebinding -o=jsonpath='{range .items[*]}{.subjects[0].kind}{"\t"}{.metadata.name}{"\n"}{end}'|grep -i group
Group cluster-admin
Group kubeadm:get-nodes
Group kubeadm:kubelet-bootstrap
Group kubeadm:node-autoapprove-bootstrap
Group kubeadm:node-autoapprove-certificate-rotation
Group system:basic-user
Group system:discovery
Group system:monitoring
Group system:public-info-viewer
Group system:service-account-issuer-discovery
OpenShift用户与组的管理功能如何在Kubernetes上实现 - 简书 (jianshu.com)
默认的clusterrole
clusterrole | binding | 权限 |
---|---|---|
cluster-admin | system:masters 组 | 集群所有权限 |
admin | 无 | 管理员权限,此角色不允许对资源配额或者名字空间本身进行写操作 |
edit | 无 | 允许对名字空间的大多数对象进行读/写操作。此角色不允许查看或者修改role或rolebinding |
view | 无 | 允许对名字空间的大多数对象有只读权限。 它不允许查看role或rolebinding。 |
system:monitoring | system:monitoring 组 | 允许对控制平面监控端点的读取访问(例如:kube-apiserver 存活和就绪端点(/healthz、/livez、/readyz), 各个健康检查端点(/healthz/、/livez/、/readyz/*)和 /metrics)。 请注意,各个运行状况检查端点和度量标准端点可能会公开敏感信息。 |
dashboard 基于用户角色的实践
[root@hdss7-22 ~]# cat /tmp/mini.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
k8s-app: kubernetes-dashboard
addonmanager.kubernetes.io/mode: Reconcile
name: kubernetes-dashboard
namespace: kube-system
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
labels:
k8s-app: kubernetes-dashboard
addonmanager.kubernetes.io/mode: Reconcile
name: kubernetes-dashboard-minimal
namespace: kube-system
rules:
#a11ow Dashboard to get,update and delete Dashboard exclusive secrets.
- apiGroups: [""]
resources: ["secrets"]
resourceNames: ["kubernetes-dashboard-key-holder","kubernetes-dashboard-certs"]
verbs: ["get","update","delete"]
#a11ow Dashboard to get and update ' kubernetes-dashboard-settings' config map.
- apiGroups: [""]
resources: ["secrets"]
resourceNames: ["kubernetes-dashboard-settings"]
verbs: ["get","update"]
# Allow Dashboard to get metrics from heapster.
- apiGroups: [""]
resources: ["services"]
resourceNames: ["heapster"]
verbs: ["proxy"]
- apiGroups: [""]
resources: ["services/proxy"]
resourceNames: ["heapster", "http:heapster:","https:heapster:"]
verbs: [ "get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: kubernetes-dashboard-minima1
namespace: kube-system
labels:
k8s-app: kubernetes-dashboard
addonmanager.kubernetes.io/mode: Reconcile
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: kubernetes-dashboard-minimal
subjects:
- kind: ServiceAccount
name: kubernetes-dashboard
namespace: kube-system
rbac授权示例:
kubectl -n kube-system create sa admin
kubectl create clusterrolebinding admin --clusterrole=cluster-admin --serviceaccount=kube-system:admin
kubectl -n kube-system describe secret $(kubectl -n kube-system get sa admin -ojsonpath='{.secrets[0].name}' ) |grep token
# 获取 token
TOKEN=$(kubectl -n kube-system get secret $(kubectl -n kube-system get sa admin -o jsonpath="{.secrets[0].name}") -o jsonpath="{.data.token}" | base64 --decode)
# 使用 token 访问 Kubernetes API 以验证授权
curl -k -H "Authorization: Bearer $TOKEN" https://<KUBERNETES_API_SERVER>/api/v1/nodes