Amazon Elastic Container Service
开发人员指南 (API Version 2014-11-13)
AWS 服务或AWS文档中描述的功能,可能因地区/位置而异。请点击 Amazon AWS 入门,可查看中国地区的具体差异

在任务中使用数据卷

有多个在 Amazon ECS 任务定义中使用数据卷的使用案例。一些常见示例旨在提供与容器一起使用的持久性数据卷,定义空的非持久性数据卷并将其挂载到同一容器实例上的多个容器上,以及在同一容器实例上的不同容器中的不同位置共享定义的数据卷。

注意

对于使用 devicemapper(如 Amazon Linux 和经 Amazon ECS 优化的 AMI)的操作系统,仅启动 Docker 守护程序时可用的文件系统将对 Docker 容器可用。您可以在 Docker 守护程序启动前使用 cloud boothook 挂载安装系统,也可以在挂载文件系统以使文件系统对容器卷挂载可用后重新启动 Docker 守护程序和 Amazon ECS 容器代理。

为容器提供持久性数据卷

如果使用 sourcePath 值定义卷,则数据卷即使在引用它的所有容器停止后也将保留。存在于 sourcePath 的任何文件将提供给位于 containerPath 值的容器,而且通过运行挂载数据卷的容器写入 containerPath 值的任何文件将写入容器实例上的 sourcePath 值。

重要

Amazon ECS 不会跨容器实例同步数据卷。使用持久性数据卷的任务可置于您的集群中具有可用容量的任何容器实例上。如果您的任务在停止和重新启动后需要持久性数据卷,则您应始终在使用 AWS CLI start-task 命令启动任务时指定相同的容器实例。

  1. 在任务定义 volumes 部分中,使用 namesourcePath 值定义数据卷。

      "volumes": [
        {
          "name": "webdata",
          "host": {
            "sourcePath": "/ecs/webdata"
          }
        }
      ]
  2. containerDefinitions 部分中,使用引用已定义卷的名称的 mountPoints 和将卷挂载到容器上所在的 containerPath 值定义容器。

      "containerDefinitions": [
        {
          "name": "web",
          "image": "nginx",
          "cpu": 99,
          "memory": 100,
          "portMappings": [
            {
              "containerPort": 80,
              "hostPort": 80
            }
          ],
          "essential": true,
          "mountPoints": [
            {
              "sourceVolume": "webdata",
              "containerPath": "/usr/share/nginx/html"
            }
          ]
        }
      ]

为容器提供非持久性空数据卷

在某些情况下,您希望容器共享同一空数据卷,但您不希望在完成任务后保留该数据。例如,您可能在任务期间具有需要访问同一临时文件存储位置的两个数据库容器。

  1. 在任务定义 volumes 部分中,使用名称 database_scratch 定义数据卷。

    注意

    由于 database_scratch 卷未指定源路径,因此 Docker 守护程序会为您管理该卷。如果任何容器均未引用此卷,则 Amazon ECS 容器代理任务清除服务最终会将其删除(默认情况下,此情况会在容器存在 3 小时后出现,但您可以使用 ECS_ENGINE_TASK_CLEANUP_WAIT_DURATION 代理变量配置此持续时间)。有关更多信息,请参阅 Amazon ECS 容器代理配置。如果您需要保留此数据,请为卷指定 sourcePath 值。

      "volumes": [
        {
          "name": "database_scratch",
          "host": {}
        }
      ]
  2. containerDefinitions 部分中,创建数据库容器定义,以便它们挂载非持久性数据卷。

      "containerDefinitions": [
        {
          "name": "database1",
          "image": "my-repo/database",
          "cpu": 100,
          "memory": 100,
          "essential": true,
          "mountPoints": [
            {
              "sourceVolume": "database_scratch",
              "containerPath": "/var/scratch"
            }
          ]
        },
        {
          "name": "database2",
          "image": "my-repo/database",
          "cpu": 100,
          "memory": 100,
          "essential": true,
          "mountPoints": [
            {
              "sourceVolume": "database_scratch",
              "containerPath": "/var/scratch"
            }
          ]
        }
      ]

在多个容器上挂载定义的卷

您可以在任务定义中定义数据卷并在其他容器上的不同位置挂载该卷。例如,您的主机容器具有位于 /data/webroot 的网站数据文件夹,并且您可能想在具有不同文档根目录的两个不同 Web 服务器上以只读方式挂载该数据卷。

  1. 在任务定义 volumes 部分中,使用名称 webroot 和源路径 /data/webroot 定义数据卷。

      "volumes": [
        {
          "name": "webroot",
          "host": {
            "sourcePath": "/data/webroot"
          }
        }
      ]
  2. containerDefinitions 部分中,使用将 webroot 卷与指向容器的文档根目录的 containerPath 值关联的 mountPoints 值为每个 Web 服务器定义容器。

      "containerDefinitions": [
        {
          "name": "web-server-1",
          "image": "my-repo/ubuntu-apache",
          "cpu": 100,
          "memory": 100,
          "portMappings": [
            {
              "containerPort": 80,
              "hostPort": 80
            }
          ],
          "essential": true,
          "mountPoints": [
            {
              "sourceVolume": "webroot",
              "containerPath": "/var/www/html",
              "readOnly": true
            }
          ]
        },
        {
          "name": "web-server-2",
          "image": "my-repo/sles11-apache",
          "cpu": 100,
          "memory": 100,
          "portMappings": [
            {
              "containerPort": 8080,
              "hostPort": 8080
            }
          ],
          "essential": true,
          "mountPoints": [
            {
              "sourceVolume": "webroot",
              "containerPath": "/srv/www/htdocs",
              "readOnly": true
            }
          ]
        }
      ]

使用 volumesFrom 从其他容器挂载卷

您可以在一个容器上定义一个或多个卷,然后在不同的容器定义中使用 volumesFrom 参数(相同任务内)从其初始定义的挂载点的 sourceContainer 中挂载所有卷。volumesFrom 参数适用于任务定义中定义的卷以及使用 Dockerfile 内置到映像中的卷。

  1. (可选)要共享内置到映像中的卷,您需要使用在 VOLUME 指令中声明的卷构建映像。以下示例 Dockerfile 使用 httpd 映像,然后添加卷并在 Apache 文档根目录(这是由 httpd Web 服务器使用的文件夹)中的 dockerfile_volume 挂载卷:

    FROM httpd
    VOLUME ["/usr/local/apache2/htdocs/dockerfile_volume"]

    您可以使用此 Dockerfile 构建映像并将其推送至存储库(如 Docker Hub),然后在任务定义中使用它。以下步骤中使用的示例 my-repo/httpd_dockerfile_volume 映像是通过上述 Dockerfile 构建的。

  2. 创建一个为您的容器定义其他卷和挂载点的任务定义。在此示例 volumes 部分中,您将创建一个称为 empty 的空卷,此卷由 Docker 守护程序管理。此外,还将定义一个称为 host_etc 的主机卷,该卷导出主机容器实例上的 /etc 文件夹。

    Copy
    { "family": "test-volumes-from", "volumes": [ { "name": "empty", "host": {} }, { "name": "host_etc", "host": { "sourcePath": "/etc" } } ],

    在容器定义部分中,创建一个挂载之前定义的卷的容器。在此示例中,web 容器(此容器使用通过 Dockerfile 中的卷构建的映像)挂载 emptyhost_etc 卷。

    Copy
    "containerDefinitions": [ { "name": "web", "image": "my-repo/httpd_dockerfile_volume", "cpu": 100, "memory": 500, "portMappings": [ { "containerPort": 80, "hostPort": 80 } ], "mountPoints": [ { "sourceVolume": "empty", "containerPath": "/usr/local/apache2/htdocs/empty_volume" }, { "sourceVolume": "host_etc", "containerPath": "/usr/local/apache2/htdocs/host_etc" } ], "essential": true },

    创建另一个容器,该容器使用 volumesFrom 挂载与 web 容器关联的所有卷。web 容器上的所有卷也同样会挂载到 busybox 容器上(包括 Dockerfile 中指定的用于构建 my-repo/httpd_dockerfile_volume 映像的卷)。

    Copy
    { "name": "busybox", "image": "busybox", "volumesFrom": [ { "sourceContainer": "web" } ], "cpu": 100, "memory": 500, "entryPoint": [ "sh", "-c" ], "command": [ "echo $(date) > /usr/local/apache2/htdocs/empty_volume/date && echo $(date) > /usr/local/apache2/htdocs/host_etc/date && echo $(date) > /usr/local/apache2/htdocs/dockerfile_volume/date" ], "essential": false } ] }

    当此任务运行时,这两个容器将挂载卷,并且 command 容器中的 busybox 会将日期和时间写入每个卷文件夹中称为 date 的文件,这些卷随后将显示在由 web 容器显示的网站上。

    注意

    由于 busybox 容器运行快速命令然后退出,因此它需要在容器定义中设置为 "essential": false 以防止它在退出时停止整个任务。