本文介绍使用ossfs 2.0存储卷的常见问题和解决方法。
问题导航
类型 | 问题 |
挂载 | |
扩容 | |
使用 |
挂载
OSS存储卷挂载失败
问题现象
通过ossfs 2.0挂载OSS存储卷失败,Pod无法启动,Event提示FailedMount。
问题原因
原因1:AccessKey权限不足导致挂载失败。
原因2:Event的内容中包含
failed to get secret secrets "xxx" is forbidden: User "serverless-xxx" cannot get resource "secrets" in API group "" in the namespace "xxx"
。对于创建在虚拟节点(ACS Pod)上的应用,当PVC需要通过nodePublishSecretRef字段来指定鉴权信息时,Secret必须与PVC位于同一个命名空间。原因3:Event的内容中包含
FailedMount /run/fuse.ossfs/xxxxxx/mounter.sock: connect: no such file or directory
,原因为ossfs 2.0所在Pod未正常拉起或被意外删除。原因4:OSS Bucket配置了镜像回源,挂载目录未从源站同步。
原因5:OSS Bucket配置了静态网站托管,ossfs 2.0检查OSS端挂载目录时,请求转发到index.html等文件中。
解决方案
原因1解决方案
确认挂载使用的RAM用户的策略权限满足要求。具体请参见使用ossfs 2.0静态存储卷。
确认挂载时使用的AccessKey是否被禁用或已轮转。
重要仅修改在PV中通过
nodePublishSecretRef
字段指定的Secret中的AccessKey信息无法直接生效,需要重启ossfs 2.0客户端Pod。ossfs 2.0客户端重启方式,请参见如何重启ossfs 2.0进程。
原因2解决方案:
请在PVC所在的命名空间下创建所需的Secret,新建PV时,将
nodePublishSecretRef
指向该Secret。具体操作,请参见方式二:通过RAM用户AccessKey鉴权方式挂载。原因3解决方案
确认ossfs 2.0所在Pod存在。
其中
PV_NAME
为挂载的OSS PV名称,NODE_NAME
为需挂载存储卷的业务Pod所在的节点名称。kubectl -n ack-csi-fuse get pod -l csi.alibabacloud.com/volume-id=<PV_NAME> -owide | grep <NODE_NAME>
若Pod存在且状态异常,请排查Pod的异常原因,确保Pod正常Running后重启业务Pod触发重新挂载。
若Pod不存在,请按后续步骤继续排查。
(可选)通过查询审计日志等方式确认Pod是否被意外删除。
常见的意外删除原因包括业务脚本清理、节点排水、节点自愈等。建议您做相关调整,避免问题重现。
确认是否残留VolumeAttachment资源。
kubectl get volumeattachment | grep <PV_NAME> | grep <NODE_NAME>
重启业务Pod触发重新挂载,并确认ossfs 2.0 Pod有正常创建流程。
原因4解决方案
您需要同步源站数据后,再进行挂载。更多信息,请参见回源配置概述。
原因5解决方案
您需要关闭或调整静态网站托管的配置,再进行挂载。更多信息,请参见静态网站托管概述。
如何通过OSS存储卷仅挂载OSS中的某个文件
ossfs 2.0工具可将OSS的某个路径以文件系统的形式挂载到Pod中,但ossfs 2.0本身不支持直接挂载单个文件。若您希望Pod仅访问OSS中的某个特定文件,可通过指定subpath的方式实现。
假设需要挂载的OSS Bucket中/subpath
下的a.txt和b.txt文件到两个不同的Pod中,在Pod中的存放路径为/path/to/file/
,可参考以下YAML创建对应的PV:
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-oss
spec:
capacity:
storage: 5Gi
accessModes:
- ReadOnlyMany
persistentVolumeReclaimPolicy: Retain
csi:
driver: ossplugin.csi.alibabacloud.com
volumeHandle: pv-oss
volumeAttributes:
bucket: bucket
path: subpath #subpath为a.txt与b.txt的父路径
url: "oss-cn-hangzhou.aliyuncs.com"
fuseType: ossfs2
创建对应的PVC后,Pod中挂载PVC相应的VolumeMounts配置为:
volumeMounts:
- mountPath: /path/to/file # bucket:/subpath对应Pod中的挂载路径
name: oss-pvc # 与Volumes中的名称一致
subPath: a.txt # 或者b.txt,bucket:/subpath中文件的相对路径
挂载后,Pod中访问a.txt的完整路径为/path/to/file/a.txt
,实际访问的是bucket:/subpath/a.txt
。
更多信息,请参见使用ossfs 2.0静态存储卷。
如何跨账号挂载OSS Bucket?
建议通过RRSA鉴权方式跨账号挂载OSS Bucket。
请确认集群和CSI组件版本满足RRSA鉴权要求的版本。
以下操作以在账号A(集群所在账号)中,挂载账号B(OSS Bucket所在账号)的Bucket为例。需完成RAM授权相关准备工作后,再正常创建通过RRSA鉴权方式挂载的存储卷。
在账号B中的操作:
在账号B中创建可信实体为账号A的RAM角色roleB,详情请参见创建可信实体为阿里云账号的RAM角色。
为roleB授权需要挂载的OSS Bucket权限。
在RAM控制台,访问roleB的角色详情页,复制其ARN,如
acs:ram::130xxxxxxxx:role/roleB
。
在账号A中的操作:
为应用创建一个用于 RRSA 鉴权的 RAM 角色roleA,信任主体类型为OIDC身份提供商。
为 roleA 授予代入 roleB 的权限。具体操作请参见通过RRSA鉴权方式挂载(静态卷)或通过RRSA鉴权方式挂载(动态卷)。
roleA无需再授权OSS相关权限策略,但需要授权包含
sts:AssumeRole
API的权限策略,如系统策略AliyunSTSAssumeRoleAccess
。
在集群中配置存储卷:
在创建存储卷时,将
roleB
的 ARN 配置到assumeRoleArn
参数中:静态卷 (PV):在
volumeAttributes
中添加:assumeRoleArn: <roleB的ARN>
动态卷 (StorageClass):在
parameters
中添加:assumeRoleArn: <roleB的ARN>
如何在RRSA鉴权方式中使用指定的ARNs或ServiceAccount?
通过RRSA方式的OSS存储卷鉴权时,无法满足例如使用第三方OIDC身份提供商、使用非默认ServiceAccount等需求。
此时,只需在PV中通过roleName
配置项指定RAM角色名称,即可由CSI存储插件获取默认的Role ARN及OIDC Provider ARN。如需实现定制化的RRSA鉴权,则需要更改PV的配置信息如下。
其中,roleArn
与oidcProviderArn
需要一起配置,配置后无需再配置roleName
。
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-oss
spec:
capacity:
storage: 5Gi
accessModes:
- ReadOnlyMany
persistentVolumeReclaimPolicy: Retain
csi:
driver: ossplugin.csi.alibabacloud.com
volumeHandle: pv-oss # 需要和PV名字一致。
volumeAttributes:
bucket: "oss"
url: "oss-cn-hangzhou.aliyuncs.com"
authType: "rrsa"
fuseType: "ossfs2"
oidcProviderArn: "<oidc-provider-arn>"
roleArn: "<role-arn>"
#roleName: "<role-name>" #配置roleArn和oidcProviderArn后,roleName失效。
serviceAccountName: "csi-fuse-<service-account-name>"
参数 | 说明 |
| 需要在创建OIDC身份提供商后获取,请参见管理OIDC身份提供商。 |
| 需要在创建可信实体为上述OIDC身份提供商的RAM角色后获取,请参见使用OIDC进行角色SSO的示例。 |
| 可选,ossfs容器所在的Pod使用ServiceAccount名称,必须以csi-fuse-开头,需要预先创建。配置为空时,使用CSI维护的默认ServiceAccount。 |
扩容
实际存储容量超出OSS存储卷的配置时,是否需要扩容存储卷
OSS不限制Bucket或子路径的容量,且不提供容量配额功能,因此PV的.spec.capacity
字段和PVC的.spec.resources.requests.storage
字段的配置将被忽略,不会生效,您只需确保互相绑定的PV与PVC的容量配置值保持一致即可。
实际存储容量超出配置时,不影响正常使用,您无需扩容存储卷。
使用
如何重启ossfs 2.0进程
问题现象
修改鉴权信息或ossfs 2.0版本后,已经在运行的ossfs 2.0进程无法自动变更。
问题原因
ossfs 2.0运行后无法变更鉴权信息等配置,变更配置后,需要重启ossfs 2.0进程(即为
ack-csi-fuse
命名空间下名为csi-fuse-ossfs2-*
的Pod)与对应的应用Pod,造成业务中断。因此,默认情况下CSI不会对已经运行的ossfs 2.0进行变更。在正常操作流程中,ossfs 2.0存储卷的创建与删除完全由CSI管理。若手动终止了运行ossfs 2.0的Pod,CSI将无法触发存储卷的自动恢复或重建。
解决方案
重启ossfs 2.0进程的流程中需要重启挂载对应OSS存储卷的业务Pod,请谨慎操作。
确认当前FUSE Pod被哪些应用Pod使用。
确认需要变更的
csi-fuse-ossfs2-*
Pod。其中
<pv-name>
为PV名称,<node-name>
为节点名称。kubectl -n ack-csi-fuse get pod -lcsi.alibabacloud.com/volume-id=<pv-name> -owide | grep <node-name>
确认正在挂载该OSS存储卷的所有Pod。
其中
<ns>
为命名空间名称,<pvc-name>
为PVC名称。kubectl -n <ns> describe pvc <pvc-name>
预期输出(包含Used By):
Used By: oss-static-94849f647-4**** oss-static-94849f647-6**** oss-static-94849f647-h**** oss-static-94849f647-v**** oss-static-94849f647-x****
获取通过
csi-fuse-ossfs2-xxxx
挂载的Pod,即与csi-fuse-ossfs2-xxxx
运行在同一节点的Pod。kubectl -n <ns> get pod -owide | grep cn-beijing.192.168.XX.XX
预期输出:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES oss-static-94849f647-4**** 1/1 Running 0 10d 192.168.xx.xx cn-beijing.192.168.xx.xx <none> <none> oss-static-94849f647-6**** 1/1 Running 0 7m36s 192.168.xx.xx cn-beijing.192.168.xx.xx <none> <none>
重启业务与ossfs 2.0进程。
将应用Pod(上述示例中为
oss-static-94849f647-4****
和oss-static-94849f647-6****
)通过kubectl scale
等方式同时删除。在无应用Pod挂载时,csi-fuse-ossfs2-xxxx
Pod将自动被回收;恢复副本数后,将使用PV的新配置重新挂载,由CSI创建新的csi-fuse-ossfs2-yyyy
Pod。如果无法保证这些Pod能同时被删除(如删除Deployment、StatefulSet、DaemonSet管理的Pod均会立即触发重启),或Pod能容忍OSS读写失败,执行以下命令,找到存储卷对应的volumeattachment资源:
kubectl get volumeattachment | grep <pv-name> | grep cn-beijing.192.168.XX.XX
预期输出:
csi-bd463c719189f858c2394608da7feb5af8f181704b77a46bbc219b********** ossplugin.csi.alibabacloud.com <pv-name> cn-beijing.192.168.XX.XX true 12m
直接删除该VolumeAttachment,此时应用Pod内读写OSS将返回
disconnected error
。然后,逐个重启业务Pod,重启后的Pod将通过CSI新建的
csi-fuse-ossfs2-yyyy
Pod恢复OSS读写。