RBAC
RBAC即Role-Based Access Control(基于角色的访问控制),使用"rbac.authorization.k8s.io" API Group实现授权决策,允许管理员通过API动态配置策略,从Kubernetes 1.8版本开始进入稳定,并由rbac.authorization.k8s.io/v1 API提供支持。
要使用RBAC,通过kube-apiserver配置启用
--authorization-mode=RBAC
复制
API概述
Kubernetes RBAC API定义了四种类型:Role、ClusterRole、RoleBinding与ClusterRoleBinding
Role和ClusterRole描述角色和权限的关系。在RBAC API中,一个角色定义了一组特定权限的规则。namespaces中的角色由Role对象定义,而整个Kubernetes集群范围内的角色则通过ClusterRole对象实现。
RoleBinding和ClusterRoleBinding描述subjects(如users, groups等)和角色的关系。将一个角色中定义的各种权限授予一个或一组用户称为角色绑定,绑定后的该用户或用户组则具有对应绑定的Role或ClusterRole定义的权限。
Role:Role的对象只能用于授予对某一单一namespaces中资源的访问权限。
ClusterRole:ClusterRole对象可以授予整个集群范围内资源访问权限。
RoleBinding:可以将同一namespaces中的subject绑定到某个的Role下,RoleBinding对象也可以引用一个ClusterRole对象用于在RoleBinding所在的namespaces内授予用户对所引用的ClusterRole中定义的namespaces中资源的访问权限。
ClusterRoleBinding:ClusterRoleBinding在整个集群范围和所有namespaces将特定的subject与ClusterRole绑定,授予整个集群范围内资源访问权限。
更多资料请查阅官方文档
面向用户的角色
Kubernetes集群初始化后,API Server会创建一组默认的ClusterRole和ClusterRoleBinding对象。这些默认对象中带有system:前缀的资源为Kubernetes基础组件"拥有",且每次启动时,API Server都会更新默认ClusterRole所缺乏的各种权限,并更新默认ClusterRoleBinding所缺乏的各个角色绑定主体。一些默认角色并不包含system:前缀,它们是面向用户的角色:
cluster-admin:超级用户权限,允许对任何资源执行任何操作。
admin:管理员权限,利用RoleBinding在某一namespaces内部授予。但不允许对资源配额(resource quota)或namespaces本身的写访问,不允许访问集群范围资源(如node)。
edit:允许对某一个namespaces内大部分对象的读写访问,但不允许查看或者修改角色或者角色绑定,不允许访问集群范围资源(如node)。
view:允许对某一个namespaces内大部分对象的只读访问,不允许查看角色、角色绑定和secret等资源,不允许访问集群范围资源(如node)。
kubectl命令权限控制
1、创建集群只读用户
创建证书
//prodan(只读)用户操作
[prodan@kube-master01 ssl]$ vi readonly-csr.json
{
"CN": "readonly",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Guangzhou",
"L": "Guangzhou",
"O": "system:readonly",
"OU": "System"
}
]
}
[prodan@kube-master01 ssl]$ cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes readonly-csr.json | cfssljson -bare readonly复制
配置kubectl客户端,配置文件在~/.kube/config
//prodan(只读)用户操作
# 设置集群参数
kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/cert/ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER}
# 设置客户端认证参数
kubectl config set-credentials readonly \
--client-certificate=./readonly.pem \
--embed-certs=true \
--client-key=./readonly-key.pem
# 设置上下文参数
kubectl config set-context kubernetes \
--cluster=kubernetes \
--user=readonly
# 设置默认上下文
kubectl config use-context kubernetes复制
没有授权,没有权限访问集群资源
//prodan(只读)用户操作
[prodan@kube-master01 ssl]$ kubectl get pod
Error from server (Forbidden): pods is forbidden: User "readonly" cannot list resource "pods" in API group "" in the namespace "default"
[prodan@kube-master01 ssl]$复制
给readonly用户授予只读权限
办法1: 通过kubectl get clusterrole admin -o yaml >readonly.yaml导出Role并去掉create、delete等权限,然后通过角色绑定readonly用户。
办法2: 将readonly用户角色绑定ClusterRole中的view,本文选该办法
//root(管理员)用户操作
[root@kube-master01 prodan]# vi readonly-binding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: readonly
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: view
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:readonly
[root@kube-master01 prodan]# kubectl create -f readonly-binding.yaml复制
验证
//prodan(只读)用户操作
[prodan@kube-master01 ~]$ kubectl get pod,svc --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
default pod/busybox 1/1 Running 417 17d
default pod/falco-daemonset-k6s7v 1/1 Running 11 49d
ingress-nginx pod/nginx-ingress-controller-9dfc54f55-l5jp5 1/1 Running 12 59d
kube-system pod/calico-kube-controllers-648f4868b8-rdjn6 1/1 Running 13 68d
kube-system pod/calico-node-c5qjh 1/1 Running 13 68d
kube-system pod/coredns-65894485d5-q4xvg 1/1 Running 12 59d
kube-system pod/kubernetes-dashboard-76885b464f-6rfbw 1/1 Running 0 12h
kube-system pod/metrics-server-v0.3.6-c9544dbc4-dx4kq 2/2 Running 24 59d
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default service/falco-service ClusterIP 10.254.138.138 <none> 8765/TCP 50d
default service/kubernetes ClusterIP 10.254.0.1 <none> 443/TCP 68d
kube-system service/kube-dns ClusterIP 10.254.0.2 <none> 53/UDP,53/TCP,9153/TCP 59d
kube-system service/kubernetes-dashboard ClusterIP 10.254.72.239 <none> 443/TCP 12h
kube-system service/metrics-server ClusterIP 10.254.213.206 <none> 443/TCP 59d
[prodan@kube-master01 ~]$ kubectl logs --tail 3 coredns-65894485d5-q4xvg -n kube-system
[INFO] plugin/reload: Running configuration MD5 = 4e235fcc3696966e76816bcd9034ebc7
CoreDNS-1.6.5
linux/amd64, go1.13.4, c2fd1b2
[prodan@kube-master01 ~]$
//不允许访问集群范围资源
[prodan@kube-master01 ~]$ kubectl get nodes
Error from server (Forbidden): nodes is forbidden: User "readonly" cannot list resource "nodes" in API group "" at the cluster scope
//没有权限删除资源和进入容器
[prodan@kube-master01 ~]$ kubectl delete pod busybox
Error from server (Forbidden): pods "busybox" is forbidden: User "readonly" cannot delete resource "pods" in API group "" in the namespace "default"
[prodan@kube-master01 ~]$ kubectl exec -it busybox sh
Error from server (Forbidden): pods "busybox" is forbidden: User "readonly" cannot create resource "pods/exec" in API group "" in the namespace "default"复制
2、创建访问指定namespace的用户,以kube-system namespace为例
创建证书
//kubeadmin用户操作
[kubeadmin@kube-master01 ssl]$ vi kubeadmin-csr.json
{
"CN": "kubeadmin",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Guangzhou",
"L": "Guangzhou",
"O": "system:kubeadmin",
"OU": "System"
}
]
}
[kubeadmin@kube-master01 ssl]$ cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kubeadmin-csr.json | cfssljson -bare kubeadmin复制
配置kubectl客户端,配置文件在~/.kube/config
//kubeadmin用户操作
kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/cert/ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER}
# 设置客户端认证参数
kubectl config set-credentials kubeadmin \
--client-certificate=./kubeadmin.pem \
--embed-certs=true \
--client-key=./kubeadmin-key.pem
# 设置上下文参数
kubectl config set-context kubernetes \
--cluster=kubernetes \
--namespace=kube-system \
--user=kubeadmin
# 设置默认上下文
kubectl config use-context kubernetes复制
给kubeadmin用户授予kube-system namespaces权限
办法1: 通过kubectl get clusterrole admin -o yaml >kubeadmin.yaml导出并在kube-system namespaces创建,然后通过角色绑定kubeadmin用户。
办法2: 将kubeadmin用户角色绑定ClusterRole中的admin,本文选该办法
//root用户操作
[root@kube-master01 kubeadmin]# vi tets.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: kubeadmin
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: admin
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:kubeadmin
[root@kube-master01 kubeadmin]#复制
验证
//kubeadmin用户操作,在配置kubectl时指定了kube-system namespaces,默认get的是kube-system的资源
[kubeadmin@kube-master01 ~]$ kubectl get pod
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-648f4868b8-rdjn6 1/1 Running 13 68d
calico-node-c5qjh 1/1 Running 13 68d
coredns-65894485d5-q4xvg 1/1 Running 12 59d
kubernetes-dashboard-76885b464f-6rfbw 1/1 Running 0 13h
metrics-server-v0.3.6-c9544dbc4-dx4kq 2/2 Running 24 59d
[kubeadmin@kube-master01 ~]$ kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-648f4868b8-rdjn6 1/1 Running 13 68d
calico-node-c5qjh 1/1 Running 13 68d
coredns-65894485d5-q4xvg 1/1 Running 12 59d
kubernetes-dashboard-76885b464f-6rfbw 1/1 Running 0 13h
metrics-server-v0.3.6-c9544dbc4-dx4kq 2/2 Running 24 59d
[kubeadmin@kube-master01 ~]$ kubectl delete pod metrics-server-v0.3.6-c9544dbc4-dx4kq
pod "metrics-server-v0.3.6-c9544dbc4-dx4kq" deleted
//不允许访问集群范围资源
[kubeadmin@kube-master01 ~]$ kubectl get nodes
Error from server (Forbidden): nodes is forbidden: User "kubeadmin" cannot list resource "nodes" in API group "" at the cluster scope
[kubeadmin@kube-master01 ~]$复制
kube-dashboard权限控制
需求:创建一个test用户,对kube-system namespaces下的pod,副本控制集、jobs和events有读写权限
//创建ServiceAccount
[root@kube-master01 dashboard]# kubectl create sa test -n kube-system
//新建一个角色role-test
[root@kube-master01 dashboard]# vi role-test.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: kube-system
name: role-test
rules:
- apiGroups: [""]
resources: ["pods", "events"]
verbs: ["get", "watch", "list"]
- apiGroups: ["apps", "batch"]
resources: ["deployments", "daemonsets", "statefulsets", "cronjobs", "jobs", "replicasets"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
[root@kube-master01 dashboard]# kubectl create -f role-test.yaml
//角色绑定,将上面的角色role-test绑定到test的ServiceAccount上
[root@kube-master01 dashboard]# vi role-bind-test.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: role-bind-test
namespace: kube-system
subjects:
- kind: ServiceAccount
name: test
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
# kind: ClusterRole
# name: admin
kind: Role
name: role-test
[root@kube-master01 dashboard]# kubectl create -f role-bind-test.yaml复制
获取test token
[root@kube-master01 dashboard]# kubectl get secrets -n kube-system | grep test |awk '{print $1}' | xargs kubectl describe secrets -n kube-system
Name: test-token-6kzxt
Namespace: kube-system
Labels: <none>
Annotations: kubernetes.io/service-account.name: test
kubernetes.io/service-account.uid: 1a15b68e-f4e0-454a-820a-b300d662f11d
Type: kubernetes.io/service-account-token
Data
====
ca.crt: 1371 bytes
namespace: 11 bytes
token: eyJhbGciOiJSUzI1NiIsImtpZCI6IllYYXBJNzFTLThLVW5NQzlYTW8wRVozZTFXcE1TNmZXTkYyc1pTbHhRZDAifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJ0ZXN0LXRva2VuLTZrenh0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6InRlc3QiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiIxYTE1YjY4ZS1mNGUwLTQ1NGEtODIwYS1iMzAwZDY2MmYxMWQiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06dGVzdCJ9.FZJMU-k-VXvz4q12vGFwy0n5p_OhcQphr3mNdyzqVy95del7KK5Eu_LsqZjk6zBPbhNZNLbg02T3AxslNHZDWOknI02baP7i95-iyAM5-tH6or50QBhvB_Qvy-O-kz6SlRaBHmuSKXqzXot3BW9onXtX4J5vNr67epKnPUh1YvzIW0LAeevRjifJpHSlnwFIDAHPXazZpmpRgI0c5rT9sUUkGBT3P1GRNzU188tHOZS3AKVOn44Q9awqlbSJVA5bJ2-c0SG2zYHWLVwCzWTi3ig1iWciGbwBIJgL1AyCDJJtPjNO4mIOIPQnKt765TQVCE65lxwmvLDDfkKYZ_s6Sg
[root@kube-master01 dashboard]#复制
使用token登录kubernetes-dashboard
登录进去后,url中的namespace=default,需要修改成namespace=kube-system,因为该用户只对kube-system有权限。
可以访问role-test中定义的资源对象
往期回顾