别再裸奔了:Kubernetes + 数据平台访问控制的“防猥琐指南”
别再裸奔了:Kubernetes + 数据平台访问控制的“防猥琐指南”
大家好,我是Echo_Wish。
说句实话,这几年我见过太多“看起来很高级”的数据平台——
Kubernetes 上跑着 Spark、Flink、ClickHouse,搞得云原生味儿十足。
但你稍微扒一扒权限设计,基本是这样的:
👉 所有人共用一个 kubeconfig
👉 数据库 root 账号写在 YAML 里
👉 RBAC?不存在的,直接 cluster-admin 起飞
说难听点:这不是云原生,这是云上裸奔。
今天咱就聊点实在的——
Kubernetes + 数据平台,访问控制到底该怎么落地?
一、先把问题说透:你到底在保护什么?
很多人一上来就搞 RBAC、搞 IAM,其实根本没想清楚一件事:
👉 你保护的不是 Kubernetes,而是“数据 + 操作能力”
拆开来看有三层:
- 集群层(K8s API)
- 计算层(Spark / Flink / Airflow)
- 数据层(Hive / Iceberg / ClickHouse / MySQL)
绝大多数安全事故,都是因为:
👉 权限“横向打通”,而不是单点突破
比如:
- 一个开发者有 pod 创建权限
- 然后他挂载了生产数据库密钥
- 再直接 dump 数据
完事。
二、第一道防线:Kubernetes RBAC 不只是“会写 YAML”
很多人觉得 RBAC 就是写几个 RoleBinding。
但关键点在这:
👉 RBAC 的核心是“最小权限 + 边界隔离”
我们先来一个典型错误示范:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: dev-admin
subjects:
- kind: User
name: dev-user
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
这玩意儿的意思就是:
👉 “来吧兄弟,整个集群都是你的”
正确做法:命名空间级隔离
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: dev
name: dev-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]
再绑定:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: dev-reader-binding
namespace: dev
subjects:
- kind: User
name: dev-user
roleRef:
kind: Role
name: dev-reader
apiGroup: rbac.authorization.k8s.io
👉 核心思想:
- 不给跨 namespace 权限
- 不给写权限,默认只读
- 不给 secret 访问
三、第二道防线:ServiceAccount 才是真正的“幕后黑手”
很多人忽略一个点:
👉 真正操作数据的,不是人,是 Pod
而 Pod 用的是:
👉 ServiceAccount
如果你不管它,就会出现:
spec:
serviceAccountName: default
默认账号 + 默认权限 = 灾难套餐
正确姿势:为不同任务绑定独立身份
apiVersion: v1
kind: ServiceAccount
metadata:
name: spark-job-sa
namespace: data
再绑定权限:
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: data
name: spark-job-role
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["create", "get"]
👉 核心点:
- 每种任务一个 SA
- 不共享
- 不滥用 default
四、第三道防线:别把数据库密码写进 YAML(真的别)
我见过最离谱的一个配置:
env:
- name: DB_PASSWORD
value: root123
兄弟,这不叫配置,这叫自爆程序。
正确做法:使用 Secret + 外部密钥管理
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
data:
password: cm9vdDEyMw== # base64
Pod 引用:
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: password
更进一步:接入 Vault(推荐)
annotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/role: "data-platform"
👉 好处:
- 密钥动态生成
- 自动过期
- 不落地
五、第四道防线:数据平台的“最后一公里权限”
很多人以为 Kubernetes 控制住了就完事了。
其实:
👉 数据权限,才是最终裁判
比如 Hive:
GRANT SELECT ON TABLE sales_data TO USER dev_user;
REVOKE INSERT ON TABLE sales_data FROM USER dev_user;
比如 ClickHouse:
CREATE USER dev_user IDENTIFIED BY 'password';
GRANT SELECT ON db.* TO dev_user;
👉 原则:
- K8s 控“谁能跑任务”
- 数据系统控“任务能看啥”
这俩必须“双保险”。
六、一个真实事故复盘(血的教训)
某公司数据平台:
- Kubernetes RBAC 做了 ✔
- Namespace 隔离 ✔
- Secret 也用了 ✔
但他们犯了一个致命错误:
👉 所有 Spark Job 用同一个 ServiceAccount
结果:
- A 业务有权限读用户数据
- B 业务没有
但 B 的 Job 直接复用了 A 的 SA
👉 数据直接泄露
七、我的一套“接地气安全原则”
说一堆技术不如总结几条人话:
1️⃣ 权限一定要“碎片化”
不要搞“一个账号走天下”。
2️⃣ 永远不要相信 default
default namespace、default SA,都是坑。
3️⃣ 数据权限 > Kubernetes 权限
别搞反了重点。
4️⃣ 能不用长期密钥,就别用
动态密钥才是未来。
5️⃣ 安全不是功能,是“约束设计”
不是加一个组件就解决的。
八、最后说点真心话
很多人觉得安全是“成本”,不是“价值”。
但我这几年看下来:
👉 真正毁掉系统的,不是性能瓶颈,而是权限失控
你可以慢一点,但不能“全员 root”。
云原生这套东西,本质上给了你更细粒度的控制能力,
但如果你不用,那它只会让你的风险指数级放大。
如果你现在在做数据平台,我给你一句建议:
👉 先把权限模型设计好,再写第一行代码
否则你后面补安全,就像在高速公路上换轮胎。
——能换,但很容易翻车。
- 点赞
- 收藏
- 关注作者
评论(0)