2、Kubernetes核心概念回顾:Pod、Deployment、StatefulSet、Service、ConfigMap、Secret在数据库迁移中的作用
在将数据库迁移至Kubernetes之前,必须深刻理解Kubernetes的六大核心原语。数据库是有状态、高敏感、网络拓扑固定的工作负载,与无状态微服务有着本质区别。本章将逐一剖析每个资源对象在数据库迁移场景中的具体职责与配置要点。
2.1 Pod:数据库进程的最小运行单元
Pod是Kubernetes中可创建和部署的最小计算单元。在数据库迁移中,一个Pod通常对应一个数据库实例进程(如MySQL、PostgreSQL、MongoDB)。
- 容器镜像:使用官方或定制化的数据库镜像,包含数据库引擎、备份工具、健康检查脚本。
- 资源请求与限制:必须精确设置CPU和内存的
requests与limits,避免数据库因资源竞争导致OOM或性能抖动。 - 存活探针与就绪探针:使用TCP Socket或自定义SQL查询(如
SELECT 1)检测数据库健康状态。 - 卷挂载:通过
PersistentVolumeClaim将数据目录挂载到Pod内,保证数据持久化。
关键原则:数据库Pod应使用
spec.nodeName或节点亲和性固定调度到特定节点,避免迁移过程中因Pod重建导致数据丢失或连接中断。
2.2 Deployment vs StatefulSet:无状态与有状态的分水岭
Deployment适用于无状态应用,而数据库迁移必须使用StatefulSet。下表对比两者在数据库场景下的核心差异:
| 特性 | Deployment | StatefulSet |
|---|---|---|
| Pod标识 | 随机哈希名称(如app-7d8f9c6b4-abcde) |
有序且稳定的名称(如db-0、db-1) |
| 存储卷 | 所有Pod共享同一卷模板,重建后卷可能重新绑定 | 每个Pod拥有独立的PersistentVolumeClaim,重建后自动挂载原卷 |
| 启动顺序 | 并行启动,无顺序保证 | 按序启动(从0到N-1),前一个Pod就绪后才启动下一个 |
| 网络标识 | 无固定DNS名称 | 每个Pod拥有稳定的$(statefulset)-$(ordinal).$(service).namespace.svc.cluster.local DNS |
| 数据库适用性 | ❌ 不适合主从复制、分片集群 | ✅ 适合主从、分片、有状态集群 |
迁移建议:对于主从复制架构的数据库,StatefulSet的序号(ordinal)可以直接映射为复制拓扑中的角色(如0为主库,1、2为从库),配合Headless Service实现稳定的节点发现。
2.3 Service:数据库流量的稳定入口
Service为数据库Pod提供稳定的网络访问抽象。在数据库迁移中,Service的类型选择直接影响客户端连接方式:
- ClusterIP(默认):仅集群内部访问,适用于微服务间数据库调用。
- Headless Service:不分配ClusterIP,直接返回所有Pod的IP列表,配合StatefulSet实现数据库集群节点发现。
- NodePort / LoadBalancer:用于外部客户端连接数据库,需谨慎暴露端口并配置安全策略。
以下是一个为PostgreSQL StatefulSet配置的Headless Service示例:
apiVersion: v1
kind: Service
metadata:
name: postgres-hl
labels:
app: postgres
spec:
clusterIP: None # 关键:Headless Service
selector:
app: postgres
ports:
- port: 5432
name: postgres
客户端可通过postgres-0.postgres-hl.namespace.svc.cluster.local:5432直接访问主库。
2.4 ConfigMap:数据库配置的集中管理
ConfigMap用于将数据库配置文件(如my.cnf、postgresql.conf、mongod.conf)从容器镜像中解耦,实现配置的版本化与动态更新。
- 挂载方式:将ConfigMap作为卷挂载到Pod的
/etc/config/目录,数据库启动时读取。 - 热更新:ConfigMap更新后,Pod内的配置文件会自动同步(需数据库支持
reload或SIGHUP)。 - 典型配置项:最大连接数、缓冲区大小、日志级别、字符集、时区。
注意:ConfigMap存储的是明文配置,切勿将数据库密码、TLS证书等敏感信息放入ConfigMap。敏感数据应使用Secret。
2.5 Secret:数据库凭证的安全载体
Secret用于存储数据库密码、SSL证书、API密钥等敏感信息。在数据库迁移中,Secret的典型用途包括:
- 数据库用户密码:如
root、replicator、app_user的密码。 - TLS/SSL证书:用于数据库加密连接。
- 迁移工具凭证:如
pg_dump、mysqldump、mongodump使用的连接字符串。
Secret以Base64编码存储,但Kubernetes不会自动加密etcd中的Secret数据(需启用静态加密)。推荐使用外部密钥管理服务(如HashiCorp Vault)与CSI Secret Store Driver集成。
2.6 核心概念在数据库迁移中的协作关系
下图展示了六大核心原语在数据库迁移架构中的协同工作方式:
2.7 数据库迁移中的典型资源组合模式
在实际迁移项目中,上述资源通常按以下模式组合使用:
| 迁移场景 | 核心资源组合 | 说明 |
|---|---|---|
| 单实例迁移 | StatefulSet + PVC + ClusterIP Service + ConfigMap + Secret | 适用于MySQL、PostgreSQL单库迁移 |
| 主从复制迁移 | StatefulSet + Headless Service + ConfigMap + Secret + InitContainer | InitContainer负责初始化复制关系 |
| 分片集群迁移 | 多个StatefulSet + Headless Service + ConfigMap + Secret + Operator | 如MongoDB Sharded Cluster、Vitess |
| 跨集群迁移 | StatefulSet + LoadBalancer Service + Secret + Job(数据同步) | 使用Job执行逻辑复制或快照迁移 |
最佳实践:在迁移前,使用
kubectl explain命令深入理解每个资源的字段含义。例如:kubectl explain statefulset.spec.podManagementPolicy 了解OrderedReady与Parallel策略对数据库启动顺序的影响。
2.8 常见配置陷阱与避坑指南
- Pod反亲和性缺失:未设置
podAntiAffinity导致数据库主从Pod调度到同一节点,造成单点故障。 - 资源限制过紧:
limits.memory设置过低导致数据库OOMKilled,建议为数据库预留20%内存余量。 - ConfigMap热更新未触发reload:数据库进程不会自动重载配置文件,需通过Sidecar或PostStart钩子触发
pg_ctl reload或mysqladmin reload。 - Secret轮换未更新Pod:Secret更新后,已运行的Pod不会自动获取新值,需手动重启Pod或使用Reloader控制器。
安全提醒:永远不要在ConfigMap中存储数据库密码。即使是在测试环境,也应使用Secret或外部密钥管理服务。Kubernetes Secret默认仅Base64编码,并非加密,生产环境必须启用etcd加密或使用外部KMS。