排查 EKS 中的 EFS 挂载失败:IAM 挂载选项之谜

发布: (2026年1月14日 GMT+8 08:57)
6 min read
原文: Dev.to

Source: Dev.to

TL;DR

如果在 EKS 中挂载 EFS 卷时看到 mount.nfs4: access denied by server while mounting 127.0.0.1:/,且安全组配置正确,那么很可能是在使用 EFS 文件系统策略时,PersistentVolume 定义中缺少 iam 挂载选项。

问题

在将一个需要将报告写入共享 EFS 文件系统的新报告服务集成到我们的 EKS 集群时,Pod 一直因以下神秘错误而挂载失败:

MountVolume.SetUp failed for volume "efs-pv": rpc error: code = Internal desc = Could not mount "{efs_id}:/"
Output: mount.nfs4: access denied by server while mounting 127.0.0.1:/

调查之旅

初始怀疑(全错)

理论 1:安全组问题

  • 已验证工作节点与 EFS 挂载目标之间的 NFS 流量(TCP 2049)已放行。
  • 挂载目标在所有可用区均已创建。

结果: 安全组配置完美。不是问题所在。

理论 2:EFS 文件系统策略

  • 最近添加了基于 IAM 的文件系统策略以限制访问。
  • 策略中包含 aws:PrincipalArn 等条件,用于白名单特定 IAM 角色。

突破口: 删除该策略后即可正常工作!

灵光一现

阅读 AWS EFS 故障排除文档 时发现:

如果未在带有限制性文件系统策略的情况下添加 iam 挂载选项,则 pod 会出现以下错误信息:
mount.nfs4: access denied by server while mounting 127.0.0.1:/

根本原因分析

1. EFS 文件系统策略条件

我们在策略条件中使用了 aws:PrincipalArn

{
  "Condition": {
    "ArnLike": {
      "aws:PrincipalArn": [
        "arn:aws:iam::123456789012:role/worker-node-role",
        "arn:aws:iam::123456789012:role/efs-csi-driver-role"
      ]
    }
  }
}

问题: 根据 AWS 文档,aws:PrincipalArn 和大多数 IAM 条件键 不对 NFS 客户端挂载到 EFS 强制执行。只有以下条件键有效:

  • aws:SecureTransport (Boolean)
  • aws:SourceIp (String – 仅公共 IP)
  • elasticfilesystem:AccessPointArn (String)
  • elasticfilesystem:AccessedViaMountTarget (Boolean)

2. 缺少 IAM 挂载选项

我们的 PersistentVolume 定义遗漏了 iam 挂载选项:

# BEFORE – Missing iam mount option
apiVersion: v1
kind: PersistentVolume
metadata:
  name: efs-pv
spec:
  storageClassName: aws-efs-csi-sc
  csi:
    driver: efs.csi.aws.com
    volumeHandle: "{efs_id}"

如果没有 iam,EFS CSI 驱动程序将不会使用 IAM 角色进行身份验证,因此任何带有 IAM 限制的文件系统策略都会失效。

3. EFS 挂载流程

使用带有 tls 挂载选项的 EFS CSI 驱动程序时:

  1. 节点级挂载 首先发生(通过工作节点的 IAM 角色)。
  2. 没有 iam → 匿名 NFS 挂载。
  3. iam → 使用 IAM 角色凭证进行身份验证的挂载。

解决方案

修复 1:在 mountOptions 中添加 iam

# AFTER – With iam mount option
apiVersion: v1
kind: PersistentVolume
metadata:
  name: efs-pv
spec:
  storageClassName: aws-efs-csi-sc
  mountOptions:
    - tls   # Encryption in transit
    - iam   # Enable IAM authentication
  csi:
    driver: efs.csi.aws.com
    volumeHandle: "{efs_id}"

修复 2:仅使用受支持的 EFS 条件键

如果需要文件系统策略,请将其限制在受支持的条件范围内:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": { "AWS": "*" },
      "Action": [
        "elasticfilesystem:ClientMount",
        "elasticfilesystem:ClientWrite",
        "elasticfilesystem:ClientRootAccess"
      ],
      "Resource": "arn:aws:elasticfilesystem:us-east-1:123456789012:file-system/{efs_id}",
      "Condition": {
        "Bool": {
          "elasticfilesystem:AccessedViaMountTarget": "true",
          "aws:SecureTransport": "true"
        }
      }
    }
  ]
}

此策略:

  • 要求 TLS 加密(aws:SecureTransport)。
  • 要求通过挂载目标访问(elasticfilesystem:AccessedViaMountTarget)。
  • 仅使用受支持的条件键。
  • 依赖安全组进行网络层访问控制。

关键要点

  1. IAM 挂载选项是 IAM 授权的必需条件
    没有 -o iam,EFS 挂载是匿名的。任何基于 IAM 的文件系统策略都会拒绝访问。

  2. 并非所有 IAM 条件都适用于 EFS
    对于 NFS 挂载,仅强制执行四个条件键。使用其他条件会产生错误的安全感。

  3. 正确分层您的安全

    • 网络层: 安全组(谁可以访问挂载目标)。
    • IAM 层: 角色上的 IAM 策略(允许哪些操作)。
    • 文件系统层: EFS 策略(额外的限制)。
  4. 仔细阅读错误日志
    错误中提到 127.0.0.1 是因为 EFS 挂载助手会为 TLS 创建本地 stunnel 代理。实际的失败发生在 IAM 授权层,而不是网络层。

  5. 手动测试挂载操作
    SSH 到工作节点并使用 EFS 挂载助手测试挂载:

    sudo mount -t efs -o tls,iam {efs_id}:/ /mnt/test

    这可以在 Kubernetes 之外验证配置。

结论

看似复杂的 IAM 策略问题实际上是缺少挂载选项。关键的洞察是,EFS 文件系统策略 需要显式的 IAM 认证,通过 iam 挂载选项实现,并且大多数 IAM 条件键不适用于 NFS 挂载。

Back to Blog

相关文章

阅读更多 »