K8s-RBAC权限管理
一、RBAC概述 RBAC引入了四个新的顶级资源对象。Role、ClusterRole、RoleBinding、 ClusterRoleBinding。同其他 API 资源对象一样,用户可以使用 kubectl 或者 API 调用等 方式操作这些资源对象。kubernetes集群相关所有的交互都通过apiserver来完成,对于这样集中式管理的系统来说,从1.6版本起,K8S默认启用RBAC访问控制策略,目前RBAC已作为稳定的功能,通过启动文件kube-apiserver.service中的-authorization-mode=RBAC 来启用RABC. API Server目前支持以下几种授权策略: AlwaysDeny:表示拒绝所有请求,一般用于测试。 AlwaysAllow:允许接收所有请求。如果集群不需要授权流程,则可以采用该策略,这也是Kubernetes的默认配置。 ABAC(Attribute-Based Access Control):基于属性的访问控制。表示使用用户配置的授权规则对用户请求进行匹配和控制。 Webhook:通过调用外部REST服务对用户进行授权。 RBAC:Role-Based Access Control,基于角色的访问控制(本章讲解)。 Node:是一种专用模式,用于对kubelet发出的请求进行访问控制。
二、用户分类 K8s的用户分两种,一种是普通用户,一种是ServiceAccount(服务账户)。 1、普通用户 普通用户是假定被外部或独立服务管理的。管理员分配私钥。平时常用的kubectl命令都是普通用户执行的。 如果是用户需求权限,则将Role与User(或Group)绑定(这需要创建User/Group),是给用户使用的。 2、ServiceAccount(服务账户) ServiceAccount(服务帐户)是由KubernetesAPI管理的用户。它们绑定到特定的命名空间,并由API服务器自动创建或通过API调用手动创建。 服务帐户与存储为Secrets的一组证书相关联,这些凭据被挂载到pod中,以便集群进程与Kubernetes API通信。(登录dashboard时我们使用的就是ServiceAccount) 如果是程序需求权限,将Role与ServiceAccount指定(这需要创建ServiceAccount并且在deployment中指定ServiceAccount),是给程序使用的。
三、K8s角色&角色绑定 1.授权介绍 在RABC API中,通过如下的步骤进行授权: 创建主体:创建用户 定义角色:在定义角色时会指定此角色对于资源的访问控制的规则。 绑定角色:将主体与角色进行绑定,对用户进行访问授权。 主体(subject) User:用户 Group:用户组 ServiceAccount:服务账号 角色(一组权限的集合) Role:授权特定命名空间的访问权限 ClusterRole:授权所有命名空间(集群范围内)的访问权限 角色绑定 RoleBinding:将角色绑定到主体(即subject) ClusterRoleBinding:将集群角色绑定到主体 2.角色相关参数(资源和权限) 1、Role和ClsuterRole的Verbs可配置参数(资源) get、 list、watch、create、 update、 patch、 delete、 exec、proxy、redirect、 deletecollection 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可配置参数(kubectl api-resources ) apps、 autoscaling、 batch 主体说明 Kubernetes 有着以下几个内建的用于特殊目的的组: system:unauthenticated :未能通过任何一个授权插件检验的账号,即未通过认证测 试的用户所属的组 。 system :authenticated :认证成功后的用户自动加入的一个组,用于快捷引用所有正常通过认证的用户账号。 system : serviceaccounts :当前系统上的所有 Service Account 对象。 system :serviceaccounts :<namespace>:特定命名空间内所有的 Service Account 对象。 1.名称为 “alice@example.com”用户: subjects: - kind: User name: "alice@example.com" apiGroup: rbac.authorization.k8s.io 2.名称为“frontend-admins”的组: subjects: - kind: Group name: "frontend-admins" apiGroup: rbac.authorization.k8s.io 3.在kube-system命名空间中,名称为“default”的服务帐户: subjects: - kind: ServiceAccount name: default namespace: kube-system 4.在“qa”命名空间中,所有的服务帐户: subjects: - kind: Group name:system: serviceaccounts:qa apiGroup: rbac.authorization.k8s.io 5.所有的服务帐户: subjects: - kind: Group name: system:serviceaccounts apiGroup: rbac.authorization.k8s.io 6.所有被认证的用户 (version 1.5+): subjects: - kind: Group name:system: authenticated apiGroup: rbac.authorization.k8s.io
实例1:基于Role 1.1:在指定namespace创建账户: [root@localhost7C role]# kubectl create serviceaccount laomao -n linux39 1.2:角色:创建role规则: [root@localhost7C role]# cat linux39-role.yml kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: namespace: linux39 name: linux39-role #角色名 rules: - apiGroups: ["*"] resources: ["pods"] #资源 #verbs: ["*"] #权限 ##RO-Role verbs: ["get", "watch", "list"] - apiGroups: ["extensions", "apps"] #允许读/写在 “extensions” 和 “apps” API 组中的 “deployments” 资源: resources: ["deployments"] #verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] ##RO-Role verbs: ["get", "watch", "list"] 1.3:角色绑定,将规则与账户进行绑定: [root@localhost7C role]# cat linux39-bind.yml kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: role-bind-linux39 namespace: linux39 subjects: #主体 - kind: ServiceAccount #主体类型 name: laomao #调用主体名 namespace: linux39 roleRef: #角色 kind: Role #角色类型 name: linux39-role #调用角色名 apiGroup: rbac.authorization.k8s.io 1.4 查看 [root@localhost7C role]# kubectl apply -f ./ [root@localhost7C role]# kubectl get role -n linux39 [root@localhost7C role]# kubectl describe role -n linux39 [root@localhost7C role]# kubectl get RoleBinding -n linux39 [root@localhost7C role]# kubectl describe RoleBinding -n linux39 1.5:登录dashboard测试(手动输入namespace) [root@localhost7C role]# kubectl describe secrets -n linux39 laomao-token-cjxnh https://192.168.80.160:30002/#/pod?namespace=linux39
实例2: 基于ClusterRole [root@localhost7C ClsuterRole]# cat ClsuterRole.yml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: pod-clusterrole rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "watch", "list"] [root@localhost7C ClsuterRole]# cat ClsuterRole-Binding.yml 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
实战3: 1.基于Role角色创建用户和绑定角色 2.创建用户的dashboard的登录配置文件,而不是使用token登录。 1.1:在指定namespace创建账户: # kubectl create serviceaccount laomao -n linux39 1.2:创建role规则: # cat linux39-role.yml kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: namespace: linux39 name: linux39-role rules: - apiGroups: ["*"] resources: ["pods"] #verbs: ["*"] ##RO-Role verbs: ["get", "watch", "list"] - apiGroups: ["extensions", "apps"] resources: ["deployments"] #verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] ##RO-Role verbs: ["get", "watch", "list"] 1.3:将规则与账户进行绑定: # cat linux39-bind.yml kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: role-bind-linux39 namespace: linux39 subjects: - kind: ServiceAccount name: laomao namespace: linux39 roleRef: kind: Role name: linux39-role apiGroup: rbac.authorization.k8s.io 1.4:获取token名称: # kubectl get secret -n linux39 | grep laomao laomao-token-cd4b9 kubernetes.io/service-account-token 3 5m37s 1.5:使用base加密: (等同= kubectl describe secrets -n linux39 laomao-token-cd4b9) # kubectl get secret laomao-token-cd4b9 -o jsonpath={.data.token} -n linux39 |base64 -d eyJhbGciOiJSUzI1NiIsImtpZCI6IkR5eEg0ckg0VFlTYkdEcUtTUzFad3R6OEJzOVJHdFRsZ0tGTGVUUFJiTncifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJsaW51eDM5Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6Imxhb21hby10b2tlbi1jZDRiOSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJsYW9tYW8iLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJhNTQyZTlkYy1mMDYyLTQwNmMtOWUwZi05NzA5MjQ2MWNlOTYiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6bGludXgzOTpsYW9tYW8ifQ.BK9bv8gqDxeN_ilJiDBm3COf7t2ybE0QM1M56JnGmEnzRRMJCs6uzCds9b9bB-XgVvJwqNi6W8vOj6r2iW4rMdqS9pbJrWOSl9mR756wlMSbLdAUsgHB_ywzy0L20ew13590mor_BPAvTOF5We-_2MwswNgQtUaEU6Yixpg-73Cq1UyZaCILi0h_oLqusEFwxkkunI4dmsUF3QkJ96d_TOerizizWwR716tUm_jGb05izobUjghoL526ngIdzYtND-QQM4_039vzC9WW-yobeNypM-BQADqfvD4g6g_tKiXe61SuegOyobQYQ7jom-dcqVbOU5uVDK_oHg6frHYaLQ 1.6:登录dashboard测试: 二:基于kube-config文件登录dashboard: 2.1:创建csr文件: # cat laomao-csr.json { "CN": "jack", "hosts": [], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "ST": "BeiJing", "L": "BeiJing", "O": "k8s", "OU": "System" } ] } 2.2:签发证书: # cfssl gencert -ca=/etc/kubernetes/ssl/ca.pem -ca-key=/etc/kubernetes/ssl/ca-key.pem -config=/etc/kubernetes/ssl/ca-config.json -profile=kubernetes laomao-csr.json | cfssljson -bare laomao # ls laomao* laomao.csr laomao-csr.json laomao-key.pem laomao.pem 2.3:生成普通用户kubeconfig文件:cluster1群集名(kubectl config get-clusters) --server是VIP地址(可以使用本master地址)。参考cat /root/.kube/config # kubectl config set-cluster cluster1 --certificate-authority=/etc/kubernetes/ssl/ca.pem --embed-certs=true --server=https://192.168.80.120:6443 --kubeconfig=laomao.kubeconfig 查看config cat laomao.kubeconfig 2.4:设置客户端认证参数: # cp *.pem /etc/kubernetes/ssl/ # kubectl config set-credentials laomao \ --client-certificate=/etc/kubernetes/ssl/laomao.pem \ --client-key=/etc/kubernetes/ssl/laomao-key.pem \ --embed-certs=true \ --kubeconfig=laomao.kubeconfig 2.5:设置上下文参数 kubectl config set-context cluster1 \ --cluster=cluster1 \ --user=laomao \ --namespace=linux39 \ --kubeconfig=laomao.kubeconfig 2.5: 设置默认上下文 kubectl config use-context cluster1 --kubeconfig=laomao.kubeconfig 2.7:获取token: # kubectl describe secrets laomao-token-cd4b9 -n linux39 Name: laomao-token-cd4b9 Namespace: linux39 Labels: <none> Annotations: kubernetes.io/service-account.name: laomao kubernetes.io/service-account.uid: a542e9dc-f062-406c-9e0f-97092461ce96 Type: kubernetes.io/service-account-token Data ==== ca.crt: 1350 bytes namespace: 7 bytes token: eyJhbGciOiJSUzI1NiIsImtpZCI6IkR5eEg0ckg0VFlTYkdEcUtTUzFad3R6OEJzOVJHdFRsZ0tGTGVUUFJiTncifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJsaW51eDM5Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6Imxhb21hby10b2tlbi1jZDRiOSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJsYW9tYW8iLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJhNTQyZTlkYy1mMDYyLTQwNmMtOWUwZi05NzA5MjQ2MWNlOTYiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6bGludXgzOTpsYW9tYW8ifQ.BK9bv8gqDxeN_ilJiDBm3COf7t2ybE0QM1M56JnGmEnzRRMJCs6uzCds9b9bB-XgVvJwqNi6W8vOj6r2iW4rMdqS9pbJrWOSl9mR756wlMSbLdAUsgHB_ywzy0L20ew13590mor_BPAvTOF5We-_2MwswNgQtUaEU6Yixpg-73Cq1UyZaCILi0h_oLqusEFwxkkunI4dmsUF3QkJ96d_TOerizizWwR716tUm_jGb05izobUjghoL526ngIdzYtND-QQM4_039vzC9WW-yobeNypM-BQADqfvD4g6g_tKiXe61SuegOyobQYQ7jom-dcqVbOU5uVDK_oHg6frHYaLQ 2.8:将token写入用户kube-config文件(注意格式): 2.9:dashboard登录测试: https://172.31.7.201:30002/#/pod?namespace=linux39
实战4:基于角色访问控制(RBAC)子系统会确定用户是否有权针对 某资源执行特定的操作。 普通用户并不是通过k8s来创建和维护,是通过创建证书和切换上下文环境的方式来创建和切换用户。 尽管无法通过 API 调用来添加给kubernetes增加普通用户,Kubernetes 仍然认为能够提供由集群的证书 机构签名的合法证书的用户是通过身份认证的用户。 基于这样的配置,Kubernetes 使用证书中的 ‘subject’ 的通用名称(Common Name)字段(例如,"/CN=devuser")来 确定用户名, Kubernetes使用证书中的 ‘subject’ 的单位名称 (Organization Name) 字段(例如,"/O=system:masters")来确定用户组。 说明 --embed-certs=true的作用是不在配置文件中显示证书信息。 --kubeconfig=/root/jenkins.conf 用于创建新的配置文件,如果不加此选项,则内容会"追加"到当前用户家目录下.kube/config文件中。(温馨提示,保存老的~/kube/config) 可以使用use-context来切换不同的用户管理k8s集群。可以不加context简单的理解就是用什么用户来管理哪个集群,即用户和集群的结合。 1、创建证书 创建K8S用户 #创建私钥 $(umask 077;openssl genrsa -out zzhz.key 2048) #用此私钥创建一个csr(证书签名请求)文件 $openssl req -new -key zzhz.key -subj "/CN=zzhz" -out zzhz.csr #拿着私钥和请求文件生成证书 $openssl x509 -req -in zzhz.csr -CA /etc/kubernetes/ssl/ca.pem -CAkey /etc/kubernetes/ssl/ca-key.pem -CAcreateserial -out zzhz.crt -days 365 2.集群配置 生成普通用户kubeconfig文件:cluster1群集名(kubectl config get-clusters) --server是VIP地址(可以使用本master地址)。参考cat /root/.kube/config 当--kubeconfig=zzhz.kubeconfig不指定,并且/root/.kube/config已存在,此步可以不用操作。 kubectl config set-cluster cluster1 --certificate-authority=/etc/kubernetes/ssl/ca.pem --embed-certs=true --server=https://192.168.80.120:6443 --kubeconfig=zzhz.kubeconfig #生成账号和设置客户端认证参数:用户配置 $kubectl config set-credentials zzhz --client-certificate=./zzhz.crt --client-key=./zzhz.key --embed-certs=true --kubeconfig=zzhz.kubeconfig 3、设置上下文参数, 创建context #设置上下文, 默认会保存在 $HOME/.kube/config $ kubectl config set-context zzhz@cluster1 --cluster=cluster1 --user=zzhz --namespace=linux39 --kubeconfig=zzhz.kubeconfig #查看 $ kubectl config get-contexts --kubeconfig=zzhz.kubeconfig CURRENT NAME CLUSTER AUTHINFO NAMESPACE * cluster1 cluster1 admin zzhz@cluster1 cluster1 zzhz linux39 #切换context $ kubectl config use-context zzhz@cluster1 --kubeconfig=./zzhz.kubeconfig #测试 发现使用我们创建的用户查询是失败的,是因为账号还没授权,接下来就是对账号进行授权。这里需要先把用切回来,要不然就无法进行下一步授权了。 $ kubectl get nodes --kubeconfig=./zzhz.kubeconfig Error from server (Forbidden): nodes is forbidden: User "zzhz" cannot list resource "nodes" in API group "" at the cluster scope 切回管理员用户 kubectl config use-context cluster1 5、对用户授权 上述操作完成后,用户还没有具体的访问权限,创建Role和RoleBinding,为该用户授权,只有linux39名称空间的相关权限 cat /role-pod-reader.yaml kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: namespace: linux39 name: pods-reader rules: - apiGroups: [""] resources: ["pods","services","pods/*"] verbs: ["get","watch","list","create"] 绑定角色 cat role-binding-zzhz.yaml kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: zzhz namespace: linux39 subjects: - kind: User name: zzhz apiGroup: rbac.authorization.k8s.io roleRef: kind: Role name: pods-reader apiGroup: rbac.authorization.k8s.io 6、验证 切回管理员用户 kubectl config use-context zzhz@cluster1 --kubeconfig=./zzhz.kubeconfig kubectl get pods -n linux39 [root@localhost7C zzhz]# kubectl get pods -n zzhz --kubeconfig=./zzhz.kubeconfig zzhz.crt zzhz.csr zzhz.key zzhz-rolebinding.yaml zzhz-role.yaml [root@localhost7C zzhz]# kubectl get pods -n default --kubeconfig=./zzhz.kubeconfig Error from server (Forbidden): pods is forbidden: User "zzhz" cannot list resource "pods" in API group "" in the namespace "default"
Group因为跟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 参考文档 https://blog.csdn.net/qq_35745940/article/details/120693490