在ACK中通过ossfs 2.0挂载静态OSS存储卷

当应用需要持久化存储,或多Pod间共享数据时,可通过静态PVPVC的方式,将OSS Bucket 挂载为 ossfs 2.0 存储卷。这让应用容器可以像访问本地文件系统一样,使用标准的POSIX接口读写OSS数据,适用于大数据分析、AI训练、静态资源访问等场景。

相较于ossfs 1.0ossfs 2.0在顺序读写性能上表现优异,可以更好地利用OSS的高带宽优势。

ossfs 2.0的性能说明,请参见ossfs 2.0客户端压测性能

流程指引

ACK集群中挂载ossfs 2.0静态存储卷主要流程如下。

image

  1. 确定挂载存储卷时的鉴权方式(支持访问密钥(AccessKey)和RRSA)并准备访问凭证。

    展开查看鉴权方式对比

    • RRSA:安全级别更高,使用自动轮换的临时凭证,支持Pod级权限隔离,适用于生产、多租户等高安全要求的环境。

      选择RRSA时,需创建并授权一个专用于OSS访问的RAM角色。

    • AccessKey:配置简单,但使用静态长期密钥,存在泄露风险,推荐用于测试或开发环境。

      选择AccessKey时,需创建RAM用户,获取其AccessKey,并将其存储为Kubernetes Secret。

  2. 创建PV:在集群中“注册”已有的OSS Bucket,声明其位置(根目录或特定子目录)、存储大小、访问模式等。

  3. 创建PVC:“申请”使用已注册的OSS存储资源。PVC会与符合条件的PV自动绑定。

  4. 在应用中挂载:将PVC作为存储卷挂载到容器的指定目录中。

注意事项

  • 读写场景:ossfs 2.0 主要适用于只读和顺序追加写场景。对于需要随机写或并发写的场景,无法保证数据一致性,建议使用 ossfs 1.0。

  • 数据安全:通过ossfs挂载后,在应用Pod或宿主机上对挂载目录内文件的修改或删除均会同步至源OSS Bucket。为防止数据误删,建议为Bucket开启版本控制

  • 应用健康检查:建议为使用OSS存储卷的Pod配置健康检查(Liveness Probe),例如检查挂载目录是否可用。当挂载异常时,可自动重启Pod以恢复。

  • 分片管理:当上传大文件(>10MB)时,ossfs会自动分片。若上传中断,产生的碎片文件会残留在Bucket中,可手动删除碎片通过生命周期规则删除碎片,以节省存储成本。

方式一:通过RRSA鉴权方式挂载

基于适用于服务账户的RAM角色(RAM Roles for Service Accounts,简称RRSA),可在集群内实现PV维度的OpenAPI权限隔离,从而实现云资源访问权限的细粒度隔离,降低安全风险。详情请参见通过RRSA配置ServiceAccountRAM权限实现Pod权限隔离

前提条件

步骤一:创建RAM角色

若集群已通过 RRSA 挂载过 OSS,可跳过此步。首次配置时请按以下步骤操作。

  1. 容器服务管理控制台启用RRSA功能,操作请参见启用RRSA功能

  2. OSS存储卷RRSA鉴权新建RAM角色,即使用RRSA功能扮演的指定角色,请参见创建OIDC身份提供商的RAM角色

    demo-role-for-rrsa为例,主要参数说明如下。

    配置项

    描述

    身份提供商类型

    OIDC

    身份提供商

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

    条件

    • oidc:iss:保持默认。

    • oidc:aud:保持默认。

    • oidc:sub:需手动添加该条件。

      • 条件键:选择oidc:sub

      • 运算符:选择StringEquals

      • 条件值:默认输入system:serviceaccount:ack-csi-fuse:csi-fuse-ossfs

        其中,ack-csi-fuseossfs客户端所在的命名空间,无法自定义。csi-fuse-ossfs为服务账户名称,可修改为指定的服务账户名称。

        关于如何修改服务账户名称,如何在RRSA鉴权方式中使用指定的ARNsServiceAccount?

    角色名称

    demo-role-for-rrsa。

步骤二:为demo-role-for-rrsa角色授权

  1. 创建如下OSS访问的自定义权限策略。具体操作,请参见创建自定义权限策略

    以下只读和读写权限策略请根据使用需求选择,并替换mybucket为您实际创建的Bucket名称。

    • OSS只读权限策略

      展开查看OSS只读权限策略内容

      {
          "Statement": [
              {
                  "Action": [
                      "oss:Get*",
                      "oss:List*"
                  ],
                  "Effect": "Allow",
                  "Resource": [
                      "acs:oss:*:*:mybucket",
                      "acs:oss:*:*:mybucket/*"
                  ]
              }
          ],
          "Version": "1"
      }
    • OSS读写权限

      展开查看OSS读写权限策略内容

      {
          "Statement": [
              {
                  "Action": "oss:*",
                  "Effect": "Allow",
                  "Resource": [
                      "acs:oss:*:*:mybucket",
                      "acs:oss:*:*:mybucket/*"
                  ]
              }
          ],
          "Version": "1"
      }
  2. (可选)若您使用KMS托管的指定CMK ID加密OSS Object,还需要为该RAM用户配置KMS权限。具体操作,请参见加密操作

  3. demo-role-for-rrsa角色授权。具体操作,请参见RAM角色授权

    说明

    您也可以通过修改RAM角色信任策略的方式使用已有的授权了OSS权限的RAM角色。具体操作,请参见使用已存在的RAM角色并授权

步骤三:创建PV

创建PV,在集群中“注册”已有的OSS Bucket。

  1. 修改以下YAML,保存为ossfs2-pv.yaml。

    以下PV将名为cnfs-oss-test 的 OSS Bucket挂载为一个 20GB 的只读文件系统,供集群内的 Pod 使用。
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: pv-ossfs2  # PV名称
    spec:
      capacity:
        storage: 20Gi  # 定义存储卷容量 (此值仅用于匹配PVC)
      accessModes:  # 访问模式
        - ReadOnlyMany
      persistentVolumeReclaimPolicy: Retain
      csi:
        driver: ossplugin.csi.alibabacloud.com
        volumeHandle: pv-ossfs2  # 与PV名称(metadata.name)保持一致
        volumeAttributes:
          fuseType: ossfs2
          bucket: cnfs-oss-test # OSS Bucket名称
          path: /subpath  # 待挂载的子目录,留空则挂载根目录
          url: oss-cn-hangzhou-internal.aliyuncs.com  # OSS Bucket所在地域的Endpoint
          otherOpts: "-o close_to_open=false"
          authType: "rrsa"
          roleName: "demo-role-for-rrsa"  # 此前创建的RAM角色
    • volumeAttributes参数说明

      参数

      是否必选

      说明

      fuseType

      必选

      使用ossfs 2.0客户端时,固定为ossfs2

      bucket

      必选

      待挂载的OSS Bucket。

      path

      可选

      待挂载的OSS Bucket的子目录。不填写时默认挂载Bucket根目录。

      url

      必选

      待挂载OSS访问域名(Endpoint)。

      • 挂载节点和Bucket处于相同地域,或已打通VPC网络时,使用内网地址。

      • 挂载节点和Bucket不同地域时,使用外网地址。

      不同访问端口的常见填写格式如下:

      • 内网格式:http://oss-{{regionName}}-internal.aliyuncs.comhttps://oss-{{regionName}}-internal.aliyuncs.com

        内网访问端口格式vpc100-oss-{{regionName}}.aliyuncs.com已废弃,请及时切换。
      • 外网格式:http://oss-{{regionName}}.aliyuncs.comhttps://oss-{{regionName}}.aliyuncs.com

      otherOpts

      可选

      OSS存储卷输入定制化参数,格式为-o *** -o ***,例如-o close_to_open=false

      close-to-open:默认为关闭。开启后,每次打开文件时,系统会主动向OSS发送GetObjectMeta请求,以获取文件在OSS中的最新元数据信息,从而确保元数据的实时性。但在需要大量读取小文件的场景下,频繁的元数据查询会显著增加访问延迟。

      更多可选参数,请参见ossfs 2.0挂载选项说明

      authType

      必选

      配置为rrsa,声明使用RRSA方式鉴权。

      roleName

      必选

      配置为此前创建或修改的RAM角色名称。

      如需为不同PV配置不同权限,可创建不同的RAM角色,并在PV中配置不同的roleName

      如需在RRSA鉴权方式中使用指定的ARNsServiceAccount,请参见如何在RRSA鉴权方式中使用指定的ARNsServiceAccount?
  2. 创建PV。

    kubectl create -f ossfs2-pv.yaml
  3. 确认PV状态。

    kubectl get pv pv-ossfs2

    预期输出如下,确认PV的状态为Available

    NAME        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   VOLUMEATTRIBUTESCLASS   REASON   AGE
    pv-ossfs2   20Gi       ROX            Retain           Available                          <unset>                          15s

步骤四:创建PVC

创建PVC,为应用声明其所需的持久化存储容量。

  1. 修改以下YAML,保存为ossfs2-pvc-static.yaml。

    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: pvc-ossfs2  # PVC名称
      namespace: default
    spec:
      # 以下配置需要与PV一致
      accessModes:
        - ReadOnlyMany
      resources:
        requests:
          storage: 20Gi
      volumeName: pv-ossfs2  #待绑定的PV
  2. 创建PVC。

    kubectl create -f ossfs2-pvc-static.yaml
  3. 确认PVC状态。

    kubectl get pvc pvc-ossfs2

    预期输出如下,PVC已绑定PV。

    NAME         STATUS   VOLUME      CAPACITY   ACCESS MODES   STORAGECLASS   VOLUMEATTRIBUTESCLASS   AGE
    pvc-ossfs2   Bound    pv-ossfs2   20Gi       ROX                           <unset>                 6s

步骤五:创建应用并挂载存储卷

PVC创建后,可将其绑定的 PV 挂载到应用中。

  1. 使用以下YAML,创建ossfs2-test.yaml。

    以下YAML示例创建包含1PodStatefulSet,Pod通过名为pvc-ossfs2PVC申请存储资源,挂载路径为/data

    展开查看YAML

    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: ossfs2-test
      namespace: default
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: ossfs2-test
      template:
        metadata:
          labels:
            app: ossfs2-test
        spec:
          containers:
          - name: nginx
            image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6
            ports:
            - containerPort: 80
            volumeMounts:
            - name: pvc-ossfs2
              mountPath: /data
          volumes:
            - name: pvc-ossfs2
              persistentVolumeClaim:
                claimName: pvc-ossfs2  # 待引用的PVC
  2. 创建StatefulSet并挂载存储卷。

    kubectl create -f ossfs2-test.yaml
  3. 查看Pod部署情况。

    kubectl get pod -l app=ossfs2-test

    预期输出:

    NAME            READY   STATUS    RESTARTS   AGE
    ossfs2-test-0   1/1     Running   0          12m
  4. 验证应用是否能正常访问OSS数据。

    kubectl exec -it ossfs2-test-0 -- ls /data

    预期输出中可以看到OSS挂载路径下的数据。

方式二:通过RAM用户AccessKey鉴权方式挂载

ACK也支持通过创建包含静态AccessKeySecret,来为应用挂载OSS存储卷进行授权。此方式适用于为特定应用授予长期、固定OSS访问权限的业务场景。

  • 如果PV所引用的AccessKey被撤销或权限变更,正在使用该存储卷的应用将失去访问权限并报权限错误。恢复访问时,需先更新Secret中的凭证,然后重启应用Pod来强制重新挂载。此过程将导致业务服务短暂中断,请在维护窗口操作。

  • 为避免由于AccessKey轮转导致业务中断,建议通过RRSA鉴权方式挂载

前提条件

步骤一:创建具有OSS访问权限的RAM用户并获取AccessKey

创建RAM用户并授权

  1. 创建RAM用户,如已创建可跳过。具体操作,请参见创建RAM用户

  2. 创建如下OSS访问的自定义权限策略。具体操作,请参见创建自定义权限策略

    以下只读和读写权限策略请根据使用需求选择,并替换mybucket为您实际创建的Bucket名称。

    • OSS只读权限策略

      展开查看OSS只读权限策略内容

      {
          "Statement": [
              {
                  "Action": [
                      "oss:Get*",
                      "oss:List*"
                  ],
                  "Effect": "Allow",
                  "Resource": [
                      "acs:oss:*:*:mybucket",
                      "acs:oss:*:*:mybucket/*"
                  ]
              }
          ],
          "Version": "1"
      }
    • OSS读写权限

      展开查看OSS读写权限策略内容

      {
          "Statement": [
              {
                  "Action": "oss:*",
                  "Effect": "Allow",
                  "Resource": [
                      "acs:oss:*:*:mybucket",
                      "acs:oss:*:*:mybucket/*"
                  ]
              }
          ],
          "Version": "1"
      }
  3. (可选)若您使用KMS托管的指定CMK ID加密OSS Object,还需要为该RAM用户配置KMS权限。具体操作,请参见加密操作

  4. RAM用户添加OSS权限。具体操作,请参见RAM用户授权

  5. RAM用户创建AccessKey。具体操作,请参见获取AccessKey

使用 AccessKey 创建 Secret

使用以下命令创建用于 OSS 鉴权的 Secret。将 akIdakSecret 替换为真实凭证。

kubectl create -n default secret generic oss-secret --from-literal='akId=xxxxxx' --from-literal='akSecret=xxxxxx'

步骤二:创建PV

创建PV,在集群中“注册”已有的OSS Bucket。

  1. 修改以下YAML,保存为ossfs2-pv.yaml。

    以下PV将名为cnfs-oss-test 的 OSS Bucket挂载为一个 20GB 的只读文件系统,供集群内的 Pod 使用。
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: pv-ossfs2  # PV名称
    spec:
      capacity:
        storage: 20Gi  # 定义存储卷容量 (此值仅用于匹配PVC)
      accessModes:  # 访问模式
        - ReadOnlyMany
      persistentVolumeReclaimPolicy: Retain
      csi:
        driver: ossplugin.csi.alibabacloud.com
        volumeHandle: pv-ossfs2   # 与PV名称(metadata.name)保持一致
        # 使用此前创建的Secret
        nodePublishSecretRef:
          name: oss-secret  # 存储AK信息的Secret名称
          namespace: default  # 该Secret所在的命名空间
        volumeAttributes:
          fuseType: ossfs2
          bucket: cnfs-oss-test  # OSS Bucket名称
          path: /subpath  # 待挂载的子目录,留空则挂载根目录
          url: oss-cn-hangzhou-internal.aliyuncs.com  # OSS Bucket所在地域的Endpoint
          otherOpts: "-o close_to_open=false"
    • nodePublishSecretRef参数说明

      参数

      是否必选

      说明

      name

      必选

      存储AccessKey信息的Secret名称。

      namespace

      必选

      存储AccessKey信息的Secret所在的命名空间。

    • volumeAttributes参数说明

      参数

      是否必选

      说明

      fuseType

      必选

      使用ossfs 2.0客户端时,固定为ossfs2

      bucket

      必选

      需要挂载的OSS Bucket。

      path

      可选

      OSS Bucket挂载路径表示挂载时相对Bucket根文件的目录结构。

      url

      必选

      挂载OSSEndpoint,EndpointOSS控制台Bucket概览页为准。

      • 挂载节点和Bucket相同地域,或已打通VPC网络时,请使用内网地址。

      • 挂载节点和Bucket不同地域时,请使用外网地址。

      不同访问端口的常见填写格式如下:

      • 内网格式:http://oss-{{regionName}}-internal.aliyuncs.comhttps://oss-{{regionName}}-internal.aliyuncs.com

      • 外网格式:http://oss-{{regionName}}.aliyuncs.comhttps://oss-{{regionName}}.aliyuncs.com

      重要

      vpc100-oss-{{regionName}}.aliyuncs.com的内网访问端口格式已废弃,请及时切换。

      otherOpts

      可选

      OSS存储卷输入定制化参数,格式为-o *** -o ***,例如-o close_to_open=false

      close-to-open:默认为关闭。开启后,每次打开文件时,系统会主动向OSS发送GetObjectMeta请求,以获取文件在OSS中的最新元数据信息,从而确保元数据的实时性。但在需要大量读取小文件的场景下,频繁的元数据查询会显著增加访问延迟。

      更多可选参数,请参见ossfs 2.0挂载选项说明

  2. 创建PV。

    kubectl create -f ossfs2-pv.yaml
  3. 确认PV状态。

    kubectl get pv pv-ossfs2

    预期输出如下,确认PV的状态为Available

    NAME        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   VOLUMEATTRIBUTESCLASS   REASON   AGE
    pv-ossfs2   20Gi       ROX            Retain           Available                          <unset>                          15s

步骤三:创建PVC

创建PVC,为应用声明其所需的持久化存储容量。

  1. 修改以下YAML,保存为ossfs2-pvc-static.yaml。

    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: pvc-ossfs2  # PVC名称
      namespace: default
    spec:
      # 以下配置需要与PV一致
      accessModes:
        - ReadOnlyMany
      resources:
        requests:
          storage: 20Gi
      volumeName: pv-ossfs2  #待绑定的PV
  2. 创建PVC。

    kubectl create -f ossfs2-pvc-static.yaml
  3. 确认PVC状态。

    kubectl get pvc pvc-ossfs2

    预期输出如下,可以看到PVC已绑定PV。

    NAME         STATUS   VOLUME      CAPACITY   ACCESS MODES   STORAGECLASS   VOLUMEATTRIBUTESCLASS   AGE
    pvc-ossfs2   Bound    pv-ossfs2   20Gi       ROX                           <unset>                 6s

步骤四:创建应用并挂载存储卷

PVC创建后,可将其绑定的 PV 挂载到应用中。

  1. 使用以下YAML,创建ossfs2-test.yaml。

    以下YAML示例创建包含1PodStatefulSet,Pod通过名为pvc-ossfs2PVC申请存储资源,挂载路径为/data

    展开查看YAML

    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: ossfs2-test
      namespace: default
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: ossfs2-test
      template:
        metadata:
          labels:
            app: ossfs2-test
        spec:
          containers:
          - name: nginx
            image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6
            ports:
            - containerPort: 80
            volumeMounts:
            - name: pvc-ossfs2
              mountPath: /data
          volumes:
            - name: pvc-ossfs2
              persistentVolumeClaim:
                claimName: pvc-ossfs2  # 待引用的PVC
  2. 创建StatefulSet并挂载存储卷。

    kubectl create -f ossfs2-test.yaml
  3. 查看Pod部署情况。

    kubectl get pod -l app=ossfs2-test

    预期输出:

    NAME            READY   STATUS    RESTARTS   AGE
    ossfs2-test-0   1/1     Running   0          12m
  4. 验证应用是否能正常访问OSS数据。

    kubectl exec -it ossfs2-test-0 -- ls /data

    预期输出中可以看到OSS挂载路径下的数据。

生产环境使用建议

维度

说明

安全与权限管理

  • 优先使用RRSA鉴权:在生产环境中,推荐使用RRSA进行鉴权。RRSA通过OIDC和临时安全令牌(STS)为Pod提供访问凭证,降低凭证泄露风险,还可实现Pod级别的精细化权限隔离。

  • 遵循最小权限原则:为RAM角色或为RAM用户授予权限时,应严格遵循最小权限原则。

性能与成本优化

  • 合理配置挂载参数 (otherOpts):

    • 元数据缓存 (-o close_to_open=false):默认行为,适用于大量读取小文件的场景,可缓存文件元数据,从而降低延迟和API请求费用。

    • 实时元数据 (-o close_to_open=true):当OSS文件会被其他系统频繁更新,且Pod需要立即感知时,可开启。但会增加API调用次数和访问延迟,请谨慎使用。

    • 根据业务场景,参见ossfs 2.0挂载选项说明进行更精细的性能调优。

  • 评估工作负载:

    • ossfs 2.0适用于AI 训练、推理、大数据处理及自动驾驶等新型计算密集型负载场景,以顺序和随机读取、仅追加(Append-only)写入为主要特征,且不依赖完整 POSIX 语义的应用场景。

    • 由于不支持随机写入,ossfs 2.0 不适用于需要频繁修改文件内容的场景,如数据库、在线编辑等。

  • 管理分片生命周期:对于写密集型应用,如果上传大文件时频繁中断,会产生大量未合并分片。建议在OSS Bucket上配置生命周期规则,定期自动清理碎片,节省存储成本。

  • 使用内网Endpoint:当集群与OSS Bucket位于同一地域时,请使用内网Endpoint,以避免公网带宽费用,并获得更低的网络延迟。

运维管理

  • 配置健康检查:为应用Pod配置存活探针(Liveness Probe)。当挂载点因网络抖动、CSI组件异常等原因失效时,健康检查会失败,ACK会自动重启Pod,触发存储卷的重新挂载。

  • 监控与告警:利用容器存储监控配置告警,及时发现容量或性能瓶颈。

常见问题