全部产品
Search
文档中心

容器服务 Kubernetes 版 ACK:将 OSS 数据按需预填充到高性能存储卷

更新时间:Jan 21, 2026

在 AI 训练、数据分析等任务开始前,将存储于对象存储(OSS) 的海量冷数据按需预热到高性能存储卷(如 CPFS智算版、云盘),计算任务可直接从高性能卷中高速读取数据,任务结束后存储卷自动回收,实现计算加速与成本优化的平衡。

工作原理

功能实现

该功能基于 Kubernetes 的 Volume Populators 特性实现,由 ACK 的 storage-operator 进行管理。当创建引用自定义资源 OSSVolumePopulator (OSSVP) 的 PVC 时,storage-operator会拦截该请求并执行数据填充操作。

根据目标存储卷的类型,填充操作分为以下模式。

模式

适用存储类型

说明

bmcpfs-dataflow
原生数据流动模式

CPFS智算版

storage-operator 调用 CPFS 自身的数据流动能力进行数据填充。

此模式不占用集群计算资源,效率更高。

image

generic
通用 Pod 填充模式

其他类型存储,如云盘、CPFS通用版等

storage-operator 在 ack-volume-populator 命名空间创建临时 Pod,负责挂载新建存储卷,并将指定 OSS 数据下载至卷内。填充完成后,该Pod 被销毁。

此模式将占用集群计算资源。

image

数据填充成功后,PVC 状态会从 Pending 变为 Bound,此时业务 Pod 便可以挂载该 PVC 并访问已预热的数据。

典型应用场景

该功能主要支持以下两种典型应用场景。

维度

场景一:预热数据至CPFS 智算版共享卷

场景二:预热数据至云盘隔离卷

适用场景

AI 模型训练、推理等高吞吐、只读密集型计算,旨在解决 OSS 访问的性能瓶颈。

批处理、数据流水线等需要独立、可读写工作空间的并行任务,旨在解决并发冲突和数据隔离问题。

技术实现

使用 CPFS 智算版,通过 bmcpfs-dataflow 模式进行原生数据填充。

使用云盘等任意动态存储,通过 generic 模式的临时 Pod 进行通用数据填充。

核心特点

  • 成本优化:利用原生能力加速,不占计算资源,存储使用后即释放。

  • 数据共享:支持多对一访问,多个 GPU 任务可共享一份预热好的数据。

  • 数据隔离与灵活性:每个任务独占存储,互不干扰,适配多种动态存储类型。

  • 弹性伸缩:支持一对一访问,存储与任务生命周期绑定,成本更为精确可控。

操作流程

两种模式下,使用 VolumePopulator 功能的核心步骤相似。

image

  1. 环境准备:在storage-operator中开启Feature Gate VolumePopulator

    开启VolumePopulator后,将默认创建ack-volume-populator命名空间,用于运行数据预填充期间产生的临时PVC与Pod。
  2. 权限配置:为数据填充任务授予访问 OSS 的权限:bmcpfs-dataflow 模式需要为 OSS Bucket 打上特定标签;generic 模式需要配置 RRSA 或 AccessKey。

  3. 定义数据源 (OSSVP):创建一个 OSSVolumePopulator对象,定义从拉取数据的OSS Bucket路径和填充模式。

  4. 创建存储卷并发起预热 (PVC):创建一个PVC对象,指定StorageClass,并使用 dataSourceRef 字段指向此前创建的 OSSVP。此操作将启动数据预热流程(启动时机取决于 StorageClass 的 volumeBindingMode)。

  5. 验证与使用:PVC 状态变为 Bound 后,创建业务工作负载(Pod、Deployment 等)挂载此 PVC 进行高速数据读写。

    数据预热是存储卷创建时的一次性操作。创建后,OSS 源数据的任何修改都不会同步到该存储卷中。
  6. 资源回收:任务结束后,删除 PVC。若 StorageClass 的 reclaimPolicyDelete,关联的高性能存储资源(如 CPFS FileSet、云盘)将被自动删除并停止计费,OSS 中的源数据不受影响。

准备工作

  • 确认集群为 1.26 及以上版本,且使用 CSI 插件。本功能依赖动态创建并预填充数据的存储卷,仅支持动态存储卷。

    如需升级集群,请参见手动升级集群;如需迁移Flexvolume至CSI,请参见通过csi-compatible-controller组件迁移Flexvolume至CSI
  • 已升级storage-operator 至 v1.35.1 及以上版本,且已开启Feature Gate VolumePopulator

    若已有其他特性门控,参数格式为 xxxxxx=true,yyyyyy=false,VolumePopulator=true

场景一:预热数据至CPFS 智算版共享卷

本方案面向模型训练、推理等只读、高吞吐场景,利用CPFS 智算版的数据流动能力,将 OSS 中的模型按需预热到 CPFS 智算版存储卷,供多个 GPU 任务高速读取。

准备工作

1. 为 OSS Bucket 设置特定标签

参见对象标签操作方式为 OSS Bucket 设置特定标签,cpfs-dataflowtrue

使用过程中,请勿删除或修改此标签,以免存储卷创建失败。

2. 创建 OSSVolumePopulator (OSSVP)

在业务应用和PVC所在的命名空间创建 OSSVolumePopulator 资源,定义从 OSS 拉取的数据源。

apiVersion: storage.alibabacloud.com/v1beta1
kind: OSSVolumePopulator
metadata:
  name: qwen3-32b
  # 需要与业务应用和 PVC 处于同一命名空间
  namespace: bmcpfs-dataflow-demo 
spec:
  bucket: <your-bucket-name>
  region: cn-hangzhou
  endpoint: oss-cn-hangzhou-internal.aliyuncs.com
  path: /Qwen3-32B/
  # 专用于 CPFS 智算版存储卷,利用其数据流动能力
  mode: bmcpfs-dataflow
  
  # 以下为 bmcpfs-dataflow 模式的可选高级配置
  # 本实践推荐使用默认配置,此处仅为展示,若无特殊需求可忽略
  # bmcpfsDataflow:
    # 数据流动的最大吞吐 (MB/s),可选值为 600, 1200, 1500。默认为 600
    # throughput: 1200
    # 是否启用加密传输,默认为空(不启用)
    # sourceSecurityType: SSL
    # 数据预热模式。默认为 metadataAndData,实现数据完全预热
    # 如需仅预热元数据,可设置为 metadata
    # dataType: metadataAndData

参数说明:

参数名称

描述

是否可选

默认值

namespace

OSSVolumePopulator需要与业务应用和 PVC 处于同一命名空间。

不涉及

bucket

OSS Bucket名称。

不涉及

region

OSS 所在地域

不涉及

endpoint

OSS 服务访问 Endpoint 地址。

不涉及

path

OSS Bucket内的路径前缀,如 /data/

/

mode

运行模式。可选值:

  • generic(默认):通用的数据填充模式,适用于任何后端动态存储卷(如云盘、CPFS 通用版等)。通过在 ack-volume-populator 命名空间中创建一个临时的 Pod 来完成数据下载,此过程会消耗集群的计算资源。

  • bmcpfs-dataflow:仅支持CPFS 智算版存储卷的高性能模式。利用原生的数据流动能力进行数据填充,效率更高,且不占用集群的计算资源。

  • auto:根据目标存储类型自动选择最佳模式。但在绝大多数情况下会回退到 generic 模式。如需使用bmcpfs-dataflow模式,推荐手动指定。

auto

bmcpfsDataflow.throughput

CPFS 智算版数据流的最大吞吐量(单位:MB/s),支持 60012001500

与 CPFS 智算版数据流动默认值一致

bmcpfsDataflow.sourceSecurityType

数据传输的安全协议类型,例如 "SSL"表示启用加密传输。

不开启加密传输

bmcpfsDataflow.dataType

指定同步的数据类型:

  • metadata:仅同步文件元信息。

    仅同步元信息时,实际数据将在首次读取时从 OSS 拉取,可能影响初次访问性能。

  • metadataAndData:同时同步元信息和文件内容。

metadataAndData

3. 准备 StorageClass 和 PVC

创建引用CPFS 智算版的StorageClass,然后创建 PVC 并通过 dataSourceRef 引用此前创建的 OSSVP。

创建 StorageClass

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: bmcpfs-dataflow-demo
parameters:
  bmcpfsId: bmcpfs-29000z8xz3xxxxxxxxxxx
  vpcMountTarget: cpfs-29000z8xz3xxxxxxxxxxx-vpc-xxxxxx.cn-wulanchabu.cpfs.aliyuncs.com
  mountpointAutoSwitch: "true"
provisioner: bmcpfsplugin.csi.alibabacloud.com
# 关键:确保 PVC 删除后,CPFS 上的 FileSet 和数据能被自动清理
reclaimPolicy: Delete
# 建议设置为 Immediate,以便 PVC 创建后立即开始数据预热
volumeBindingMode: Immediate

通过此StorageClass创建的每个动态卷默认在后端CPFS智算版创建Fileset。可通过在创建 OSSVolumePopulator时创建不同的OSSVP资源,为相同StorageClass创建的不同动态卷按需预填充不同的OSS数据。

创建 PVC

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: qwen3-32b
  namespace: bmcpfs-dataflow-demo
spec:
  accessModes:
    - ReadOnlyMany
  dataSourceRef:
    apiGroup: storage.alibabacloud.com
    kind: OSSVolumePopulator
    # 引用上面创建的 OSSVP 名称
    name: qwen3-32b
  resources:
    requests:
      # 必须不低于 OSSVP 指向数据源的数据量
      storage: 80Gi
  storageClassName: bmcpfs-dataflow-demo
  volumeMode: Filesystem

StorageClass配置了volumeBindingMode: Immediate,因此PVC创建后storage-operator将立即执行OSS到CPFS智算版的数据流动任务。

4. 验证数据预热状态

查询数据流动进度:数据填充期间,PVC 的状态会保持为 Pending,填充完成后变为 Bound

对于 bmcpfs-dataflow 模式,除检查 PVC 状态外,也可通过以下命令查询实时的CPFS智算版数据流动进展。

kubectl -n bmcpfs-dataflow-demo describe ossvp qwen3-32b
  • 数据填充期间的status为:

      Bmcpfs Dataflow:
        62a4e7ec-fae1-4f11-848f-b57cxxxxxxxx:
          Data Flow Id:       df-29d3ad9e9xxxxxxx
          Data Flow Task Id:  task-2993179xxxxxxxxx
          File Set Id:        fset-2997498xxxxxxxxx
          File System Id:     bmcpfs-29000z8xz3lf5xxxxxxxx
          Progress:           59%
  • 数据填充完成后的status为:

    Message:  Populated successfully

5. 创建工作负载并使用数据

待 PVC 变为 Bound 后,创建工作负载挂载该 PVC。

本示例使用 GPU 资源。如仅需验证数据,可创建一个 CPU Pod,使用 kubectl exec 命令登录容器进行检查。

展开查看示例代码

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: demo-apply-qwen3-32b
  namespace: bmcpfs-dataflow-demo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: demo-apply-qwen3-32b
  template:
    metadata:
      labels:
        app: demo-apply-qwen3-32b
      # 使用 ACS HPN 机型,挂载 CPFS 存储卷
      # alibabacloud.com/compute-class: "gpu-hpn"
    spec:
      # 使用 ACS HPN 机型,挂载 CPFS 存储卷
      # nodeSelector: 
      #   alibabacloud.com/node-type: reserved
      # tolerations:
      # - key: "virtual-kubelet.io/provider" 
      #   operator: "Exists"
      #   effect: "NoSchedule"
      volumes:
        - name: model-storage
          persistentVolumeClaim:
            # 指定已创建的 PVC
            claimName: qwen3-32b
        - name: dshm
          emptyDir:
            medium: Memory
            sizeLimit: 15Gi
      containers:
        - command: ["sh", "-c", "python3 -m sglang.launch_server --model-path /models/Qwen3-32B --tp 2"]
          image: registry.cn-beijing.aliyuncs.com/tool-sys/ossfs-public:demo-env-python3.12.7-sglang0.5.5
          name: sglang
          ports:
            - containerPort: 8000
              name: http
          resources:
            limits:
              nvidia.com/gpu: "2"
            requests:
              nvidia.com/gpu: "2"
          volumeMounts:
            - mountPath: /models/Qwen3-32B
              name: model-storage
            - mountPath: /dev/shm
              name: dshm

资源释放指引

AI 训推任务完成后,请及时释放为其创建的 CPFS 智算版共享卷及相关工作负载。

待释放资源:

  • 使用共享卷的工作负载(本例中为 StatefulSet

  • 用于数据预热的PVC

  • 由 PVC 自动创建的后端存储资源(CPFS 智算版 FileSet)

释放流程:

  1. 删除工作负载

    删除正在使用该存储卷的 StatefulSet,以解除对 PVC 的占用。

    kubectl delete statefulset demo-apply-qwen3-32b -n bmcpfs-dataflow-demo
  2. 删除PVC

    StorageClass 配置了 reclaimPolicy: Delete,此操作将自动触发后端 CPFS FileSet 的自动删除,从而释放存储空间并停止计费。

    kubectl delete pvc qwen3-32b -n bmcpfs-dataflow-demo
  3. 验证资源释放:

    • 验证 CPFS智算版文件系统:访问NAS控制台,选择文件系统>文件系统列表,确认该 PVC 关联的 FileSet 已被删除,且文件系统的已用容量有所回落。

    • 验证 OSS 源数据:该操作不会改动 OSS 的源数据。为进行验证,可访问OSS管理控制台,确认数据集依然完整。

场景二:预热数据至云盘隔离卷

本方案适用于批处理工作流,通过 Argo Workflows 为每个任务动态创建并预热一个独立的云盘,实现数据处理的隔离与弹性。

准备工作

  • 在storage-operator中额外开启VolumePopulatorPodHandler

    开启后,系统会自动为相关组件和创建的临时 Pod 授予必要的 RBAC 权限。请在开启前评估此操作可能带来的安全风险。

    关于自动配置的 RBAC 权限

    • 为 storage-operator 授予在 ack-volume-populator 命名空间下的 Pod 操作权限

      - apiGroups: [""]
        resources: [pods]
        verbs: [get, list, watch, create, delete]
    • 为临时任务 Pod 授予集群级别的访问权限

      - apiGroups: [""]
        resources: [events]
        verbs: [create, patch, get, list]
      - apiGroups: [volumepopulators.storage.alibabacloud.com]
        resources: [ossvolumepopulators]
        verbs: [get, list, watch]
  • 已安装 Argo Workflows组件。

    展开查看具体步骤

    1. 登录容器服务管理控制台,在左侧导航栏选择集群列表

    2. 集群列表页面,单击目标集群名称,然后在左侧导航栏,单击组件管理

    3. 组件管理页面,定位Argo Workflows,按照页面提示完成组件的安装。

      安装后,您可以在集群管理页左侧导航栏,选择应用 > Helm,查看ack-workflow的状态。当显示为已部署时,表明安装成功。

  • 场景示例使用Serverless算力(ECI)运行数据预填充任务和工作流,还需安装ack-virtual-node组件。如使用非Serverless算力验证,可删除资源中相关的labels alibabacloud.com/eci: "true" 配置。

1. 为数据预热任务授权访问 OSS

generic 模式下的数据预热任务会以一个临时 Pod 的形式运行在 ack-volume-populator 命名空间中。需为该 Pod 授予访问源数据所在 OSS Bucket 的权限。

  • RRSA方式:为 Pod 动态授予临时、自动轮换的 RAM 角色,实现应用级别的精细化权限隔离,安全性较高。

  • AccessKey方式:将静态、长期的密钥存储在 Secret 中。配置简单,但安全性较低。

RRSA方式

1. 在集群中启用RRSA

  1. ACK集群列表页面,单击目标集群名称,选择集群信息

  2. 基本信息页签的安全与审计区域,单击RRSA OIDC右侧的开启,按照页面提示在业务低峰期完成RRSA的启用。

    当集群状态由更新中变为运行中,表明RRSA已成功启用。

    重要

    启用RRSA功能后,集群内新创建的ServiceAccount Token的最大有效期将限制为12小时。

2. 创建RAM角色并授权

创建一个供 Pod 扮演的 RAM 角色,以通过 RRSA 鉴权来访问 OSS 存储卷。

展开查看步骤

  1. 创建一个RAM角色。

    1. 访问RAM控制台-创建角色页面,选择信任主体类型身份提供商,然后切换编辑器,进入可视化编辑页面。

    2. 选择主体身份提供商,单击编辑,参见以下说明完成配置。

      主要配置如下,其余参数保持默认即可。详见创建OIDC身份提供商的RAM角色

      配置项

      描述

      身份提供商类型

      OIDC

      身份提供商

      选择ack-rrsa-<cluster_id>。其中,<cluster_id>为集群ID。

      条件

      手动添加oidc:sub。

      • 条件键:选择oidc:sub

      • 运算符:选择StringEquals

      • 条件值:默认输入system:serviceaccount:ack-volume-populator:plugin-account

      角色名称

      本示例为demo-role-for-rrsa。

  2. 创建权限策略。

    本示例遵循最小权限原则,创建自定义权限策略,授予访问目标OSS Bucket的权限(OSS只读权限或OSS读写权限)。

    访问RAM控制台-创建权限策略页面,切换为脚本编辑,按照页面提示配置策略脚本。

    若已有授权OSS权限的RAM角色,修改其信任策略即可复用,请参见使用已存在的RAM角色并授权

    展开查看OSS只读权限策略

    替换<myBucketName>为实际Bucket名称。
    {
        "Statement": [
            {
                "Action": [
                    "oss:Get*",
                    "oss:List*"
                ],
                "Effect": "Allow",
                "Resource": [
                    "acs:oss:*:*:<myBucketName>",
                    "acs:oss:*:*:<myBucketName>/*"
                ]
            }
        ],
        "Version": "1"
    }
  3. 将该策略授权给RAM角色。

    1. 访问RAM控制台-角色页面,在RAM角色列表的操作列,单击目标角色对应的新增授权

    2. 权限策略区域,按照页面提示搜索并选择上一步创建的权限策略,并完成授权的新增。

AccessKey方式

  1. 创建RAM用户(如有,可跳过)。

    访问RAM控制台-创建用户页面,按照页面提示完成RAM用户的创建,如登录名称、密码等。

  2. 创建权限策略。

    本示例遵循最小权限原则,创建一个自定义权限策略,授予访问目标OSS Bucket的权限(OSS只读权限或OSS读写权限)。

    访问RAM控制台-创建权限策略页面,切换为脚本编辑,按照页面提示配置策略脚本。

    展开查看OSS只读权限策略

    替换<myBucketName>为实际Bucket名称。
    {
        "Statement": [
            {
                "Action": [
                    "oss:Get*",
                    "oss:List*"
                ],
                "Effect": "Allow",
                "Resource": [
                    "acs:oss:*:*:<myBucketName>",
                    "acs:oss:*:*:<myBucketName>/*"
                ]
            }
        ],
        "Version": "1"
    }
  3. 将该策略授权给RAM用户。

    1. 访问RAM控制台-用户页面,在RAM用户列表的操作列,单击目标用户对应的添加权限

    2. 权限策略区域,按照页面提示搜索并选择上一步创建的权限策略,并完成授权的新增。

  4. 为RAM用户创建AccessKey,以便后续将其存储为Secret,供后续数据预填充使用。

    1. 访问RAM控制台-用户页面,在RAM用户列表单击目标用户,然后在AccessKey区域,单击创建 AccessKey

    2. 按照页面提示,在对话框进行AccessKey的创建,获取并妥善保管其AccessKey ID和AccessKey Secret。

  5. 在集群中创建 Secret。

    参见以下 YAML,在 ack-volume-populator 命名空间下创建一个 Secret 来存储 AccessKey。

    apiVersion: v1
    kind: Secret
    metadata:
      name: oss-secret
      # 固定为 ack-volume-populator
      namespace: ack-volume-populator
    stringData:
      # 替换为此前获取的 AccessKey ID
      accessKeyId: <your-AccessKey-ID>
      # 替换为此前获取的 AccessKey Secret
      accessKeySecret: <your-AccessKey-Secret>

2. 创建 OSSVolumePopulator (OSSVP)

在业务应用和PVC所在的命名空间创建OSSVolumePopulator 资源,定义数据源,并指定 modegeneric 及授权方式。

apiVersion: storage.alibabacloud.com/v1beta1
kind: OSSVolumePopulator
metadata:
  name: generic-demo
  # 需要与业务和 PVC 处于同一命名空间
  namespace: argo 
spec:
  bucket: my-test-bucket
  region: cn-hangzhou
  endpoint: oss-cn-hangzhou-internal.aliyuncs.com
  path: /many-files/
  # 通用模式,适用于任意后端存储卷
  mode: generic
  generic:
    # 为数据填充任务 Pod 追加 Labels,可用于指定调度到 ECI Pod
    labels:
      alibabacloud.com/eci: "true"
    # 为数据填充任务 Pod 追加 Annotation,可用于配置 ECI 规格
    annotations:
      k8s.aliyun.com/eci-use-specs: "2-4Gi"
    # secretRef 与 rrsaConfigs 配置二选一
    # secretRef: oss-secret
    rrsaConfigs:
      # RRSA 授权使用的 RAM 角色 ARN
      roleArn: "acs:ram::1234567*****:role/oss-populator"
      # 集群的 OIDC Provider ARN
      oidcProviderArn: "acs:ram::1234567*****:oidc-provider/my-oidc-provider"
    # 为数据填充任务 Pod 配置亲和性,以指定调度到特定节点
    affinity:
      nodeAffinity:
        requiredDuringSchedulingIgnoredDuringExecution:
          nodeSelectorTerms:
            - matchExpressions:
                - key: "disktype"
                  operator: NotIn
                  values:
                    - "hdd"
    # 为数据填充任务 Pod 配置容忍度
    tolerations:
      - key: "virtual-kubelet.io/provider"
        operator: Equal
        value: "alibabacloud"
        effect: NoSchedule
    # 最大吞吐量 (单位:MB/s)
    # throughput: 1000

参数说明:

参数名称

描述

是否可选

默认值

namespace

OSSVolumePopulator需要与业务应用和 PVC 处于同一命名空间。

不涉及

bucket

OSS Bucket名称。

不涉及

region

OSS 所在地域

不涉及

endpoint

OSS 服务访问 Endpoint 地址。

不涉及

path

OSS Bucket内的路径前缀,如 /data/

/

mode

运行模式。可选值:

  • generic(默认):通用的数据填充模式,适用于任何后端动态存储卷(如云盘、CPFS 通用版等)。通过在 ack-volume-populator 命名空间中创建一个临时的 Pod 来完成数据下载,此过程会消耗集群的计算资源。

  • bmcpfs-dataflow:仅支持CPFS 智算版存储卷的高性能模式。利用原生的数据流动能力进行数据填充,效率更高,且不占用集群的计算资源。

  • auto:根据目标存储类型自动选择最佳模式。但在绝大多数情况下会回退到 generic 模式。如需使用bmcpfs-dataflow模式,推荐手动指定。

auto

generic.labels

为数据填充任务 Pod 追加的 Labels,可用于指定调度到 ECI。

不涉及

generic.annotations

为数据填充任务 Pod 追加的 Annotation,可用于配置 ECI 规格。

不涉及

generic.secretRef

引用存储 AccessKey 的 Secret 名称,与 generic.rrsaConfigs 二选一。

不涉及

generic.rrsaConfigs.roleArn

RRSA 授权使用的 RAM 角色 ARN。

可访问RAM控制台-角色,单击RAM角色名称,在详情页面获取。

使用 RRSA 时必填

不涉及

generic.rrsaConfigs.oidcProviderArn

集群的 OIDC Provider ARN。

可访问ACK集群列表页面,单击目标集群名称,选择集群信息,在基本信息页签的RRSA OIDC区域获取。

使用 RRSA 时必填

不涉及

generic.affinity

为数据填充任务 Pod 配置亲和性,以指定调度到特定节点。

不涉及

generic.tolerations

为数据填充任务 Pod 配置容忍。

不涉及

generic.throughput

最大吞吐量(单位:MB/s),用于设置数据填充任务 Pod 的最大下载速度。

与 bmcpfs-dataflow 不同,generic的实际性能受节点资源(网络、CPU)和存储写入能力的制约。此配置为目标上限,主要用于防止预热任务占用过多集群资源。

不限制(实际速率受节点网络、CPU 及存储写入性能影响)

3. 准备 StorageClass

此场景需要一个用于动态创建云盘的 StorageClass。ACK提供默认StorageClass,也支持手动创建StorageClass

  • 本示例使用alicloud-disk-essd,其reclaimPolicyDeletevolumeBindingModeImmediate,适用于使用 Serverless 算力等无需关心节点可用区的场景。

  • 如需使用非 Serverless 算力运行工作流,建议使用 volumeBindingModeWaitForFirstConsumer 的StorageClass(如 alicloud-disk-topology-alltype),以确保云盘与业务 Pod 创建在同一可用区,避免因可用区不匹配导致的调度失败。

4. 创建 Argo Workflow

以下 Workflow 示例中使用 ephemeral 类型的 volumeClaimTemplate ,为每个并行任务动态创建一个已预填充好初始数据的独立云盘。

展开查看示例代码

apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
  generateName: parallel-data-process-with-ossvp-
  namespace: argo
spec:
  # 定义输入参数
  arguments:
    parameters:
      - name: number
        value: 2

  entrypoint: main
  # 定义 Workflow 中为每个并发副本创建的存储声明模版
  volumes:
    - name: scratch-volume
      # 声明为临时存储卷,Workflow 结束后自动删除
      ephemeral:
        volumeClaimTemplate:
          metadata:
            labels:
              diskType: scratch-volume
          spec:
            accessModes: [ "ReadWriteOnce" ]
            # 若使用非 Serverless 算力,可替换为 alicloud-disk-topology-alltype
            storageClassName: "alicloud-disk-essd"
            resources:
              requests:
                # 必须不低于 OSSVP 指向数据源的数据量
                storage: 20Gi
            # 引用 OSSVP 作为数据源
            dataSourceRef:
              apiGroup: storage.alibabacloud.com
              kind: OSSVolumePopulator
              name: generic-demo

  templates:
    - name: main
      dag:
        tasks:
          # 并行执行多个 echo 任务
          - name: echo-task
            template: echo-template
            arguments:
              parameters:
                - name: index
                  value: "{{item}}"
            withSequence:
              count: "{{workflow.parameters.number}}"

    - name: echo-template
      metadata:
        labels:
          # 使用 ECI 运行任务
          alibabacloud.com/eci: "true" 
      container:
        image: mirrors-ssl.aliyuncs.com/busybox:latest
        command:
          - sh
          - -c
        args:
          - |
            echo "子任务启动,编号: {{inputs.parameters.index}}"
            echo "创建一个新的日志文件..."
            touch /scratch-volume/"{{inputs.parameters.index}}-logs"
            echo "列出从 OSSVP 创建的磁盘中的内容:"
            ls /scratch-volume
            echo "子任务完成,编号: {{inputs.parameters.index}}"
        volumeMounts:
        - name: scratch-volume
          mountPath: /scratch-volume
        resources:
          limits:
            cpu: '4'
            memory: 16Gi
          requests:
            cpu: '4'
            memory: 16Gi
      inputs:
        parameters:
          - name: index

Workflow 创建完成后,查看任意任务 Pod 的日志,确认已正常读取预填充的数据。

实际生产环境中,也可通过 Argo Workflows 的 Artifact 功能将最终的计算结果持久化存储在 OSS中。
# 将 <your-workflow-pod-name> 替换为实际 Pod 名称
kubectl -n argo logs <your-workflow-pod-name>

预期输出如下:

子任务启动,编号: 1
创建一个新的日志文件...
列出从 OSSVP 创建的磁盘中的内容:
1-logs
lost+found
results-2025-04-16T07:48:00Z
...
子任务完成,编号: 1

结果分析:

  • 1-logs:任务中新写入的文件,验证存储卷可读写,且不同并行任务间的存储隔离。

  • results-2025-04-16T07:48:00Z 等文件:即从 OSS 预填充到云盘中的数据,表明数据预热功能正常。

  • lost+found:文件系统格式化后自动生成的目录,可忽略。

资源释放指引

批处理任务完成后,请及时释放由 Argo Workflow 动态创建的云盘隔离卷及相关工作流。

待释放的资源:

  • Argo Workflow 实例

  • 由 Workflow 自动创建的临时PVC

  • 由 PVC 自动创建的后端存储资源(云盘)。

释放流程:

  1. 删除 Argo Workflow:

    对于本场景,通常只需删除 Workflow 资源。工作流中使用 ephemeral 临时卷声明,删除 Workflow 会自动级联删除其创建的所有 PVC。 StorageClass 配置了 reclaimPolicy: Delete,将进一步触发后端云盘的自动删除,从而释放资源并停止计费。

    # 将 <workflow-name> 替换为 Workflow 实际名称
    kubectl -n argo delete workflow <workflow-name>
  2. 验证资源释放:

    • 验证 PVC:执行 kubectl -n argo get pvc,确认与该工作流相关的 PVC 均已被删除。

    • 验证云盘资源:访问ECS控制台-块存储-云盘,在云盘列表中确认没有因该工作流产生的云盘资源残留。

    • 验证 OSS 源数据:该操作不会改动 OSS 的源数据。为进行验证,可访问OSS管理控制台,确认数据集依然完整。

生产环境使用建议

  • 成本与资源管理:

    • 设置资源自动回收:为动态创建卷的 StorageClass 设置 reclaimPolicy: Delete,确保任务结束后,高性能存储资源被自动清理。

    • 优化数据填充成本(generic 模式):在 generic 模式下,数据填充会消耗计算资源,通过在 OSSVolumePopulator 中配置 affinity 和 tolerations,可将临时任务 Pod 调度到成本更低的Serverless算力(包括ACS、ECI)或抢占式实例上运行。

    • 规划存储容量:创建 PVC 时申请的 storage 容量需大于源数据大小,否则数据填充将因空间不足而失败。

  • 性能与稳定性:

    • 云盘可用区对齐:云盘是可用区级别的资源。在 ECS 节点上使用时,建议将 StorageClass 的 volumeBindingMode 设置为 WaitForFirstConsumer,以确保云盘始终与业务 Pod 创建在同一个可用区,避免因跨可用区调度而导致的挂载失败。

    • 权衡 CPFS 智算版预热模式:若追求 PV 快速就绪,允许首次读取文件时有一定延迟,可选择 dataType: metadata 模式;若业务对首次读取性能要求高,希望数据完全预热,则应选择 dataType: metadataAndData 模式。

    • 状态观测:通过 kubectl describe ossvp <name> 关注数据预热任务的状态和事件,以便快速监控和排查问题。

  • 安全与权限:

    • 使用 RRSA 安全授权:在 generic 模式下,为数据填充任务 Pod 授予 OSS 访问权限时,推荐使用 RRSA方式,避免 AccessKey 泄漏带来的安全风险。

计费说明

本功能涉及以下计费:

  • 高性能存储费用:根据创建的存储卷类型(如CPFS智算版云盘)及其生命周期计费。

  • OSS 存储费用:源数据在 OSS 中产生的存储费用

  • 数据传输费用:建议在 OSSVP 中配置 OSS 的内网 Endpoint,数据传输不产生流量费。使用公网 Endpoint 时将产生流量费用

  • 计算资源费用 (仅 generic 模式):generic 模式下的临时 Pod 会消耗集群计算资源(如CPU、内存和带宽)并按其规格和时长计费。

  • CPFS 智算版数据流动任务费用(仅 bmcpfs-dataflow 模式):CPFS智算版的数据流动功能当前公测中,免费使用

常见问题

预热完成后,更新了 OSS 上的源文件,存储卷里的数据会同步更新吗?

不会。数据预热是在存储卷创建时的一次性操作,卷创建成功并填充完毕后,其内容与 OSS 源数据解耦。后续对 OSS 的任何更改都不会同步到已创建的卷上。

为什么创建的 PVC 一直处于 Pending 状态?

Pending 是数据预热过程中的正常状态。若长时间未变为 Bound,请按以下步骤排查。

  1. kubectl describe pvc <pvc-name> -n <namespace>:查看 PVC 的 Events 中是否有 Populator 相关的错误信息。

  2. kubectl describe ossvp <ossvp-name> -n <namespace>:查看 OSSVP 的 Status 和 Events,确认填充任务的状态、进度或失败原因。

  3. 若使用 generic 模式,检查 ack-volume-populator 命名空间下是否有失败的 Pod,并查看其日志,常见原因包括 OSS 权限不足、网络不通、存储空间不足等。