使用 RBAC 鉴权。基于角色(Role)的访问控制(RBAC)是一种基于企业中用户的角色来调节控制对计算机或网络资源的访问方法。 RBAC 使用 rbac.authorization.k8s.io API 组 来驱动鉴权操作,允许管理员通过 Kubernetes API 动态配置策略。
在 1.8 版本中,RBAC 模式是稳定的并通过 rbac.authorization.k8s.io/v1 API 提供支持。
要启用 RBAC,在启动 API 服务器时添加 --authorization-mode=RBAC 参数。
RBAC主要是在描述一件事:给那些对象授权了那些权限其中涉及到了下面几个概念:
Role、ClusterRole
一个角色就是一组权限的集合,这里的权限都是许可形式的(白名单)
# Role只能对命名空间内的资源进行授权,需要指定nameapce
kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
namespace: dev
name: authorization-role
rules:
- apiGroups: [""] # 支持的API组列表,"" 空字符串,表示核心API群
resources: ["pods"] # 支持的资源对象列表
verbs: ["get", "watch", "list"] # 允许的对资源对象的操作方法列表
# ClusterRole可以对集群范围内资源、跨namespaces的范围资源、非资源类型进行授权
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: authorization-clusterrole
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
需要详细说明的是,rules中的参数:
"","apps", "autoscaling", "batch"
"services", "endpoints", "pods","secrets","configmaps","crontabs","deployments","jobs",
"nodes","rolebindings","clusterroles","daemonsets","replicasets","statefulsets",
"horizontalpodautoscalers","replicationcontrollers","cronjobs"
"get", "list", "watch", "create", "update", "patch", "delete", "exec"
RoleBinding、ClusterRoleBinding
角色绑定用来把一个角色绑定到一个目标对象上,绑定目标可以是User、Group或者ServiceAccount。
# RoleBinding可以将同一namespace中的subject绑定到某个Role下,则此subject即具有该Role定义的权限
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: authorization-role-binding
namespace: dev
subjects:
- kind: User
name: heima
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: authorization-role
apiGroup: rbac.authorization.k8s.io
# ClusterRoleBinding在整个集群级别和所有namespaces将特定的subject与ClusterRole绑定,授予权限
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: authorization-clusterrole-binding
subjects:
- kind: User
name: heima
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: authorization-clusterrole
apiGroup: rbac.authorization.k8s.io
RoleBinding引用ClusterRole进行授权
RoleBinding可以引用ClusterRole,对属于同一命名空间内ClusterRole定义的资源主体进行授权。
一种很常用的做法就是,集群管理员为集群范围预定义好一组角色(ClusterRole),然后在多个命名空间中重复使用这些ClusterRole。这样可以大幅提高授权管理工作效率,也使得各个命名空间下的基础性授权规则与使用体验保持一致。
例如:
# 虽然authorization-clusterrole是一个集群角色,但是因为使用了RoleBinding
# 所以heima只能读取dev命名空间中的资源
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: authorization-role-binding-ns
namespace: dev
subjects:
- kind: User
name: heima
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: authorization-clusterrole
apiGroup: rbac.authorization.k8s.io
创建一个只能管理dev空间下Pods资源的账号
1、首先拷贝k8s证书和私钥:ca.pem和ca-key.pem签署证书需要
[root@k8s-master1 ~]# mkdir /etc/kubernetes/pki/ -p
[root@k8s-master1 ~]# cd /etc/kubernetes/pki/
[root@k8s-master1 pki]# cp /opt/kubernetes/ssl/ca #拷贝k8s证书和私钥
ca-key.pem ca.pem
[root@k8s-master1 pki]# cp /opt/kubernetes/ssl/ca* ./
2、创建账号user1
# 1) 创建证书
[root@k8s-master1 pki]# (umask 077;openssl genrsa -out user1.key 2048)
Generating RSA private key, 2048 bit long modulus
.............................+++
...............................+++
e is 65537 (0x10001)
# 2) 用apiserver的证书去签署
# 2-1) 签名申请,申请的组是myland-01 ,用户是user1
[root@k8s-master1 pki]# openssl req -new -key user1.key -out user1.csr -subj "/O=myland-01 /CN=user1"
# 2-2) 签署证书,用的了k8s证书和私钥已经拷贝过来了
[root@k8s-master1 pki]# openssl x509 -req -in user1.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out user1.crt -days 3650
Signature ok
subject=/O=myland-01 /CN=user1
Getting CA Private Key
# 3) 设置集群、用户、上下文信息
[root@k8s-master01 pki]# kubectl config set-cluster myland-01 --server=https://10.0.19.127:6443 \
--certificate-authority=ca.pem \
--embed-certs=true
[root@k8s-master01 pki]# kubectl config set-credentials user1 \
--client-certificate=/etc/kubernetes/pki/user1.crt \
--client-key=user1.key \
--embed-certs=true
[root@k8s-master01 pki]# kubectl config set-context user1@kubernetes \
--cluster=myland-01 \
--user=user1
# 切换账户到user1
[root@k8s-master1 pki]# kubectl config use-context user1@kubernetes
Switched to context "user1@kubernetes"
#查看账号发生变化
[root@k8s-master1 pki]# cat /root/.kube/config |grep current-context
current-context: user1@kubernetes
# 查看dev下pod,发现没有权限
[root@k8s-master1 pki]# kubectl get pods -n dev
Error from server (Forbidden): pods is forbidden: User "user1" cannot list resource "pods" in API group "" in the namespace "dev"
# 切换到admin账户,查看config账号
[root@k8s-master1 pki]# kubectl config use-context default
Switched to context "default".
[root@k8s-master1 pki]# cat /root/.kube/config |grep current-context
current-context: default
2) 创建Role和RoleBinding,为user1用户授权
[root@k8s-master1 pki]# vim dev-role.yaml
kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
namespace: dev
name: dev-role
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: authorization-role-binding
namespace: dev
subjects:
- kind: User
name: user1
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: dev-role
apiGroup: rbac.authorization.k8s.io
[root@k8s-master1 pki]# kubectl create -f dev-role.yaml
role.rbac.authorization.k8s.io/dev-role created
rolebinding.rbac.authorization.k8s.io/authorization-role-binding created
切换账户,再次验证
[root@k8s-master1 pki]# kubectl config use-context user1@kubernetes
Switched to context "user1@kubernetes".
[root@k8s-master1 pki]# kubectl get pod -n dev
NAME READY STATUS RESTARTS AGE
nginx-deployment-6696798b78-9k5gf 1/1 Running 1 47h
nginx-deployment-6696798b78-xqhbx 1/1 Running 1 47h
nginx-deployment-6696798b78-zj259 1/1 Running 1 47h
tomcat-deployment-58467d5474-2lcwz 1/1 Running 1 47h
tomcat-deployment-58467d5474-7nlxl 1/1 Running 1 47h
tomcat-deployment-58467d5474-rdz47 1/1 Running 1 47h