首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >K8s 集群出事了,因为有人直接改了 etcd

K8s 集群出事了,因为有人直接改了 etcd

作者头像
一根头发丝的宽度
发布2026-07-15 13:25:14
发布2026-07-15 13:25:14
60
举报

答案是:理论上可以,但你的集群大概率会废掉。

刚接触 Kubernetes 的时候,大概率产生过一个念头:

既然所有资源最终都存在 etcd 里,那我直接连 etcd 改数据行不行?还省得经过 API Server,多一次网络跳转。

听起来合理。甚至有人真的在故障排查时,想直接去 etcd 里改个状态"快速恢复"。

K8s 官方文档几乎每一页都在强调——不要直接操作 etcd。这不是惯例,是设计底线。今天讲清楚为什么,一共 7 个原因,最后做一个实验让你亲眼看看后果。


你以为的架构 vs 真实的架构

很多人脑子里的 K8s 数据流是这样的:

代码语言:javascript
复制
kubectl → etcd

就两步。简单粗暴。

但真实链路是这样的:

API Server 不是"多一次跳转"。它是认证、鉴权、准入、校验、并发控制、事件分发的集合体。etcd 只是最底层那个"安全保存数据"的数据库。

API Server 是大脑,etcd 是硬盘。你不会绕过大脑直接往硬盘里写数据吧?


直接改 etcd 会绕过什么?7 个致命问题

7 个原因讲完,最后我会直接从 etcd 读一条数据给你看——返回的不是 YAML,是一段二进制乱码。

❶ 所有安全校验全部失效

正常流程下,每次资源变更都要经过认证(Authentication)和授权(Authorization)。

普通开发者只能操作 default 命名空间?RBAC 说了算。

但你直接 etcdctl put ...整个 RBAC 体系形同虚设。任何人可以改任何数据。这是官方严禁直连 etcd 的头号原因。

❷ 准入控制链被跳过

API Server 内置了多层 Admission Controller:

  • LimitRange—— 限制资源配额
  • ResourceQuota—— 命名空间配额
  • PodSecurity—— Pod 安全策略
  • MutatingWebhook—— 自动注入标签/边车
  • ValidatingWebhook—— 自定义校验逻辑

比如企业要求所有 Pod 必须带 team=backend标签,MutatingWebhook 会自动补齐。直接写 etcd?这些规则全部失效,集群里可能出现大量非法资源。

❸ 数据合法性没人管了

K8s 对资源有严格校验:replicas不能是负数,containers不能为空,ClusterIP不能重复。

这些校验全由 API Server 完成。绕过它直接写 etcd,你可以写进去一个 replicas: -100,etcd 不会有任何意见——它只是个键值存储,不关心你存什么。

❹ 乐观锁彻底失效

ResourceVersion 是 K8s 乐观锁的核心。两个人同时改同一个 Deployment 时,API Server 会检查版本号:不一致就返回 409 Conflict,让你重新拉取再改。

直接改 etcd?版本控制不存在了。并发更新悄悄覆盖,集群状态出现难以排查的错乱。你以为你改成功了,其实把别人的修改踩没了。

❺ Watch 机制的一致性被破坏

这是 7 个问题里后果最隐蔽、但最严重的一个。

K8s 的核心运转模式不是"存数据",而是持续同步

代码语言:javascript
复制
Controller → Informer → API Server Watch Cache → etcd

Deployment Controller、Scheduler、kubelet——它们都不直连 etcd,而是 Watch API Server 的 Cache。

你直接改 etcd,etcd 本身会生成 Watch 事件并推送给 API Server。但如果写入的数据格式不合法(比如 protobuf 无法解码),API Server 会拒绝应用该事件并记录错误,导致 Watch Cache 始终不更新。控制器基于过期快照做决策,然后触发错误的 Reconcile 循环。集群的最终一致性被打破,而且你完全不知道哪里出了问题。

❻ 声明式系统的闭环断裂

K8s 是声明式系统。你声明 replicas=3,Controller 不断工作直到实际运行着 3 个 Pod。

绕过 API Server 直接改 etcd,Controller 可能拿不到完整上下文(因为 Cache 没更新),触发异常恢复流程。系统状态变得不可预测——这恰恰是 K8s 设计上竭力避免的局面。

❼ 集群升级时可能直接炸掉

很多人不知道:K8s 存进 etcd 的不是 YAML,是 protobuf 二进制格式,还封装了 Storage Version 机制(用于多版本兼容)。

不同版本的 K8s 存储格式可能不同。官方升级时,API Server 会自动做版本转换。但你直接写进去的数据没有这层转换——未来某次集群升级,这些数据无法被正确解码,集群可能直接启动失败。


用一个实验直接读 etcd 会看到什么

⚠️ 以下操作仅在实验环境进行,生产环境严禁尝试。

第一步,创建一个 Deployment:

代码语言:javascript
复制
kubectl create deployment nginx --image=m.daocloud.io/docker.io/library/nginx

第二步,正常查看:

代码语言:javascript
复制
kubectl get deploy nginx -o yaml

返回的是熟悉的 YAML,replicas、image、selector 一目了然。

第三步,直接从 etcd 读:

代码语言:javascript
复制
ETCDCTL_API=3 etcdctl \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key \
  get /registry/deployments/default/nginx

返回的不是 YAML,不是 JSON,是一段二进制乱码。(如果你用 -w json会看到 base64 编码的字节,同样不可读。)

这就是 protobuf 序列化后的样子,外面还包裹了 Storage Version 的元数据。API Server 在存储层之上做了一层编解码:写入时把 Kubernetes 对象编码成紧凑的二进制格式,读回时再解码还原。

绕过 API Server,等于绕过所有编解码逻辑,直接操作原始字节流。这就是为什么升级时数据会损坏——你写进去的字节,新版本的 API Server 可能根本不认识。


那想改资源怎么办?正确姿势

  • 修改已有资源:kubectl patchkubectl replace,或直接调 API(PATCH/PUT)。
  • 调试紧急状态:使用 kubectl scalekubectl delete等命令,必要时可通过 kubectl edit修改。
  • 实在需要恢复 etcd 数据?官方支持从备份整体恢复(etcdctl snapshot restore),但那是整库回滚,不是定点修改。

请记住:永远只通过 API Server 操作集群状态。


总结

API Server 是业务中心,etcd 是它底层的状态数据库。

API Server 承担着认证、鉴权、准入、校验、乐观锁、Watch Cache、存储版本转换、审计、API 聚合——9 项核心职责。etcd 只负责一件事:安全可靠地保存集群状态。

所有资源都必须经过 API Server,这不是"多一次跳转",而是整个 K8s 安全性、一致性、可扩展性的设计基石。

下次再有人问"能不能直接改 etcd",把这篇甩给他。


互动话题:你有没有想过或者试过直接连 etcd 操作集群数据?或者在排查故障时被诱惑过?留言聊聊,我知道有人真干过。

关注 1HairLabs下一篇我们模拟 API Server 挂掉后集群各组件的真实反应——Controller 会怎样?kubelet 还能跑吗?Pod 会不会被杀?结果可能和你想的不一样。


本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-07-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 一根头发丝的宽度 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 你以为的架构 vs 真实的架构
  • 直接改 etcd 会绕过什么?7 个致命问题
    • ❶ 所有安全校验全部失效
    • ❷ 准入控制链被跳过
    • ❸ 数据合法性没人管了
    • ❹ 乐观锁彻底失效
    • ❺ Watch 机制的一致性被破坏
    • ❻ 声明式系统的闭环断裂
    • ❼ 集群升级时可能直接炸掉
  • 用一个实验直接读 etcd 会看到什么
  • 那想改资源怎么办?正确姿势
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档