[snapshot]2-snapshot部署

Snapshot 部署

项目仍在早期(README 写明 under construction ),不能当生产系统用。本文只覆盖:在已有 GPU Kubernetes 集群上装 Snapshot 控制面和节点 agent,并做一次 capture / restore 通路检查。

官方 chart 说明:charts/snapshot/README.md。组件职责:snapshot0-snapshot介绍。GPU 侧依赖:snapshot4-cuda-checkpoint分析、snapshot5-cuda-checkpoint依赖。restore Pod 合同:docs/restore-pod-contract.md。


1. 会装上什么

一次 Helm release 装这些东西(默认 release 名 snapshot):

组件 形态 作用
operator Deployment 调和 SnapshotJob / PodSnapshot / PodSnapshotContent,建工单、镜像状态、清孤儿目录
agent 特权 DaemonSet(hostPID / hostIPC / hostNetwork) 在 GPU 节点上真正 dump / restore;调 CRIU 和 cuda-checkpoint-helper
snapshot-pvc RWX PVC(可改成已有 PVC) 所有 agent 挂同一块盘存 artifact。workload Pod 不挂这块盘
CRD PodSnapshot、PodSnapshotContent、SnapshotJob 用户 API
RBAC / seccomp ClusterRole 等;CRIU 用的 block-iouring profile agent 碰节点、堵 io_uring

装 一份 即可覆盖全集群。agent 看所有 namespace 里的工单和 restore 注解。

调用方只跟 kube-apiserver 打交道:capture 写 CR,restore 给 Pod 打 nvidia.com/restore-from。不要给 agent 另开 HTTP/gRPC。


2. 前置条件

项 要求
节点架构 x86_64 / amd64 。agent 镜像和上游 cuda-checkpoint 目前没有别的架构
GPU 节点 节点上有 NVIDIA GPU;chart 默认 nodeSelector: nvidia.com/gpu.present=true,并容忍 nvidia.com/gpu taint
驱动 580.xx+ (cuCheckpoint*)。多卡 --launch-job 需要 610+
运行时 containerd (默认)或 CRI-O (runtime.type=crio)
权限 集群允许特权 DaemonSet + hostPID/IPC/Network
存储 能供给 ReadWriteMany 的 StorageClass。多节点 agent 同时挂同一 PVC
工具 kubectl、helm;自己编镜像还要 Docker buildx
内核 restore 用的 ns-bind-mount 需要 Linux ≥ 5.12 (mount_setattr)

OpenShift:额外设 openshift.enabled=true,runtime.type=crio。

PVC accessMode 不能原地改 。已有 RWO 盘不能直接当 snapshot PVC。需要 RWX 新盘,必要时把旧数据拷过去,再 storage.pvc.create=false + storage.pvc.name={新PVC}。


3. 镜像

chart 默认:

text 复制代码
ghcr.io/ai-dynamo/snapshot/operator:{chart appVersion}
ghcr.io/ai-dynamo/snapshot/agent:{chart appVersion}

当前 charts/snapshot/Chart.yaml 的 appVersion 是 0.1.0。拉不到就改 tag,或本仓库自己编:

bash 复制代码
make docker-build-operator TAGS=dev
make docker-build-agent TAGS=dev

推到集群能拉的仓库后,Helm 覆盖:

bash 复制代码
--set image.operator.repository={仓库}/operator \
--set image.operator.tag=dev \
--set image.agent.repository={仓库}/agent \
--set image.agent.tag=dev

agent 镜像里已经带了:从源码编的 CRIU、cuda-checkpoint-helper、官方 cuda-checkpoint、restore 用的 /snapshot-binaries bundle。节点上还要有 真的 libcuda.so(驱动 / NVIDIA Container Toolkit 注入),stubs 不能冻 GPU。


4. 安装

仓库根目录:

bash 复制代码
export NAMESPACE=snapshot

helm upgrade --install snapshot ./charts/snapshot \
  --namespace "${NAMESPACE}" \
  --create-namespace \
  --set storage.pvc.create=true

没有默认 StorageClass 时加上:

bash 复制代码
--set storage.pvc.storageClass={RWX 的 class}

已有 RWX PVC:

bash 复制代码
helm upgrade --install snapshot ./charts/snapshot \
  --namespace "${NAMESPACE}" \
  --create-namespace \
  --set storage.pvc.create=false \
  --set storage.pvc.name=my-snapshot-pvc

CRI-O / OpenShift:

bash 复制代码
helm upgrade --install snapshot ./charts/snapshot \
  --namespace "${NAMESPACE}" --create-namespace \
  --set storage.pvc.create=true \
  --set runtime.type=crio \
  --set openshift.enabled=true

常用值(完整列表见 charts/snapshot/values.yaml):

值 含义 默认
storage.pvc.create 是否建 snapshot-pvc true
storage.pvc.name PVC 名 snapshot-pvc
storage.pvc.size 容量 1Ti
storage.pvc.basePath agent 里挂载路径 /checkpoints
runtime.type containerd / crio containerd
seccomp.deploy 部署 CRIU seccomp(字段名是 deploy,不是 enabled) true
crdUpgrade.enabled operator init 容器 server-side apply CRD true
rbac.create 建 RBAC true

helm upgrade 不会 更新 CRD。默认靠 operator 的 crd-installer init 容器补。关掉 crdUpgrade.enabled 后要自己:

bash 复制代码
kubectl apply --server-side --force-conflicts -f ./charts/snapshot/crds/

5. 验收

bash 复制代码
kubectl get pvc snapshot-pvc -n "${NAMESPACE}"
kubectl rollout status deployment/snapshot-operator -n "${NAMESPACE}"
kubectl rollout status daemonset/snapshot-agent -n "${NAMESPACE}"
kubectl get pods -n "${NAMESPACE}" -l app.kubernetes.io/name=snapshot -o wide
kubectl logs deployment/snapshot-operator -n "${NAMESPACE}" -c crd-installer

期望:

  • PVC Bound
  • operator Ready
  • 每台目标 GPU 节点上有一个 agent Running(不是只有一台)
  • crd-installer 日志里能看到三个 CRD Applied / unchanged

agent 起不来时先看:节点有没有 nvidia.com/gpu.present=true、特权/SCC、CRI socket 路径、镜像能否拉取、PVC 是否 RWX。


6. 装完之后怎么用

6.1 两条 API 路径

Capture 必须 operator + 本机 agent:

text 复制代码
调用方创建 PodSnapshot 或 SnapshotJob
  → operator 写成 cluster 级 PodSnapshotContent(钉死 nodeName)
  → 源 Pod 所在节点的 agent dump
  → artifact 写到共享 PVC

Restore 不经过 operator。 新 Pod 带注解,调度到哪台节点,那台节点的 agent 执行 restore。那台机器上也要有 agent,并且能读同一 PVC。

yaml 复制代码
metadata:
  annotations:
    nvidia.com/restore-from: snapshot-name
    # 可选:一份快照灌进多个容器
    # nvidia.com/restore-container-map: main=engine-0,main=engine-1

restore Pod 还要满足合同:提供控制卷、CRIU seccomp 配置和等待 agent 灌入状态的惰性入口。Go 侧可用 api/podcontract 的 Build。placeholder 的临时目录必须可写,供 agent bind-mount 工具包。

6.2 SnapshotJob(一次「起 Pod 再拍」)

适合:用 pod 模板把 worker 拉起来,等 Ready,再打成 PodSnapshot。镜像、GPU 请求、DRA、shm 都是调用方自己的。完成条件是 dump 成功 并且 helper 容器干净退出,不是 CRIU 一结束就算完。

6.3 snapshotctl(调试用)

不是主用户路径。chart 已经装好、agent 在跑之后:

bash 复制代码
# 需要 operator:会建 PodSnapshot
snapshotctl checkpoint \
  --manifest ./worker-pod.yaml \
  --snapshot worker-snapshot \
  --container main \
  --namespace "${NAMESPACE}"

# 不需要 operator:只给新 Pod 打注解并创建
snapshotctl restore \
  --manifest ./worker-pod.yaml \
  --namespace "${NAMESPACE}" \
  --snapshot worker-snapshot

manifest 必须是 Pod ,不是 Deployment/Job。checkpoint 必须 --container 指定唯一目标容器(当前 API 一次只拍一个容器)。

多卡:snapshotctl --cuda-checkpoint-wrap 会把容器命令包成 cuda-checkpoint --launch-job ...。打开后,源镜像和 placeholder 里 cuda-checkpoint 绝对路径必须一致。单卡可以不包。

6.4 看结果

bash 复制代码
kubectl get podsnapshots,podsnapshotcontents,snapshotjobs -A
kubectl describe podsnapshot {name} -n {ns}
kubectl logs daemonset/snapshot-agent -n "${NAMESPACE}"

PodSnapshot Ready=True 才能拿去 restore。restore 看 Pod 条件 nvidia.com/Restored:全成功 / 部分成功 / 失败。部分成功和失败都是终态,重试要新建 restore Pod。


7. 和工作负载相关的硬约束

  • 源 Pod 所在节点必须有 agent;dump 不能换到别的节点做。
  • restore 落点由 kube-scheduler 决定(GPU、亲和性、驱动兼容),不绑死原机。
  • 源/目标 GPU 张数必须一致;型号和驱动要兼容。
  • 冻 GPU 走 cuda-checkpoint-helper,不走 CRIU cuda_plugin。 helper 的 lock/checkpoint 失败则整次 capture 失败。
  • placeholder / 源镜像 glibc 要和 agent 基座对得上(当前 agent 基座是 Ubuntu 24.04 这一档)。
  • 当前 v1alpha1:一次 capture 恰好一个容器。

8. 卸载

bash 复制代码
helm uninstall snapshot -n "${NAMESPACE}"

chart 不会自动删 PVC。要清掉盘上的 artifact:

bash 复制代码
kubectl delete pvc snapshot-pvc -n "${NAMESPACE}"

CRD 也可能留下。确认没有业务对象后再删:

bash 复制代码
kubectl delete crd \
  podsnapshots.nvidia.com \
  podsnapshotcontents.nvidia.com \
  snapshotjobs.nvidia.com

9. 和 e2e 的关系

e2e/ 会在目标集群上 helm install 同一份 chart 再跑生命周期测试。集群已有同名 release 时,要么复用要么先卸。chart 的 ClusterRole 名是固定的(如 snapshot-operator),两个 namespace 各装一份会抢这些名字。

本地直连集群示例见 e2e/README.md 的 Direct Mode。


参考

  • charts/snapshot/README.md、charts/snapshot/values.yaml
  • operator/cmd/snapshotctl/README.md
  • docs/restore-pod-contract.md
  • snapshot0-snapshot介绍
  • snapshot4-cuda-checkpoint分析
  • snapshot5-cuda-checkpoint依赖
相关推荐
龙虾电话6 小时前
写 telephony 网关时,我把「拨不通」查了三天:AT 命令回 OK 不代表通话接通
人工智能
方方洛6 小时前
ai-agent教程-08-多智能体协作
人工智能·llm·agent
changshuaihua0016 小时前
LangChain · LangGraph · LangSmith 全景解析:LLM应用开发完整生态
人工智能·大模型·ai编程
ITOM运维行者6 小时前
WAN监控怎么做?从链路质量指标到路径级定位的完整方法
数据库·人工智能·机器学习
shaibdoio6 小时前
瞬维AI技术拆解:AI获客智能体的双层漏斗算法原理
大数据·人工智能·算法
用户674874273346 小时前
我踩了3个坑才搞懂智能体提效该从哪下手
人工智能
Mickey同学6 小时前
生产级 RAG:从文档切分、混合检索到引用与评估
人工智能
lucas_AI6 小时前
别让旗舰大模型当调度员:APUS 开源 Reflex Agent,4.5B 小模型管事、大模型干活
人工智能
同城验收6 小时前
本地部署一个小模型,我踩了五个坑:编译、量化、显存、上下文、开机自启
人工智能