在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)并准备访问凭证。

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

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

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

适用范围

步骤一:选择鉴权方式(RRSAAccessKey)并准备访问凭证

为确保集群能够安全、合规地访问OSS Bucket资源,需先配置一种鉴权机制。

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

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

重要
  • 1.26及以上版本的集群中,为避免因AccessKey轮转导致的ossfs重挂载和业务重启,建议使用RRSA鉴权方式。

  • 本示例中集群与OSS Bucket处于同一阿里云账号下。如需跨账号挂载OSS Bucket,建议使用RRSA鉴权方式。

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-csi-fuse:csi-fuse-ossfs

      角色名称

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

  2. 创建权限策略。

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

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

      若已有授权OSS权限的RAM角色,修改其信任策略即可复用,请参见使用已存在的RAM角色并授权
      OSS只读权限策略
      替换<myBucketName>为实际Bucket名称。
      {
          "Statement": [
              {
                  "Action": [
                      "oss:Get*",
                      "oss:List*"
                  ],
                  "Effect": "Allow",
                  "Resource": [
                      "acs:oss:*:*:<myBucketName>",
                      "acs:oss:*:*:<myBucketName>/*"
                  ]
              }
          ],
          "Version": "1"
      }
      OSS读写权限策略
      替换<myBucketName>为实际Bucket名称。
      {
          "Statement": [
              {
                  "Action": "oss:*",
                  "Effect": "Allow",
                  "Resource": [
                      "acs:oss:*:*:<myBucketName>",
                      "acs:oss:*:*:<myBucketName>/*"
                  ]
              }
          ],
          "Version": "1"
      }
    2. (可选)使用KMS托管的指定CMK ID加密OSS Object时,还需为该角色配置KMS权限,详见使用KMS托管的指定CMK ID加密

  3. 将该策略授权给RAM角色。

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

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

AccessKey方式

创建具有OSS访问权限的RAM用户并获取其AccessKey,使其拥有OSS Bucket的操作权限。

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

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

  2. 创建权限策略。

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

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

      OSS只读权限策略

      替换<myBucketName>为实际Bucket名称。
      {
          "Statement": [
              {
                  "Action": [
                      "oss:Get*",
                      "oss:List*"
                  ],
                  "Effect": "Allow",
                  "Resource": [
                      "acs:oss:*:*:<myBucketName>",
                      "acs:oss:*:*:<myBucketName>/*"
                  ]
              }
          ],
          "Version": "1"
      }

      OSS读写权限策略

      替换mybucket为实际Bucket名称。
      {
          "Statement": [
              {
                  "Action": "oss:*",
                  "Effect": "Allow",
                  "Resource": [
                      "acs:oss:*:*:<myBucketName>",
                      "acs:oss:*:*:<myBucketName>/*"
                  ]
              }
          ],
          "Version": "1"
      }

      使用控制台创建PV时,还需拥有oss:ListBuckets权限。

      {
        "Effect": "Allow",
        "Action": "oss:ListBuckets",
        "Resource": "*"
      }
    2. (可选)使用KMS托管的指定CMK ID加密OSS Object时,还需为该RAM用户配置KMS权限,详见使用KMS托管的指定CMK ID加密

  3. 将该策略授权给RAM用户。

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

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

  4. RAM用户创建AccessKey,以便后续将其存储为Secret,供PV使用。

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

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

步骤二:创建PV

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

RRSA方式

  1. 创建ossfs2-pv.yaml

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

    主要参数说明如下:

    参数

    是否必选

    说明

    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

    sigVersion

    可选

    请求OSS服务端的请求签名版本。

    若默认的RRSA鉴权不满足需求(如使用非默认ServiceAccount或第三方OIDC),可通过修改PV配置来指定具体的ARNServiceAccount,详见如何在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

AccessKey方式

  1. 步骤一获取的AccessKey存储为Secret,供PV使用。

    将 <yourAccessKeyID><yourAccessKeySecret> 替换为真实凭证。SecretNamespace需要和应用Namespace一致。

    kubectl create -n default secret generic oss-secret --from-literal='akId=<yourAccessKeyID>' --from-literal='akSecret=<yourAccessKeySecret>'
  2. 创建ossfs2-pv.yaml

    以下PV将名为cnfs-oss-test 的 OSS Bucket挂载为一个 20GiB 的只读文件系统。
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      # PV名称
      name: pv-ossfs2  
    spec:
      capacity:
        # 定义存储卷容量 (此值仅用于匹配PVC)
        storage: 20Gi  
      # 访问模式
      accessModes:  
        - ReadOnlyMany
      persistentVolumeReclaimPolicy: Retain
      csi:
        driver: ossplugin.csi.alibabacloud.com
        # 与PV名称(metadata.name)保持一致
        volumeHandle: pv-ossfs2   
        # 使用此前创建的Secret
        nodePublishSecretRef:
          # 存储AK信息的Secret名称
          name: oss-secret  
          # 该Secret所在的命名空间
          namespace: default  
        volumeAttributes:
          fuseType: ossfs2
          # 替换为实际Bucket名称
          bucket: cnfs-oss-test  
          # 待挂载的子目录,留空则挂载根目录
          path: /
          # OSS Bucket所在地域的Endpoint
          url: "http://oss-cn-hangzhou-internal.aliyuncs.com"  
          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

      必选

      待挂载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挂载选项说明

  3. 创建PV。

    kubectl create -f ossfs2-pv.yaml
  4. 确认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. 创建ossfs2-pvc.yaml

    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      # PVC名称
      name: pvc-oss
      namespace: default
    spec:
      # 配置访问模式。ReadOnlyMany表明ossfs将以只读模式挂载OSS Bucket
      accessModes:
        - ReadOnlyMany
      resources:
        requests:
          # 声明存储容量,不能大于存储卷总量
          storage: 20Gi
      #待绑定的PV
      volumeName: pv-ossfs2  
  2. 创建PVC。

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

    kubectl get pvc pvc-oss

    输出中,PVC已绑定(Bound)PV。

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

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

在应用中引用PVC,完成挂载。

  1. (可选)为存储卷启用监控能力。

    ossfs 2.0 存储卷的监控能力正在灰度发布中。如需启用监控能力,需在挂载存储卷前按如下流程启用。

    此监控配置仅对新挂载的存储卷生效。如需为已挂载的存储卷启用,需重启应用 Pod,并确认ack-csi-fuse命名空间下的ossfs2 Pod已重建。

    展开查看开启步骤

    1. 升级CSI版本至1.34.1,请参见升级csi-plugincsi-provisioner

    2. 创建csi-pluginConfigMap。

      cat << EOF | kubectl create -f 
      apiVersion: v1
      kind: ConfigMap
      metadata:
        name: csi-plugin
        namespace: kube-system
      data:
        fuse-ossfs2: |
          metrics-mode=enabled
      EOF

      csi-pluginConfigMap已存在,请在fuse-ossfs2下追加metrics-mode=enabled配置。

    3. 重启csi-plugin使配置生效。

      kubectl -nkube-system delete pod -lapp=csi-plugin
  2. 创建应用并挂载。

    1. 创建oss-workload.yaml。

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: oss-workload
        labels:
          app: nginx
      spec:
        replicas: 2
        selector:
          matchLabels:
            app: nginx
        template:
          metadata:
            labels:
              app: nginx
          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-oss
                  mountPath: "/data"
              # 配置健康检查
              livenessProbe:
                exec:
                  command:
                  - ls
                  - /data
                initialDelaySeconds: 30
                periodSeconds: 30
            volumes:
              - name: pvc-oss
                persistentVolumeClaim:
                  # 引用此前创建的PVC
                  claimName: pvc-oss
    2. 创建应用。

      kubectl create -f oss-workload.yaml
    3. 验证挂载结果。

      • 确认Pod处于Running状态。

        kubectl get pod -l app=nginx
      • 进入Pod,查看挂载点。

        kubectl exec -it <pod-name> -- ls /data

        输出中,可查看OSS挂载路径下的数据。

步骤五:验证共享存储和持久化存储

验证共享存储

在一个Pod中创建文件,然后在另一个Pod中查看,以验证共享存储特性。

  1. 查看Pod信息,在输出中获取Pod名称。

    kubectl get pod -l app=nginx
  2. 在一个Pod中创建tmpfile文件。 以名为 oss-workload-66fbb85b67-d**** 的Pod为例:

    • ReadWriteMany:在/data路径下创建tmpfile文件。

      kubectl exec oss-workload-66fbb85b67-d**** -- touch /data/tmpfile
    • ReadOnlyMany:通过OSS控制台cp(上传文件)等方式上传tmpfile文件至OSS Bucket对应的路径。

  3. 在另一个Pod挂载路径下查看文件。

    以名为oss-workload-66fbb85b67-l****、挂载路径为dataPod为例。

    kubectl exec oss-workload-66fbb85b67-l**** -- ls /data | grep tmpfile

    预期输出如下,Pod挂载路径下均存在此文件,表明两个Pod可共享数据。

    tmpfile
    若无预期输出,请确认CSI组件版本是否为v1.20.7及以上版本。

验证持久化存储

删除并重建Pod,在新建的Pod中查看文件是否存在,验证数据的持久化存储。

  1. 删除一个应用Pod以触发重建。

    kubectl delete pod oss-workload-66fbb85b67-d****
  2. 查看Pod,等待新Pod启动并进入Running状态。

    kubectl get pod -l app=nginx
  3. 查看/data路径下的文件。

    以名为oss-workload-66fbb85b67-z****、挂载路径为dataPod为例。

    kubectl exec oss-workload-66fbb85b67-z**** -- ls /data | grep tmpfile

    预期输出如下,tmpfile文件仍存在,表明数据可持久化存储。

    tmpfile

功能已知影响

  • 读写场景:ossfs 2.0 主要适用于只读和顺序追加写场景。对于需要随机写的场景,建议使用 ossfs 1.0。

  • 数据同步与误删风险:挂载状态下,在应用Pod或宿主机上对挂载路径下的文件删除或变更操作会直接同步到OSS Bucket源文件。为避免数据误删除,建议为OSS Bucket开启版本控制

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

  • 碎片成本:当传输文件大于10 MB时,ossfs会将文件分片上传。若上传因业务自身重启等特殊原因意外中断,请手动删除碎片通过生命周期规则删除碎片,避免碎片占用存储空间并产生费用。

  • 密钥失效风险(AccessKey鉴权方式):若PV引用的AccessKey失效或权限变更,关联应用会立即失去访问权限。

    恢复访问需更新Secret中的凭证,并重启应用Pod以强制重新挂载(将导致业务中断),请在维护窗口期执行。详见解决方案

生产环境使用建议

维度

说明

安全与权限管理

  • 优先使用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 语义的应用场景。

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

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

运维管理

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

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

相关文档