暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

RBAC — 基于角色的访问控制

ProdanLabs 2020-03-06
695


01

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

复制


02

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中资源的访问权限。

ClusterRoleBindingClusterRoleBinding在整个集群范围和所有namespaces将特定的subject与ClusterRole绑定,授予整个集群范围内资源访问权限。

更多资料请查阅官方文档


03

面向用户的角色

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)


04

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 ~]$ 

复制


05

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中定义的资源对象




往期回顾

Falco:云原生运行时入侵和异常检测

OPA: Kubernetes的安全策略和治理

文章转载自ProdanLabs,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论