

# Amazon ECS 绑定挂载示例
<a name="bind-mount-examples"></a>

以下示例介绍了为容器使用绑定挂载的常见使用案例。

**为 Fargate 任务分配更多的临时存储空间**

对于在使用平台版本 `1.4.0` 或更高版本（Linux）或 `1.0.0`（Windows）的 Fargate 上托管的 Amazon ECS 任务，您可以为任务中要使用的容器分配超过原定设置数量的短暂存储。此示例可以合并到其他示例中，以便为 Fargate 任务分配更多的临时存储空间。
+ 在任务定义中，定义 `ephemeralStorage` 对象。`sizeInGiB` 必须是介于 `21` 和 `200` 之间的整数，单位是 GiB。

  ```
  "ephemeralStorage": {
      "sizeInGiB": integer
  }
  ```

**为一个或多个容器提供空数据卷**

在某些使用案例中，您希望为任务中的容器提供一些临时空间。例如，您可能在任务期间具有需要访问同一临时文件存储位置的两个数据库容器。可以通过绑定挂载实现此目标。

1. 在任务定义 `volumes` 部分中，使用名称 `database_scratch` 定义绑定挂载。

   ```
     "volumes": [
       {
         "name": "database_scratch"
       }
     ]
   ```

1. 在 `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"
           }
         ]
       }
     ]
   ```

**将 Dockerfile 中的路径及其内容公开给容器**

在本例中，您有一个 Dockerfile，用于写入要挂载到容器中的数据。此示例适用于 Fargate 或 Amazon EC2 实例上托管的任务。

1. 创建 Dockerfile。下面的示例使用公共 Amazon Linux2 容器映像，并在我们希望挂载容器的 `/var/log/exported` 目录中创建一个名为 `examplefile` 的文件。`VOLUME` 指令应该指定绝对路径。

   ```
   FROM public.ecr.aws/amazonlinux/amazonlinux:latest
   RUN mkdir -p /var/log/exported
   RUN touch /var/log/exported/examplefile
   VOLUME ["/var/log/exported"]
   ```

   预设情况下，卷权限设置为 `0755` 和所有者设置为 `root`。可以在 Dockerfile 中变更这些权限。在下面的示例中，`/var/log/exported` 目录的所有者设置为 `node`。

   ```
   FROM public.ecr.aws/amazonlinux/amazonlinux:latest
   RUN yum install -y shadow-utils && yum clean all
   RUN useradd node
   RUN mkdir -p /var/log/exported && chown node:node /var/log/exported					    
   USER node
   RUN touch /var/log/exported/examplefile
   VOLUME ["/var/log/exported"]
   ```

1. 在任务定义 `volumes` 部分中，使用名称 `application_logs` 定义卷。

   ```
     "volumes": [
       {
         "name": "application_logs"
       }
     ]
   ```

1. 在 `containerDefinitions` 部分中，创建应用程序容器定义。以便它们挂载存储。`containerPath` 值必须与 Dockerfile 的 `VOLUME` 指令中指定的绝对路径匹配。

   ```
     "containerDefinitions": [
       {
         "name": "application1",
         "image": "my-repo/application",
         "cpu": 100,
         "memory": 100,
         "essential": true,
         "mountPoints": [
           {
             "sourceVolume": "application_logs",
             "containerPath": "/var/log/exported"
           }
         ]
       },
       {
         "name": "application2",
         "image": "my-repo/application",
         "cpu": 100,
         "memory": 100,
         "essential": true,
         "mountPoints": [
           {
             "sourceVolume": "application_logs",
             "containerPath": "/var/log/exported"
           }
         ]
       }
     ]
   ```

**为与主机 Amazon EC2 实例生命周期相关的容器提供空数据卷**

对于在 Amazon EC2 实例上托管的任务，可以使用绑定挂载，并将数据绑定到主机 Amazon EC2 实例的生命周期。您可以通过使用 `host` 参数并指定 `sourcePath` 值进行此操作。存在于 `sourcePath` 的任何文件将提交至值为 `containerPath` 的容器。写入 `containerPath` 值的任何文件将会写入主机 Amazon EC2 实例上的 `sourcePath` 值。
**重要**  
Amazon ECS 不会跨 Amazon EC2 实例同步您的存储。使用持久性存储的任务可置于您的集群中具有可用容量的任何 Amazon EC2 实例上。如果任务在停止和重新启动后需要持久存储，应始终在任务启动时使用 AWS CLI [start-task](https://docs.aws.amazon.com/cli/latest/reference/ecs/start-task.html) 命令指定相同的 Amazon EC2 实例。您也可以将 Amazon EFS 卷用于持久性存储。有关更多信息，请参阅 [将 Amazon EFS 卷与 Amazon ECS 结合使用](efs-volumes.md)。

1. 在任务定义 `volumes` 部分中，使用 `name` 和 `sourcePath` 值定义绑定挂载。在下面的示例中，主机 Amazon EC2 实例包含 `/ecs/webdata` 您希望挂载容器中的数据。

   ```
     "volumes": [
       {
         "name": "webdata",
         "host": {
           "sourcePath": "/ecs/webdata"
         }
       }
     ]
   ```

1. 在 `containerDefinitions` 部分中，使用引用绑定挂载的名称的 `mountPoints` 值和要在容器上挂载绑定挂载的 `containerPath` 值定义容器。

   ```
     "containerDefinitions": [
       {
         "name": "web",
         "image": "public.ecr.aws/docker/library/nginx:latest",
         "cpu": 99,
         "memory": 100,
         "portMappings": [
           {
             "containerPort": 80,
             "hostPort": 80
           }
         ],
         "essential": true,
         "mountPoints": [
           {
             "sourceVolume": "webdata",
             "containerPath": "/usr/share/nginx/html"
           }
         ]
       }
     ]
   ```

**在不同位置多个容器上挂载定义的卷**

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

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

   ```
     "volumes": [
       {
         "name": "webroot",
         "host": {
           "sourcePath": "/data/webroot"
         }
       }
     ]
   ```

1. 在 `containerDefinitions` 部分中，使用将 `mountPoints` 卷与指向容器的文档根目录的 `webroot` 值关联的 `containerPath` 值为每个 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` 从其他容器挂载卷**

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

1. （可选）要共享映像中内置的卷，请使用 Dockerfile 中的 `VOLUME` 指令。以下示例 Dockerfile 使用了 `httpd` 映像，然后添加卷并在 Apache 文档根目录中的 `dockerfile_volume` 处挂载卷。这是 `httpd` Web 服务器使用的文件夹。

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

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

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

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

   在容器定义部分中，创建一个挂载之前定义的卷的容器。在此示例中，`web` 容器会挂载 `empty` 和 `host_etc` 卷。该容器使用通过 Dockerfile 中的卷构建的映像。

   ```
   "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` 映像的卷。

   ```
       {
         "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
       }
     ]
   }
   ```

   当此任务运行时，这两个容器将挂载卷，并且 `busybox` 容器中的 `command` 会将日期和时间写入文件。此文件在每个卷文件夹中被称为 `date`。这些文件夹随后将显示在由 `web` 容器显示的网站上。
**注意**  
由于 `busybox` 容器运行快速命令然后退出，它必须在容器定义中设置为 `"essential": false`。否则，它在退出时会停止整个任务。