Не удается записать файлы на смонтированный том aws efs

#amazon-web-services #permissions #amazon-ecs #mount

#amazon-веб-сервисы #разрешения #amazon-ecs #монтировать

Вопрос:

Я создаю масштабируемую и распределенную архитектуру для рабочих процессов в нашей компании, используя Apache Airflow. Я использую ECS Fargate.

Поскольку это распределенная архитектура, требуется нецентрализованная файловая система для обеспечения согласованного общего просмотра на всех компьютерах (т. Е. веб-серверу также необходим доступ к файлам базы данных, планировщику и рабочим ресурсам).

Для этой цели я использую 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 ——> Предоставляет клиенту NFS права на запись в файловой системе.

Я монтирую, выполнив следующую команду:

  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
  

Буду признателен за любую помощь. Спасибо.

Комментарии:

1. возможно ли, что у ec2-пользователя нет разрешения на запись. вы пробовали писать в sudo?

2. вы пытались также получить разрешения на чтение самостоятельно? может быть, стоит попробовать

3. В конце концов, я мог бы создать / коснуться файла, полностью удалив политику файловой системы и став root пользователем. в экземпляре EC2.

Ответ №1:

Я успешно достиг цели, и этот ответ предназначен для того, чтобы поделиться своим опытом на случай, если кто-то столкнется с тем же вариантом использования.

Если вы используете 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 конфигурацию. Вот terraform:

 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"
    }
  }
}
  

Надеюсь, это поможет. Дайте мне знать, если есть что-то двусмысленное или неясное.

Комментарии:

1. можете ли вы сказать мне, что это containerPath означает? Я не могу выполнить запись на том, и я не уверен, как следует задать этот путь. У меня есть root_directory="/" , но я хочу, чтобы мое приложение (grafana) выполняло запись в несколько каталогов внутри тома

2. containerPath — это путь с точки зрения контейнера, на котором расположена точка монтирования EFS. Предположим, что вы находились в терминале контейнера, тогда каталог «/ usr / local /airflow / dag» на самом деле будет каталогом EFS «/».

Ответ №2:

Я также столкнулся с этой проблемой. Решение, которое сработало для меня, состояло из двух шагов

  1. Добавьте elasticfilesystem:ClientRootAccess к инструкции о действиях политики. Например,

         "Action": [
            "elasticfilesystem:ClientRootAccess",
            "elasticfilesystem:ClientMount",
            "elasticfilesystem:ClientWrite"
        ],
      
  2. Затем, после монтирования EFS, измените его разрешения, чтобы разрешить запись. Например, если я подключился к /efs/data , то

     cd /efs/data
    sudo chmod 775 /efs/data
      

И теперь это работает.

Если вы хотите избежать шага 2, вы можете зайти в настройки AWS «Точка доступа» и обновить «Пользователь POSIX» и «Разрешения на создание корневого каталога», чтобы они были вашими идентификаторами пользователя / группы. Например, в ubuntu пользователь по умолчанию обычно имеет идентификатор POSIX «1000» и идентификатор группы «1000».

Чтобы узнать свой идентификатор пользователя,

  id -u <username>
  

Чтобы узнать идентификатор вашей группы,

  id -g <username>
  

Комментарии:

1. Служба поддержки AWS только что ответила на мое обращение по этому вопросу. Они подтвердили эту проблему и указали, что для предотвращения ClientRootAccess по умолчанию и сохранения доступа на запись для некоторых подключений вам необходимо следовать инструкциям в этой статье docs.aws.amazon.com/efs/latest/ug/enable-root-squashing.html . Это включает в себя создание определенной роли IAM.