一. 基础知识:
- K8s默认采用RBAC鉴权方式,包含4个顶级资源对象,Role/ClusterRole/RoleBinding/ClusterRoleBinding
- Role/ClusterRole:角色和集群角色,角色/集群角色 = 一组对K8s资源对象操作权限的集合(如get pod,delete deployment等操作均需要权限)
- RoleBinding/ClusterRoleBinding:角色绑定和集群角色绑定,通过这两种资源对象,可以将Role/ClusterRole与集群中对象进行绑定,包括User/Group/Service Account
- 上述集群中对象User/Group/service Account与宿主机无直接关系,如此处User为k8s集群内用户,而/etc/passwd中的为Linux系统用户
- 通过kubeconfig可以将系统用户和K8s集群用户关联,如:
[root@test ~]
(执行该命令需要先切换kubeconfig中当前的上下文,配置过程中会详细说明)
二. 举例说明Linux系统用户、K8s集群User用户、Role/ClusterRole、RoleBinding/ClusterRoleBinding间的关系:
班级中的对应关系:
Linux系统用户:助教小明
K8s集群User用户:职务,如班长、学习委员...
Role/ClusterRole:责任或权利,如收作业,安排值日...
RoleBinding/ClusterRoleBinding:老师安排职务和权利对应关系
ca.pem/ca-key.pem或ca.crt/ca.key(集群CA根证书和CA私钥):班级公章,用于盖章生成集群证明
--kubeconfig指定的文件:印的写有某职务名的肩章,如“三年二班班长”肩章
运维工程师:班主任
- 绑定职务及权利(Role/ClusterRole与RoleBinding/ClusterRoleBinding原理)
三年二班中有很多日常工作要做,如收作业,安排值日,检查着装等;班主任为了便于管理,就设置了几个职务如班长、学习委员,并且规定,班长的权利有:安排值日,检查着装,学习委员的权利有:收作业。老师通过规定(RoleBinding/ClusterRoleBinding)将职务(User)与权利(Role/ClusterRole)进行绑定,这样同学们就知道班长(User)有什么权利能干什么(Role/ClusterRole)。当然,老师同样可以规定,班级中有班长和副班长,但是两人的权利完全相同,即多个User绑定同一个Role/ClusterRole。 - 制作肩章过程(生成kubeconfig文件)
班级通过一致决定(通过集群认证)将每个职位做成肩章,如带有“三年二班班长”字样的班长肩章(–kubeconfig对应的文件),并规定戴上肩章的人才有肩章对应的权利而忘戴则没有。肩章的制作过程首先需要班主任写好带有职务名(写有K8s集群用户readonly的readonly.json文件)和职务有效期等信息(写有过期时间的ca配置文件ca-config-readonly.json)的两个文件,之后班主任使用班级公章(ca根证书和私钥)和写好的两个文件(两个json)通过计算机算法得到用于证明肩章有效的文件(readonly.pem客户端证书,用于K8s的解密认证)和另一个文件(readonly-key.pem客户端私钥,实在编不出来了。。。)。之后将班级公章(ca.pem/ca-key.pem或ca.crt/ca.key:CA根证书和CA私钥)和证明肩章有效的两个文件(readonly.pem/readonly-key.pem:客户端证书和客户端私钥)提交至班级系统里,从而注册班长职务并备注过期时间等信息。学校获取到班长职务信息后,要求班主任提供肩章样式(context上下文),再根据职务名(K8s集群User用户名)和样式制作出肩章(–kubeconfig指定的文件)并返回给班主任 - (K8s RBAC权限控制)
班级中除班主任外还有一些助教,其中助教小明经班主任任命得到了“三年二班班长”肩章,只要他(Linux系统用户)戴着写有“三年二班班长”(K8s集群User用户)字样的肩章(kubectl时指定–kubeconfig),他就对班级中的同学(集群资源对象如pod)有权利检查着装(Role/ClusterRole)。某天助教小明忘戴了班长肩章(未指定–kubeconfig),则班级就不认可(认证失败)他的任何权利。若班主任(运维工程师)将助教小明的工作服上均印有“三年二班班长”字样的班长肩章(将kubeconfig文件cp为/home/xiaoming/.kube/config),则即使小明忘戴,依然有班长的默认权利(–kubeconfig默认路径为/home/$USER/.kube/config)
三. 具体操作:
- 安装cfssl和cfssljson工具用于生成证书
wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
chmod +x cfssl_linux-amd64
mv cfssl_linux-amd64 /usr/local/bin/cfssl
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
chmod +x cfssljson_linux-amd64
mv cfssljson_linux-amd64 /usr/local/bin/cfssljson
- 使用集群CA自签名证书生成client证书和client私钥
mkdir /tmp/test && cd /tmp/test
cp /etc/kubernetes/ssl/ca.pem ./
cp /etc/kubernetes/ssl/ca-key.pem ./
- 新增用于生成Client证书的Json文件,其中声明了User相关信息
vim readonly.json
{
"CN": "readonly",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "HangZhou",
"L": "HangZhou",
"O": "develop:readonly",
"OU": "develop"
}
]
}
- 新增用于生成Client证书的Json文件,包含有效期等信息
vim ca-config-readonly.json
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"kubernetes": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "87600h"
}
}
}
}
- 创建readonly用户Client证书和Client私钥
sudo cfssl gencert --ca ca.pem --ca-key ca-key.pem --config ca-config-readonly.json --profile=kubernetes readonly.json | cfssljson --bare readonly
- 基于已有kubeconfig文件添加新K8s集群User及Context信息
cp /root/.kube/config ./readonly.kubeconfig
- 新增环境准备脚本
vim kubeconfig.sh
kubectl config set-credentials readonly \
--certificate-authority=/tmp/test/ca.pem \
--embed-certs=true \
--client-key=/tmp/test/readonly-key.pem \
--client-certificate=/etc/kubernetes/pki/test/readonly.pem \
--kubeconfig=/etc/kubernetes/pki/test/readonly.kubeconfig
kubectl config set-context readonly-context --cluster=kubernetes \
--user=readonly \
--kubeconfig=readonly.kubeconfig
kubectl config use-context readonly-context --kubeconfig=readonly.kubeconfig
sh kubeconfig.sh
- 创建ClusterRole,并通过ClusterroleBinding将名为readonly-clusterrole的ClusterRole与名为readonly的K8s集群User用户绑定(也可以使用已有clusterrole----view)
vim clusterrole_and_binding.yaml
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
name: readonly-clusterrole
rules:
- apiGroups:
- ""
resources:
- pods
- pods/attach
- pods/exec
- pods/portforward
- pods/proxy
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- configmaps
- endpoints
- persistentvolumeclaims
- replicationcontrollers
- replicationcontrollers/scale
- secrets
- serviceaccounts
- services
- services/proxy
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- bindings
- events
- limitranges
- namespaces/status
- pods/log
- pods/status
- replicationcontrollers/status
- resourcequotas
- resourcequotas/status
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- namespaces
verbs:
- get
- list
- watch
- apiGroups:
- apps
resources:
- deployments
- deployments/rollback
- deployments/scale
- statefulsets
verbs:
- get
- list
- watch
- apiGroups:
- autoscaling
resources:
- horizontalpodautoscalers
verbs:
- get
- list
- watch
- apiGroups:
- batch
resources:
- cronjobs
- jobs
- scheduledjobs
verbs:
- get
- list
- watch
- apiGroups:
- extensions
resources:
- daemonsets
- deployments
- ingresses
- replicasets
verbs:
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: cluster-readonly
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: readonly-clusterrole
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: readonly
kubectl apply -f clusterrole_and_binding.yaml
- 验证通过指定存有readonly-context上下文和readonly集群用户的kubeconfig文件,能否访问node和pod
kubectl --kubeconfig=readonly.kubeconfig get nodes
kubectl --kubeconfig=readonly.kubeconfig get nodes -n kube-system
kubectl --kubeconfig=readonly.kubeconfig delete pods xxx -n kube-system
- Linux用户的权限限制
mkdir -p /home/test/.kube/ && cp /tmp/test/readonly.kubeconfig /home/test/.kube/config
chown -R test:test /home/test/.kube/
su - test
kubectl get pods -nkube-system
kubectl get nodes