一、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