首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >别再把 K8s 当“万能盒子”:CockroachDB、Vitess、Cassandra 到底怎么跑?

别再把 K8s 当“万能盒子”:CockroachDB、Vitess、Cassandra 到底怎么跑?

原创
作者头像
Echo_Wish
发布2026-09-02 08:09:56
发布2026-09-02 08:09:56
660
举报

别再把 K8s 当“万能盒子”:CockroachDB、Vitess、Cassandra 到底怎么跑?

作者:Echo_Wish

很多人第一次在 Kubernetes 上部署数据库,脑子里想的都是一句话: “数据库嘛,写个 Deployment,挂个 PVC,不就完事了?”

如果只是跑个 MySQL 测试环境,这么干问题可能不大。

但当你面对 CockroachDB、Vitess、Cassandra 这种分布式数据库时,事情就完全不一样了。

因为这时候真正的问题已经不是:

“怎么把数据库跑起来?”

而是:

“Kubernetes 到底能不能把数据库跑稳?”

这篇文章就不绕弯子,我们直接拿 CockroachDB、Vitess、Cassandra 三个典型选手,看看它们在 K8s 上到底应该怎么玩。


一、先说一个很多人容易踩的坑

Kubernetes 很擅长管理:

  • Pod
  • Service
  • Deployment
  • StatefulSet
  • ConfigMap
  • Secret
  • PVC
  • 自动重启
  • 服务发现

但 Kubernetes 并不懂数据库业务

比如:

代码语言:text
复制
Pod 挂了
   ↓
K8s
   ↓
重新创建 Pod
   ↓
数据库恢复了吗?

K8s 的答案是:

“Pod 活了,我任务完成了。”

但数据库真正关心的是:

代码语言:text
复制
节点是否加入集群?
数据副本是否完整?
Leader 是否正常?
数据是否同步?
磁盘是否损坏?
节点是否应该重新加入?
集群是否满足 quorum?

所以我一直比较认同一个观点:

K8s 负责“容器活着”,数据库负责“数据活着”。

这两个概念千万不要混在一起。


二、为什么分布式数据库特别适合 StatefulSet?

如果你用过 Deployment,会发现它特别喜欢:

代码语言:text
复制
Pod A
Pod B
Pod C

哪个 Pod 死了,随便再拉一个。

但是数据库通常不是这么玩的。

例如 Cassandra:

代码语言:text
复制
cassandra-0
cassandra-1
cassandra-2

它们不是三个完全一样的无状态 Pod。

它们都有自己的数据。

所以我们通常使用:

代码语言:yaml
复制
kind: StatefulSet

而不是:

代码语言:yaml
复制
kind: Deployment

StatefulSet 最大的价值之一,就是给数据库提供稳定身份。

比如:

代码语言:text
复制
cassandra-0
cassandra-1
cassandra-2

即使:

代码语言:text
复制
cassandra-1

重启,它回来以后依然叫:

代码语言:text
复制
cassandra-1

同时还能绑定自己的:

代码语言:text
复制
PVC

于是就形成:

代码语言:text
复制
cassandra-0
   ↓
PVC-0

cassandra-1
   ↓
PVC-1

cassandra-2
   ↓
PVC-2

这才符合数据库的基本逻辑。


三、第一位选手:CockroachDB

Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image
Image

CockroachDB 的定位非常有意思。

你可以简单理解成:

“看起来像 PostgreSQL,骨子里是分布式数据库。”

它对开发人员比较友好,因为使用 SQL:

代码语言:sql
复制
CREATE DATABASE shop;

CREATE TABLE orders (
    id UUID PRIMARY KEY,
    user_id UUID,
    amount DECIMAL
);

但是数据库内部已经不是传统单机数据库那套玩法了。

数据会被拆成多个 Range,然后通过 Raft 进行副本同步。

例如:

代码语言:text
复制
                CockroachDB
                     |
        +------------+------------+
        |            |            |
      Node1        Node2        Node3
        |            |            |
      Range A      Range A      Range A
      Range B      Range B      Range B

一个节点挂了:

代码语言:text
复制
Node1 ❌

只要副本数量和 quorum 仍然满足:

代码语言:text
复制
Node2 ✅
Node3 ✅

整个数据库依然可以继续工作。


四、CockroachDB 在 K8s 怎么部署?

最简单的实验环境可以直接使用 StatefulSet。

例如:

代码语言:yaml
复制
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: cockroachdb
spec:
  serviceName: cockroachdb
  replicas: 3
  selector:
    matchLabels:
      app: cockroachdb

  template:
    metadata:
      labels:
        app: cockroachdb

    spec:
      containers:
        - name: cockroachdb
          image: cockroachdb/cockroach:v25.2.0

          command:
            - "/cockroach/cockroach"

          args:
            - "start"
            - "--insecure"
            - "--join=cockroachdb-0.cockroachdb,cockroachdb-1.cockroachdb,cockroachdb-2.cockroachdb"
            - "--advertise-addr=$(POD_NAME)"

          env:
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name

          ports:
            - containerPort: 26257
            - containerPort: 8080

          volumeMounts:
            - name: data
              mountPath: /cockroach/cockroach-data

  volumeClaimTemplates:
    - metadata:
        name: data
      spec:
        accessModes:
          - ReadWriteOnce
        resources:
          requests:
            storage: 100Gi

然后:

代码语言:bash
复制
kubectl apply -f cockroachdb.yaml

检查:

代码语言:bash
复制
kubectl get pods

应该能看到:

代码语言:text
复制
cockroachdb-0
cockroachdb-1
cockroachdb-2

进入 Pod:

代码语言:bash
复制
kubectl exec -it cockroachdb-0 -- ./cockroach sql --insecure

然后:

代码语言:sql
复制
SHOW DATABASES;

就可以开始干活了。


五、但是,生产环境千万别直接照抄

上面的:

代码语言:text
复制
--insecure

只是为了方便演示。

生产环境你应该考虑:

代码语言:text
复制
TLS
RBAC
Secret
NetworkPolicy
备份
监控
资源限制
PodDisruptionBudget
TopologySpreadConstraints

尤其是:

代码语言:text
复制
TopologySpreadConstraints

这个东西非常重要。

你不能出现:

代码语言:text
复制
Node-A
 ├── cockroach-0
 ├── cockroach-1
 └── cockroach-2

然后 Node-A:

代码语言:text
复制
宕机

三个数据库一起没了。

真正合理的是:

代码语言:text
复制
K8s Node-A
 └── cockroach-0

K8s Node-B
 └── cockroach-1

K8s Node-C
 └── cockroach-2

分布式数据库最大的敌人,不是 Pod 挂掉,而是你把所有副本放到了同一个故障域。


六、第二位选手:Vitess

Image
Image
Image
Image
Image
Image
Image
Image

Vitess 和 CockroachDB 完全不是一路人。

如果说:

CockroachDB 是“重新设计了一套分布式数据库”。

那么:

Vitess 更像是“把 MySQL 改造成能够横向扩展的数据库平台”。

这也是 Vitess 特别有意思的地方。

假设你有一个巨大的 MySQL:

代码语言:text
复制
MySQL
  |
  +-- 10TB 数据
  +-- 100000 QPS
  +-- CPU 爆炸

怎么办?

Vitess 可以把数据库拆成:

代码语言:text
复制
                 Vitess
                    |
          +---------+---------+
          |         |         |
       shard-0   shard-1   shard-2
          |         |         |
        MySQL     MySQL     MySQL

例如:

代码语言:text
复制
user_id % 3

决定数据去哪。

代码语言:text
复制
user_id = 100
100 % 3 = 1

进入:

代码语言:text
复制
shard-1

这样就实现水平扩展。


七、Vitess 的核心不是 MySQL,而是“中间层”

Vitess 里面有几个特别重要的组件。

可以简单理解:

代码语言:text
复制
Application
     |
     v
   VTGate
     |
     +---------+
     |         |
  VTTablet  VTTablet
     |         |
   MySQL      MySQL

应用程序通常不直接访问 MySQL。

而是:

代码语言:text
复制
Application
     ↓
VTGate
     ↓
Shard
     ↓
MySQL

VTGate 会帮助你:

  • 路由 SQL
  • 找 Shard
  • 连接池管理
  • 故障切换
  • 读写路由

所以应用侧甚至可以继续使用:

代码语言:text
复制
MySQL Driver

而不用把整个业务推翻重写。

这就是 Vitess 最大的吸引力。


八、Vitess 在 K8s 中尤其适合 Operator

如果自己手写 Vitess 的 StatefulSet,你很快就会发现:

“这玩意儿怎么这么多组件?”

所以生产环境更推荐使用 Vitess Operator 或官方生态提供的 Kubernetes 管理方式。

你最终管理的不是简单的:

代码语言:text
复制
Deployment

而更像是:

代码语言:text
复制
VitessCluster

然后由 Operator 帮你处理:

代码语言:text
复制
VTGate
VTTablet
MySQL
Topology
Backup
Failover

这就是 Kubernetes Operator 真正有价值的地方:

把数据库专家的运维经验,写成 Kubernetes Controller。


九、第三位选手:Cassandra

Image
Image
Image
Image
Image
Image
Image
Image
Image
Image

Cassandra 又是另一种思路。

它特别适合:

代码语言:text
复制
海量数据
高写入
高并发
多节点
多数据中心

例如:

代码语言:text
复制
IoT
日志
用户行为
时序数据
推荐系统

Cassandra 的核心特点之一就是:

没有传统意义上的单一 Master。

你可以把它理解成:

代码语言:text
复制
Node1 ←→ Node2
 ↑        ↓
 ↓        ↑
Node3 ←→ Node4

节点之间共同维护集群状态。

所以它非常适合横向扩展。


十、Cassandra 为什么特别适合 StatefulSet?

因为 Cassandra 非常依赖节点身份和数据目录。

典型结构:

代码语言:text
复制
cassandra-0
cassandra-1
cassandra-2
cassandra-3

每个节点:

代码语言:text
复制
Pod
 ↓
PVC
 ↓
SSTable

例如:

代码语言:yaml
复制
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: cassandra
spec:
  serviceName: cassandra
  replicas: 3

  selector:
    matchLabels:
      app: cassandra

  template:
    metadata:
      labels:
        app: cassandra

    spec:
      containers:
        - name: cassandra
          image: cassandra:5.0

          ports:
            - containerPort: 9042

          env:
            - name: CASSANDRA_CLUSTER_NAME
              value: "prod-cluster"

            - name: CASSANDRA_DC
              value: "dc1"

          volumeMounts:
            - name: data
              mountPath: /var/lib/cassandra

  volumeClaimTemplates:
    - metadata:
        name: data
      spec:
        accessModes:
          - ReadWriteOnce

        resources:
          requests:
            storage: 200Gi

部署:

代码语言:bash
复制
kubectl apply -f cassandra.yaml

查看:

代码语言:bash
复制
kubectl get pods -l app=cassandra

进入节点:

代码语言:bash
复制
kubectl exec -it cassandra-0 -- cqlsh

查看集群:

代码语言:bash
复制
nodetool status

你会看到类似:

代码语言:text
复制
Datacenter: dc1

Status=Up/Down
State=Normal/Leaving/Joining

UN  cassandra-0
UN  cassandra-1
UN  cassandra-2

十一、三个数据库到底有什么区别?

如果把它们放在一张桌子上:

数据库

核心定位

适合场景

CockroachDB

分布式 SQL

金融、交易、SaaS

Vitess

MySQL 扩展平台

大型互联网业务

Cassandra

分布式 NoSQL

海量写入、IoT、日志

更直白一点:

想要 SQL + 分布式?

考虑:

代码语言:text
复制
CockroachDB

已经有大量 MySQL?

考虑:

代码语言:text
复制
Vitess

数据量巨大、写入量恐怖?

考虑:

代码语言:text
复制
Cassandra

十二、真正生产环境,别只盯着 Pod

这是我觉得最容易被忽略的地方。

很多人的数据库监控是:

代码语言:text
复制
kubectl get pods

看到:

代码语言:text
复制
3/3 Running

然后:

“稳了。”

实际上可能:

代码语言:text
复制
Pod:Running
数据库:异常

例如:

代码语言:text
复制
PVC 磁盘快满
代码语言:text
复制
数据库副本不同步
代码语言:text
复制
Leader 频繁切换
代码语言:text
复制
GC 爆炸
代码语言:text
复制
网络延迟升高

K8s 全都可能告诉你:

代码语言:text
复制
Running

所以真正生产环境至少要建立:

代码语言:text
复制
Kubernetes
      ↓
Prometheus
      ↓
Grafana
      ↓
Database Metrics

例如监控:

代码语言:text
复制
CPU
Memory
Disk
Disk IO
Network
QPS
Latency
Replication
Compaction
Errors
Connections

数据库监控不能只看:

代码语言:text
复制
Pod Running

十三、还有一个非常容易被忽略的问题:备份

很多人觉得:

“我用了 3 副本,所以不用备份。”

这是一个非常危险的想法。

假设:

代码语言:text
复制
Node1
Node2
Node3

数据都有三份。

然后某个管理员:

代码语言:bash
复制
kubectl delete pvc --all

你会发现:

代码语言:text
复制
三份数据
↓
一起没了

副本解决的是:

节点故障。

备份解决的是:

人为误删、逻辑错误、灾难恢复。

两者完全不是一个东西。


十四、我更建议这样设计

生产环境可以考虑:

代码语言:text
复制
                    Internet
                       |
                    Ingress
                       |
                    Service
                       |
              +--------+--------+
              |                 |
           App Pod           App Pod
              |                 |
              +--------+--------+
                       |
                    Database
                       |
        +--------------+--------------+
        |              |              |
      Node-A         Node-B         Node-C
        |              |              |
      DB-0           DB-1           DB-2
        |              |              |
      PVC-A          PVC-B          PVC-C

再往上:

代码语言:text
复制
Prometheus
    ↓
Grafana

旁边再放:

代码语言:text
复制
Backup
  ↓
Object Storage

例如:

代码语言:text
复制
S3 / MinIO / OSS

最终形成:

代码语言:text
复制
业务
 ↓
K8s
 ↓
分布式数据库
 ↓
PVC
 ↓
Backup
 ↓
对象存储

这才是比较完整的生产体系。


十五、最后聊聊:K8s 到底适不适合跑数据库?

我的观点非常明确:

适合,但绝不是“部署一个 StatefulSet 就完事”。

Kubernetes 最大的价值并不是:

代码语言:text
复制
kubectl apply

而是把:

代码语言:text
复制
部署
扩容
故障恢复
服务发现
配置管理
监控
滚动升级
资源隔离

这些东西统一起来。

但是数据库本身的:

代码语言:text
复制
数据一致性
副本
Leader
Quorum
分片
故障转移
备份
恢复

仍然需要数据库自己解决。

所以真正成熟的架构应该是:

代码语言:text
复制
Kubernetes
     +
Operator
     +
StatefulSet
     +
Persistent Volume
     +
Monitoring
     +
Backup
     +
Database Native HA

而不是:

代码语言:text
复制
Kubernetes
     +
PVC
     =
数据库高可用

这两个结论,看起来只差几个组件,实际上差的是整个运维思维。


写在最后

CockroachDB、Vitess、Cassandra,其实代表了三种完全不同的数据库发展路线:

代码语言:text
复制
CockroachDB
     ↓
重新设计分布式 SQL

Vitess
     ↓
让 MySQL 走向水平扩展

Cassandra
     ↓
为海量数据和高吞吐而生

而 Kubernetes 更像是一个“基础设施操作系统”。

它可以帮你管理这些数据库,但它不会替你理解数据库。

所以如果你准备把分布式数据库放进 K8s,我建议先问自己三个问题:

第一,我为什么需要分布式数据库?

第二,我到底需要分片,还是需要副本?

第三,如果整个 Kubernetes 集群明天没了,我的数据怎么回来?

尤其是第三个问题。

很多所谓的“高可用架构”,平时看起来一个比一个漂亮,真正遇到故障的时候才发现:

Pod 是自动拉起来了,但数据呢?

这才是 K8s 上跑数据库真正值得思考的地方。

我是 Echo_Wish,一个喜欢把复杂技术掰开揉碎聊给你听的运维人。

如果只记住今天的一句话,我希望是:

K8s 能帮你把数据库“跑起来”,但只有数据库架构、存储、备份和故障恢复体系,才能让它真正“跑得住”。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

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

目录
  • 别再把 K8s 当“万能盒子”:CockroachDB、Vitess、Cassandra 到底怎么跑?
  • 一、先说一个很多人容易踩的坑
  • 二、为什么分布式数据库特别适合 StatefulSet?
  • 三、第一位选手:CockroachDB
  • 四、CockroachDB 在 K8s 怎么部署?
  • 五、但是,生产环境千万别直接照抄
  • 六、第二位选手:Vitess
  • 七、Vitess 的核心不是 MySQL,而是“中间层”
  • 八、Vitess 在 K8s 中尤其适合 Operator
  • 九、第三位选手:Cassandra
  • 十、Cassandra 为什么特别适合 StatefulSet?
  • 十一、三个数据库到底有什么区别?
    • 想要 SQL + 分布式?
    • 已经有大量 MySQL?
    • 数据量巨大、写入量恐怖?
  • 十二、真正生产环境,别只盯着 Pod
  • 十三、还有一个非常容易被忽略的问题:备份
  • 十四、我更建议这样设计
  • 十五、最后聊聊:K8s 到底适不适合跑数据库?
  • 写在最后
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档