本文主要基于Kubernetes1.21.9和Linux操作系统CentOS7.4。
服务器版本 | docker软件版本 | Kubernetes(k8s)集群版本 | CPU架构 |
---|---|---|---|
CentOS Linux release 7.4.1708 (Core) | Docker version 20.10.12 | v1.21.9 | x86_64 |
Kubernetes集群架构:k8scloude1作为master节点,k8scloude2,k8scloude3作为worker节点。
服务器 | 操作系统版本 | CPU架构 | 进程 | 功能描述 |
---|---|---|---|---|
k8scloude1/192.168.110.130 | CentOS Linux release 7.4.1708 (Core) | x86_64 | docker,kube-apiserver,etcd,kube-scheduler,kube-controller-manager,kubelet,kube-proxy,coredns,calico | k8s master节点 |
k8scloude2/192.168.110.129 | CentOS Linux release 7.4.1708 (Core) | x86_64 | docker,kubelet,kube-proxy,calico | k8s worker节点 |
k8scloude3/192.168.110.128 | CentOS Linux release 7.4.1708 (Core) | x86_64 | docker,kubelet,kube-proxy,calico | k8s worker节点 |
Kubernetes作为目前最流行的容器编排平台之一,提供了强大的安全性能。在Kubernetes集群中,访问控制是保障集群安全的重要组成部分。其中,权限管理是访问控制的核心。本篇博客将介绍Kubernetes中的权限管理机制之RBAC鉴权。
使用RBAC鉴权的前提是已经有一套可以正常运行的Kubernetes集群,关于Kubernetes(k8s)集群的安装部署,可以查看博客《Centos7 安装部署Kubernetes(k8s)集群》https://www.cnblogs.com/renshengdezheli/p/16686769.html。
用户使用 kubectl、客户端库或构造 REST 请求来访问 Kubernetes API。 用户账户和 Kubernetes 服务账号都可以被鉴权访问 API。 当请求到达 API 时,它会经历多个阶段,如下图所示:
整体过程简述:请求发起方进行K8s API请求,建立 TLS 后,经过Authentication(认证)、Authorization(鉴权)、AdmissionControl(准入控制)三个阶段的校验,最后把请求转化为对K8s对象的变更操作持久化至etcd中。
关于Authentication(认证)详细内容请查看博客《Kubernetes(k8s)访问控制:身份认证》。
在Kubernetes中,鉴权(Authorization)是指检查用户是否有权限执行请求所需的操作的过程。鉴权机制由Kubernetes API server实现,并可以支持RBAC(基于角色的访问控制)、ABAC(基于属性的访问控制)和Node鉴权等多种方式。
RBAC/ABAC/Node鉴权区别:
在本篇博客中,我们将重点介绍RBAC鉴权。
如下是我们的kubernetes集群。
[root@k8scloude1 ~]# kubectl get nodes -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME k8scloude1 Ready control-plane,master 67d v1.21.0 192.168.110.130 <none> CentOS Linux 7 (Core) 3.10.0-693.el7.x86_64 docker://20.10.12 k8scloude2 Ready <none> 67d v1.21.0 192.168.110.129 <none> CentOS Linux 7 (Core) 3.10.0-693.el7.x86_64 docker://20.10.12 k8scloude3 Ready <none> 67d v1.21.0 192.168.110.128 <none> CentOS Linux 7 (Core) 3.10.0-693.el7.x86_64 docker://20.10.12
先准备一台机器作为访问k8s集群的客户端,机器etcd1作为客户端,不是k8s集群的一部分。
访问k8s集群需要客户端工具kubectl,下面安装kubectl,--disableexcludes=kubernetes 表示禁掉除了这个之外的别的仓库。
[root@etcd1 ~]# yum -y install kubectl-1.21.0-0 --disableexcludes=kubernetes
配置kubectl命令自动补全。
[root@etcd1 ~]# vim /etc/profile [root@etcd1 ~]# grep source /etc/profile source <(kubectl completion bash)
使配置生效。
[root@etcd1 ~]# source /etc/profile [root@etcd1 ~]# kubectl get node The connection to the server localhost:8080 was refused - did you specify the right host or port?
kubernetes默认的授权模式为:authorization-mode=Node,RBAC。
[root@k8scloude1 ~]# ls /etc/kubernetes/manifests/kube-apiserver.yaml /etc/kubernetes/manifests/kube-apiserver.yaml [root@k8scloude1 ~]# grep authorization-mode /etc/kubernetes/manifests/kube-apiserver.yaml - --authorization-mode=Node,RBAC
设置k8s允许所有请求访问。
[root@k8scloude1 ~]# vim /etc/kubernetes/manifests/kube-apiserver.yaml [root@k8scloude1 ~]# grep authorization-mode /etc/kubernetes/manifests/kube-apiserver.yaml #- --authorization-mode=Node,RBAC - --authorization-mode=AlwaysAllow
重启kubelet使配置生效。
[root@k8scloude1 ~]# systemctl restart kubelet [root@k8scloude1 ~]# systemctl status kubelet ● kubelet.service - kubelet: The Kubernetes Node Agent Loaded: loaded (/usr/lib/systemd/system/kubelet.service; enabled; vendor preset: disabled) Drop-In: /usr/lib/systemd/system/kubelet.service.d └─10-kubeadm.conf Active: active (running) since 五 2022-03-18 18:36:24 CST; 11s ago Docs: https://kubernetes.io/docs/ Main PID: 28054 (kubelet) Memory: 42.4M CGroup: /system.slice/kubelet.service └─28054 /usr/bin/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --config=/var/lib/kubelet/config.yaml --network-plugin=cni --pod-in...
当- --authorization-mode=AlwaysAllow 设置为允许所有请求之后,客户端机器可以随意访问所有资源。
kctest这个自定义的kubeconfig文件博客《Kubernetes(k8s)访问控制:身份认证》已经详细讲解过了,这里就不赘述了。
在etcd1机器上可以访问任何资源。
[root@etcd1 ~]# kubectl get nodes --kubeconfig=kctest NAME STATUS ROLES AGE VERSION k8scloude1 Ready control-plane,master 68d v1.21.0 k8scloude2 Ready <none> 68d v1.21.0 k8scloude3 Ready <none> 68d v1.21.0 [root@etcd1 ~]# kubectl get pod -A --kubeconfig=kctest NAMESPACE NAME READY STATUS RESTARTS AGE ingress-nginx ingress-nginx-admission-create-2lg57 0/1 Completed 0 31d ingress-nginx ingress-nginx-admission-patch-hd7p4 0/1 Completed 1 31d ingress-nginx ingress-nginx-controller-59b8bf5fdc-t2f7z 1/1 Running 14 31d kube-system calico-kube-controllers-6b9fbfff44-4jzkj 1/1 Running 78 68d kube-system calico-node-bdlgm 1/1 Running 38 68d kube-system calico-node-hx8bk 1/1 Running 38 68d kube-system calico-node-nsbfs 1/1 Running 38 68d kube-system coredns-545d6fc579-7wm95 1/1 Running 38 68d kube-system coredns-545d6fc579-87q8j 1/1 Running 38 68d kube-system etcd-k8scloude1 1/1 Running 38 68d kube-system kube-apiserver-k8scloude1 0/1 Running 1 8m36s kube-system kube-controller-manager-k8scloude1 1/1 Running 45 68d kube-system kube-proxy-599xh 1/1 Running 38 68d kube-system kube-proxy-lpj8z 1/1 Running 38 68d kube-system kube-proxy-zxlk9 1/1 Running 38 68d kube-system kube-scheduler-k8scloude1 1/1 Running 45 68d kube-system metrics-server-bcfb98c76-n4fnb 1/1 Running 42 60d metallb-system controller-7dcc8764f4-qdwl2 1/1 Running 24 34d metallb-system speaker-892pm 1/1 Running 16 34d metallb-system speaker-jfccb 1/1 Running 16 34d metallb-system speaker-nkrgk 1/1 Running 16 34d volume nfs-client-provisioner-76c576954d-5x7t2 1/1 Running 16 57d
设置k8s拒绝所有请求访问。
[root@k8scloude1 ~]# vim /etc/kubernetes/manifests/kube-apiserver.yaml #设置为拒绝所有请求 [root@k8scloude1 ~]# grep authorization-mode /etc/kubernetes/manifests/kube-apiserver.yaml #- --authorization-mode=Node,RBAC - --authorization-mode=AlwaysDeny
重启kubelet使配置生效。
[root@k8scloude1 ~]# systemctl restart kubelet
设置为拒绝所有请求 - --authorization-mode=AlwaysDeny之后,客户端机器访问不了了。
[root@etcd1 ~]# kubectl get pod -A --kubeconfig=kctest error: the server doesn't have a resource type "pod" [root@etcd1 ~]# kubectl get nodes --kubeconfig=kctest error: the server doesn't have a resource type "nodes" [root@etcd1 ~]# kubectl get node --kubeconfig=kctest error: the server doesn't have a resource type "node"
设置为拒绝所有请求 - --authorization-mode=AlwaysDeny之后,admin管理员用户无影响,其他用户访问不了。
[root@k8scloude1 ~]# kubectl get node NAME STATUS ROLES AGE VERSION k8scloude1 Ready control-plane,master 68d v1.21.0 k8scloude2 Ready <none> 68d v1.21.0 k8scloude3 Ready <none> 68d v1.21.0
RBAC支持基于角色的授权,即将一组权限分配给一个角色,再将该角色分配给一个或多个用户或服务账户。在Kubernetes中,RBAC鉴权由以下三个部分组成:
想要使用RBAC授权,需要恢复- --authorization-mode=Node,RBAC,想要查看什么,都是我们敲命令获取,其实有很多我们看不到的操作(比如master和worker之间交互查询,审计等等),- --authorization-mode=Node 表示允许worker向master查询相应信息,想要--authorization-mode=Node生效,--enable-admission-plugins=NodeRestriction准入控制器要开启。
[root@k8scloude1 ~]# vim /etc/kubernetes/manifests/kube-apiserver.yaml [root@k8scloude1 ~]# grep authorization-mode /etc/kubernetes/manifests/kube-apiserver.yaml - --authorization-mode=Node,RBAC #- --authorization-mode=AlwaysDeny
重启kubelet使配置生效。
[root@k8scloude1 ~]# systemctl restart kubelet
管理员拥有所有权限,查看管理员的权限就可以知道k8s有哪些权限。
[root@k8scloude1 ~]# kubectl describe clusterrole cluster-admin Name: cluster-admin Labels: kubernetes.io/bootstrapping=rbac-defaults Annotations: rbac.authorization.kubernetes.io/autoupdate: true PolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- *.* [] [] [*] [*] [] [*]
可以看到admin角色对各种资源Resources的权限Verbs。
[root@k8scloude1 ~]# kubectl describe clusterrole admin Name: admin Labels: kubernetes.io/bootstrapping=rbac-defaults Annotations: rbac.authorization.kubernetes.io/autoupdate: true PolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- rolebindings.rbac.authorization.k8s.io [] [] [create delete deletecollection get list patch update watch] roles.rbac.authorization.k8s.io [] [] [create delete deletecollection get list patch update watch] ...... services/proxy [] [] [get list watch create delete deletecollection patch update] bindings [] [] [get list watch] events [] [] [get list watch] limitranges [] [] [get list watch] namespaces/status [] [] [get list watch] namespaces [] [] [get list watch] persistentvolumeclaims/status [] [] [get list watch] pods/log [] [] [get list watch] pods/status [] [] [get list watch] replicationcontrollers/status [] [] [get list watch] ...... pods.metrics.k8s.io [] [] [get list watch] ingresses.networking.k8s.io/status [] [] [get list watch] poddisruptionbudgets.policy/status [] [] [get list watch] serviceaccounts [] [] [impersonate create delete deletecollection patch update get list watch]
注意:RBAC不是直接把权限授予用户,而是把权限都放在角色role里,再把角色role绑定rolebinding到用户,这样用户就具有了相应的权限,注意对于命名空间ns1里的角色role1,命名空间ns2不能使用。
除了role,还有clusterrole,role是归属于某一个namespace,clusterrole是全局生效的,clusterrole除了可以使用rolebinding绑定之外,还可以使用clusterrolebingding绑定,rolebinding归属于某一个命名空间,clusterrolebingding全局生效。
查看角色role。
[root@k8scloude1 ~]# kubectl get role No resources found in safe namespace. [root@k8scloude1 ~]# cd safe/
我们使用yaml文件的方式创建角色role :kubectl create role role1 --verb=get,list --resource=pods --dry-run=client -o yaml > role1.yaml。
--verb=get,list指定权限为get和list,--resource=pods表示权限作用在pod上。
[root@k8scloude1 safe]# kubectl create role role1 --verb=get,list --resource=pods --dry-run=client -o yaml > role1.yaml
查看yaml文件,功能为:在 Kubernetes 集群中创建一个叫做 "role1" 的角色(Role),该角色具有操作(Kubernetes Pod)的权限。
[root@k8scloude1 safe]# vim role1.yaml [root@k8scloude1 safe]# cat role1.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: creationTimestamp: null #name: role1: 该角色的名称为 "role1"。 name: role1 #rules: 角色的规则部分定义了角色能够执行的操作列表。 rules: #- apiGroups: [""]: apiGroups 字段指定资源所属的 API 组(或者不属于任何组)。在本例中,Pod 不属于任何 API 组,所以值为空字符串。 - apiGroups: - "" #resources: ["pods"]: resources 字段指定角色能够访问的资源列表。在本例中,只有 Pod 是被授权的资源。 resources: - pods #verbs: ["get", "list"]: verbs 字段列出了角色可用的动词列表。在本例中,角色可以执行 "get" 和 "list" 操作。这意味着此角色可以查看 Pod 的详细信息和列表信息。 verbs: - get - list
生成role。
[root@k8scloude1 safe]# kubectl apply -f role1.yaml role.rbac.authorization.k8s.io/role1 created
查看role。
[root@k8scloude1 safe]# kubectl get role NAME CREATED AT role1 2022-03-19T09:52:13Z
查看role的权限:对pod具有get list权限。
[root@k8scloude1 safe]# kubectl describe role role1 Name: role1 Labels: <none> Annotations: <none> PolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- pods [] [] [get list]
把角色role1绑定到test用户上,test用户不属于任何命名空间。
[root@k8scloude1 safe]# kubectl create rolebinding rolebind1 --role=role1 --user=test rolebinding.rbac.authorization.k8s.io/rolebind1 created
查看rolebinding。
[root@k8scloude1 safe]# kubectl get rolebinding NAME ROLE AGE rolebind1 Role/role1 110s
查看rolebind1的描述信息。
[root@k8scloude1 safe]# kubectl describe rolebinding rolebind1 Name: rolebind1 Labels: <none> Annotations: <none> Role: Kind: Role Name: role1 Subjects: Kind Name Namespace ---- ---- --------- User test
在客户端进行权限测试,把角色role1绑定给test用户之后,客户端具有了safe命名空间里pod的查询权限。
[root@etcd1 ~]# kubectl get pods --kubeconfig=kctest -n safe No resources found in safe namespace.
客户端不具有default命名空间里pod的查询权限。
[root@etcd1 ~]# kubectl get pods --kubeconfig=kctest Error from server (Forbidden): pods is forbidden: User "test" cannot list resource "pods" in API group "" in the namespace "default"
如下是使用nginx镜像创建pod的配置文件。
[root@etcd1 ~]# cat pod.yaml apiVersion: v1 kind: Pod metadata: labels: test: podtest name: podtest spec: #当需要关闭容器时,立即杀死容器而不等待默认的30秒优雅停机时长。 terminationGracePeriodSeconds: 0 containers: - name: nginx image: nginx #imagePullPolicy: IfNotPresent:表示如果本地已经存在该镜像,则不重新下载;否则从远程 Docker Hub 下载该镜像 imagePullPolicy: IfNotPresent
现在想在客户端创建一个pod,用户test只对pod有get ,list权限,没有创建pod权限,创建失败。
[root@etcd1 ~]# kubectl apply -f pod.yaml -n safe --kubeconfig=kctest Error from server (Forbidden): error when creating "pod.yaml": pods is forbidden: User "test" cannot create resource "pods" in API group "" in the namespace "safe"
修改yaml文件,添加pod的create权限。
[root@k8scloude1 safe]# vim role1.yaml [root@k8scloude1 safe]# cat role1.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: creationTimestamp: null name: role1 rules: - apiGroups: - "" resources: - pods #添加了创建权限create verbs: - get - list - create
应用role。
[root@k8scloude1 safe]# kubectl apply -f role1.yaml role.rbac.authorization.k8s.io/role1 configured
现在role1具有了对pod的get list create权限。
[root@k8scloude1 safe]# kubectl describe role role1 Name: role1 Labels: <none> Annotations: <none> PolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- pods [] [] [get list create]
role1添加pod的create权限之后,成功在客户端创建pod。
[root@etcd1 ~]# kubectl apply -f pod.yaml -n safe --kubeconfig=kctest pod/podtest created [root@etcd1 ~]# kubectl get pod -n safe --kubeconfig=kctest NAME READY STATUS RESTARTS AGE podtest 1/1 Running 0 22s
用户test没有pod删除权限。
[root@etcd1 ~]# kubectl delete pod podtest -n safe --kubeconfig=kctest Error from server (Forbidden): pods "podtest" is forbidden: User "test" cannot delete resource "pods" in API group "" in the namespace "safe"
给角色role1增加删除pod的权限。
[root@k8scloude1 safe]# vim role1.yaml [root@k8scloude1 safe]# cat role1.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: creationTimestamp: null name: role1 rules: - apiGroups: - "" resources: - pods #增加删除权限delete verbs: - get - list - create - delete
应用role。
[root@k8scloude1 safe]# kubectl apply -f role1.yaml role.rbac.authorization.k8s.io/role1 configured
现在role1具有了对pod的get list create delete权限。
[root@k8scloude1 safe]# kubectl describe role role1 Name: role1 Labels: <none> Annotations: <none> PolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- pods [] [] [get list create delete]
给角色role1增加删除pod的权限之后,客户端成功删除了pod。
[root@etcd1 ~]# kubectl delete pod podtest -n safe --kubeconfig=kctest pod "podtest" deleted [root@etcd1 ~]# kubectl get pod -n safe --kubeconfig=kctest No resources found in safe namespace.
test用户没有对services的list权限。
[root@etcd1 ~]# kubectl get svc -n safe --kubeconfig=kctest Error from server (Forbidden): services is forbidden: User "test" cannot list resource "services" in API group "" in the namespace "safe"
修改yaml文件,对role1添加service的get list create delete权限,注意:services不能简写。
[root@k8scloude1 safe]# vim role1.yaml [root@k8scloude1 safe]# cat role1.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: creationTimestamp: null name: role1 rules: - apiGroups: - "" #资源里增加services resources: - pods - services verbs: - get - list - create - delete
应用role。
[root@k8scloude1 safe]# kubectl apply -f role1.yaml role.rbac.authorization.k8s.io/role1 configured
查看角色的描述信息,角色role1增加了services的get list create delete权限。
[root@k8scloude1 safe]# kubectl describe role role1 Name: role1 Labels: <none> Annotations: <none> PolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- pods [] [] [get list create delete] services [] [] [get list create delete]
给角色role1增加了services的get list create delete权限之后,客户端可以查询svc了。
[root@etcd1 ~]# kubectl get svc -n safe --kubeconfig=kctest No resources found in safe namespace.
客户端没有对deployments的list权限。
[root@etcd1 ~]# kubectl get deploy -n safe --kubeconfig=kctest Error from server (Forbidden): deployments.apps is forbidden: User "test" cannot list resource "deployments" in API group "apps" in the namespace "safe"
修改yaml文件,给role1添加deployments的get list create delete权限。
[root@k8scloude1 safe]# vim role1.yaml [root@k8scloude1 safe]# cat role1.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: creationTimestamp: null name: role1 rules: - apiGroups: - "" resources: - pods - services - deployments verbs: - get - list - create - delete
应用role。
[root@k8scloude1 safe]# kubectl apply -f role1.yaml role.rbac.authorization.k8s.io/role1 configured
查看角色的描述信息,角色role1增加了deployments的get list create delete权限。
[root@k8scloude1 safe]# kubectl describe role role1 Name: role1 Labels: <none> Annotations: <none> PolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- deployments [] [] [get list create delete] pods [] [] [get list create delete] services [] [] [get list create delete]
给角色role1增加了deployments的get list create delete权限之后,客户端还是没有对deployments的list权限。
[root@etcd1 ~]# kubectl get deploy -n safe --kubeconfig=kctest Error from server (Forbidden): deployments.apps is forbidden: User "test" cannot list resource "deployments" in API group "apps" in the namespace "safe"
给角色role1增加了deployments的get list create delete权限之后,客户端还是没有对deployments的list权限,原因为:pod,service对应的apiVersion为v1,deploy对应的apiVersion为apps/v1。
apiVersion的结构有 xx ,yy/zz ,对于xx结构,apiGroups写为:apiGroups:"",对于yy/zz结构,apiGroups写为:apiGroups:"yy"。
如果apiGroups只写为“”,不写"apps"则pods,services生效,deployments不生效,因为没有父级,如果apiGroups只写为"apps",不写""则pods,services不生效,deployments生效,因为pods,services没有父级。
下面才是正确的写法,修改yaml文件。
[root@k8scloude1 safe]# vi role1.yaml [root@k8scloude1 safe]# cat role1.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: creationTimestamp: null name: role1 rules: #- apiGroups: ["apps"]: apiGroups 字段指定资源所属的 API 组(或者不属于任何组)。在本例中,deployments 属于 apps/v1 组,所以值为apps。 - apiGroups: - "" - "apps" resources: - pods - services - deployments verbs: - get - list - create - delete
应用role。
[root@k8scloude1 safe]# kubectl apply -f role1.yaml role.rbac.authorization.k8s.io/role1 configured
查看role1的描述信息。
[root@k8scloude1 safe]# kubectl describe role role1 Name: role1 Labels: <none> Annotations: <none> PolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- deployments [] [] [get list create delete] pods [] [] [get list create delete] services [] [] [get list create delete] deployments.apps [] [] [get list create delete] pods.apps [] [] [get list create delete] services.apps [] [] [get list create delete]
给role1添加deployment的get list create delete权限之后,客户端可以查询deploy了。
[root@etcd1 ~]# kubectl get deploy -n safe --kubeconfig=kctest No resources found in safe namespace.
如下是使用Nginx镜像创建deploy的yaml文件。
[root@etcd1 ~]# cat nginx.yaml apiVersion: apps/v1 kind: Deployment metadata: creationTimestamp: null labels: app: nginx name: nginx spec: #5个副本 replicas: 5 selector: matchLabels: app: nginx strategy: {} template: metadata: creationTimestamp: null labels: app: nginx spec: #当需要关闭容器时,立即杀死容器而不等待默认的30秒优雅停机时长。 terminationGracePeriodSeconds: 0 containers: - image: nginx name: nginx #imagePullPolicy: IfNotPresent:表示如果本地已经存在该镜像,则不重新下载;否则从远程 Docker Hub 下载该镜像 imagePullPolicy: IfNotPresent resources: {} status: {}
在客户端创建deploy,由于被授权了,deploy创建成功。
[root@etcd1 ~]# kubectl apply -f nginx.yaml -n safe --kubeconfig=kctest deployment.apps/nginx created [root@etcd1 ~]# kubectl get deploy -n safe --kubeconfig=kctest NAME READY UP-TO-DATE AVAILABLE AGE nginx 5/5 5 5 23s [root@etcd1 ~]# kubectl get pod -n safe --kubeconfig=kctest NAME READY STATUS RESTARTS AGE nginx-6cf858f6cf-62m8t 1/1 Running 0 72s nginx-6cf858f6cf-74nzb 1/1 Running 0 72s nginx-6cf858f6cf-bw84g 1/1 Running 0 72s nginx-6cf858f6cf-cmj95 1/1 Running 0 72s nginx-6cf858f6cf-fzs4l 1/1 Running 0 72s
刚才给role1添加deployments权限写的不好,如下为优化后的写法:
[root@k8scloude1 safe]# vim role1.yaml #对于给role1添加权限还可以有另一种写法(这种方法更好),如下 [root@k8scloude1 safe]# cat role1.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: creationTimestamp: null name: role1 rules: - apiGroups: - "" resources: - pods - services verbs: - get - list - create - delete - apiGroups: - "apps" resources: - deployments verbs: - get - list - create - delete
把nginx的deploy的副本数变为2,发现用户test没有deployments/scale的patch权限。
[root@etcd1 ~]# kubectl scale deploy nginx --replicas=2 -n safe --kubeconfig=kctest Error from server (Forbidden): deployments.apps "nginx" is forbidden: User "test" cannot patch resource "deployments/scale" in API group "apps" in the namespace "safe"
修改yaml文件,添加deployments/scale的patch权限。
[root@k8scloude1 safe]# vim role1.yaml [root@k8scloude1 safe]# cat role1.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: creationTimestamp: null name: role1 rules: - apiGroups: - "" resources: - pods - services - deployments verbs: - get - list - create - delete - apiGroups: - "apps" resources: - deployments - deployments/scale verbs: - get - list - create - delete - patch
应用role。
[root@k8scloude1 safe]# kubectl apply -f role1.yaml role.rbac.authorization.k8s.io/role1 configured
查看role1的描述信息。
[root@k8scloude1 safe]# kubectl describe role role1 Name: role1 Labels: <none> Annotations: <none> PolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- deployments.apps/scale [] [] [get list create delete patch] deployments.apps [] [] [get list create delete patch] deployments [] [] [get list create delete] pods [] [] [get list create delete] services [] [] [get list create delete]
添加deployments/scale的patch权限之后,客户端可以修改副本数了。
[root@etcd1 ~]# kubectl scale deploy nginx --replicas=2 -n safe --kubeconfig=kctest deployment.apps/nginx scaled [root@etcd1 ~]# kubectl get deploy -n safe --kubeconfig=kctest NAME READY UP-TO-DATE AVAILABLE AGE nginx 2/2 2 2 7m19s
删除deploy。
[root@etcd1 ~]# kubectl delete -f nginx.yaml -n safe --kubeconfig=kctest deployment.apps "nginx" deleted [root@etcd1 ~]# kubectl get deploy -n safe --kubeconfig=kctest No resources found in safe namespace.
上面做的权限都是role,rolebinding,下面开始clusterrole,clusterrolebinding。
删除role。
[root@k8scloude1 safe]# kubectl get role NAME CREATED AT role1 2022-03-19T09:52:13Z [root@k8scloude1 safe]# kubectl delete -f role1.yaml role.rbac.authorization.k8s.io "role1" deleted [root@k8scloude1 safe]# kubectl get role No resources found in safe namespace.
删除rolebinding。
[root@k8scloude1 safe]# kubectl get rolebinding NAME ROLE AGE rolebind1 Role/role1 25h [root@k8scloude1 safe]# kubectl delete rolebinding rolebind1 rolebinding.rbac.authorization.k8s.io "rolebind1" deleted [root@k8scloude1 safe]# kubectl get rolebinding No resources found in safe namespace.
生成创建clusterrole的yaml文件,--verb指定权限,--resource指定作用的资源。
[root@k8scloude1 safe]# kubectl create clusterrole clusterrole1 --verb=get,create --resource=pod,svc,deploy --dry-run=client -o yaml >clusterrole1.yaml
查看ClusterRole的yaml文件,功能为:在 Kubernetes 集群中创建一个叫做 "clusterrole1" 的集群角色(ClusterRole),该角色具有对 Pod、Service 和 Deployment 资源的操作权限。
使用这个 YAML 文件在 Kubernetes 中创建 "clusterrole1" 集群角色后,该角色将能够访问 Pod、Service 和 Deployment 资源,并且具有 get 和 create 操作权限。
[root@k8scloude1 safe]# vim clusterrole1.yaml [root@k8scloude1 safe]# cat clusterrole1.yaml apiVersion: rbac.authorization.k8s.io/v1 #kind: ClusterRole: ClusterRole 是 Kubernetes 集群级别的角色授权机制,与 Role 类似,但是它可以跨命名空间使用。 kind: ClusterRole metadata: creationTimestamp: null name: clusterrole1 rules: - apiGroups: - "" resources: - pods - services verbs: - get - create - apiGroups: - apps resources: - deployments verbs: - get - create
应用clusterrole。
[root@k8scloude1 safe]# kubectl apply -f clusterrole1.yaml clusterrole.rbac.authorization.k8s.io/clusterrole1 created
查看clusterrole。
[root@k8scloude1 safe]# kubectl get clusterrole | grep clusterrole1 clusterrole1 2022-03-20T11:24:36Z
kubernetes集群自带的clusterrole有很多。
[root@k8scloude1 safe]# kubectl get clusterrole | wc -l 75
把集群角色clusterrole1使用clusterrolebinding绑定给用户test。
[root@k8scloude1 safe]# kubectl create clusterrolebinding clusterrolebinding1 --clusterrole=clusterrole1 --user=test clusterrolebinding.rbac.authorization.k8s.io/clusterrolebinding1 created
查看clusterrolebinding。
[root@k8scloude1 safe]# kubectl get clusterrolebinding | grep clusterrolebinding1 clusterrolebinding1 ClusterRole/clusterrole1 25s [root@k8scloude1 safe]# kubectl get clusterrolebinding | wc -l 60
查看集群绑定的描述信息。
[root@k8scloude1 safe]# kubectl describe clusterrolebinding clusterrolebinding1 Name: clusterrolebinding1 Labels: <none> Annotations: <none> Role: Kind: ClusterRole Name: clusterrole1 Subjects: Kind Name Namespace ---- ---- --------- User test
查看集群角色的描述信息。
[root@k8scloude1 safe]# kubectl describe clusterrole clusterrole1 Name: clusterrole1 Labels: <none> Annotations: <none> PolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- pods [] [] [get create] services [] [] [get create] deployments.apps [] [] [get create]
在客户端进行测试,设置了clusterrole,clusterrolebinding之后,发现用户test没有对deploy的list权限。
[root@etcd1 ~]# kubectl get deploy -n safe --kubeconfig=kctest Error from server (Forbidden): deployments.apps is forbidden: User "test" cannot list resource "deployments" in API group "apps" in the namespace "safe"
修改yaml文件,增加list权限。
[root@k8scloude1 safe]# vim clusterrole1.yaml #添加list权限 [root@k8scloude1 safe]# cat clusterrole1.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: creationTimestamp: null name: clusterrole1 rules: - apiGroups: - "" resources: - pods - services verbs: - get - create - list - apiGroups: - apps resources: - deployments verbs: - get - create - list
应用clusterrole。
[root@k8scloude1 safe]# kubectl apply -f clusterrole1.yaml clusterrole.rbac.authorization.k8s.io/clusterrole1 configured
查看clusterrole1的描述信息。
[root@k8scloude1 safe]# kubectl describe clusterrole clusterrole1 Name: clusterrole1 Labels: <none> Annotations: <none> PolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- pods [] [] [get create list] services [] [] [get create list] deployments.apps [] [] [get create list]
clusterrole1添加了list权限之后,客户端可以get信息了。
[root@etcd1 ~]# kubectl get deploy -n safe --kubeconfig=kctest No resources found in safe namespace. [root@etcd1 ~]# kubectl get deploy -n default --kubeconfig=kctest No resources found in default namespace.
可以发现,clusterrolebinding全局生效,在所有namespace里都生效。
[root@etcd1 ~]# kubectl get deploy -n kube-system --kubeconfig=kctest NAME READY UP-TO-DATE AVAILABLE AGE calico-kube-controllers 1/1 1 1 70d coredns 2/2 2 2 70d metrics-server 1/1 1 1 69d
在本篇博客中,我们介绍了Kubernetes中的权限管理机制之RBAC鉴权。通过创建Role、RoleBinding、ClusterRole和ClusterRoleBinding等对象,管理员可以有效地控制用户和服务账户的访问权限,保障集群的安全性。
除了RBAC、ABAC和Node鉴权外,Kubernetes还支持Webhook鉴权、Service Account Token Volume Projection等多种鉴权方式。同时,在进行权限管理时,管理员还需注意以下事项: