使用docker-compose本地挂载AWS EFS

4
我想知道是否有一种简单的方法可以利用Amazon EFS(弹性文件系统)将其作为本地docker-compose设置中的卷挂载。
原因是对于本地开发,创建的卷会持久保存在我的笔记本电脑上-如果我更换设备,我无法访问任何底层数据。云NFS将解决此问题,因为它可以从任何地方轻松访问。
AWS文档(https://docs.aws.amazon.com/efs/latest/ug/efs-onpremises.html)似乎建议使用AWS Direct Connect / VPN-是否有任何方法可以通过在安全组中打开端口2049(NFS流量)并将该安全组应用于新创建的EFS来避免这种情况?
这是我的docker-compose.yml:
version: "3.2"
 
services:
  postgres_db:
    container_name: "postgres"
    image: "postgres:13"
    ports:
      - 5432:5432
    volumes:
      - type: volume
        source: postgres_data
        target: /var/lib/postgresql/data
        volume:
          nocopy: true
    environment: 
      POSTGRES_USER: 'admin'
      POSTGRES_PASSWORD: "password"
 
volumes: 
  postgres_data:
    driver_opts:
      type: "nfs"
      o: "addr=xxx.xx.xx.xx,nolock,soft,rw"
      device: ":/docker/example"

我遇到了以下错误:

ERROR: for postgres_db  Cannot start service postgres_db: error while mounting volume '/var/lib/docker/volumes/flowstate_example/_data': failed to mount local volume: mount :/docker/example:/var/lib/docker/volumes/flowstate_example/_data, data: addr=xxx.xx.xx.xx,nolock,soft: connection refused

我理解的意思是我的笔记本连接不属于AWS EFS VPC,因此无法挂载EFS。
为了更好地理解,我想将网络爬虫设置容器化,并在云中保留数据卷,以便可以从任何地方连接到它。

有没有可行的解决方案?我们遇到了类似的情况,下面的答案不起作用。 - toing
3个回答

3
EFS默认假定使用nfs4,因此:
version: '3.8'

services:

  postgres:
    volumes:
      postgres_data:/var/lib/postgresql/data

volumes: 

  postgres_data:
    driver_opts:
      type: "nfs4"
      o: "addr=xxx.xx.xx.xx,nolock,soft,rw"
      device: ":/docker/postgres_data"

当然,被引用的nfs-export/path必须存在。Swarm不会自动创建不存在的文件夹。
在重新创建堆栈之前,请确保手动删除任何旧的此类/名称的docker卷(在所有swarm节点上!)。
docker volume rm $(docker volume ls -f name=postgres_data -q)

重要说明:Docker NFS卷实际上只是声明数据的位置,当您更新docker-compose.yml时不会自动更新,因此您必须删除该卷以便任何新配置生效。
请查看以下输出:
docker service ps stack_postgres --no-trunc

了解有关卷无法安装的更多信息,请确保能够通过 mount -t nfs4... 挂载 NFS 导出。

请查看 showmount -e your.efs.ip.address


这对我不起作用。你能否请公开更多的 Docker Compose 文件? - toing
很可能是因为nfs4不允许使用“addr =”作为选项。请使用“nfs”作为类型。 - nnsense

1
volumes:
  nginx_test_vol:
    driver_opts:
      type: "nfs"
      o: "addr=fs-xxxxxxxxxxxxxxxxxx.efs.us-east-1.amazonaws.com,rw,nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport"
      device: ":/nginx-test"

这使我能够很好地使用它。


你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心中找到有关如何编写良好答案的更多信息。 - Community

0
简而言之,答案是否定的。如果没有 VPN 或端口重定向,就无法在本地机器或运行在 AWS VPC 之外的任何设备上挂载 EFS 卷:EFS 使用子网 CIDR 范围内的私有 IP,它没有公共 IP,其 DNS 是内部 DNS,无法从互联网解析。
相反,您可以使用 S3,如果这是一个选项的话(我能想到的第一个警告是:没有 Unix 权限)。
在 Linux 上,s3fs 是一个可靠的选择。
安装和挂载后,您可以将其用作部署的卷,就像任何其他目录一样,您还可以像 here 中所示那样自动化它,通过运行 s3fs 作为容器并将其挂载到辅助容器中(以及本地访问文件非常方便):
.env 文件中设置 S3 的身份验证:
AWS_S3_BUCKET=
AWS_S3_ACCESS_KEY_ID=
AWS_S3_SECRET_ACCESS_KEY=

然后,在docker-compose.yaml文件中:

version: '3.8'

services:
  s3fs:
    privileged: true
    image: efrecon/s3fs:1.90
    restart: unless-stopped
    env_file: .env
    volumes:
      # This also mounts the S3 bucket to `/mnt/s3data` on the host machine
      - /mnt/s3data:/opt/s3fs/bucket:shared

  test:
    image: bash:latest
    restart: unless-stopped
    depends_on:
      - s3fs
    # Just so this container won't die and you can test the bucket from within
    command: sleep infinity
    volumes:
      - /mnt/s3data:/data:shared

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接