K8S的RBAC实战案例
作者:尹正杰
版权声明:原创作品,谢绝转载!否则将追究法律责任。
目录
一.Kubernetes鉴权体系概述
1.启用authorization模式
在kube-apiserver上使用“--authorization-mode”选项进行定义,多个模块彼此间以逗号分隔。
如上图所示,kubeadm部署的集群,默认启用了Node和RBAC。
API Server中的鉴权框架及启用的鉴权模块负责鉴权:
支持的鉴权模块:
Node:
专用的授权模块,它基于kubelet将要运行的Pod向kubelet进行授权。
ABAC:
通过将属性(包括资源属性、用户属性、对象和环境属性等)组合在一起的策略,将访问权限授予用户。
RBAC:
基于企业内个人用户的角色来管理对计算机或网络资源的访问的鉴权方法。
Webhook:
用于支持同Kubernetes外部的授权机制进行集成。
另外两个特殊的鉴权模块是AlwaysDeny和AlwaysAllow。
参考链接:
https://kubernetes.io/zh-cn/docs/reference/access-authn-authz/
2.RBAC基础概念
实体(Entity):
在RBAC也称为Subject,通常指的是User、Group或者是ServiceAccount;
角色(Role):
承载资源操作权限的容器。
资源(Resource):
在RBAC中也称为Object,指代Subject期望操作的目标,例如Service,Deployments,ConfigMap,Secret、Pod等资源。
仅限于"/api/v1/..."及"/apis/<group>/<version>/..."起始的路径;
其它路径对应的端点均被视作“非资源类请求(Non-Resource Requests)”,例如"/api"或"/healthz"等端点;
动作(Actions):
Subject可以于Object上执行的特定操作,具体的可用动作取决于Kubernetes的定义。
资源型对象:
只读操作:get、list、watch等。
读写操作:create、update、patch、delete、deletecollection等。
非资源型端点仅支持"get"操作。
角色绑定(Role Binding):
将角色关联至实体上,它能够将角色具体的操作权限赋予给实体。
角色的类型:
Namespace级别:
称为Role,定义名称空间范围内的资源操作权限集合。
Namespace和Cluster级别:
称为ClusterRole,定义集群范围内的资源操作权限集合,包括集群级别及名称空间级别的资源对象。
角色绑定的类型:
Cluster级别:
称为ClusterRoleBinding,可以将实体(User、Group或ServiceAccount)关联至ClusterRole。
Namespace级别:
称为RoleBinding,可以将实体关联至ClusterRole或Role。
即便将Subject使用RoleBinding关联到了ClusterRole上,该角色赋予到Subject的权限也会降级到RoleBinding所属的Namespace范围之内。
3.ClusterRole
类别 | 功能说明 |
---|---|
API发现相关的角色 | 包括system:basic-user、system:discovery和system:public-info-viewer。 |
面向用户的角色 | 包括cluster-admin、admin、edit和view。 |
核心组件专用的角色 | 包括system:kube-scheduler、system:volume-scheduler、system:kube-controller-manager、system:node和system:node-proxier等。 |
其它组件专用的角色 | 包括system:kube-dns、system:node-bootstrapper、system:node-problem-detector和system:monitoring等。 |
内置控制器专用的角色 | 专为内置的控制器使用的角色,具体可参考官网文档。 |
启用RBAC鉴权模块时,API Server会自动创建一组ClusterRole和ClusterRoleBinding对象
多数都以“system:”为前缀,也有几个面向用户的ClusterRole未使用该前缀,如cluster-admin、admin等。
它们都默认使用“kubernetes.io/bootstrapping: rbac-defaults”这一标签。
如上表所示,默认的ClusterRole大体可以分为5个类别。
4.K8S内置的面向用户的集群角色
角色 | 功能描述 |
---|---|
cluster-admin | 允许用户在目标范围内的任意资源上执行任意操作;使用ClusterRoleBinding关联至用户时,授权操作集群及所有名称空间中任何资源;使用RoleBinding关联至用户时,授权控制其所属名称空间中的所有资源,包括Namespace资源自身,隶属于"system:masters 组"。 |
admin | 管理员权限,主要用于结合RoleBinding为特定名称空间快速授权生成管理员用户,它能够将RoleBinding所属名称空间中的大多数资源的读/写权限授予目标用户,包括创建Role和RoleBinding的能力;但不支持对ResourceQuota及Namespace本身进行操作; |
edit | 接近于admin的权限,支持对名称空间内的大多数对象进行读/写操作,包括Secret,但不允许查看或修改Role及RoleBinding; |
view | 允许以只读方式访问名称空间中的大多数对象,但不包括Role、RoleBinding和Secret; |
如上表所示,面向用户的角色是安装K8S集群默认创建的集群角色。
5.验证集群管理员kubeconfig证书案例
1.导出kubeconfig的用户证书
[root@master231 ~]# kubectl config view --raw -o jsonpath='{.users[0].user.client-certificate-data}' | base64 -d > admin.crt
[root@master231 ~]#
2.查看证书信息【注意观察'O'(表示组)和'CN'(表示用户)字段】
[root@master231 ~]# openssl x509 -noout -text -in admin.crt
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 6152070814068099595 (0x55608bcf7193ca0b)
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN = kubernetes
Validity
Not Before: Dec 15 07:46:30 2024 GMT
Not After : Dec 15 07:46:32 2025 GMT
Subject: O = system:masters, CN = kubernetes-admin # 注意哈,组对为"system:masters"
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:d0:c9:64:e2:2d:81:38:0d:85:a7:90:4e:bb:09:
89:a3:cb:88:dc:ad:3c:d4:e9:9c:e1:b8:d9:af:79:
ed:1e:1b:ef:bf:fa:f2:5c:2e:ae:c4:3c:03:a0:a4:
00:d9:25:c6:64:dd:22:36:0d:3e:27:16:90:a1:46:
1d:5b:53:0b:3c:a5:9f:f7:bb:f3:6b:53:08:46:11:
82:24:7b:b8:c6:01:fa:5f:0b:12:fa:8d:99:ff:08:
9f:f1:dd:1c:59:cb:0f:a1:af:18:e2:00:8e:a9:d8:
f3:20:be:79:b1:d8:1f:a6:2f:b5:0a:bb:6f:a0:cb:
24:fe:ca:ac:6f:dd:63:12:75:14:0d:2e:93:d3:4d:
a9:fc:7c:1d:cc:9b:d1:4a:d4:79:77:fe:d7:01:fd:
6a:c8:2e:a1:10:0f:ec:7d:7a:9e:bd:e1:6e:d5:9d:
e4:f4:8a:81:4c:01:62:ac:33:cf:d5:7d:0f:27:57:
fa:40:47:23:43:fc:1f:99:14:ff:60:18:08:e8:42:
ec:89:df:8b:33:7b:09:e6:88:2d:eb:db:aa:e4:57:
c3:a0:15:dd:a1:36:78:71:65:a3:d6:c0:b9:86:cf:
2d:50:01:79:31:a6:ab:59:e1:ce:f8:2a:05:96:50:
c8:55:53:94:f8:38:46:77:1f:db:b9:da:76:3c:31:
91:45
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 Extended Key Usage:
TLS Web Client Authentication
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Authority Key Identifier:
A9:68:3B:A5:67:CD:1E:C6:1F:B0:26:C5:E2:24:93:83:B4:E8:13:BF
Signature Algorithm: sha256WithRSAEncryption
Signature Value:
6e:37:19:55:c2:4b:45:47:68:bc:bd:67:89:c1:29:39:fe:04:
4e:93:b2:c6:9b:e3:0e:1b:89:0d:98:21:93:87:23:62:d5:26:
0b:8f:23:ec:c2:79:2a:6a:26:c6:2f:6d:27:49:d7:18:b2:61:
92:77:01:06:f5:4a:0a:90:3d:84:f9:fe:b4:ca:de:97:d5:ca:
37:79:43:20:97:51:94:00:00:69:9e:08:b8:eb:16:37:bd:88:
02:38:fa:41:bf:25:c7:f8:aa:63:a5:a0:5f:16:95:55:e4:da:
30:c6:08:cd:f8:6c:76:92:5a:13:f2:d3:7b:71:c2:77:4b:99:
93:d5:e7:40:0c:54:5c:41:43:a6:9b:de:b6:79:ac:74:ce:8e:
48:17:a0:8a:e5:33:3c:b0:57:8a:f7:61:9e:0a:48:9b:10:09:
ab:7e:5d:5c:85:7e:94:ec:08:b5:62:7f:b7:82:7f:d0:f8:d3:
13:a1:f0:5a:51:dd:3c:b3:84:a2:62:a3:f3:43:4e:34:ca:28:
a2:78:85:d8:a5:5d:2d:9f:b1:13:eb:0f:b6:a6:85:74:45:9b:
98:1a:9e:54:c1:0a:95:3f:8d:41:3f:e7:3c:dd:14:6c:74:a8:
4b:c7:8e:f4:e2:07:8a:20:9c:5e:26:70:7e:50:5e:c5:f1:1f:
f1:16:fe:a5
[root@master231 ~]#
3.验证角色绑定信息
[root@master231 ~]# kubectl get clusterrolebindings cluster-admin -oyaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
creationTimestamp: "2024-12-15T07:46:38Z"
labels:
kubernetes.io/bootstrapping: rbac-defaults
name: cluster-admin
resourceVersion: "148"
uid: f226043e-b3b7-4ac1-98e8-9100d710785f
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:masters # 很明显,此处使用了‘system:masters’这个组哟~
[root@master231 ~]#
二.RBAC实战
1.Role和RoleBinding案例
1.创建sa
[root@master231 ~]# kubectl -n kube-public create serviceaccount yinzhengjie
serviceaccount/yinzhengjie created
[root@master231 ~]#
2.在default名称空间下响应式创建Role,名为"reader"
[root@master231 ~]# kubectl create role reader --verb=get,list,watch --resource=deployments,services,pods -n default
role.rbac.authorization.k8s.io/reader created
[root@master231 ~]#
3.将default名称空间下的角色reader绑定到kube-public名称空间下的名为"yinzhengjie"的sa
[root@master231 ~]# kubectl create rolebinding yinzhengjie-as-reader --role=reader --serviceaccount=kube-public:yinzhengjie -n default
rolebinding.rbac.authorization.k8s.io/yinzhengjie-as-reader created
[root@master231 ~]#
4.创建Pod并指定sa
[root@master231 ~]# cat yinzhengjie-xiuxian.yaml
apiVersion: v1
kind: Pod
metadata:
name: pods-xiuxian
namespace: kube-public
spec:
serviceAccountName: yinzhengjie
containers:
- image: registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/apps:v1
name: xiuxian
[root@master231 ~]#
[root@master231 ~]# kubectl apply -f yinzhengjie-xiuxian.yaml
pod/pods-xiuxian created
[root@master231 ~]#
[root@master231 ~]# kubectl get pods,sa -n kube-public -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/pods-xiuxian 1/1 Running 0 30s 10.100.203.146 worker232 <none> <none>
NAME SECRETS AGE
serviceaccount/default 1 69d
serviceaccount/yinzhengjie 1 10m
[root@master231 ~]#
5.Pod使用token验证sa权限
[root@master231 ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
xiuxian-v1 1/1 Running 0 5h42m 10.100.203.145 worker232 <none> <none>
xiuxian-v2 1/1 Running 0 5h42m 10.100.140.83 worker233 <none> <none>
[root@master231 ~]#
[root@master231 ~]# kubectl -n kube-public exec -it pods-xiuxian -- sh
/ #
/ # ls -l /run/secrets/kubernetes.io/serviceaccount/
total 0
lrwxrwxrwx 1 root root 13 Feb 22 10:50 ca.crt -> ..data/ca.crt
lrwxrwxrwx 1 root root 16 Feb 22 10:50 namespace -> ..data/namespace
lrwxrwxrwx 1 root root 12 Feb 22 10:50 token -> ..data/token
/ #
/ # TOKEN=$(cat /run/secrets/kubernetes.io/serviceaccount/token)
/ #
/ # curl -k -H "Authorization: Bearer ${TOKEN}" https://kubernetes.default/api/v1/namespaces
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {},
"status": "Failure",
"message": "namespaces is forbidden: User \"system:serviceaccount:kube-public:yinzhengjie\" cannot list resource \"namespaces\" in API group \"\" at the cluster scope",
"reason": "Forbidden",
"details": {
"kind": "namespaces"
},
"code": 403
}
/ #
/ # # 上面的案例验证了没有权限访问ns,但是可以访问default名称空间下的Pod哟~说明咱们的权限是生效的!
/ # curl -k -H "Authorization: Bearer ${TOKEN}" https://kubernetes.default/api/v1/namespaces/default/pods/xiuxian-v1
{
"kind": "Pod",
"apiVersion": "v1",
"metadata": {
"name": "xiuxian-v1",
"namespace": "default",
...
2.ClusterRole和ClusterRoleBinding案例
1.创建集群角色cluster-reader【集群角色可以绑定名称空间级别的也可以绑定集群级别】
[root@master231 ~]# kubectl create clusterrole cluster-reader --verb=get,list,watch --resource=sts,sc,pv,pvc,ns,svc
clusterrole.rbac.authorization.k8s.io/cluster-reader created
[root@master231 ~]#
2.创建集群角色绑定
[root@master231 ~]# kubectl create clusterrolebinding jasonyin-as-cluster-reader --clusterrole=cluster-reader --user=jasonyin
clusterrolebinding.rbac.authorization.k8s.io/jasonyin-as-cluster-reader created
[root@master231 ~]#
3.后续步骤测试
略,参考前面的案例实验即可。
3.部署kuboard连接K8S集群
推荐阅读:
https://kuboard.cn/v4/install/quickstart.html
本文来自博客园,作者:尹正杰,转载请注明原文链接:https://www.cnblogs.com/yinzhengjie/p/18730497,个人微信: "JasonYin2020"(添加时请备注来源及意图备注,有偿付费)
当你的才华还撑不起你的野心的时候,你就应该静下心来学习。当你的能力还驾驭不了你的目标的时候,你就应该沉下心来历练。问问自己,想要怎样的人生。