欢迎光临
我们一直在努力

实践高可用(HA)存储与故障转移?

在AI模型部署和基础设施管理中,高可用性(HA)存储至关重要。这不仅包括存储模型二进制文件,更重要的是存储关键的元数据,如模型版本控制、A/B测试配置、推理请求日志以及分布式训练的检查点(Checkpoints)。如果存储层发生故障,整个服务可能会中断或丢失关键状态信息。

本篇文章将聚焦于如何利用Kubernetes中的持久卷(PVC)以及Patroni(一个基于PostgreSQL的HA解决方案)来构建一个具备自动故障转移能力的、高可用的状态存储层。Patroni利用底层的持久存储来同步数据,并使用分布式锁(如Etcd或ZooKeeper)来管理主节点选举。

关键技术栈

  1. Kubernetes StatefulSet: 确保每个数据库副本都有稳定、唯一的网络标识和持久存储。
  2. Persistent Volume Claims (PVC): 依赖底层存储类(如Ceph RBD, Rook, 或云服务商的EBS/GCE PD)提供持久的、高可用的块存储。
  3. Patroni: 管理PostgreSQL集群,实现基于RAFT或Paxos机制的主从同步和故障转移。

步骤一:准备存储类和环境

为了演示,我们假设您的Kubernetes集群已经配置了一个支持

1
ReadWriteOnce

(RWO) 的

1
StorageClass

。对于生产环境中的HA,Patroni的每个节点都需要独立的RWO卷。

首先,确保您的存储类是可用的:


1
2
3
4
kubectl get storageclass
# 预期输出类似:
# NAME              PROVISIONER            RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
# standard (default) kubernetes.io/gce-pd   Delete          Immediate           true                   2d

步骤二:使用PostgreSQL Operator部署Patroni集群

为了简化部署和运维,我们通常使用如Zalando或CrunchyData的PostgreSQL Operator来管理Patroni集群。这里我们以Zalando Operator为例进行部署。

首先,安装Operator(如果尚未安装):


1
2
3
4
# 假设Operator已安装,它会监听Custom Resource Definition (CRD) PDBs
kubectl apply -f https://raw.githubusercontent.com/zalando/postgres-operator/master/manifests/configmap.yaml
kubectl apply -f https://raw.githubusercontent.com/zalando/postgres-operator/master/manifests/operator-service-account-rbac.yaml
kubectl apply -f https://raw.githubusercontent.com/zalando/postgres-operator/master/manifests/postgres-operator.yaml

接下来,定义一个3副本的高可用PostgreSQL集群(名为

1
ai-metadata-db

)。Operator将自动创建StatefulSet、PVCs、Service以及Patroni配置。

1
ai-db-cluster.yaml

:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
apiVersion: "acid.zalan.do/v1"
kind: "postgresql"
metadata:
  name: "ai-metadata-db"
  labels:
    cluster: ai-metadata
spec:
  teamId: "aiinfra"
  volume:
    size: "10Gi"
    storageClass: "standard" # 使用您环境中的StorageClass名称
  numberOfInstances: 3 # 部署3个副本,实现高可用
  users:
    adminuser: # 数据库用户定义
      password: adminpassword
      options: ["superuser", "createdb"]
  databases:
    metadata_store: adminuser
  postgresql:
    version: "15"
  patroni:
    # Patroni配置,默认使用Kubernetes作为分布式锁的后端
    leader_downtime_limit: 30 # 30秒内未响应则触发故障转移
    failover_timeout: 10 # 故障转移等待时间

应用配置:


1
kubectl apply -f ai-db-cluster.yaml

步骤三:验证HA状态和模拟故障转移

集群启动后,Operator会创建三个Pod,每个Pod拥有独立的PVC(即持久存储)。通过查看标签可以识别主节点(Primary)和备用节点(Replica)。

  1. 检查集群状态和主节点:

1
2
3
4
5
6
# 查看Pod状态
kubectl get pods -l cluster-name=ai-metadata-db

# 确定当前的主节点 (Primary)
PRIMARY_POD=$(kubectl get pods -l role=master,cluster-name=ai-metadata-db -o jsonpath='{.items[0].metadata.name}')
echo "当前主节点: $PRIMARY_POD"
  1. 验证存储持久性:

检查PVC是否已成功绑定到各个Pod。即使Pod重启或被调度到其他节点,它们仍会挂载回原来的存储卷。


1
kubectl get pvc -l cluster-name=ai-metadata-db
  1. 模拟主节点故障转移:

现在,我们模拟当前主节点突然终止(例如节点宕机、OOM Kill)。这会测试Patroni的故障转移机制和StatefulSet的自愈能力。


1
2
# 强制删除主节点Pod
kubectl delete pod $PRIMARY_POD --grace-period=0 --force
  1. 观察故障转移过程:

监控Pod列表和日志。在几秒到一分钟内(取决于Patroni的配置),Patroni会检测到原主节点丢失,并在剩余的两个备用节点中通过选举选出一个新的主节点。


1
2
3
4
5
# 持续观察新的主节点出现
watch kubectl get pods -l cluster-name=ai-metadata-db

# 检查日志确认故障转移事件
kubectl logs -l cluster-name=ai-metadata-db

一旦新的主节点被选举出来,原有的服务(例如,您的AI服务后端)可以立即通过Kubernetes Service(Operator自动创建)连接到新的主节点,而不会丢失数据,因为所有节点的数据都是通过底层的持久存储卷同步的。

总结

通过结合Kubernetes的StatefulSet和持久存储(PVC),以及Patroni这样的专用HA工具,我们能够为AI基础设施提供强大且自动化的状态存储高可用性。这确保了在底层硬件故障或节点中断的情况下,关键的AI元数据和状态能够保持完整并快速恢复服务,极大地提高了系统的韧性(Resilience)。

【本站文章皆为原创,未经允许不得转载】:汤不热吧 » 实践高可用(HA)存储与故障转移?
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址