启动 Docker 容器的 ECS 代理未完成。手动启动成功

ECS Agent starting Docker container doesn't complete. Manual start successful

我按照 ECS Getting Started tutorial 进行操作,但 ECS 代理无法启动容器。当我在同一个实例上手动启动图像时,它启动正常。

图像是一个 Spring 启动 Web 应用程序,在 returns 字符串 "Hello world!!" 上有一个端点。容器 运行 在本地很好,在我创建的 CentOS EC2 实例上 运行 也很好。当我 运行 CentOS EC2 实例上的 docker 图像时,端点公开可用。

ECS 实例具有向导创建的安全组并打开了端口 80。我为 SSH 访问添加了端口 22。

当我通过 SSH 进入 ECS 实例以查看我的容器的 Docker 日志时,看起来它在入口点执行期间挂起。

以下是挂起实例的 Docker 日志:

[ec2-user@ip-10-0-0-156 ~]$ docker logs --tail 100 107d4cf04dd8

  .   ____          _            __ _ _
 /\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.4.2.RELEASE)

2016-11-25 17:36:22.505  INFO 1 --- [           main] ecstest.Application                      : Starting Application on 107d4cf04dd8 with PID 1 (/ecstest-1.0-SNAPSHOT.jar started by root in /)
2016-11-25 17:36:22.546  INFO 1 --- [           main] ecstest.Application                      : No active profile set, falling back to default profiles: default
2016-11-25 17:36:23.059  INFO 1 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@6d21714c: startup date [Fri Nov 25 17:36:23 UTC 2016]; root of context hierarchy
2016-11-25 17:36:30.972  INFO 1 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
2016-11-25 17:36:31.014  INFO 1 --- [           main] o.apache.catalina.core.StandardService   : Starting service Tomcat
2016-11-25 17:36:31.016  INFO 1 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/8.5.6
2016-11-25 17:36:31.464  INFO 1 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2016-11-25 17:36:31.464  INFO 1 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 8458 ms

起初它似乎是我的容器镜像中的应用程序错误,但是当我停止 docker 进程并手动停止 运行 同一镜像时,输出符合预期,我可以访问我的预期来自实例外部的端点。

[ec2-user@ip-10-0-1-124 ~]$ docker stop -t 1 4d2401d7db93 && docker run -p 80:8080 -d ############.dkr.ecr.us-west-2.amazonaws.com/ecstest
4d2401d7db93
db8cffa89995401d9314d7d70e954f09c7fde972a5e6a423615827d8c47b9d10
[ec2-user@ip-10-0-1-124 ~]$ docker ps
CONTAINER ID        IMAGE                                                  COMMAND                  CREATED             STATUS              PORTS                  NAMES
db8cffa89995        ############.dkr.ecr.us-west-2.amazonaws.com/ecstest   "java -jar ecstest-1."   10 seconds ago      Up 9 seconds        0.0.0.0:80->8080/tcp   small_gates
85bd18480c99        amazon/amazon-ecs-agent:latest                         "/agent"                 11 minutes ago      Up 11 minutes                              ecs-agent
[ec2-user@ip-10-0-1-124 ~]$ docker logs --tail 1000 db8cffa89995

  .   ____          _            __ _ _
 /\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.4.2.RELEASE)

2016-11-25 18:06:57.960  INFO 1 --- [           main] ecstest.Application                      : Starting Application on db8cffa89995 with PID 1 (/ecstest-1.0-SNAPSHOT.jar started by root in /)
2016-11-25 18:06:58.004  INFO 1 --- [           main] ecstest.Application                      : No active profile set, falling back to default profiles: default
2016-11-25 18:06:58.578  INFO 1 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@6d21714c: startup date [Fri Nov 25 18:06:58 UTC 2016]; root of context hierarchy
2016-11-25 18:07:05.784  INFO 1 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
2016-11-25 18:07:05.866  INFO 1 --- [           main] o.apache.catalina.core.StandardService   : Starting service Tomcat
2016-11-25 18:07:05.876  INFO 1 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/8.5.6
2016-11-25 18:07:06.283  INFO 1 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2016-11-25 18:07:06.283  INFO 1 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 7753 ms
2016-11-25 18:07:07.026  INFO 1 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean  : Mapping servlet: 'dispatcherServlet' to [/]
2016-11-25 18:07:07.031  INFO 1 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'characterEncodingFilter' to: [/*]
2016-11-25 18:07:07.031  INFO 1 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2016-11-25 18:07:07.032  INFO 1 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2016-11-25 18:07:07.033  INFO 1 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'requestContextFilter' to: [/*]
2016-11-25 18:07:08.432  INFO 1 --- [           main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@6d21714c: startup date [Fri Nov 25 18:06:58 UTC 2016]; root of context hierarchy
2016-11-25 18:07:08.786  INFO 1 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[],methods=[GET]}" onto public java.lang.String ecstest.Application.get()
2016-11-25 18:07:08.800  INFO 1 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2016-11-25 18:07:08.801  INFO 1 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2016-11-25 18:07:09.036  INFO 1 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2016-11-25 18:07:09.036  INFO 1 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2016-11-25 18:07:09.204  INFO 1 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2016-11-25 18:07:09.893  INFO 1 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2016-11-25 18:07:10.201  INFO 1 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2016-11-25 18:07:10.216  INFO 1 --- [           main] ecstest.Application                      : Started Application in 14.385 seconds (JVM running for 16.522)

知道为什么 ECS 代理无法启动我的应用程序吗?

任务定义JSON

{
  "attributes": null,
  "requiresAttributes": [
    {
      "value": null,
      "name": "com.amazonaws.ecs.capability.ecr-auth",
      "targetId": null,
      "targetType": null
    }
  ],
  "taskDefinitionArn": "arn:aws:ecs:us-west-2:############:task-definition/DcTaskDefinition:4",
  "networkMode": "bridge",
  "status": "ACTIVE",
  "revision": 4,
  "taskRoleArn": null,
  "containerDefinitions": [
    {
      "volumesFrom": [],
      "memory": 128,
      "extraHosts": null,
      "dnsServers": null,
      "disableNetworking": null,
      "dnsSearchDomains": null,
      "portMappings": [
        {
          "hostPort": 80,
          "containerPort": 8080,
          "protocol": "tcp"
        }
      ],
      "hostname": null,
      "essential": true,
      "entryPoint": null,
      "mountPoints": [],
      "name": "DcContainer",
      "ulimits": null,
      "dockerSecurityOptions": null,
      "environment": [],
      "links": null,
      "workingDirectory": null,
      "readonlyRootFilesystem": null,
      "image": "############.dkr.ecr.us-west-2.amazonaws.com/ecstest:latest",
      "command": null,
      "user": null,
      "dockerLabels": null,
      "logConfiguration": null,
      "cpu": 0,
      "privileged": null,
      "memoryReservation": null
    }
  ],
  "placementConstraints": [],
  "volumes": [],
  "family": "DcTaskDefinition"
}

任务定义中的 memory 键 JSON 对容器施加了 硬内存限制 。当容器试图超过该限制时,Docker 守护程序应该将其杀死。 我不确定这是否会导致您的容器获得 "stuck",但这是我在 ECS 运行时容器的运行方式与从命令行运行的方式之间看到的唯一重要区别。 因此,我会尝试将 memory 值至少设置为 300,或者使用 memoryReservation 键来代替,这会施加 soft 内存限制。

有关硬内存限制和软内存限制之间差异的更多信息,请参阅 official ECS documentation