无法在已安装的卷 aws efs 上写入文件

Cannot write files on mounted volume aws efs

我正在利用 Apache Airflow 为公司内部的工作流构建一个可扩展的分布式架构。我正在使用 ECS Fargate。

由于这是一个分布式架构,为了在所有机器上有一个一致的共享视图,需要一个非集中式文件系统(即,网络服务器需要访问 DAG 文件、调度程序和工作程序) .

为此,我正在使用 AWS EFS,我可以成功地将文件系统挂载到 EC2 实例中,但我无法在其中写入或创建文件。

这是附加到 fs 的策略:

{
    "Version": "2012-10-17",
    "Id": "ExamplePolicy01",
    "Statement": [
        {
            "Sid": "ExampleSatement01",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": [
                "elasticfilesystem:ClientMount",
                "elasticfilesystem:ClientWrite"
            ],
            "Resource": "arn:aws:elasticfilesystem:eu-west-1:XXXXXXXXXX:file-system/fs-aaaaaaa"
        }
    ]
}

正如文档所说:

elasticfilesystem:ClientWrite ------> Provides an NFS client with write permissions on a file system.

我正在通过执行以下命令进行挂载:

 sudo mount -t efs -o tls,accesspoint=fsap-oooooooooooooooo fs-aaaaaaa:/ efs

的确,我能看到内容,但每次我尝试写的时候都Permission denied

[ec2-user@ip-XXXX ~]$ sudo mount -t efs -o tls,accesspoint=fsap-oooooooooooooooo fs-aaaaaaa:/ efs
[ec2-user@ip-XXXX ~]$ df -h
Filesystem      Size  Used Avail Use% Mounted on
devtmpfs        2.0G     0  2.0G   0% /dev
tmpfs           2.0G     0  2.0G   0% /dev/shm
tmpfs           2.0G  616K  2.0G   1% /run
tmpfs           2.0G     0  2.0G   0% /sys/fs/cgroup
/dev/xvda1      8.0G  2.7G  5.4G  33% /
tmpfs           395M     0  395M   0% /run/user/1000
tmpfs           395M     0  395M   0% /run/user/0
127.0.0.1:/     8.0E     0  8.0E   0% /home/ec2-user/efs
[ec2-user@ip-XXXX ~]$
[ec2-user@ip-XXXX ~]$ cd efs/
[ec2-user@ip-XXXX efs]$ touch a
touch: cannot touch ‘a’: Permission denied
[ec2-user@ip-XXXX efs]$
[ec2-user@ip-XXXX efs]$ sudo touch a
touch: cannot touch ‘a’: Permission denied
[ec2-user@ip-XXXX efs]$ sudo su -
Last login: Wed Aug 19 21:29:39 UTC 2020 on pts/0
[root@ip-XXXX ~]#
[root@ip-XXXX ~]# cd /home/ec2-user/efs/
[root@ip-XXXX efs]#
[root@ip-XXXX efs]# touch d
touch: cannot touch ‘d’: Permission denied

如有任何帮助,我们将不胜感激。谢谢。

我已经成功实现了目标,此回答旨在分享我的经验,以防有人遇到相同的用例。

如果您使用的是 ECS Fargate,则可以选择在平台 1.4.0 的版本中装载卷。因此,在 container_definitions 中有一个名为 mountPoints:

的选项
    ...
    "entryPoint": [],
    "command": [],
    "portMappings": [
      {
        "hostPort": ${host_port},
        "protocol": "tcp",
        "containerPort": ${container_port}
      }
    ],
    "mountPoints": [
      {
        "sourceVolume": "dags",
        "containerPath": "/usr/local/airflow/dags",
        "readOnly": false
      }
    ],
    "cpu": ${cpu},
    "environment": [
      {
        "name": "POSTGRES_HOST",
        "value": "${postgres_host}"
      },
      {
        "name": "AIRFLOW_COMPONENT",
        "value": "webserver"
      },
      {
        "name": "REDIS_HOST",
        "value": "${redis_host}"
      }
    ]
    ...

这将装载 EFS 卷。请记住指定 volume 配置。这是地形:

resource "aws_ecs_task_definition" "task_definition_airflow_webserver" {
  family                    = "airflow-webserver"
  requires_compatibilities  = ["FARGATE"]
  network_mode              = "awsvpc"
  execution_role_arn        = "${aws_iam_role.ecs_service_role_airflow_webserver.arn}"
  container_definitions     = "${data.template_file.airflow_webserver.rendered}"
  cpu                       = 1024
  memory                    = 2048

  volume {
    name = "dags"

    efs_volume_configuration {
      file_system_id          = "${aws_efs_file_system.airflow_dags_efs.id}"
      root_directory          = "/"
      transit_encryption      = "ENABLED"
    }
  }
}

希望这对您有所帮助。如果有什么不明确或不清楚的地方,请告诉我。