RBAC(基于角色的访问控制)
role/roleBingding
ClusterRole/ClusterRoleBingding
ServiceAccount
1. Kubernetes认证、授权与准入控制
1.1 认证基本概念
1.1.1 为什么需要验证
对于Kubernetes系统来说,,APIServer
肯定不是任何人都能轻易访问的,如果任何人都能轻易的访问,意味着可以通过kubectl
命令访问APIServer,进而操作Kubernetes。也就意味着它能够在我们的系统上随便部署应用程序,甚至还会删除我们正在运行的应用程序,这是非常危险的。所以我们需要对用户进行身份认证
,确保身份是合法.
1.1.2 认证流程
任何客户端用户试图通过 APIServer
操作资源对象时,它们必须经历多个阶段的访问控制,才会被接受处理,其中包含认证、授权以及准入控制
1.认证:任何客户端访问,经过API操作之前,需要先完成认证操作,也就是进行身份认证
;
2.授权:认证通过后仅代表它是一个合法的系统用户,但它是否拥有删除对应资源权限,需要进行授权检查
3.准入控制:虽然我们有了权限,也可以创建Pod等各种资源,但创建Pod是否能成功呢,假设ops名称空间限制最多创建2个Pod,目前已经有2个Pod了,那么这次的创建就会失败。
1.1.3 认证方式
UserAccount
使用kubectl创建资源,首先要进行客户端身份认证,所以客户端每次在请求APIServer时都会携带上数字证书,用于认证API-Server,当认证通过后,证书中的Subject
将被识别为用户标识,其中的CN字段的值为用户名,字段O的值就是用户所属的组,例如:Subject:0=ops,CN=k8
用户名为k8,用户的组为ops。
ServiceAccount
有些情况下,我们希望在pod内部能够访问API-Server,获取集群的信息,甚至对集群进行改动。针对这种情况,kubernetes提供了一种特殊的认证方式:ServiceAccount。
默认情况下,创建的Pod如果没有指定ServiceAccount则系统会默认提供一个ServiceAccount,而后通过mount方式挂载到Pod的文件系统中(/var/run/secretes/kubernetes.io/serviceaccount/token),该ServiceAccount能通过DownWardAPI获取该Pod相关的一些元数据信息。当然也可以自行创建ServiceAccount来完成API-Server的身份认证,至于能否对集群进行改变,则需要看该ServiceAccount是否拥有权限。
❌ 注意
- 同一个命名空间下的多个pod可以使用同一个ServiceAccount
- pod只能使用同一个命名空间下的ServiceAccount
- 如果在pod的manifest文件中没有显示的指定ServiceAccount名称.则默认使用default ServiceAccount
1.2 RBAC授权
1.2.0 如何开启RBAC
grep -C3 'authorization-mode' /etc/kubernetes/manifests/kube-apiserver.yaml
#- --feature-gates=RemoveSelfLink=false
- --advertise-address=10.103.236.201
- --allow-privileged=true
- --authorization-mode=Node,RBAC
- --client-ca-file=/etc/kubernetes/pki/ca.crt
- --enable-admission-plugins=NodeRestriction
- --enable-bootstrap-token-auth=true
grep -C3 'authorization-mode' /etc/kubernetes/manifests/kube-apiserver.yaml
#- --feature-gates=RemoveSelfLink=false
- --advertise-address=10.103.236.201
- --allow-privileged=true
- --authorization-mode=Node,RBAC
- --client-ca-file=/etc/kubernetes/pki/ca.crt
- --enable-admission-plugins=NodeRestriction
- --enable-bootstrap-token-auth=true
API Server目前支持以下几种授权策略:
- AlwaysDeny:表示拒绝所有请求,一般用于测试。
- AlwaysAllow:允许接收所有请求。 如果集群不需要授权流程,则可以采用该策略,这也是Kubernetes的默认配置。
- ABAC(Attribute-Based Access Control):基于属性的访问控制。 表示使用用户配置的授权规则对用户请求进行匹配和控制。
- Webhook:通过调用外部REST服务对用户进行授权。
- RBAC:Role-Based Access Control,基于角色的访问控制
- Node:是一种专用模式,用于对kubelet发出的请求进行访问控制。
1.2.1 什么是RBAC
RBAC(RoleBasedAccessControl)
基于角色的访问控制;其实就是将资源的操作权限授予给指定的角色,而后将用户加入该角色,那么该用户则拥有了对应角色的权限;
授权过程:
- 定义角色(Role and ClusterRole):在定义角色时会指定此角色对于资源访问控制的一系列规则;
- 定义主体("User", "Group" or "ServiceAccount"): 客户端标识;
- 绑定角色RoleBinding and ClusterRoleBinding:将主体与角色进行绑定,对用户进行访问授权。
简单来说:
- RBAC(Role-Based Access Control,基于角色的访问控制),允许通过Kubernetes API动态配置策略。
- 角色
- Role:授权特定命名空间的访问权限
- ClusterRole:授权所有命名空间的访问权限
- 角色绑定
- RoleBinding:将角色绑定到主体(即subject)
- ClusterRoleBinding:将集群角色绑定到主体
- 主体(subject)
- User:用户
- Group:用户组
- ServiceAccount:服务账号
1.2.2 RBAC角色与集群角色
Kubernetes系统的RBAC授权插件将角色分为了RoLe和CLusterRoLe两类:
- RoLe:仅作用于名称空间级别,用于承载名称空间级别内的资源权限集合。
- ClusterRole:作用于集群范围,能够同时承载名称空间和集群级别的资源权限集合。
Kubernetes利用Role
和CLusterRoLe
两类角色来赋予对应的权限,同时也需要用到另外两类资源RoLebinding
和CLusterRoLebinding
来完成用户与角色之间的绑定关系;
1.2.3 Role
Role是一系列的权限的集合,在命名空间内定义的权限集合。它只能在指定的命名空间内生效。
例如一个Role可以包含读取 Pod 的权限和列出 Pod 的权限,Role只能授予单个 namespace 中资源的访问权限,比如:
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["pods"]
#resourceNames: ["my-pod"]
verbs: ["get", "watch", "list"]
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["pods"]
#resourceNames: ["my-pod"]
verbs: ["get", "watch", "list"]
参数解释:
# 首先,Role对象指定了它能产生作用的Namespace(mynamespace)。# Namespace是kubernetes项目中的一个逻辑管理单位。不同Namespace的API对象,
# 在通过kubectl命令进行操作的时候,是互相隔离的
# namespace并不会提供任何实际的隔离或者多租户能力,如果没有设置namespace默认则是default
# apiGroups: 支持的API组列表,例如"“apiVersion: batch/v1”“apiVersion: extensions:v1”“apiVersion: apps/v1”等”
# resources: 支持的资源对象列表,例如Pods,deployments,jobs等
# verbs: 对资源对象的操作方法列表,例如get,watch,list,delete,replace,patch等
# rules字段定义它的是权限规则,这条规则的含义就是允许"被作用者" ,对namespace下面Pod(resources中定义)有哪些权限;
# 用户的权限对应的API资源对象已经创建了,但是还没有绑定,也就是只有一个规则没有规定哪些用户有这个权限
# 首先,Role对象指定了它能产生作用的Namespace(mynamespace)。# Namespace是kubernetes项目中的一个逻辑管理单位。不同Namespace的API对象,
# 在通过kubectl命令进行操作的时候,是互相隔离的
# namespace并不会提供任何实际的隔离或者多租户能力,如果没有设置namespace默认则是default
# apiGroups: 支持的API组列表,例如"“apiVersion: batch/v1”“apiVersion: extensions:v1”“apiVersion: apps/v1”等”
# resources: 支持的资源对象列表,例如Pods,deployments,jobs等
# verbs: 对资源对象的操作方法列表,例如get,watch,list,delete,replace,patch等
# rules字段定义它的是权限规则,这条规则的含义就是允许"被作用者" ,对namespace下面Pod(resources中定义)有哪些权限;
# 用户的权限对应的API资源对象已经创建了,但是还没有绑定,也就是只有一个规则没有规定哪些用户有这个权限
1.2.4 ClusterRole
ClusterRole授权 >= Role授予(与Role类似),但ClusterRole属于集群级别对象,可以在整个集群范围内生效。
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
# "namespace" omitted since ClusterRoles are not namespaced
name: secret-reader
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "watch", "list"]
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
# "namespace" omitted since ClusterRoles are not namespaced
name: secret-reader
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "watch", "list"]
#默认 获取 ClusterRole
kubectl get clusterroles --namespace=kube-system
#默认 获取 ClusterRole
kubectl get clusterroles --namespace=kube-system
[root@kube-master manifests]# 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
--------- ----------------- -------------- -----
*.* [] [] [*]
[*] [] [*]
[root@kube-master manifests]# 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
--------- ----------------- -------------- -----
*.* [] [] [*]
[*] [] [*]
1.2.5 RoleBinding
将 Role 与一个或多个用户、组或服务账户绑定,赋予在特定命名空间内的权限。
比如以下 RoleBinding 是将 default 命名空间的 pod-reader Role 授予 bmw 用户,此后 bmw 用户在 default 命名空间中将具有 pod-reader 的权限
# This role binding allows "bmw" to read pods in the "default" namespace.
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: read-pods
namespace: default
subjects:
- kind: User # May be "User", "Group" or "ServiceAccount"
name: bmw
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
# This role binding allows "bmw" to read pods in the "default" namespace.
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: read-pods
namespace: default
subjects:
- kind: User # May be "User", "Group" or "ServiceAccount"
name: bmw
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
- kubectl
$ kubectl create rolebinding read-pods --role=pod-reader --user=bmw --namespace=default
$ kubectl get rolebindings.rbac.authorization.k8s.io -o wide
其它类似 subjects:
$ kubectl create rolebinding read-pods-svc --role=pod-reader --serviceaccount=default:bmw-svc --namespace=default
$ kubectl create rolebinding read-pods-group --role=pod-reader --group=bmw-group --namespace=default
$ kubectl create rolebinding read-pods --role=pod-reader --user=bmw --namespace=default
$ kubectl get rolebindings.rbac.authorization.k8s.io -o wide
其它类似 subjects:
$ kubectl create rolebinding read-pods-svc --role=pod-reader --serviceaccount=default:bmw-svc --namespace=default
$ kubectl create rolebinding read-pods-group --role=pod-reader --group=bmw-group --namespace=default
1.2.6 ClusterRoleBinding
ClusterRoleBinding 适用于集群范围内的授权,也就是说可以跨namespace
比如以下 ClusterRoleBinding 是将 bmw 用户在任意namespace中都具有 pod-reader 的权限:
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: read-pods-global
subjects:
- kind: User
name: bmw
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: cluster-pod-reader
apiGroup: rbac.authorization.k8s.io
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: read-pods-global
subjects:
- kind: User
name: bmw
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: cluster-pod-reader
apiGroup: rbac.authorization.k8s.io
- kubectl
$ kubectl create clusterrolebinding read-pods-global --clusterrole=cluster-pod-reader --user=bmw
$ kubectl get clusterrolebindings.rbac.authorization.k8s.io -o wide
$ kubectl create clusterrolebinding read-pods-global --clusterrole=cluster-pod-reader --user=bmw
$ kubectl get clusterrolebindings.rbac.authorization.k8s.io -o wide
1.2.7 ServiceAccount
一种特殊的 Kubernetes 账户,通常用于容器或应用程序访问 Kubernetes API。
1.3 RBAC权限定义
1. apiGroups: 指定哪个 API 组下的权限,比如:apps,可以使用该命令获取apiGroups,如果为空字符串,代表就是core下的api: kubectl api-resources -o wide
2. resources: 该apiGroups组下具体资源,比如 pod,service,secret 等
3. verbs: 指对该资源具体执行哪些动作,如 get, delete,list 等
1. apiGroups: 指定哪个 API 组下的权限,比如:apps,可以使用该命令获取apiGroups,如果为空字符串,代表就是core下的api: kubectl api-resources -o wide
2. resources: 该apiGroups组下具体资源,比如 pod,service,secret 等
3. verbs: 指对该资源具体执行哪些动作,如 get, delete,list 等
1.3.1 系统预定义角色
Kubernetes有一个很基本的特性就是它的所有资源都是模型化的API对象,允许执行CRUD(Create、Read、Update、Delete)操作。资源如下
# Pods
# ConfigMaps
# Deployments
# Nodes
# Secrets
# Namespaces
# 资源对象可能存在的操作有如下
# create
# get
# delete
# list
# update
# edit
# watch
# exec
# Pods
# ConfigMaps
# Deployments
# Nodes
# Secrets
# Namespaces
# 资源对象可能存在的操作有如下
# create
# get
# delete
# list
# update
# edit
# watch
# exec
- 通过命令查看
kubectl get role -n kube-system
kubectl get clusterrole
kubectl get rolebinding -n kube-system
kubectl get clusterrolebinding
kubectl get clusterrole view -o yaml
kubectl get role -n kube-system
kubectl get clusterrole
kubectl get rolebinding -n kube-system
kubectl get clusterrolebinding
kubectl get clusterrole view -o yaml
1.4 涉及命令
#查看上下文
[root@kube-master manifests]# kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
* kubernetes-admin@kubernetes kubernetes kubernetes-admin
#切换
kubectl config use-context name
#返回生成 kubeconfig 条目所针对的所有集群的列表
kubectl config view
#1.创建role
kubectl create role pod-reader --verb=get,list --resource=pods --namespace=development
#2.创建ClusterRole:创建集群范围内的角色
kubectl create clusterrole pod-admin --verb=get,list,create,delete --resource=pods
#3.创建RoleBinding:将Role绑定给特定用户或服务账户
kubectl create rolebinding read-pods --role=pod-reader --user=johndoe --namespace=development
#4.创建ClusterRoleBinding:将ClusterRole绑定到用户,授予其集群范围的权限
kubectl create clusterrolebinding cluster-admin-binding --clusterrole=cluster-admin --user=admin-user
#查看
#查看Role:列出命名空间中的所有角色
kubectl get roles --namespace=development
#查看RoleBinding:查看所有角色绑定
kubectl get rolebindings --namespace=development
#查看ClusterRole和ClusterRoleBinding:查看集群范围的角色和角色绑定
kubectl get clusterroles
kubectl get clusterrolebindings
#生成yaml文件
kubectl create role han --namespace monitor --verb=get,list,watch --resource=pods -o yaml
#查看上下文
[root@kube-master manifests]# kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
* kubernetes-admin@kubernetes kubernetes kubernetes-admin
#切换
kubectl config use-context name
#返回生成 kubeconfig 条目所针对的所有集群的列表
kubectl config view
#1.创建role
kubectl create role pod-reader --verb=get,list --resource=pods --namespace=development
#2.创建ClusterRole:创建集群范围内的角色
kubectl create clusterrole pod-admin --verb=get,list,create,delete --resource=pods
#3.创建RoleBinding:将Role绑定给特定用户或服务账户
kubectl create rolebinding read-pods --role=pod-reader --user=johndoe --namespace=development
#4.创建ClusterRoleBinding:将ClusterRole绑定到用户,授予其集群范围的权限
kubectl create clusterrolebinding cluster-admin-binding --clusterrole=cluster-admin --user=admin-user
#查看
#查看Role:列出命名空间中的所有角色
kubectl get roles --namespace=development
#查看RoleBinding:查看所有角色绑定
kubectl get rolebindings --namespace=development
#查看ClusterRole和ClusterRoleBinding:查看集群范围的角色和角色绑定
kubectl get clusterroles
kubectl get clusterrolebindings
#生成yaml文件
kubectl create role han --namespace monitor --verb=get,list,watch --resource=pods -o yaml
1.5 实践
假如我们想给用户 bmw 开通一个只可以查看集群中default namespace中的 pods,services 权限,该如何实现呢?一般分如下几个步骤
1. 定义个角色(Role/ClusterRole),角色包含资源(resources)和动作(verbs)
2. 分别以 User,Group, ServiceAccount 模式定义一个主体
3. 定义一个 (RoleBinding/ClusterRoleBinding), 把 subjects 与 Role/ClusterRole 进行关联
4. 配置 kubeconfig,使用 kubectl 验证
1. 定义个角色(Role/ClusterRole),角色包含资源(resources)和动作(verbs)
2. 分别以 User,Group, ServiceAccount 模式定义一个主体
3. 定义一个 (RoleBinding/ClusterRoleBinding), 把 subjects 与 Role/ClusterRole 进行关联
4. 配置 kubeconfig,使用 kubectl 验证
1.创建role
# bmw-svc-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader
rules:
- apiGroups:
- ""
resources:
- pods
- pods/status
- pods/log
- services
- services/status
- endpoints
- endpoints/status
verbs:
- get
- list
- watch
# bmw-svc-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader
rules:
- apiGroups:
- ""
resources:
- pods
- pods/status
- pods/log
- services
- services/status
- endpoints
- endpoints/status
verbs:
- get
- list
- watch
2.serviceAccount
$ kubectl create serviceaccount bmw-svc
$ kubectl get sa bmw-svc -o yaml
$ kubectl get secrets bmw-svc-token-8f9js -o yaml
$ kubectl create serviceaccount bmw-svc
$ kubectl get sa bmw-svc -o yaml
$ kubectl get secrets bmw-svc-token-8f9js -o yaml
3.创建角色绑定
# bmw-svc-rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: bmw-svc-role
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: bmw-svc-role
subjects:
- kind: ServiceAccount
name: bmw-svc
namespace: default
# bmw-svc-rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: bmw-svc-role
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: bmw-svc-role
subjects:
- kind: ServiceAccount
name: bmw-svc
namespace: default
4.修改config view
#kubectl config view
...
- context:
cluster: kubernetes
user: bmw-svc
name: bmw-svc
- context:
cluster: kubernetes
user: admin
name: kubernetes
...
users:
- name: admin
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
- name: bmw-svc
user:
token: xxxx
#kubectl config view
...
- context:
cluster: kubernetes
user: bmw-svc
name: bmw-svc
- context:
cluster: kubernetes
user: admin
name: kubernetes
...
users:
- name: admin
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
- name: bmw-svc
user:
token: xxxx
- 查看上下文
[root@kube-master manifests]# kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
* kubernetes-admin@kubernetes kubernetes kubernetes-admin
[root@kube-master manifests]# kubectl config get-users
NAME
kubernetes-admin
[root@kube-master manifests]# kubectl config get-clusters
NAME
kubernetes
#切换context:
$ kubectl config use-context bmw-svc
[root@kube-master manifests]# kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
* kubernetes-admin@kubernetes kubernetes kubernetes-admin
[root@kube-master manifests]# kubectl config get-users
NAME
kubernetes-admin
[root@kube-master manifests]# kubectl config get-clusters
NAME
kubernetes
#切换context:
$ kubectl config use-context bmw-svc
role实践2
- 创建命名空间
kubectl create namespace test-namespace
kubectl create namespace test-namespace
- 创建 Role
创建一个 Role,允许在 test-namespace 命名空间中查看 Pods 和 Services
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: test-namespace
name: viewer-role
rules:
- apiGroups: [""]
resources: ["pods", "services"]
verbs: ["get", "list"]
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: test-namespace
name: viewer-role
rules:
- apiGroups: [""]
resources: ["pods", "services"]
verbs: ["get", "list"]
kubectl apply -f viewer-role.yaml
kubectl apply -f viewer-role.yaml
- 创建 ServiceAccount
创建一个 ServiceAccount,命名为 viewer-sa,用于测试授权效果
kubectl -n test-namespace create serviceaccount viewer-sa
kubectl -n test-namespace create serviceaccount viewer-sa
- 创建 RoleBinding
将 Role viewer-role 绑定到 ServiceAccount viewer-sa
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: viewer-rolebinding
namespace: test-namespace
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: viewer-role
subjects:
- kind: ServiceAccount
name: viewer-sa
namespace: test-namespace
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: viewer-rolebinding
namespace: test-namespace
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: viewer-role
subjects:
- kind: ServiceAccount
name: viewer-sa
namespace: test-namespace
kubectl apply -f viewer-rolebinding.yaml
kubectl apply -f viewer-rolebinding.yaml
- 验证权限
使用 kubectl auth can-i 命令验证 viewer-sa 是否可以查看 Pods 和 Services
kubectl -n test-namespace auth can-i get pods --as=system:serviceaccount:test-namespace:viewer-sa
kubectl -n test-namespace auth can-i list services --as=system:serviceaccount:test-namespace:viewer-sa
kubectl -n test-namespace auth can-i get pods --as=system:serviceaccount:test-namespace:viewer-sa
kubectl -n test-namespace auth can-i list services --as=system:serviceaccount:test-namespace:viewer-sa
cluster实践3
- 创建 ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: viewer-clusterrole
rules:
- apiGroups: [""]
resources: ["pods", "services"]
verbs: ["get", "list"]
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: viewer-clusterrole
rules:
- apiGroups: [""]
resources: ["pods", "services"]
verbs: ["get", "list"]
kubectl apply -f viewer-clusterrole.yaml
kubectl apply -f viewer-clusterrole.yaml
- 创建 ClusterRoleBinding
将 ClusterRole viewer-clusterrole 绑定到 viewer-sa
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: viewer-clusterrolebinding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: viewer-clusterrole
subjects:
- kind: ServiceAccount
name: viewer-sa
namespace: test-namespace
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: viewer-clusterrolebinding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: viewer-clusterrole
subjects:
- kind: ServiceAccount
name: viewer-sa
namespace: test-namespace
kubectl apply -f viewer-clusterrolebinding.yaml
kubectl apply -f viewer-clusterrolebinding.yaml
2. 推荐配置
访问资源 | 角色类型 | 绑定类型 |
---|---|---|
集群级别的资源(Nodes,PersistentVolumes,……) | ClusterRole | ClusterRoleBinding |
非资源URL(/api,/healthz……) | ClusterRole | ClusterRoleBinding |
在任何名称空间中的资源(跨所有名称空间的资源) | ClusterRole | ClusterRoleBinding |
具体名称空间中的资源(在多个名称空间中重用这个相同的ClusterRole | ClusterRole | RoleBinding |
在具体名称空间中的资源(Role必须在每个名称空间中定义) | Role | RoleBinding |
2.1 总结
#创建ServiceAccount
kubectl create serviceaccount 服务账号名
#将ServiceAccount分配给pod
在pod的manifest配置文件中指定ServiceAccount名:
serviceAccountName: 服务账号名
#RBAC4种角色资源
Role: 常规角色.定义了对某个资源具有某种访问权限
RoleBinding: 常规角色绑定.定义了该角色绑定到哪个主体
ClusterRole: 集群角色.同上
ClusterRoleBinding: 集群角色绑定.同上
区别在于:
常规角色和集群角色绑定作用于某个名称空间下.
集群角色和集群角色绑定作用于整个集群,不受限于任何名称空间
#创建ServiceAccount
kubectl create serviceaccount 服务账号名
#将ServiceAccount分配给pod
在pod的manifest配置文件中指定ServiceAccount名:
serviceAccountName: 服务账号名
#RBAC4种角色资源
Role: 常规角色.定义了对某个资源具有某种访问权限
RoleBinding: 常规角色绑定.定义了该角色绑定到哪个主体
ClusterRole: 集群角色.同上
ClusterRoleBinding: 集群角色绑定.同上
区别在于:
常规角色和集群角色绑定作用于某个名称空间下.
集群角色和集群角色绑定作用于整个集群,不受限于任何名称空间
3.RBAC案例
角色(权限的集合)
- Role:授权特定命名空间的访问权限
- ClusterRole:授权所有命名空间的访问权限(集群角色)
角色绑定
- RoleBinding:将角色(Role)绑定到主体(即subject)
- ClusterRoleBinding:将集群角色(ClusterRole)绑定到主体
主体(subject)
- User:用户
- Group:用户组
- ServiceAccount:服务账号
Role ---> RoleBinding ---> User/Group/ServiceAccount
ClusterRole ---> ClusterRoleBinding ---> User/Group/ServiceAccount
#将准备要设置赋予的权限,放到角色(Role/ClusterRole)里,
#通过角色绑定(RoleBinding/ClusterRoleBinding)
#将权限放在绑定到主体(User/Group/ServiceAccount)上
Role ---> RoleBinding ---> User/Group/ServiceAccount
ClusterRole ---> ClusterRoleBinding ---> User/Group/ServiceAccount
#将准备要设置赋予的权限,放到角色(Role/ClusterRole)里,
#通过角色绑定(RoleBinding/ClusterRoleBinding)
#将权限放在绑定到主体(User/Group/ServiceAccount)上
3.1 部署cfssl
为 Han用户授权 nginx 命名空间的 Pod 读取权限
1.创建CA证书签名请求文件
cat > han-ca-csr.json << EOF
{
"CN": "han",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "k8s",
"OU": "System"
}
]
}
EOF
# "CN: feiyi": Common Name,feiyi作为之后要授权的用户
# C: 国家 ST: 州/省 L: 地区/城市
# O: Organization,kube-apiserver 从证书中提取该字段作为请求用户所属的组 (Group),也就是feiyi用户所属的组,之后也可给该组授权
# OU: 组织单位名称,公司部门
cat > han-ca-csr.json << EOF
{
"CN": "han",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "k8s",
"OU": "System"
}
]
}
EOF
# "CN: feiyi": Common Name,feiyi作为之后要授权的用户
# C: 国家 ST: 州/省 L: 地区/城市
# O: Organization,kube-apiserver 从证书中提取该字段作为请求用户所属的组 (Group),也就是feiyi用户所属的组,之后也可给该组授权
# OU: 组织单位名称,公司部门
2. 部署k8s使用当时生成CA 签发证书
cfssl gencert \
-ca=/etc/kubernetes/pki/ca.crt \
-ca-key=/etc/kubernetes/pki/ca.key \
-config=ca-config.json \
-profile=kubernetes han-ca-csr.json | cfssljson -bare han
# -ca: 指定k8s的ca文件所在位置
# -ca-key: 指定k8s的ca密钥文件所在位置
# -config: 指定刚刚创建好的CA-config.json文件
# -profile: 指定ca-config.json中的profile---kubernetes
# cfssljson -bare han:将以上信息解析,生成以han为前缀的证书文件
cfssl gencert \
-ca=/etc/kubernetes/pki/ca.crt \
-ca-key=/etc/kubernetes/pki/ca.key \
-config=ca-config.json \
-profile=kubernetes han-ca-csr.json | cfssljson -bare han
# -ca: 指定k8s的ca文件所在位置
# -ca-key: 指定k8s的ca密钥文件所在位置
# -config: 指定刚刚创建好的CA-config.json文件
# -profile: 指定ca-config.json中的profile---kubernetes
# cfssljson -bare han:将以上信息解析,生成以han为前缀的证书文件
新增三个文件
han-key.pem # ca的私钥
han.pem # ca证书
han.csr # 签署请求
han-key.pem # ca的私钥
han.pem # ca证书
han.csr # 签署请求
3.2 创建kubeconfig 授权文件
在创建完集群后,会让你执行如下命令
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
- 把集群信息写入kubeconfig文件
# 因为创建的kubeconfig也将作用于K8S集群,所以需要指定K8S的API信息
kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/pki/ca.crt \
--embed-certs=true \
--server=https://192.168.1.11:6443 \
--kubeconfig=han.kubeconfig
# --certificate-authority:ca证书
# --server:apiserver地址
# --kubeconfig:根据给定的信息生成的kubeconfig名字
# --embed-certs:为true时,将证书信息写入kubeconfig文件;为false时,在kubeconfig文件中引用证书所在路径
################################################################
# 这一步主要生成了以下信息
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0t
...
ejhKYld1OHY3WmI4TVR2MG9GVQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
server: https://192.168.1.11:6443
name: kubernetes
# 因为创建的kubeconfig也将作用于K8S集群,所以需要指定K8S的API信息
kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/pki/ca.crt \
--embed-certs=true \
--server=https://192.168.1.11:6443 \
--kubeconfig=han.kubeconfig
# --certificate-authority:ca证书
# --server:apiserver地址
# --kubeconfig:根据给定的信息生成的kubeconfig名字
# --embed-certs:为true时,将证书信息写入kubeconfig文件;为false时,在kubeconfig文件中引用证书所在路径
################################################################
# 这一步主要生成了以下信息
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0t
...
ejhKYld1OHY3WmI4TVR2MG9GVQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
server: https://192.168.1.11:6443
name: kubernetes
客户端信息写入 kubeconfig
kubectl config set-credentials han \
--client-key=han-key.pem \
--client-certificate=han.pem \
--embed-certs=true \
--kubeconfig=han.kubeconfig
# set-credentials: 在 kubeconfig 中设置用户条目
# --client-key: 指定刚才生成私钥
# --client-certificate=han.pem: 指定生成的数字证书
# --kubeconfig: 将客户端信息加入刚才生成的kubeconfig文件中
################################################################
# 这一步主要生成了以下信息
users:
- name: han
user:
client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0
...
Si8rbHRhdXM4UWFRVmhCOHlndz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
client-key-data: LS0tLS1CRUdJTi BSU0EgUFJJVkFURSBLRVktLS0tLQp
...
ck9xK0pFdDJDNGpidmh0Ci0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg==
kubectl config set-credentials han \
--client-key=han-key.pem \
--client-certificate=han.pem \
--embed-certs=true \
--kubeconfig=han.kubeconfig
# set-credentials: 在 kubeconfig 中设置用户条目
# --client-key: 指定刚才生成私钥
# --client-certificate=han.pem: 指定生成的数字证书
# --kubeconfig: 将客户端信息加入刚才生成的kubeconfig文件中
################################################################
# 这一步主要生成了以下信息
users:
- name: han
user:
client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0
...
Si8rbHRhdXM4UWFRVmhCOHlndz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
client-key-data: LS0tLS1CRUdJTi BSU0EgUFJJVkFURSBLRVktLS0tLQp
...
ck9xK0pFdDJDNGpidmh0Ci0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg==
上下文信息写入 kubeconfig
设置默认上下文加入 kubeconfig:如果存在多套集群,通过设置上下文可以在多套集群间切换
kubectl config set-context kubernetes \
--cluster=kubernetes \
--user=han \
--kubeconfig=han.kubeconfig
# set-context: 设置上下文,默认在名为kubernetes的集群
# --user=han: 使用客户端用户为han
# --cluster=kubernetes: 用户作用到名为kubernetes的集群
# --kubeconfig:将上下文信息加入刚才生成的kubeconfig文件中
################################################################
# 这一步主要生成了以下信息,表示使用feiyi用户访问集群kubernetes
contexts:
- context:
cluster: kubernetes
user: han
name: kubernetes
kubectl config set-context kubernetes \
--cluster=kubernetes \
--user=han \
--kubeconfig=han.kubeconfig
# set-context: 设置上下文,默认在名为kubernetes的集群
# --user=han: 使用客户端用户为han
# --cluster=kubernetes: 用户作用到名为kubernetes的集群
# --kubeconfig:将上下文信息加入刚才生成的kubeconfig文件中
################################################################
# 这一步主要生成了以下信息,表示使用feiyi用户访问集群kubernetes
contexts:
- context:
cluster: kubernetes
user: han
name: kubernetes
3.3 验证
kubectl get node -n nginx --kubeconfig=han.kubeconfig
Error from server (Forbidden): pods is forbidden: User "han" cannot list resource "pods" in API group "" in the namespace "nginx"
#这是因为现在生成的 kubeconfig 还没有任何权限,所以任何资源还无法访问
kubectl get node -n nginx --kubeconfig=han.kubeconfig
Error from server (Forbidden): pods is forbidden: User "han" cannot list resource "pods" in API group "" in the namespace "nginx"
#这是因为现在生成的 kubeconfig 还没有任何权限,所以任何资源还无法访问
3.4 创建 RBAC 权限策略
仅给予查看 default命名空间的 pod 资源
$ vim han-rbac.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default # 将权限给到nginx命名空间
name: rbac-test
rules:
- apiGroups: [""] # 如果为空,则代表核心组(一般不指定),可以指定多个
resources: ["pods"] # 仅允许该role对pod操作,可以指定多个
verbs: ["get", "watch", "list"] # 对pod 所作的操作
---
# 将role绑定到user
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
namespace: default
name: rbac-test-binding
subjects:
- kind: User
name: han # 该名为生成证书时的CN名字
apiGroup: rbac.authorization.k8s.io
roleRef: # 指定上面创建的Role与han绑定
kind: Role
name: rbac-test
apiGroup: rbac.authorization.k8s.io
$ vim han-rbac.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default # 将权限给到nginx命名空间
name: rbac-test
rules:
- apiGroups: [""] # 如果为空,则代表核心组(一般不指定),可以指定多个
resources: ["pods"] # 仅允许该role对pod操作,可以指定多个
verbs: ["get", "watch", "list"] # 对pod 所作的操作
---
# 将role绑定到user
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
namespace: default
name: rbac-test-binding
subjects:
- kind: User
name: han # 该名为生成证书时的CN名字
apiGroup: rbac.authorization.k8s.io
roleRef: # 指定上面创建的Role与han绑定
kind: Role
name: rbac-test
apiGroup: rbac.authorization.k8s.io
- 执行
kubectl apply -f han-rbac.yaml
kubectl apply -f han-rbac.yaml
文档参考