Kubernetes之二十: RBAC授权
1)RBAC简述
RBAC
- 基于角色的访问控制
在 1.8 版本中,RBAC 模式是稳定的并通过 rbac.authorization.k8s.io/v1 API 提供支持,要启用 RBAC,在启动 API 服务器时添加 --authorization-mode=RBAC
参数(1.6 版本以上的都默认开启了RBAC)
什么是RBAC(基于角色的访问控制)?
让一个用户(Users)扮演一个角色(Role),角色拥有权限,从而让用户拥有这样的权限,随后在授权机制当中,只需要将权限授予某个角色,此时用户将获取对应角色的权限,从而实现角色的访问控制。如图:
定义角色:在定义角色时会指定此角色对于资源的访问控制的规则;
绑定角色:将主体与角色进行绑定,对用户进行访问授权
说明:
在k8s的授权机制当中,采用RBAC的方式进行授权,其工作逻辑是,
- 把对对象的操作权限定义到一个角色当中,再将用户绑定到该角色,从而使用户得到对应角色的权限
- 如果通过rolebinding绑定role,只能对rolebinding所在的名称空间的资源有权限,上图user1这个用户绑定到role1上,只对role1这个名称空间的资源有权限,对其他名称空间资源没有权限,属于名称空间级别的;
- 另外,k8s为此还有一种集群级别的授权机制,就是定义一个集群角色(ClusterRole),对集群内的所有资源都有可操作的权限,从而将User2通过ClusterRoleBinding到ClusterRole,从而使User2拥有集群的操作权限
- Role、RoleBinding、ClusterRole和ClusterRoleBinding的关系如下图:
上面说了两个角色绑定:
(1)用户通过rolebinding绑定role
(2)用户通过clusterrolebinding绑定clusterrole
还有一种:rolebinding绑定clusterrole
假如有6个名称空间,每个名称空间的用户都需要对自己的名称空间有管理员权限,那么需要定义6个role和rolebinding,然后依次绑定
如果名称空间更多,我们需要定义更多的role,这个是很麻烦的,所以我们引入clusterrole,定义一个clusterrole,对clusterrole授予所有权限
然后用户通过rolebinding绑定到clusterrole,就会拥有自己名称空间的管理员权限
注:RoleBinding仅仅对当前名称空间有对应的权限
常见的资源: Pods,ConfigMaps , Deployments,Nodes, Secrets, Namespaces,StatefulSets,DaemonSets,Ingress,Volumes,Services,Persistents等
常见的权限: create,get,delete,list,update,edit,watch,exec,patch,proxy,redirect
2)role与rolebinding
说明:
主体由几种,分别为User和ServiceAccount
subjects: #定义组 - kind:Group name:"frontend-admins" apiGroup:rbac.authorization.k8s.io subjects: #定义用户 - kind:User name: louis apiGroup:rbac.authorization.k8s.io subjects: #sa - kind:ServiceAccount name:default namespace:kube-system subjects: #在qa命名空间下所有账户 - kind:Group name:system:serviceaccounts:qa apiGroup:rbac.authorization.k8s.io
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: devops name: pod-read rules: - apiGroups: [""] resources: ["pods"] verbs: ["get","watch","list"] --- #定义rolebinding apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: pod-read namespace: devops subjects: #定义主体 - kind: User name: louis apiGroup: rbac.authorization.k8s.io roleRef: #引用的角色 kind: Role name: pod-read apiGroup: rbac.authorization.k8s.io #创建一个louis用户 [root@master01 role]# cat create_user.sh #!/bin/bash mkdir certs # 设置一些变量 KUBE_URL=https://192.168.31.80:6443 CLUSTER=kubernetes CRT_DAYS=3650 USER_NAME=$1 # 一般就在 /etc/kubernetes/ssl 或者 /etc/kubernetes/pki 里面 CA_CRT_PATH=/etc/kubernetes/pki/ca.crt CA_KEY_PATH=/etc/kubernetes/pki/ca.key # 生成私有密钥 openssl genrsa -out certs/$USER_NAME.key 2048 # 用私钥生成证书,CN 表示用户名,O 表示用户组 openssl req -new -key certs/$USER_NAME.key -out certs/$USER_NAME.csr \ -subj "/CN=$USER_NAME/O=example" # 然后用 CA 证书来给刚才生成的证书来签名 openssl x509 -req -in certs/$USER_NAME.csr -CA $CA_CRT_PATH -CAkey $CA_KEY_PATH \ -CAcreateserial -out certs/$USER_NAME.crt -days $CRT_DAYS # 存放 kubectl config 的文件 export KUBECONFIG=/root/k8s-$USER_NAME.conf # 设置 cluster kubectl config set-cluster $CLUSTER --server="$KUBE_URL" \ --certificate-authority="$CA_CRT_PATH" --embed-certs=true # 设置私钥以及已签名证书 kubectl config set-credentials $USER_NAME --client-certificate=certs/$USER_NAME.crt \ --client-key=certs/$USER_NAME.key --embed-certs=true # 设置 context kubectl config set-context $USER_NAME-context --cluster=$CLUSTER --user=$USER_NAME kubectl config use-context $USER_NAME-context [root@master01 role]# kubectl get pods -n dev --kubeconfig /root/k8s-louis.conf Error from server (Forbidden): pods is forbidden: User "louis" cannot list resource "pods" in API group "" in the namespace "dev" [root@master01 role]# [root@master01 role]# kubectl get pods -n devops --kubeconfig /root/k8s-louis.conf #上面授权louis可以访问devops空间 NAME READY STATUS RESTARTS AGE apollo-adminservice-5f54494f55-jqf9c 1/1 Running 1 43d apollo-configservice-74bc85dcdb-2zbdg 1/1 Running 1 43d apollo-portal-5d6c8cd8dc-2vndf 1/1 Running 1 47h yapi-5df96d9984-58q2b 1/1 Running 1 8d yapi-mongodb-5d7f6d47c8-2ffn9 1/1 Running 1 9d
[root@master01 role]# kubectl get deployment -n devops --kubeconfig /root/k8s-louis.conf Error from server (Forbidden): deployments.apps is forbidden: User "louis" cannot list resource "deployments" in API group "apps" in the namespace "devops" 更改role权限 apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: devops name: pod-read rules: - apiGroups: ["apps","v1","extensions"] resources: ["pods","deployments"] verbs: ["get","watch","list"] --- #定义rolebinding apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: pod-read namespace: devops subjects: #定义主体 - kind: User name: louis apiGroup: rbac.authorization.k8s.io roleRef: #引用的角色 kind: Role name: pod-read apiGroup: rbac.authorization.k8s.io [root@master01 role]# kubectl get deployment -n devops --kubeconfig /root/k8s-louis.conf NAME READY UP-TO-DATE AVAILABLE AGE apollo-adminservice 1/1 1 1 77d apollo-configservice 1/1 1 1 77d apollo-portal 1/1 1 1 47h yapi 1/1 1 1 9d yapi-mongodb 1/1 1 1 9d
2) 命令行工具
kubectl create rolebinding
kubectl create rolebinding bob-admin-binding --clusterrole=admin --user=louis --namespace=dev (在dev命名空间中,将admin集群角色授予louis用户) kubectl create rolebinding myapp-view-binding --clusterrole=view --serviceaccount=dev:myapp --namespace=dev (在acme命名空间中,将admin集群角色授予acme:myapp服务帐户)
kubectl create clusterrolebinding
kubectl create clusterrolebinding root-cluster-admin-binding --clusterrole=cluster-admin --user=louis #授权louis拥有集群管理员权限 kubectl create clusterrolebinding myapp-view-binding --clusterrole=view --serviceaccount=dev:myapp
在dev
命名空间内,授予mysa
服务帐户view
集群角色
[root@master01 role]# kubectl create sa mysa -n dev serviceaccount/mysa created [root@master01 role]# kubectl create rolebinding mysa-view --clusterrole=view --serviceaccount=dev:mysa --namespace=dev rolebinding.rbac.authorization.k8s.io/mysa-view created
apiVersion: v1 kind: ServiceAccount metadata: name: mysa namespace: dev --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: mysa-view namespace: dev roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: view subjects: - kind: ServiceAccount name: mysa namespace: dev
案例1) 限制不同用户访问不同名称空间的资源生成一个证书
1)生成一个私钥 cd /etc/kubernetes/pki/ (umask 077; openssl genrsa -out testlouis.key 2048) (2)生成一个证书请求 openssl req -new -key testlouis.key -out testlouis.csr -subj "/CN=testlouis" (3)生成一个证书 openssl x509 -req -in testlouis.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out testlouis.crt -days 3650 在kubeconfig下新增加一个testlouis这个用户 kubectl config set-cluster kubernetes --server="https://192.168.31.80:6443" --certificate-authority="/etc/kubernetes/pki/ca.crt" --embed-certs=true --kubeconfig=/root/k8s-testlouis.conf kubectl config set-credentials testlouis --client-certificate=./testlouis.crt --client-key=./testlouis.key --embed-certs=true --kubeconfig=/root/k8s-testlouis.conf(2)在kubeconfig下新增加一个lucky这个账号 kubectl config set-context testlouis@kubernetes --cluster=kubernetes --user=testlouis --kubeconfig=/root/k8s-testlouis.conf kubectl config use-context testlouis@kubernetes --kubeconfig=/root/k8s-testlouis.conf [root@master01 pki]# kubectl get pods -n dev --kubeconfig=/root/k8s-testlouis.conf error: Missing or incomplete configuration info. Please point to an existing, complete config file: 1. Via the command-line flag --kubeconfig 2. Via the KUBECONFIG environment variable 3. In your home directory as ~/.kube/config To view or setup config directly use the 'config' command. #这个是集群用户,有任何权限 把user这个用户通过rolebinding绑定到clusterrole上,授予权限,权限只是在testlouis这个名称空间有效 授权: kubectl create rolebinding testlouis -n dev --clusterrole=cluster-admin --user=testlouis 添加一个testlouis用户 userad testlouis mkdir /home/testlouis/.kube cp -rf /root/k8s-testlouis.conf /home/testlouis/.kube/config chown -R testlouis.testlouis /home/testlouis su - testlouis [root@master01 pki]# su - testlouis Last login: Thu Aug 13 16:02:03 CST 2020 on pts/2 kubectl get pods -n dev [testlouis@master01 ~]$ kubectl get pods -n dev NAME READY STATUS RESTARTS AGE admin-server-65bd476ff8-756rs 1/1 Running 3 17d 通过上面可以发现testlouis可以管理dev名称空间