RBAC 实战案例
(一)通过用户账号的方式分配单独Namespace的权限
1.案例描述
创建一个用户,仅拥有对know-system命名空间下的pods、deployments资源操作权限,采用RoleBinding绑定ClusterRole的方式来实现。
大致实现思路:
1.生成用户的证书文件key
2.通过apiserver生成证书请求
3.通过k8s的api的ca证书签发用户的证书请求
4.配置k8s设置集群、创建用户、配置上下文信息
5.创建ClusterRole、RoleBinding资源
2.创建用户账号
1.创建证书文件[root@k8s-master ~]\# cd /etc/kubernetes/pki/[root@k8s-master /etc/kubernetes/pki]\# (umask 077;openssl genrsa -out knowman.key 2048)Generating RSA private key, 2048 bit long modulus....................................................................................+++................+++e is 65537 (0x10001)
2.使用apiserver的证书签发证书请求
2-1.申请签名,证书请求,申请的用户名是knowman,组是knowgroup[root@k8s-master /etc/kubernetes/pki]\# openssl req -new -key knowman.key -out knowman.csr -subj "/CN=knowman/O=knowgroup"[root@k8s-master /etc/kubernetes/pki]\# ll knowman.*-rw-r--r-- 1 root root 915 4月 20 13:27 knowman.csr-rw------- 1 root root 1679 4月 20 13:25 knowman.key
2-2.签发证书(使用apiserver的ca证书签发用户证书)[root@k8s-master /etc/kubernetes/pki]\# openssl x509 -req -in knowman.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out knowman.crt -days 3650Signature oksubject=/CN=knowman/O=knowgroupGetting CA Private Key
0.3 👀 先查看一下集群apiserver的监听地址,确保监听的该地址可以访问到kubernetes(这里我做了代理。。)❯ kubectl cluster-infoKubernetes control plane is running at https://127.0.0.1:52520CoreDNS is running at https://127.0.0.1:52520/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
3.配置集群、用户、上下文信息#配置集群[root@k8s-master /etc/kubernetes/pki]\# kubectl config set-cluster kubernetes --embed-certs=true --certificate-authority=/etc/kubernetes/pki/ca.crt --server=https://192.168.81.210:6443Cluster "kubernetes" set.
#配置用户信息[root@k8s-master /etc/kubernetes/pki]\# kubectl config set-credentials knowman --embed-certs=true --client-certificate=/etc/kubernetes/pki/knowman.crt --client-key=/etc/kubernetes/pki/knowman.keyUser "knowman" set.
#配置上下文信息[root@k8s-master /etc/kubernetes/pki]\# kubectl config set-context knowman@kubernetes --cluster=kubernetes --user=knowmanContext "knowman@kubernetes" created.
4.查看配置的集群信息[root@k8s-master /etc/kubernetes/pki]\# kubectl config view
5)切换到knowman用户[root@k8s-master /etc/kubernetes/pki]\# kubectl config use-context knowman@kubernetesSwitched to context "knowman@kubernetes".
6)试着查看下know-system命名空间下的资源[root@k8s-master /etc/kubernetes/pki]\# kubectl get pod -n know-systemError from server (Forbidden): pods is forbidden: User "knowman" cannot list resource "pods" in API group "" in the namespace "know-system"#可以看到没有权限访问
7)切换到admin用户进行授权[root@k8s-master ~]\# kubectl config use-context kubernetes-admin@kubernetesSwitched to context "kubernetes-admin@kubernetes"
3.创建ClusterRole资源设置权限
创建一个ClusterRole,针对资源做一些授权,由于ClusterRole是集群级别的角色授权,可以多次复用
1.编写ClusterRole资源[root@k8s-master ~/k8s_1.19_yaml/rbac]\# vim knowman-clusterrole.yamlapiVersion: rbac.authorization.k8s.io/v1kind: ClusterRolemetadata: name: knowman-clusterrolerules: #定义角色- apiGroups: ["","apps"] #对哪个api组进行授权,""核心资源组,apps组是deployment控制器所在的api组 resources: ["pods","deployments"] #对什么资源进行授权 verbs: #具体的权限列表 - get - list - watch
2.创建资源[root@k8s-master ~/k8s_1.19_yaml/rbac]\# kubectl create -f knowman-clusterrole.yamlclusterrole.rbac.authorization.k8s.io/knowman-clusterrole created
3.查看资源[root@k8s-master ~/k8s_1.19_yaml/rbac]\# kubectl get clusterrole knowman-clusterroleNAME CREATED ATknowman-clusterrole 2021-04-20T06:26:20Z
4.查看资源的详细信息[root@k8s-master ~/k8s_1.19_yaml/rbac]\# kubectl describe clusterrole knowman-clusterrole
4.创建RoleBinding资源将用户和角色绑定
通过RoleBinding角色绑定将用户与集群角色进行绑定
1.编写yaml[root@k8s-master ~/k8s_1.19_yaml/rbac]\# vim knowman-rolebinding.yamlapiVersion: rbac.authorization.k8s.io/v1kind: RoleBindingmetadata: name: knowman-rolebinding namespace: know-systemsubjects: #关联用户信息- kind: User #类型为用户 name: knowman #用户名称 namespace: know-system #角色所能控制的命名空间 apiGroup: rbac.authorization.k8s.ioroleRef: #关联角色信息 kind: ClusterRole #类型为ClusterRole name: knowman-clusterrole #角色名称 apiGroup: rbac.authorization.k8s.io
2.创建资源[root@k8s-master ~/k8s_1.19_yaml/rbac]\# kubectl create -f knowman-rolebinding.yamlrolebinding.rbac.authorization.k8s.io/knowman-rolebinding created
3.查看资源[root@k8s-master ~/k8s_1.19_yaml/rbac]\# kubectl get rolebinding knowman-rolebinding -n know-systemNAME ROLE AGEknowman-rolebinding ClusterRole/knowman-clusterrole 17s
4.查看资源的详细信息[root@k8s-master ~/k8s_1.19_yaml/rbac]\# kubectl describe rolebinding knowman-rolebinding -n know-system
5.切换knowman用户查看权限
1.切换用户[root@k8s-master ~/k8s_1.19_yaml/rbac]\# kubectl config use-context knowman@kubernetesSwitched to context "knowman@kubernetes".
2.查看可以操作的pod/deployment资源[root@k8s-master ~/k8s_1.19_yaml/rbac]\# kubectl get pod,deployment -n know-systemNAME READY STATUS RESTARTS AGEpod/deploy-nginx-5cfd6fd7bd-79z4t 1/1 Running 1 6d3hpod/deploy-nginx-5cfd6fd7bd-b67wf 1/1 Running 1 6d3hpod/deploy-nginx-5cfd6fd7bd-qpl2w 1/1 Running 1 6d3h
NAME READY UP-TO-DATE AVAILABLE AGEdeployment.apps/deploy-nginx 3/3 3 3 6d5h
3.删除pod查看是否有权限[root@k8s-master ~/k8s_1.19_yaml/rbac]\# kubectl delete pod deploy-nginx-5cfd6fd7bd-79z4t -n know-systemError from server (Forbidden): pods "deploy-nginx-5cfd6fd7bd-79z4t" is forbidden: User "knowman" cannot delete resource "pods" in API group "" in the namespace "know-system"#无权删除
除了deployment、pod资源之前无权操作其他资源
(二)通过kubeconfig授权文件实现特定资源的权限分配
1.案例描述
我们可以使用根证书签发一个客户端证书,在客户端证书里面指定用户名,然后在通过kubectl config命令生成一个kubeconfig授权文件,文件内容中包括了集群信息、用户信息、客户端证书信息,然后再创建一个rbac策略,将证书中的用户与创建的role角色进行绑定,即可实现通过授权文件的方式去访问集群的特定资源
最终实现目的: 将授权文件发给对应的人员,让人员只需kubectl命令的时候指定kubeconfig文件的路径即可请求集群资源
实现步骤:
1.安装cfssl工具,用k8s ca根证书签发一个客户端证书
2.用kubectl config生成授权文件
3.创建rbac授权策略
2.准备cfssl工具命令
1.编写脚本[root@k8s-master 1 rbac]\# cat cfssl.shwget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64chmod +x cfssl*mv cfssl_linux-amd64 /usr/bin/cfsslmv cfssljson_linux-amd64 /usr/bin/cfssljsonmv cfssl-certinfo_linux-amd64 /usr/bin/cfssl-certinfo
2.执行脚本[root@k8s-master1 rbac]\# sh cfssl.sh
3.查看是否安装成功[root@k8s-master1 rbac]\# ll /usr/bin/cfssl* /usr/local/bin/cfssl-rwxr-xr-x 1 root root 6595195 4月 17 03:17 /usr/bin/cfssl-certinfo-rwxr-xr-x 1 root root 2277873 4月 17 03:17 /usr/bin/cfssljson-rwxr-xr-x 1 root root 10376657 5月 11 10:17 /usr/local/bin/cfssl
3.利用k8s根证书签发一个客户端证书
利用k8s的ca根证书签发一个专门给某个客户端使用的证书
1.编写脚本[root@k8s-master1 rbac]\# vim cert.shcat > ca-config.json <<EOF{ "signing": { "default": { "expiry": "87600h" #证书的有效期 }, "profiles": { "kubernetes": { "usages": [ "signing", "key encipherment", "server auth", "client auth" ], "expiry": "87600h" } } }}EOF
cat > jiangxl-csr.json <<EOF{ "CN": "jiangxl", #可以理解为是用户名,rbac授权的时候也是根据这个值来授权 "hosts": [], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "ST": "BeiJing", "L": "BeiJing", "O": "k8s", "OU": "System" } ]}EOF
cfssl gencert -ca=/etc/kubernetes/pki/ca.crt -ca-key=/etc/kubernetes/pki/ca.key -config=ca-config.json -profile=kubernetes jiangxl-csr.json | cfssljson -bare jiangxl #通过cfssl生成证书,要指定k8s根证书的路径
2.生成证书[root@k8s-master1 rbac]\# sh cert.sh2021/07/06 14:52:58 [INFO] generate received request2021/07/06 14:52:58 [INFO] received CSR2021/07/06 14:52:58 [INFO] generating key: rsa-20482021/07/06 14:52:58 [INFO] encoded CSR2021/07/06 14:52:58 [INFO] signed certificate with serial number 1041204170467940755921283259523168277552181201192021/07/06 14:52:58 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable forwebsites. For more information see the Baseline Requirements for the Issuance and Managementof Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);specifically, section 10.2.3 ("Information Requirements")
3.查看生成的证书文件[root@k8s-master1 rbac]\# ll ca-config.json jiangxl*-rw-r--r-- 1 root root 292 7月 6 14:52 ca-config.json-rw-r--r-- 1 root root 997 7月 6 14:52 jiangxl.csr-rw-r--r-- 1 root root 220 7月 6 14:52 jiangxl-csr.json-rw------- 1 root root 1679 7月 6 14:52 jiangxl-key.pem-rw-r--r-- 1 root root 1281 7月 6 14:52 jiangxl.pem#主要有用的就是jiangxl.pem jiangxl-key.pem
4.生成kubeconfig授权文件
生成一个kubeconfig授权文件,文件的内容和/root/.kube/config文件基本是一致的,只是证书内容不一样,证书内容不同所属的权限也不同,用户可以通过指定kubeconfig文件去执行k8s命令
生成授权文件需要分为三个步骤:设置集群、设置证书私钥文件路径、指定用户名,每当执行一个步骤,kubeconfig的内容就会增加上相应的配置
1.生成授权文件设置集群信息:指定根证书路径、k8sapi地址、授权文件名称
kubectl config set-cluster kubernetes \ --certificate-authority=/etc/kubernetes/pki/ca.crt \ --embed-certs=true \ --server=https://192.168.16.106:6443 \ --kubeconfig=jiangxl.kubeconfig
#set-cluster kubernetes:设置集群名称为kubernetes#--certificate-authority:指定根证书路径#--server:指定k8sapi地址#--kubeconfig:指定授权文件名称
当执行了第一步设置集群信息后,查看kubeconfig的文件内容,会发现文件里面多了根证书ca的文件内容以及集群apiserver的地址
2.设置客户端认证:指定客户端证书文件路径和私钥文件路径
kubectl config set-credentials jiangxl \ --client-key=jiangxl-key.pem \ --client-certificate=jiangxl.pem \ --embed-certs=true \ --kubeconfig=jiangxl.kubeconfig
#--client-key:指定客户端证书的私钥文件#--client-certificate:指定客户端证书的证书文件#--kubeconfig:指定授权文件名称#set-credentials jiangxl:设置证书的名称为jiangxl
当第二步设置客户端证书认证完成后,kubeconfig文件就会增加客户端证书文件的内容
3.设置默认上下文:指定用户名是什么
kubectl config set-context kubernetes \ --cluster=kubernetes \ --user=jiangxl \ --kubeconfig=jiangxl.kubeconfig
第三步执行完成后,kubeconfig文件里面会增加用户信息配置,rbac授权也是将这个用户和某个role进行绑定
5.执行kubectl命令时指定授权文件
使用--kubeconfig
参数去指定使用哪个授权文件,到此时也就可以把授权文件发送给需要使用这个授权的人,虽然现在还是无权限获取资源的状态,但是已经可以连接到k8s集群了,只需要配置好rbac策略,即可有权限访问资源
[root@k8s-master1 rbac]\# kubectl --kubeconfig=jiangxl.kubeconfig get podError from server (Forbidden): pods is forbidden: User "jiangxl" cannot list resource "pods" in API group "" in the namespace "default"
6.配置rbac策略授权kubeconfig相应的权限
1.编写rbac yaml资源文件
创建一个role,授权对default命名空间下pod、deployment、svc资源的访问权限,并将该role与jiangxl用户进行绑定
[root@k8s-master1 rbac]\# vim rbac.yamlapiVersion: rbac.authorization.k8s.io/v1kind: Rolemetadata: namespace: default name: pod-readerrules:- apiGroups: ["","apps"] resources: ["pods","deployments","services"] verbs: ["get", "watch", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1kind: RoleBindingmetadata: name: read-pods namespace: defaultsubjects:- kind: User name: jiangxl apiGroup: rbac.authorization.k8s.ioroleRef: kind: Role name: pod-reader apiGroup: rbac.authorization.k8s.io
2.创建rbac资源
[root@k8s-master1 rbac]\# kubectl apply -f rbac.yamlrole.rbac.authorization.k8s.io/pod-reader createdrolebinding.rbac.authorization.k8s.io/read-pods created
7.验证kubeconfig授权文件是否有了对应的权限
[root@k8s-master1 rbac]\# kubectl --kubeconfig=jiangxl.kubeconfig get pod,deployment,svcNAME READY STATUS RESTARTS AGEpod/jenkins-0 1/1 Running 0 38spod/tools-696bf5cc5c-z2znw 1/1 Running 0 103s
NAME READY UP-TO-DATE AVAILABLE AGEdeployment.apps/tools 1/1 1 1 27d
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEservice/jenkins ClusterIP None <none> 42/TCP 15dservice/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 59dservice/tools ClusterIP None <none> 42/TCP 27d
#已经对default命名空间下的pod、deployment、svc资源有了读取权限
(三)通过Service Account账号授权实现特定资源的权限分配
1.创建一个sa账号
[root@k8s-master1 sa]\# vim nginx-sa.yamlapiVersion: v1kind: ServiceAccountmetadata: name: nginx-sa namespace: rbac labels: kubernetes.io/cluster-service: "true" addonmanager.kubernetes.io/mode: Reconcile
2.编写rbac资源授权yaml文件
[root@k8s-master1 sa]\# vim nginx-rbac.yamlkind: RoleapiVersion: rbac.authorization.k8s.io/v1metadata: namespace: rbac name: pod-readerrules:- apiGroups: ["","apps"] resources: ["pods","deployments","services"] verbs: ["get", "watch", "list"]
---
kind: RoleBindingapiVersion: rbac.authorization.k8s.io/v1metadata: name: read-pods namespace: rbacsubjects:- kind: ServiceAccount #类型填写ServiceAccount name: nginx-sa namespace: rbacroleRef: kind: Role name: pod-reader apiGroup: rbac.authorization.k8s.io
3.编写nginx pod资源并使用sa账号
apiVersion: apps/v1kind: StatefulSetmetadata: name: web namespace: statspec: serviceName: "web" #指定使用哪个headless service资源 replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: serviceAccountName: nginx-sa containers: - name: nginx image: nginx:1.17 ports: - name: web containerPort: 80
4.创建所有资源并查看
1.创建所有资源[root@k8s-master1 sa]\# kubectl apply -f ./role.rbac.authorization.k8s.io/pod-reader createdrolebinding.rbac.authorization.k8s.io/read-pods createdserviceaccount/nginx-sa createdstatefulset.apps/web created
2.查看sa账号#sa账号会生成一个token,这个token中保存这根证书ca以及sa用户的证书kube
:q,用于连接到k8s集群[root@k8s-master1 sa]\# kubectl get sa -n rbacNAME SECRETS AGEdefault 1 4m48snginx-sa 1 103s[root@k8s-master1 sa]\# kubectl get secret -n rbacNAME TYPE DATA AGEdefault-token-4fkpj kubernetes.io/service-account-token 3 5m14snginx-sa-token-vcrmv kubernetes.io/service-account-token 3 2m9s
3.查看nginx资源中是否关联sa[root@k8s-master1 sa]\# kubectl describe statefulset -n rbacName: web···········Pod Template: Labels: app=nginx Service Account: nginx-sa···········
文章来源于:https://blog.51cto.com/jiangxl/5076630
仅做个人备份学习使用.