赞
踩
kubernetes 集群相关所有的交互都通过apiserver来完成,对于这样集中式管理的系统来说,权限管理尤其重要,在1.5版的时候引入了RBAC(Role Base Access Control)的权限控制机制。
启用RBAC,需要在 apiserver 中添加参数–authorization-mode=RBAC,如果使用的kubeadm安装的集群,1.6+版本都默认开启了RBAC。
$ grep -C3 'authorization-mode' /etc/kubernetes/manifests/kube-apiserver.yaml
API Server目前支持以下几种授权策略:
更多权限管理,可参考:http://docs.kubernetes.org.cn/51.html#Kubernetes
K8s的用户分两种,一种是普通用户,一种是ServiceAccount(服务账户)。
1、普通用户
2、ServiceAccount(服务账户)**
相当于Role是一个类,用作权限申明,User/Group/ServiceAccount将成为类的实例。
工作流程图
在RABC API中,通过如下的步骤进行授权:
角色
角色绑定
主体(subject)
图解如下:
Role是权限的定义,在kubernetes中角色分为两种一种是Role针对特定的命名空间,一种是ClusterRole在整个集群范围内都生效。
Role示例如下:
cat >Role-001.yaml<<EOF
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: default
name: pod-role
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["pods"]
verbs: ["get", "watch", "list"]
EOF
$ kubectl apply -f Role-001.yaml
$ kubectl get role -n default
$ kubectl describe role pod-role -n default
ClusterRole示例如下:
cat >ClusterRole-001.yaml<<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: pod-clusterrole
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
EOF
$ kubectl apply -f ClusterRole-001.yaml
$ kubectl get clusterrole pod-clusterrole
$ kubectl describe clusterrole pod-clusterrole
相关参数
1、Role、ClsuterRole Verbs可配置参数
“get”, “list”, “watch”, “create”, “update”, “patch”, “delete”, “exec”
2、Role、ClsuterRole Resource可配置参数
“services”, “endpoints”, “pods”,“secrets”,“configmaps”,“crontabs”,“deployments”,“jobs”,“nodes”,“rolebindings”,“clusterroles”,“daemonsets”,“replicasets”,“statefulsets”,“horizontalpodautoscalers”,“replicationcontrollers”,“cronjobs”
3、Role、ClsuterRole APIGroup可配置参数
“”,“apps”, “autoscaling”, “batch”
定义好了角色也就是一个权限的集合,然后创建了一个ServiceAccount也就是一个服务账号,然后将这两个东西绑定起来,就是授权的过程了。
$ cat >RoleBinding-001.yaml<<EOF kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: rb namespace: default subjects: - kind: ServiceAccount name: zhangsan namespace: default roleRef: kind: Role name: pod-role apiGroup: rbac.authorization.k8s.io EOF $ kubectl apply -f RoleBinding-001.yaml $ kubectl get RoleBinding $ kubectl describe RoleBinding rb
$ cat >ClusterRoleBinding-001.yaml<<EOF kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: crb subjects: - kind: ServiceAccount name: mark namespace: default roleRef: kind: ClusterRole name: pod-clusterrole apiGroup: rbac.authorization.k8s.io --- apiVersion: v1 kind: ServiceAccount metadata: name: mark namespace: default EOF $ kubectl apply -f ClusterRoleBinding-001.yaml $ kubectl get ClusterRoleBinding crb $ kubectl describe ClusterRoleBinding crb
上面只是说到了绑定ServiceAccount,其实还有两种类型:User,Group,绑定类似,把subjects.kind。
尽管无法通过 API 调用来添加给kubernetes增加普通用户,Kubernetes 仍然认为能够提供由集群的证书 机构签名的合法证书的用户是通过身份认证的用户。基于这样的配置,Kubernetes 使用证书中的 ‘subject’ 的通用名称(Common Name)字段(例如,“/CN=devuser”)来 确定用户名, Kubernetes使用证书中的 ‘subject’ 的单位名称 (Organization Name) 字段(例如,“/O=system:masters”)来确定用户组。接下来,基于角色访问控制(RBAC)子系统会确定用户是否有权针对 某资源执行特定的操作。
Kubernetes 有着以下几个内建的用于特殊目的的组:
普通用户并不是通过k8s来创建和维护,是通过创建证书和切换上下文环境的方式来创建和切换用户。
a、创建证书
# 创建私钥
$ openssl genrsa -out devuser.key 2048
# 用此私钥创建一个csr(证书签名请求)文件
$ openssl req -new -key devuser.key -subj "/CN=devuser" -out devuser.csr
# 拿着私钥和请求文件生成证书
$ openssl x509 -req -in devuser.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out devuser.crt -days 365
## 注意:如果k8s集群的证书不是叫ca.crt和ca.key,需根据自己的名字来写,我这边是 ca.pem 和 ca-key.pem
b、生成账号
$ kubectl config set-credentials devuser --client-certificate=./devuser.crt --client-key=./devuser.key --embed-certs=true
c、设置上下文参数
# # 设置上下文, 默认会保存在 $HOME/.kube/config
$ kubectl config set-context devuser@kubernetes --cluster=kubernetes --user=devuser --namespace=dev
# 查看
$ kubectl config get-contexts
d、设置 默认上下文
$ kubectl config use-context devuser@kubernetes
# 查看
$ kubectl config get-contexts
$ kubectl get nodes
发现使用我们创建的用户查询是失败的,是因为账号还没授权,接下来就是对账号进行授权。这里需要先把用切回来,要不然就无法进行下一步授权了。
$ kubectl config use-context kubernetes-admin@kubernetes
$ kubectl get nodes
$ cat >devuser-role-bind<<EOF kind: Role # 角色 apiVersion: rbac.authorization.k8s.io/v1 metadata: namespace: dev name: devuser-role rules: - apiGroups: [""] # ""代表核心api组 resources: ["pods"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] --- kind: RoleBinding # 角色绑定 apiVersion: rbac.authorization.k8s.io/v1 metadata: name: devuser-rolebinding namespace: dev subjects: - kind: User name: devuser # 目标用户 apiGroup: rbac.authorization.k8s.io roleRef: kind: Role name: devuser-role # 角色信息 apiGroup: rbac.authorization.k8s.io EOF
执行并验证
$ kubectl apply -f devuser-role-bind
$ kubectl config use-context devuser@kubernetes
$ kubectl get pods # 不带命名空间,这里默认dev,也只能查看dev上面限制的命名空间的pods资源,从而也验证了role是针对命名空间的权限限制
#查看其它命名空间的资源
$ kubectl get pods -n default
$ kubectl get pods -n kube-system
$ kubectl get nodes
可以看到,用devuser,已经可以管理dev命名空间下的pod资源了,也只能管理dev命名空间下的pod资源,无法管理dev以外的资源类型,验证ok。ClusterRoleBinding绑定类似,这里就不重复了。有兴趣的小伙伴可以试试。
切回管理员用户
$ kubectl config use-context kubernetes-admin@kubernetes
因为跟user类型,这里就不过多文字介绍,直接上命令和配置
# 创建私钥 $ openssl genrsa -out devgroupuser.key 2048 # 用此私钥创建一个csr(证书签名请求)文件 $ openssl req -new -key devgroupuser.key -subj "/O=devgroup/CN=devgroupuser" -out devgroupuser.csr # 拿着私钥和请求文件生成证书 $ openssl x509 -req -in devgroupuser.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out devgroupuser.crt -days 365 # 生成账号 $ kubectl config set-credentials devgroupuser --client-certificate=./devgroupuser.crt --client-key=./devgroupuser.key --embed-certs=true # 设置上下文参数 $ kubectl config set-context devgroupuser@kubernetes --cluster=kubernetes --user=devgroupuser --namespace=dev # 查看 $ kubectl config get-contexts
$ cat >devgroup-role-bind.yaml<<EOF kind: Role # 角色 apiVersion: rbac.authorization.k8s.io/v1 metadata: namespace: dev name: devgroup-role rules: - apiGroups: [""] # ""代表核心api组 resources: ["services","pods"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] --- kind: RoleBinding # 角色绑定 apiVersion: rbac.authorization.k8s.io/v1 metadata: name: devgroup-rolebinding namespace: dev subjects: - kind: Group name: devgroup # 目标用户组 apiGroup: rbac.authorization.k8s.io roleRef: kind: Role name: devgroup-role # 角色信息 apiGroup: rbac.authorization.k8s.io EOF
执行并验证(命名空间默认dev,而不是系统的default)
$ kubectl apply -f devgroup-role-bind.yaml
#切用户
$ kubectl config use-context devgroupuser@kubernetes
# 查看
$ kubectl config get-contexts
$ kubectl get pods
$ kubectl get svc
$ kubectl get nodes
$ kubectl get jobs
从上图实验看,只能管理dev命名空间下的pods和services了,验证ok。
切回管理员用户
$ kubectl config use-context kubernetes-admin@kubernetes
上面第四节,已经很详细的介绍了ServiceAccount,这里也是直接上配置和操作命令。
$ cat >RoleBinding-ServiceAccount-001.yaml<<EOF kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: namespace: default name: role001 rules: - apiGroups: [""] # "" indicates the core API group resources: ["pods"] verbs: ["get", "watch", "list"] --- kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: rb001 namespace: default subjects: - kind: ServiceAccount name: lisi namespace: default roleRef: kind: Role name: role001 apiGroup: rbac.authorization.k8s.io --- apiVersion: v1 kind: ServiceAccount metadata: name: lisi namespace: default EOF
执行
$ kubectl delete -f RoleBinding-ServiceAccount-001.yaml
cat >ClusterRoleBinding-ServiceAccount-token-001.yaml<<EOF kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: admin annotations: rbac.authorization.kubernetes.io/autoupdate: "true" roleRef: kind: ClusterRole name: cluster-admin apiGroup: rbac.authorization.k8s.io subjects: - kind: ServiceAccount name: sa001 namespace: kube-system --- apiVersion: v1 kind: ServiceAccount metadata: name: sa001 namespace: kube-system EOF
获取token
$ kubectl -n kube-system get secret|grep sa001
$ kubectl -n kube-system describe secret sa001-token-c2klg
# 也可以使用 jsonpath 的方式直接获取 token 的值,如:
$ kubectl -n kube-system get secret sa001-token-c2klg -o jsonpath={.data.token}|base64 -d
【注意】yaml 输出里的那个 token 值是进行 base64 编码后的结果
每次创建了新的namespace下都会生成一个默认的token,名为default-token-xxxx。default就相当于该namespace下的一个用户。
$ kubectl -n dev get secret
$ kubectl -n dev describe secret default-token-67wgz
# 也可以使用 jsonpath 的方式直接获取 token 的值,如:
$ kubectl -n dev get secret default-token-67wgz -o jsonpath={.data.token}|base64 -d
可以使用下面的命令给该用户分配该namespace的管理员权限
kubectl create rolebinding R O L E B I N D I N G N A M E − − c l u s t e r r o l e = a d m i n − − s e r v i c e a c c o u n t = ROLEBINDING_NAME --clusterrole=admin --serviceaccount= ROLEBINDINGNAME−−clusterrole=admin−−serviceaccount=NAMESPACE:default --namespace=$NAMESPACE
其实kubernetes-dashboard就是通过token授权的,可以不清楚的,可以看我之前的文章:Kubernetes(k8s)安装以及搭建k8s-Dashboard详解
RoleBinding 和 ClusterRoleBinding:角色绑定和集群角色绑定,简单来说就是把声明的 Subject 和我们的 Role 进行绑定的过程(给某个用户绑定上操作的权限),二者的区别也是作用范围的区别:RoleBinding 只会影响到当前namespace 下面的资源操作权限,而 ClusterRoleBinding 会影响到所有的namespace。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。