题目
设计一个高可用的分布式数据库集群部署方案
信息
- 类型:问答
- 难度:⭐⭐⭐
考点
StatefulSet与Deployment的区别,有状态应用的数据持久化,滚动更新策略,Pod管理标识
快速回答
在Kubernetes中部署分布式数据库(如Cassandra或MySQL集群)时:
- 必须使用StatefulSet而非Deployment,确保Pod名称和网络标识稳定
- 通过volumeClaimTemplates为每个Pod创建独立的PersistentVolume
- 配置Headless Service实现Pod间的直接通信
- 采用分阶段滚动更新策略(partition控制)保证服务连续性
- 设置反亲和性规则确保Pod分散在不同节点
原理说明
StatefulSet与Deployment的核心区别在于:
- Pod标识:StatefulSet的Pod名称是顺序且稳定的(如db-0, db-1),而Deployment的Pod名称是随机的
- 存储:StatefulSet通过volumeClaimTemplate为每个Pod创建独立的PVC,实现数据持久化隔离
- 网络:配合Headless Service,Pod可通过
<pod-name>.<service-name>的固定DNS解析 - 部署顺序:StatefulSet按顺序创建/删除Pod(从0到N-1),逆序终止(从N-1到0)
代码示例
Cassandra集群的StatefulSet配置:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: cassandra
spec:
serviceName: cassandra
replicas: 3
selector:
matchLabels:
app: cassandra
template:
metadata:
labels:
app: cassandra
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values: [cassandra]
topologyKey: kubernetes.io/hostname
containers:
- name: cassandra
image: cassandra:4.0
ports:
- containerPort: 7000
volumeMounts:
- name: cassandra-data
mountPath: /var/lib/cassandra
volumeClaimTemplates:
- metadata:
name: cassandra-data
spec:
accessModes: [ ReadWriteOnce ]
storageClassName: ssd
resources:
requests:
storage: 100Gi配套的Headless Service:
apiVersion: v1
kind: Service
metadata:
name: cassandra
spec:
clusterIP: None
selector:
app: cassandra
ports:
- port: 9042最佳实践
- 更新策略:使用
spec.updateStrategy.rollingUpdate.partition实现金丝雀发布。例如设置partition=2时,只有索引≥2的Pod才会更新 - 初始化顺序:在initContainer中添加节点发现逻辑,确保新Pod能加入现有集群
- 存储配置:使用SSD storageClass并设置合适的retainPolicy(Retain/Delete)
- 监控就绪:配置readinessProbe检查数据库服务状态,避免流量导入未就绪节点
常见错误
- 误用Deployment:导致Pod重启后主机名变化,集群节点无法识别
- 共享存储卷:多个Pod共享同一个PV造成数据损坏
- 全量并行更新:一次性更新所有Pod导致集群不可用
- DNS解析缺失:未创建Headless Service导致Pod间无法通过域名通信
扩展知识
- Operator模式:对于复杂状态应用(如ETCD/Redis集群),建议使用Operator管理生命周期
- 本地存储优化:通过Local PersistentVolume提升IO性能,但需处理节点故障转移
- 跨可用区部署:使用topologySpreadConstraints将Pod分散在不同故障域
- 备份策略:结合Velero实现PVC的定时快照和跨集群迁移