3、Kubernetes集群安全:API Server安全加固、RBAC权限模型、ServiceAccount管理、Secret管理最佳实践、etcd加密与访问控制

Kubernetes 集群安全,说白了就是守住三个核心:谁可以访问能做什么数据是否加密。我这些年帮金融机构做容器平台落地,踩过最多的坑,恰恰就是这几个看似基础的点。今天咱们一个一个拆开聊。

核心原则:K8s 安全不是单点防御,而是从 API 入口到数据存储的纵深防线。任何一个环节漏了,整个集群就可能被攻破。

3.1 API Server 安全加固

API Server 是整个集群的「大门」。你想想看,所有 kubectl 命令、所有 Pod 对集群的访问,都得经过它。所以这块必须加固。

第一,关闭匿名访问。 默认情况下,K8s 允许匿名用户访问某些 API。这在开发环境无所谓,但在生产环境——尤其是金融场景——必须关掉。我建议你在 kube-apiserver 的启动参数里加上:

--anonymous-auth=false

第二,启用 TLS 双向认证。 客户端访问 API Server 时,不光要验证服务端证书,客户端也得提供证书。这样能防止中间人攻击。我曾经在某个银行项目里,发现他们的 kubeconfig 文件居然用的是管理员证书直接分发——嗯,这相当于把大门钥匙复印了 100 份。

第三,限制 API Server 的监听地址。 别把它暴露在公网。只监听内网 IP,或者用 NodePort 配合防火墙规则。我个人习惯是:API Server 只监听 6443 端口,并且只允许内网负载均衡器访问。

小技巧:--etcd-servers 参数指定 etcd 地址时,尽量用 localhost 或内网 IP,别用 0.0.0.0。etcd 的端口 2379 如果暴露出去,等于把数据库裸奔了。

3.2 RBAC 权限模型

RBAC(基于角色的访问控制)是 K8s 里最核心的权限模型。说白了就是:谁(User/ServiceAccount)能对什么资源(Pod/Service/Secret)做什么操作(get/list/create)

我见过很多团队,图省事直接给所有人绑定 cluster-admin 角色。这就像给每个员工发了把总经理办公室的钥匙——早晚出事。

RBAC 的核心要素:

  • Role / ClusterRole:定义一组权限规则。Role 是命名空间级别的,ClusterRole 是集群级别的。
  • RoleBinding / ClusterRoleBinding:把 Role 绑定到用户或 ServiceAccount 上。

举个例子,给某个开发人员只读权限:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: dev
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods
  namespace: dev
subjects:
- kind: User
  name: dev-user
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

避坑指南:我曾经遇到一个案例,运维人员给 CI/CD 系统绑定了 cluster-admin,结果某个流水线脚本被注入恶意代码,攻击者直接拿到了整个集群的控制权。所以,永远遵循最小权限原则——只给够用的权限,多一个都不行。

3.3 ServiceAccount 管理

ServiceAccount 是 Pod 用来访问 API Server 的身份凭证。每个 Pod 默认会挂载一个 ServiceAccount 的 token。但问题来了:默认的 ServiceAccount 往往权限过大。

最佳实践:

  • 每个应用使用独立的 ServiceAccount,不要用 default
  • 显式指定 automountServiceAccountToken: false,除非 Pod 确实需要访问 API。
  • 定期轮转 ServiceAccount 的 token。

我记得有一次审计,发现某个命名空间里 80% 的 Pod 都挂着 default ServiceAccount,而且这个 SA 居然有 get secrets 的权限。你想想看,任何一个被攻破的 Pod,都能直接读取所有 Secret——这太可怕了。

3.4 Secret 管理最佳实践

Secret 是用来存储敏感信息的,比如数据库密码、API 密钥。但很多人以为 Secret 是「安全」的——其实不是。Secret 只是做了 base64 编码,不是加密。谁都能解码。

我建议的做法:

  1. 启用 etcd 加密:这是最基础的。在 API Server 启动参数里加上 --encryption-provider-config,指定加密配置文件。这样 Secret 存到 etcd 里就是密文了。
  2. 使用外部密钥管理服务:比如 HashiCorp Vault、AWS KMS 或 Azure Key Vault。通过 CSI 驱动把密钥挂载到 Pod 里,而不是直接写在 YAML 里。
  3. 不要将 Secret 提交到 Git:这个我强调过无数次。用 Sealed Secrets 或 External Secrets Operator 来管理。

核心观点:Secret 的安全,取决于它存储在哪、怎么传输、谁可以访问。etcd 加密只是第一步,不是全部。

3.5 etcd 加密与访问控制

etcd 是 K8s 的「数据库」,所有集群状态都存里面。包括 Secret、ConfigMap、Pod 定义。如果 etcd 被攻破,整个集群就完了。

etcd 安全三要素:

安全维度 具体措施 我的建议
传输加密 启用 TLS 双向认证 必须做,etcd 的 peer 和 client 通信都要加密
存储加密 使用 --encryption-provider-config 推荐使用 aescbc 或 kms 提供者
访问控制 etcd 的 user/role 认证 限制只有 API Server 可以读写 etcd

我曾经帮一个客户做安全加固,发现他们的 etcd 居然没有设置密码,任何人都可以用 etcdctl 直接连上去读数据。嗯,这相当于把保险柜的门开着,上面还贴了张纸条「请随意取用」。

加密配置示例:

apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
  - resources:
      - secrets
    providers:
      - aescbc:
          keys:
            - name: key1
              secret: <base64-encoded-32-byte-key>
      - identity: {}

注意:加密密钥一定要妥善保管。如果密钥丢了,已经加密的 Secret 就永远解不开了。我建议把密钥存到硬件安全模块(HSM)或云 KMS 里。

知识体系总览

下面这张图,是我梳理的 K8s 集群安全核心逻辑。你可以把它当作一个检查清单:

Kubernetes 集群安全防护体系 API Server RBAC 权限模型 ServiceAccount 管理 Secret 管理 etcd 加密与访问控制 核心原则:纵深防御 + 最小权限 从入口认证 → 权限控制 → 身份管理 → 数据加密 → 存储保护 任何一个环节缺失,都可能成为攻击者的突破口

好了,这一章的内容就到这里。K8s 集群安全是个系统工程,每个点都值得深挖。下一章咱们聊聊容器运行时安全——那又是另一片天地了。


专注资料整理