RBAC 介绍
在 Kubernetes 中,所有资源对象都是通过 API 进行操作,他们保存在 etcd
里。而对 etcd 的操作我们需要通过访问 kube-apiserver
来实现,上面的 Service Account 其实就是 APIServer 的认证过程,而授权的机制是通过 RBAC
:基于角色的访问控制实现。
在 Kubernetes 的1.21.2版本上默认使用的是Node和RBAC。
# kubeadm部署的k8s可以在/etc/kubernetes/manifests下查看到静态pod的yaml文件
root@k8s-master01:/etc/kubernetes/manifests# grep authorization kube-apiserver.yaml
- --authorization-mode=Node,RBAC
# Node是专用于向kubelet授权使用。
# RBAC是基于角色的范文控制
常用授权逻辑
DAC
(自主访问控制)MAC
(强制访问控制)RBAC
(基于角色的访问控制)ABAC
(基于属性的访问控制)
RBAC
RBAC:Role-Based Access Control
简单来说,就是通过将权限分配给➡角色,再将角色分配给➡用户,来实现对系统资源的访问控制。
在一个组织内把一个组织内应该具有的权限的集合定义成多个角色,然后设定某个用户可以扮演其中1到多个角色。从而让某个用户拥有在组织内的某个授权。
k8s的RBAC是一种许可授权,只允许用户做什么事情,默认拒绝所有。未显示指定授予的权限,默认都会被拒绝。
Role --> Verbs --> Objects
ClusterRole --> Verbs --> Objects
Subject --> RoleBinding --> Roles
Subject --> ClusterRoleBinding --> ClusterRoles
Subject --> RoleBinding --> ClusterRoles
k8s 的 API-Server
是 RESTful 风格的 http/https 服务,其权限无非就是基于http协议所能支持的 GET, POST, PUT, DELETE, PATCH, ...等操作,在 API-Server
上 Object 指的是资源对象。
所谓的权限也就是,Action 能施加到哪些对象上;
RBAC四个资源类型
Role
: 角色,名称空间级别;ClusterRole
:集群角色,全局级别;RoleBinding
:"角色绑定",指是将用户与角色关联起来,意味着,用户仅得到了特定名称空间下的Role的权限,作用范围也限于该名称空间;ClusterRoleBinding
:集群角色绑定,让用户扮演指定的集群角色;意味着,用户得到了是集群级别的权限,作用范围也是集群级别;
User --> Rolebindig --> ClusterRole:权限降级,ClusterRole,用户得到的权限仅是 ClusterRole 的权限在 Rolebinding 所属的名称空间上的一个子集;
系统上默认的ROLE
1.查看系统上默认的role
extension-apiserver-authentication-reader 2024-04-15T06:14:01Z
kube-proxy 2024-04-15T06:14:03Z
kubeadm:kubelet-config-1.21 2024-04-15T06:14:01Z
kubeadm:nodes-kubeadm-config 2024-04-15T06:14:01Z
system::leader-locking-kube-controller-manager 2024-04-15T06:14:01Z
system::leader-locking-kube-scheduler 2024-04-15T06:14:01Z
system:controller:bootstrap-signer 2024-04-15T06:14:01Z
system:controller:cloud-provider 2024-04-15T06:14:01Z
system:controller:token-cleaner 2024-04-15T06:14:01Z
2.查看kube-proxy的role中的内容
root@k8s-master01:~# kubectl get role kube-proxy -n kube-system -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
creationTimestamp: "2024-04-15T06:14:03Z"
name: kube-proxy
namespace: kube-system
resourceVersion: "299"
uid: b92871dd-4224-4f31-8fe2-0c4b89ca40ff
rules:
- apiGroups:
- ""
resourceNames:
- kube-proxy
resources:
- configmaps
verbs:
- get
能接受施加Verb的目标有三类:
resources
:资源类型,该类型下的所有对象都是目标, pods;resourceNames
:特定的对象个体,pods/mypod;nonResourceURLs
:非资源型的URL,/status.
能施加的Verb有以下:
- create、get、list、delete、patch、update
RBAC示例
rbac资源清单创建示例
1.使用资源清单来创建role
root@k8s-master01:~/yaml/chapter09# vim pods-reader-rbac.yaml
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: pods-reader
namespace: default
rules:
- apiGroups: [""]
resources: ["pods","services","pods/log"]
verbs: ["get","list","watch"]
2.将其应用到集群上
root@k8s-master01:~/yaml/chapter09# kubectl apply -f pods-reader-rbac.yaml
role.rbac.authorization.k8s.io/pods-reader created
# 角色已经在default名称空间下生成
root@k8s-master01:~/yaml/chapter09# kubectl get role
NAME CREATED AT
pods-reader 2021-08-02T06:44:03Z
3.角色需要将其绑定到用户上
root@k8s-master01:~/yaml/chapter09# vim darius-pods-reader.yaml
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: darius-pods-reader
namespace: default
subjects:
- kind: User
name: darius
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pods-reader
apiGroup: rbac.authorization.k8s.io
4.应用绑定
root@k8s-master01:~/yaml/chapter09# kubectl apply -f darius-pods-reader.yaml
rolebinding.rbac.authorization.k8s.io/darius-pods-reader created
5.使用darius账号进行测试
root@k8s-master01:~/yaml/chapter09# kubectl get pods --kubeconfig=/tmp/newkubeconfig --context=darius@kubernetes
NAME READY STATUS RESTARTS AGE
configmaps-env-demo 1/1 Running 0 17d
configmaps-volume-demo 1/1 Running 0 17d
configmaps-volume-demo2 2/2 Running 0 17d
configmaps-volume-demo3 1/1 Running 0 16d
cronjob-demo-27131450-85h7z 0/1 Completed 0 5m1s
cronjob-demo-27131452-xqqrk 0/1 Completed 0 3m1s
cronjob-demo-27131454-fn7fp 0/1 Completed 0 61s
daemonset-demo-6qqmt 1/1 Running 0 11d
daemonset-demo-fvkhj 1/1 Running 0 11d
daemonset-demo-pxmrd 1/1 Running 0 11d
demodb-0 1/1 Running 0 6d5h
demodb-1 1/1 Running 0 6d5h
deployment-demo-77d46c4794-5whvx 1/1 Running 0 11d
# 已经能正常获取pods资源。
集群管理角色
admin集群管理角色
在 k8s 系统上存在一个 admin 的 ClusterRole,其作用的范围为集群范围,其内部定义了核心资源类型当中的非集群级别资源的管理权限。此 admin 拥有除集群级别之外的所有管理权限。
root@k8s-master01:~/yaml/chapter09# kubectl get clusterrole admin
NAME CREATED AT
admin 2024-04-15T06:13:59Z
如果我们使用 ClusterRolebinding
将某个用户绑定在 admin 这个 ClusterRole
上那么其将拥有除了集群级别管理权限之外的所有管理权限。
cluster-admin集群管理角色
cluster-admin
是集群管理员,其拥有k8s的一切管理权限。
root@k8s-master01:~/yaml/chapter09# kubectl get clusterrole cluster-admin
NAME CREATED AT
cluster-admin 2024-04-15T06:13:59Z
如果将某个用户以 clusterRoleBinding
绑定在 cluster-admin
那其将拥有集群级别的一切操作管理权限。
rbac命令行创建示例
admin集群管理角色绑定示例:
此处为了不予刚才示例混淆,先将 darius 的 role
和 rolebinding
删除
root@k8s-master01:~/yaml/chapter09# kubectl delete rolebindings.rbac.authorization.k8s.io darius-pods-reader
rolebinding.rbac.authorization.k8s.io "darius-pods-reader" deleted
root@k8s-master01:~/yaml/chapter09# kubectl delete role pods-reader
role.rbac.authorization.k8s.io "pods-reader" deleted
1.将用户于admin的clusterRole进行绑定
root@k8s-master01:~/yaml/chapter09# kubectl create clusterrolebinding darius-admin --user=darius --clusterrole=admin
clusterrolebinding.rbac.authorization.k8s.io/darius-admin created
2.使用darius账号进行测试
root@k8s-master01:~/yaml/chapter09# kubectl get pods -n kube-system --kubeconfig=/tmp/newkubeconfig --context=darius@kubernetes
NAME READY STATUS RESTARTS AGE
coredns-6f6b8cc4f6-8wm8v 1/1 Running 0 18d
coredns-6f6b8cc4f6-tzmnm 1/1 Running 0 18d
etcd-k8s-master01 1/1 Running 1 18d
kube-apiserver-k8s-master01 1/1 Running 1 18d
kube-controller-manager-k8s-master01 1/1 Running 1 18d
kube-flannel-ds-dl2rq 1/1 Running 0 18d
kube-flannel-ds-fmml6 1/1 Running 0 18d
kube-flannel-ds-rwh5f 1/1 Running 0 18d
kube-flannel-ds-tqbbv 1/1 Running 0 18d
kube-proxy-6qdpb 1/1 Running 0 18d
kube-proxy-kp5ch 1/1 Running 0 18d
kube-proxy-ntmzb 1/1 Running 0 18d
kube-proxy-vwdm8 1/1 Running 0 18d
kube-scheduler-k8s-master01 1/1 Running 1 18d
此时其能访问到 kube-system
的资源了。但是集群级别的操作依旧不能使用。
# 查看nodes相关资源
root@k8s-master01:~/yaml/chapter09# kubectl get nodes --kubeconfig=/tmp/newkubeconfig --context=darius@kubernetes
Error from server (Forbidden): nodes is forbidden: User "darius" cannot list resource "nodes" in API group "" at the cluster scope
# 权限被拒绝,因为admin的ClusterRole没有此授权。
cluster-admin集群管理角色绑定示例:
将此前创建的admin相关的 clusterrolebinding
进行删除,以免干扰
root@k8s-master01:~/yaml/chapter09# kubectl delete clusterrolebindings darius-admin
clusterrolebinding.rbac.authorization.k8s.io "darius-admin" deleted
3.将darius用户使用clusterRolebinding绑定到cluster-admin这个roles上
root@k8s-master01:~/yaml/chapter09# kubectl create clusterrolebinding darius-cluster-admin --user=darius --clusterrole=cluster-admin
clusterrolebinding.rbac.authorization.k8s.io/darius-cluster-admin created
4.再次测试其能否进行集群级别的操作
root@k8s-master01:~/yaml/chapter09# kubectl get nodes --kubeconfig=/tmp/newkubeconfig --context=darius@kubernetes
NAME STATUS ROLES AGE VERSION
k8s-master01 Ready control-plane,master 18d v1.21.2
k8s-node01 Ready <none> 18d v1.21.2
k8s-node02 Ready <none> 18d v1.21.2
k8s-node03 Ready <none> 18d v1.21.2
授权其他话题
组在k8s中的作用
在k8s中 cluster-admin
是将 system:masters
组绑定在 cluster-admin
之上的。那么组内的所有用户都将拥有此权限。
root@k8s-master01:~/yaml/chapter09# kubectl describe clusterrolebindings.rbac.authorization.k8s.io cluster-admin
Name: cluster-admin
Labels: kubernetes.io/bootstrapping=rbac-defaults
Annotations: rbac.authorization.kubernetes.io/autoupdate: true
Role:
Kind: ClusterRole
Name: cluster-admin
Subjects:
Kind Name Namespace
---- ---- ---------
Group system:masters
对于证书认证来说组信息在Subj中的O内存放,如果其O内存放的为 system:master
那么所创建的用户自动拥有管理员权限,无需再授权。
验证
# 生成私钥文件
root@k8s-master01:/etc/kubernetes/usercerts# (umask 077;openssl genrsa -out testadm.key 2048)
Generating RSA private key, 2048 bit long modulus (2 primes)
.....................................................................................................+++++
............+++++
e is 65537 (0x010001)
# 生成证书签署请求,此处subj中的O使用system:masters
root@k8s-master01:/etc/kubernetes/usercerts# openssl req -new -key testadm.key -out testadm.csr -subj "/CN=testadm/O=system:masters"
# 使用k8s集群的证书和私钥对证书签署请求进行签发
root@k8s-master01:/etc/kubernetes/usercerts# openssl x509 -req -days 3655 -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -in testadm.csr -out testadm.crt
Signature ok
subject=CN = testadm, O = system:masters
Getting CA Private Key
# 以下为制作kubeconfig文件
# 在kubeconfig文件中设定集群
root@k8s-master01:/etc/kubernetes/usercerts# kubectl config set-cluster kubernetes --server=https://kube-api:6443 --embed-certs --certificate-authority=/etc/kubernetes/pki/ca.crt --kubeconfig=/tmp/testadmcfg
Cluster "kubernetes" set.
# 在kubeconfig文件中设定用户
root@k8s-master01:/etc/kubernetes/usercerts# kubectl config set-credentials testadm --client-certificate=testadm.crt --client-key=testadm.key --embed-certs=true --kubeconfig=/tmp/testadmcfg
User "testadm" set.
# 在kubeconfig文件中设定用户和集群的关联关系
root@k8s-master01:/etc/kubernetes/usercerts# kubectl config set-context 'testadm@kubernetes' --user=testadm --cluster=kubernetes --kubeconfig=/tmp/testadmcfg
Context "testadm@kubernetes" created.
# 在kubeconfig文件中设定当前使用的账号
root@k8s-master01:/etc/kubernetes/usercerts# kubectl config use-context testadm@kubernetes --kubeconfig=/tmp/testadmcfg
Switched to context "testadm@kubernetes".
# 当前账号没有进行授权,使用该账号获取集群信息。
root@k8s-master01:/etc/kubernetes/usercerts# kubectl get nodes --kubeconfig=/tmp/testadmcfg
NAME STATUS ROLES AGE VERSION
k8s-master01 Ready control-plane,master 18d v1.21.2
k8s-node01 Ready <none> 18d v1.21.2
k8s-node02 Ready <none> 18d v1.21.2
k8s-node03 Ready <none> 18d v1.21.2
以上结果可以看出证书认证中 O
这一项如果为 system:masters
则无需再进行授权就能对集群进行操作。组这一项对k8s来说至关重要。
rolebinding来绑定ClusterRole
rolebinding
来绑定 ClusterRole
则以为着降级,其会将集群级别的操作限定在名称空间内。
验证
避免干扰先将此前创建的 clusterrolebinding
进行删除
root@k8s-master01:/etc/kubernetes/usercerts# kubectl delete clusterrolebindings darius-cluster-admin
clusterrolebinding.rbac.authorization.k8s.io "darius-cluster-admin" deleted
1.将darius用户使用 rolebinding
绑定到 cluster-admin
这个 ClusterRole
上
root@k8s-master01:/etc/kubernetes/usercerts# kubectl create rolebinding darius-admin --user=darius --clusterrole=cluster-admin
rolebinding.rbac.authorization.k8s.io/darius-admin created
# 注意此处rolebing时没有指定名称空间表示默认名称空间,darius用户的权限会限定在default名称空间下
# 如果指定了名称空间如"-n dev",darius用户则会被限定在dev名称空间下。
2.验证
# 测试访问默认名称空间内的资源
root@k8s-master01:/etc/kubernetes/usercerts# kubectl get svc --kubeconfig=/tmp/newkubeconfig --context=darius@kubernetes
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
demoapp-svc ClusterIP 10.102.254.190 <none> 80/TCP 11d
demodb ClusterIP None <none> 9907/TCP 7d3h
# 访问其他名称空间内的资源
root@k8s-master01:/etc/kubernetes/usercerts# kubectl get svc -n kube-system --kubeconfig=/tmp/newkubeconfig --context=darius@kubernetes
Error from server (Forbidden): services is forbidden: User "darius" cannot list resource "services" in API group "" in the namespace "kube-system"
root@k8s-master01:/etc/kubernetes/usercerts# kubectl get svc -n dev --kubeconfig=/tmp/newkubeconfig --context=darius@kubernetes
Error from server (Forbidden): services is forbidden: User "darius" cannot list resource "services" in API group "" in the namespace "dev"
rolebinding绑定ServiceAccount
创建一个 ServiceAccount
,并将其使用 rolebinding
绑定到admin的 ClusterRole
上
# 创建ServiceAccount
root@k8s-master01:/etc/kubernetes/usercerts# kubectl create serviceaccount dev-admin
serviceaccount/dev-admin created
# 创建rolebinding将dev-admin的sa绑定到admin这个ClusterRole上
root@k8s-master01:~# kubectl create rolebinding dev-admin --clusterrole=admin --serviceaccount=dev:dev-admin -n dev
rolebinding.rbac.authorization.k8s.io/dev-admin created
# dev:dev-admin表示dev名称空间下的dev-admin的ServiceAccount
以上操作后,如果有pod的 ServiceAcountName
为 dev-admin
那么此pod将拥有该名称空间下的所有操作权限。