简介
简介摘自Kubernetes权威指南
RBAC(Role-Based Access Control,基于角色的访问控制)在Kubernetes的1.5版本中引入,在1.6版本时升级为Beta版本,在1.8版本时升级为GA。作为kubeadm安装方式的默认选项,足见其重要程度。相对于其他访问控制方式,新的RBAC具有如下优势。
- 对集群中的资源和非资源权限均有完整的覆盖。
- 整个RBAC完全由几个API对象完成,同其他API对象一样,可以用kubectl或API进行操作
- 可以在运行时调整,无须重新启动API Server
要想使用RBAC授权模式,需要在API Server的启动参数加上–authorization-mode=RBAC.
Kubernetes RBAC
RBAC概念
RBAC引入了4个新的顶级资源对象: Role, ClusterRole,RoleBinding和ClusterRoleBinding. 同其他API资源对象一样,用户可以使用kubectl 或者API调用等方式操作这些资源对象.
我们首先要明确下面三个概念
- Role: 角色,它定义了一组规则,定义了一组对Kubernetes API对象的操作权限
- Subject: 被作用者,既可以是User,Group或ServiceAccount(默认)
- RoleBinding: 定义了”被作用者”和”角色”的绑定关系
RBAC API对象
Kubernetes有一个很基本的特性就是它的所有资源都是模型化的API对象,允许执行CRUD(Create、Read、Update、Delete)操作。
资源对象(resources)
- Pods, ConfigMaps, Deployments, Nodes, Secrets, Namespaces
资源对象操作(verbs)
- create, get, delete, list, update, edit, watch, exec
这些资源和API Group进行关联,比如Pods属于Core API Group,而Deployment属于apps API Group, 要在kubernetes中进行RBAC授权
默认ClusterRole:
view:对全部或所选命名空间下大多数资源的只读权限。 edit:对全部或所选命名空间下多数资源的读写权限。当配置在全部命名空间时能力与运维权限一致。 admin:对全部命名空间下大多数资源的读写权限,对节点、存储卷,命名空间和配额管理的只读权限。 cluster-admin:对全部命名空间下所有资源的读写权限。
Role
Role 作用于指定的namespace,不能跨namespace. 若跨namespace需用ClusterRole.
Role只能对namespace内的资源进行授权,下面的例子中定义的角色具备读取Pod的权限
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: test
name: test-role
rules:
- apiGroups: [""] # ""空字符串,表示核心API群
resources: ["pods"]
verbs: ["get", "watch", "list"]
参数说明:
# 如果没有设置namespace默认则是default
# apiGroups: 支持的API组列表,例如APIVersion: batch/v1、APIVersion: extensions:v1、apiVersion:apps/v1等
# resources: 支持的资源对象列表,例如pods,deployments,jobs等
# verbs: 对资源对象的操作方法列表,例如get,watch,list,delete,replace,patch等
# 这只是规则,需要绑定才生效
ClusterRole
ClusterRole除了具有和Role一致的命名空间内资源的管理能力,因其集群级别的范围,还可以用于以下特殊元素的授权。
- 集群范围的资源,例如Node
- 非资源型的路径,例如/healthz
- 包含全部命名空间的资源,例如pods(用于kubectl get pods –all-namespaces)
下面的集群角色可以让用户有权访问任意一个或所有命名空间的secrets
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
# ClusterRole 不受限于命名空间,所以无需设置namespace的名称
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
此外,kubernetes还提供了预先定义好的ClusterRole来提供用户直接使用
- 如: cluster-admin, admin, edit, view
[root@k8s-master01 ~]# kubectl get clusterrole view -o yaml
[root@k8s-master01 ~]# kubectl describe clusterrole cluster-admin -n kube-system
Name: cluster-admin
Labels: kubernetes.io/bootstrapping=rbac-defaults
Annotations: rbac.authorization.kubernetes.io/autoupdate: true
PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
*.* [] [] [*]
[*] [] [*]
Rolebinding和ClusterRoleBinding
Rolebinding或ClusterRoleBinding绑定用来把一个角色绑定到一个目标上,绑定目标可以是User、Group或者Service Account。 使用RoleBinding引用Role为某个命名空间授权。 使用ClusterRoleBinding为集群范围内授权。
下面的例子中的RoleBinding将在default命名空间中把pod-reader角色授予用户jane,这一操作可以让jane读取default命名空间中的Pod:
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: example-rolebinding
namespace: default
subjects:
- kind: User
name: youmen
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: example-role
apiGroup: rbac.authorization.k8s.io
RoleBinding也可以引用ClusterRole,对属于同一命名空间内ClusterRole定义的资源主体进行授权。一种常见的做法是集群管理员为集群范围预先定义好一组角色(ClusterRole),然后在多个命名空间中重复使用这些ClusterRole。
使用RoleBinding绑定集群角色secret-reader,使dave只能读取development命名空间中的secret:
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: read-secrets
namespace: development
# 集群角色中,dave用户只有development命名空间的权限
subjects:
- kind: User
name: dave
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io
对Resources的引用方式
Kubernetes API包含下级资源,例如Pod的日志(logs), Pod日志的Endpoint是GET/ api/v1/namespaces/{namespace}/pods/{name}/log。
若想获取下级资源,则使用斜线/
如 “pods/log”
下面是授权让某个主体同时能够读取Pod和Pod log
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: test
name: test-role
rules:
- apiGroups: [""] # ""空字符串,表示核心API群
resources: ["pods","pods/log"]
verbs: ["get", "watch", "list"]
Resources还可以通过ResourceName进行引用。在指定ResourceName后,使用get、delete、update、patch操作请求,就会被限制在这个资源实例范围内。
例如下面的声明让一个主体只能对一个叫my-configmap的configmap进行get和update操作:
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: default
name: configmap-updater
rules:
- apiGroups: [""]
resources: ["configmap"]
resourceNames: ["my-configmap"]
verbs: ["update", "get"]
resourceName这种用法对list,watch,create或deletecollection的操作是无效的,这是因为必须要通过URL进行授权, 而resourceName在list,watch,create,delete,collection请求中只是请求Body数据的一部分.
常见Role实例
授权sunday用户对test命名空间pods和pogs/log权限
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: test
name: pods-reader
rules:
- apiGroups: [""]
resources: ["pods","pods/log"]
verbs: ["get","list","watch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: pods-read-test
namespace: test
subjects:
- kind: User
name: sunday
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pods-reader
apiGroup: rbac.authorization.k8s.io
允许读取核心API组中的Pod资源
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get","list","watch"]
允许读写extensions和apps两个API组中的deployment资源
rules:
- apiGroups: ["extensions","apps"]
resources: ["deployments"]
verbs: ["get","list","watch","create","update","pathch","delete"]
允许读取Pods及读写Jobs
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get","list","watch"]
- apiGroups: ["batch","extensions"]
resources: ["jobs"]
verbs: ["get","list","watch","create","update","pathch","delete"]
允许读取一个名为my-config的ConfigMap(必须绑定到一个RoleBinding来限制到一个Namespace下的ConfigMap)
rules:
- apiGroups: [""]
resources: ["configmaps"]
resourceNames: ["my-config"]
verbs: ["get"]
常用RoleBinding示例
用户名alice@example.com
subjects:
- kind: User
name: "alice@example.com"
apiGroup: rbac.authorization.k8s.io
组名frontend-admins
subjects:
- kind: Group
name: "frontend-admins"
apiGroup: rbac.authorization.k8s.io
kube-system命名空间中的默认Service Account
subjects:
- kind: ServiceAccount
name: default
namespace: kube-system
test命名空间中的所有Service Account
subjects:
- kind: Group
name: system:serviceaccounts:test
apiGroup: rbac.authorization.k8s.io
所有Service Account
subjects:
- kind: Group
name: system:serviceaccounts
apiGroup: rbac.authorization.k8s.io
所有认证用户
subjects:
- kind: Group
name: system:authenticated
apiGroup: rbac.authorization.k8s.io
所有未认证用户
subjects:
- kind: Group
name: system:unauthenticated
apiGroup: rbac.authorization.k8s.io
ServiceAccount
ServiceAccount主要负责kubernetes内置用户,下面简单定义一个ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
namespace: mynamespace
name: example-sa
创建Serviceaccount
---
apiVersion: v1
kind: Namespace
metadata:
name: test
labels:
name: test
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: test
name: role-test
rules:
- apiGroups: [""]
resources: ["pods","pods/log"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: rolebinding-test
namespace: test
subjects:
- kind: ServiceAccount
name: sa-test
namespace: test
roleRef:
kind: Role
name: role-test
apiGroup: rbac.authorization.k8s.io
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: sa-test
kubectl create serviceaccount sa-test -o yaml --dry-run > serviceaccount.yaml
Kubectl命令权限
# master
cd /etc/kubernetes/pki/
(umask 077;openssl genrsa -out sunday.key 2048)
openssl req -new -key sunday.key -out sunday.csr -subj "/CN=sunday"
openssl x509 -req -in sunday.csr -CA ./ca.pem -CAkey ./ca-key.pem -CAcreateserial -out sunday.crt -days 365
# openssl x509 -in youmen.crt -text -noout
# sunday用户下操作
useradd sunday
su - sunday
kubectl config set-cluster kubernetes --server="https://192.168.1.111:8443" --certificate-authority=/etc/kubernetes/pki/ca.pem --embed-certs=true
kubectl config set-credentials sunday --client-certificate=./sunday.crt --client-key=./sunday.key --embed-certs=true
kubectl config set-context sunday@kubernetes --cluster=kubernetes --user=sunday
kubectl config use-context sunday@kubernetes
# kubectl get pod
Error from server (Forbidden): pods is forbidden: User "youmen" cannot list resource "pods" in API group "" in the namespace "default"
# master
kubectl create role pods-reader --verb=get,list,watch --resource=pods
kubectl create rolebinding sunday-pods-read --role=pods-reader --user=sunday
如查看其他namespace则无权限,因为role无法跨namespace,需使用clusterrole
[sunday@@k8s-master01 ~] kubectl get pods -n kube-system
Error from server (Forbidden): pods is forbidden: User "sunday" cannot list resource "pods" in API group "" in the namespace "kube-system"
创建clusterrole,可以访问全部的namespace
kubectl create clusterrole cluster-reader --verb=get,list,watch --resource=pods
kubectl create clusterrolebinding read-all-pods-sunday --clusterrole=cluster-reader --user=sunday
kubectl create secret tls admin-certs --key admin-key.pem --cert admin.pem -n kubernetes-dashboard
kubectl get pod -n kubernetes-dashboard -l k8s-app=kubernetes-dashboard
dashboard_pod=`kubectl get pod -n kubernetes-dashboard -l k8s-app=kubernetes-dashboard --output=jsonpath={.items..metadata.name}`
kubectl get pod -n kubernetes-dashboard $dashboard_pod -o yaml > 1.yaml
Helm
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo add stable https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts/
kubectl port-forward –namespace kubeapps service/kubeapps 8080:80
参考
https://kubernetes.io/zh-cn/docs/reference/access-authn-authz/rbac/. https://cloud.tencent.com/developer/article/1706581. https://jimmysong.io/kubernetes-handbook/concepts/rbac.html. https://www.cnblogs.com/RRecal/p/15747097.html. https://support.huaweicloud.com/usermanual-cce/cce_01_0189.html.