从漏洞到防护:如何为你的CronJob添加RBAC安全层?

前言

告别硬编码:手把手教你用Secrets保护CronJob的阿里云AK/SK这篇文章 中,已经通过 Secret 存储敏感信息,避免敏感信息硬编码,但在文中最后也提到,Secret 的内容通常是以 Base64 编码存储的,并不是 安全的,因为 Base64 编码后的字符串可以被反向解码,从而获取到原始的敏感信息。所以,要提高安全性,这里先启用 RBAC 控制。

最终还是会通过改造已经部署好的监控服务费用的 CronJob ,从实战角度讲解 RBAC(基于角色的访问控制)。

RBAC 基础概念

RBAC (Role-Based Access Control) 是 Kubernetes 中用于控制谁可以访问哪些资源的授权机制。它由以下核心对象组成:

  1. ServiceAccount (SA) :代表应用程序或用户的身份
  2. Role/ClusterRole :定义一组权限规则(能做什么)
  3. RoleBinding/ClusterRoleBinding :将角色绑定到主体(谁有这个权限)

RBAC 使用步骤

RBAC 的概念比较复杂,但是使用起来还是比较简单的,主要分为以下几个步骤:

  1. 在集群中创建一些角色,并为这些角色赋予相应的权限
  2. 将创建的角色绑定到某个账号上
  3. 将账号赋予 pod 使用

在 k8s 中控制角色的对象是 Role/ClusterRole,账号是 ServiceAccount,负责将角色和账号进行绑定的动作定义对象是 RoleBinding/ClusterRoleBinding。 Role 和 ClusterRole 的区别在于 Role 对象只在某个命名空间下生效,ClusterRole 对象在整个集群范围内生效。RoleBinding 和 ClusterRoleBinding 也是 一样。

案例改造

建议结合Kubernetes CronJob 详解:配置、原理与实践指南告别硬编码:手把手教你用Secrets保护CronJob的阿里云AK/SK 这两篇文章阅读,本案例是在此基础上,进行改造。

当前配置分析

当前的 CronJob 配置使用了 Secret 来存储阿里云凭证,但想通过 RBAC 加强安全性。让看看现有配置:

yaml 复制代码
env:
- name: ALIYUN_ACCESS_KEY_ID
  valueFrom:
    secretKeyRef:
      name: aliyun-credentials
      key: access_key_id
- name: ALIYUN_ACCESS_KEY_SECRET
  valueFrom:
    secretKeyRef:
      name: aliyun-credentials
      key: access_key_secret

这从名为 aliyun-credentials 的 Secret 中获取凭证,但没有限制哪些 Pod/SA 可以访问这个 Secret。

创建专用 ServiceAccount

首先,为这个 CronJob 创建专用 ServiceAccount:

lua 复制代码
kubectl create serviceaccount serverguard-sa -n kube-ops

创建访问 Secret 的 Role

接下来,定义一个 Role,该角色将允许特定的 ServiceAccount 访问某些资源。 在这里,我们要创建一个 Role,定义谁可以访问 aliyun-credentials Secret。

secret-reader-role.yaml 文件如下:

yaml 复制代码
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: kube-ops
  name: secret-reader
rules:
- apiGroups: [""]
  resources: ["secrets"]
  resourceNames: ["aliyun-credentials"]
  verbs: ["get"]
  • Role 对象一定要在 metadata 中声明名字空间
  • apiGroups: [""]:填写对象所属的 group,"" 表示核心组。
  • resources: ["secrets"]:填写具体对象,这里指定角色可以操作 secrets 资源。
  • resourceNames: ["aliyun-credentials"]:仅限于访问名为 aliyun-credentials 的 Secret。
  • verbs: ["get"]:指定角色可以执行的操作,这里是获取 Secret。

应用这个 Role:

复制代码
kubectl apply -f secret-reader-role.yaml

将 Role 绑定到 ServiceAccount

RoleBinding 用来将角色和服务账户绑定在一起,授权该服务账户执行与角色相关的操作。下面是 secret-reader-binding.yaml 的配置文件:

yaml 复制代码
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-secrets
  namespace: kube-ops
subjects:
- kind: ServiceAccount
  name: serverguard-sa
  namespace: kube-ops
roleRef:
  kind: Role
  name: secret-reader
  apiGroup: rbac.authorization.k8s.io
  • subjects:指定哪个 ServiceAccount 需要被授予访问权限。这里是 serverguard-sa 服务账户。
  • roleRef:指定绑定的角色,这里是 secret-reader 角色,允许读取 aliyun-credentials Secret。

应用绑定:

复制代码
kubectl apply -f secret-reader-binding.yaml

更新 CronJob 使用 ServiceAccount

为了让 CronJob 使用我们刚才创建的 ServiceAccount,需要在 CronJob 配置文件中指定 serviceAccountName:

yaml 复制代码
spec:
  jobTemplate:
    spec:
      template:
        spec:
          serviceAccountName: serverguard-sa  # 添加这行
          containers:
          - name: serverguard
            image: /server-guard:latest
            # ... 其他配置不变 ...
  • serviceAccountName: serverguard-sa:指定该 CronJob 使用我们创建的 serverguard-sa 服务账户。

验证

检查 ServiceAccount 是否存在

arduino 复制代码
kubectl get sa serverguard-sa -n kube-ops -o yaml

通过这个命令,可以确认 serverguard-sa ServiceAccount 是否已经成功创建,并查看它的详细配置

验证权限

csharp 复制代码
# 检查 SA 是否能获取 secret
kubectl auth can-i get secret/aliyun-credentials \
  --as=system:serviceaccount:kube-ops:serverguard-sa -n kube-ops
  • kubectl auth can-i:这个命令用于验证当前用户或指定服务账户是否有权限执行某个操作。它是用来测试 RBAC 配置是否有效的非常有用的工具。
  • get secret/aliyun-credentials:指定你要验证的操作,这里是验证 serverguard-sa 是否能够执行 get 操作,访问 aliyun-credentials Secret。
  • --as=system:serviceaccount:kube-ops:serverguard-sa:通过 --as 参数,指定以 serverguard-sa 服务账户的身份进行验证。system:serviceaccount:kube-ops:serverguard-sa 是该 ServiceAccount 的完全限定名,表示这是在 kube-ops 命名空间中的 serverguard-sa 服务账户。
  • -n kube-ops:指定命名空间 kube-ops,确保验证操作是在正确的命名空间下进行的。 这个命令的作用是验证 serverguard-sa 服务账户是否有权限访问 aliyun-credentials Secret。 它将返回 "yes" 或 "no" 作为结果。如果返回 "yes",则说明权限配置正确;如果返回 "no",则可能是 RBAC 配置有问题,可能需要检查角色或角色绑定的配置。

到这里就完成了,总结一下:

创建了一个专用的 ServiceAccount,并通过 Role 和 RoleBinding 配置了权限管理,确保只有指定的 ServiceAccount 能 访问敏感的 Secret。接着,更新 CronJob 配置以确保它使用正确的 ServiceAccount,这样该 CronJob 就可以安全地访问 Secret。

RBAC 解析

Role vs ClusterRole

特性 Role ClusterRole
作用范围 特定命名空间 整个集群
适用场景 命名空间内资源权限控制 集群级别资源或跨命名空间
绑定方式 RoleBinding ClusterRoleBinding

权限规则详解

每个 Rule 包含三个关键部分:

  1. apiGroups :资源所属的 API 组

    • 核心组: "" (如 pods, services, secrets)
    • 其他组: "apps", "batch"
  2. resources :资源类型(复数形式)

    • pods, deployments, secrets 等
  3. verbs :允许的操作

    • get, list, watch, create, update, delete

示例:

makefile 复制代码
rules:
- apiGroups: ["apps"]
  resources: ["deployments"]
  verbs: ["get", "list", "watch", "create", "update", "patch"]

主体 (Subjects) 类型

RBAC 可以授权给三种主体:

  1. ServiceAccount (最常见)

    yaml 复制代码
    subjects:
    - kind: ServiceAccount
      name: serverguard-sa
      namespace: kube-ops
  2. User (外部用户)

    yaml 复制代码
    subjects:
    - kind: User
      name: "alice@example.com"
      apiGroup: rbac.authorization.k8s.io
  3. Group (用户组)

    yaml 复制代码
    subjects:
    - kind: Group
      name: system:serviceaccounts:kube-ops
      apiGroup: rbac.authorization.k8s.io

授予 kube-ops 命名空间下的所有 ServiceAccount 权限

最后

到这里就完成了前言部分提到的需求,最后再总结一下,完整的 RBAC 增强方案应该是:

  1. 为 serverguard 创建专用 SA
  2. 创建最小权限 Role 只允许访问需要的 Secret
  3. 绑定 Role 到 SA
  4. 更新 CronJob 使用这个 SA
  5. 定期审计这些配置

这样即使攻击者获取了 Pod 执行权限,也只能访问你明确授权的资源,实现了纵深防御。

相关推荐
WeilinerL1 小时前
泛前端代码覆盖率探索之路
前端·javascript·测试
阿里云云原生1 小时前
移动端性能监控探索:iOS RUM SDK 技术架构与实践
云原生
阿里云云原生2 小时前
Nacos 3.1.0 正式发布,支持 A2A 注册中心与 MCP 注册协议增强
微服务·云原生
阿里云云原生2 小时前
Qoder 上线提示词增强功能,将开发者从“提示词”的负担中解放出来
云原生
suknna2 小时前
通过命令模拟pod创建
kubernetes
维诺菌3 小时前
k8s java应用pod内存占用过高问题排查
java·jvm·云原生·容器·性能优化·kubernetes
回忆是昨天里的海3 小时前
k8s安装-kubeadm join,将工作节点加入k8s集群
java·服务器·kubernetes
浪飘3 小时前
k8s device plugin
java·docker·kubernetes
helloworddm3 小时前
Orleans 与 Kubernetes 结合的价值分析
云原生·容器·kubernetes
KubeSphere 云原生4 小时前
云原生周刊:Helm 十年,成就 Kubernetes 的生态中枢
云原生·容器·kubernetes