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

  1. 用户分为 userserviceAccountgroup
  2. 角色分为 RoleClusterRole
  3. 角色和用户的绑定分为 rolebindingclusterrolebinding

三者关系:

用户/角色 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
posted @ 2021-11-07 21:42  mingtian是吧  阅读(139)  评论(0编辑  收藏  举报