别再拿 Kubernetes 硬怼数据库了:聊聊 Stateful Workloads 的正确打开方式
别再拿 Kubernetes 硬怼数据库了:聊聊 Stateful Workloads 的正确打开方式
大家好,我是 Echo_Wish。
一个在运维坑里反复横跳、被数据库 Pod 教做人无数次的人。
今天这个话题,其实挺“危险”的:
在 Kubernetes 上跑有状态服务(数据库、队列)到底靠不靠谱?
你要是在群里问一句,答案一定是两派极端:
-
A 派:
“不行!数据库就不该上 K8s!”
-
B 派:
“我们全上了,挺稳的。”
谁对?
说句不好听的:
👉 “都对,也都不对。”
问题从来不是 能不能跑,而是:
你是不是用对了姿势。
一、先泼盆冷水:Kubernetes 天生“讨厌状态”
咱先把话说透。
Kubernetes 的设计哲学是:
- Pod 随时可能死
- 节点随时可能没
- 调度是随机的
- 自愈靠重建
而数据库、队列是什么性格?
- 数据不能丢
- 身份不能乱
- 顺序不能错
- 恢复要可控
你发现没有?
👉 这俩在性格上是天然冲突的。
所以,硬把 VM 那套思维搬进 K8s,100% 出事故。
二、StatefulSet:不是“Deployment + PVC”这么简单
很多人第一次跑数据库,流程是这样的:
- 写个 Deployment
- 挂个 PVC
- 启动成功
- 心想:稳了
然后某天,节点挂了。
数据库 Pod 被调度到另一台机器,
你突然发现:
- 启动慢得要死
- IP 变了
- 主从炸了
- 客户端连不上
于是你开始骂:
“Kubernetes 不适合数据库!”
但其实,是你没用 StatefulSet。
1️⃣ StatefulSet 解决的不是“存储”,而是“身份”
StatefulSet 给你三样非常关键的东西:
- 稳定的 Pod 名字
- 固定的启动顺序
- 一一绑定的 PVC
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
serviceName: mysql
replicas: 3
selector:
matchLabels:
app: mysql
Pod 会长这样:
mysql-0
mysql-1
mysql-2
👉 这不是好看,这是“数据库的命”。
2️⃣ 我的血泪经验
当年有个 MySQL 主从集群:
- Deployment 跑的
- Pod 名字随机
- 主节点靠环境变量指定
只要滚动升级一次,
整个集群就跟抽盲盒一样。
换成 StatefulSet 后,
世界一下就安静了。
三、存储选型:别再迷信“云厂商默认盘”
Stateful Workloads,80% 的坑都在存储上。
1️⃣ 三个现实结论
我先直接给结论:
- 网络盘 != 万能
- 性能瓶颈一定会出现
- 你迟早会遇到 IO 抖动
2️⃣ 正确姿势:StorageClass 是第一等公民
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast-ssd
provisioner: kubernetes.io/csi
parameters:
type: ssd
reclaimPolicy: Retain
注意这个 Retain。
👉 数据库 PVC,千万别用 Delete。
你不想哪天误删 StatefulSet,
发现数据也跟着“自愈”了。
3️⃣ 关于本地盘(Local PV)
如果你跑的是:
- Elasticsearch
- ClickHouse
- Kafka(是的,真有人这么干)
那我会认真建议你:
考虑 Local PV + Pod 反亲和。
代价是调度复杂,
好处是:性能稳定,延迟可控。
四、数据库 ≠ 数据库:别一刀切
说点很多文章不敢说的。
1️⃣ 哪些适合上 K8s?
✅ 原生支持分布式的
- Cassandra
- Elasticsearch
- ClickHouse
- TiDB
- Pulsar BookKeeper
这些系统,本身就假设:
节点会挂
网络会抖
成员会变
和 K8s 的哲学,是对齐的。
2️⃣ 哪些要慎重?
⚠️ 强主从、强一致、单写入口
- MySQL
- PostgreSQL
- Redis(非 Cluster)
不是不能跑,而是你得:
- 上 Operator
- 上成熟方案
- 接受复杂度
五、Operator:这是“成年人的玩法”
如果你还在手写脚本搞:
- 主从切换
- 扩缩容
- 备份恢复
那我真心劝你一句:
别再折磨自己了。
1️⃣ Operator 的本质
Operator =
把数据库运维经验写进控制器
apiVersion: mysql.oracle.com/v2
kind: InnoDBCluster
metadata:
name: my-cluster
spec:
instances: 3
背后帮你做的事情包括:
- 初始化
- 健康检查
- Failover
- Rolling Upgrade
2️⃣ 我的真实感受
第一次把 MySQL 交给 Operator 后,我最大的感受是:
我终于不用 3 点起床切主了。
六、队列系统:比数据库更适合 K8s,但也别作死
Kafka、RabbitMQ、Pulsar
这些看起来很适合 K8s。
但坑也不少。
1️⃣ Kafka 的三个关键点
- StatefulSet
- 固定 Broker ID
- 外部访问别乱搞
broker.id=$(echo ${HOSTNAME##*-})
Broker ID 必须和 Pod 绑定。
2️⃣ Pulsar / RabbitMQ 的建议
- 用官方 Operator
- 别自己写启动脚本
- 集群状态交给系统管
七、我最想强调的一句话
在 Kubernetes 上跑有状态服务,本质不是“部署问题”,而是“运维模式的升级”。
如果你:
- 还想 SSH
- 还想手工修
- 还想靠经验拍脑袋
那你一定会骂 K8s。
但如果你愿意:
- 把规则写进 YAML
- 把经验交给 Operator
- 把故障当成常态
你会发现:
👉 Kubernetes 并没有你想象中那么不适合状态。
八、最后总结(很现实)
- 小规模、简单系统
👉 不上 K8s,也完全没问题 - 多环境、多集群、标准化要求高
👉 Stateful Workloads + K8s,是迟早的事
别迷信,也别恐惧。
技术不是信仰,是权衡。
- 点赞
- 收藏
- 关注作者
评论(0)