ECS 集群中的 Jenkins slave 运行 无法启动容器

Jenkins slave running in ECS cluster can not start container

我在 AWS ECS 集群中使用 jenkins slave,我的配置如下: Jenkins in ECS.

平时很好用,但是有时候高峰期,slave容器启动很慢,40多分钟,甚至启动不了容器。

我必须终止 ECS 实例,然后启动一个新实例。当容器无法启动时,我在 ecs-agent 中看到了一条日志:

STOPPED, Reason CannotCreateContainerError: API error (500): devmapper: Thin Pool has 788 free data blocks which is less than minimum required 4454 free data blocks. Create more free space in thin pool or use dm.min_free_space option to change behavior

这是我的 docker 信息,请告诉我如何解决这个问题。

[root@ip-10-124-2-159 ec2-user]# docker info
Containers: 10
 Running: 1
 Paused: 0
 Stopped: 9
Images: 2
Server Version: 1.12.6
Storage Driver: devicemapper
 Pool Name: docker-docker--pool
 Pool Blocksize: 524.3 kB
 Base Device Size: 10.74 GB
 Backing Filesystem: ext4
 Data file:
 Metadata file:
 Data Space Used: 8.646 GB
 Data Space Total: 23.35 GB
 Data Space Available: 14.71 GB
 Metadata Space Used: 2.351 MB
 Metadata Space Total: 25.17 MB
 Metadata Space Available: 22.81 MB
 Thin Pool Minimum Free Space: 2.335 GB
 Udev Sync Supported: true
 Deferred Removal Enabled: true
 Deferred Deletion Enabled: true
 Deferred Deleted Device Count: 0
 Library Version: 1.02.93-RHEL7 (2015-01-28)
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
 Volume: local
 Network: bridge host null overlay
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Security Options:
Kernel Version: 4.4.39-34.54.amzn1.x86_64
Operating System: Amazon Linux AMI 2016.09
OSType: linux
Architecture: x86_64
CPUs: 2
Total Memory: 7.8 GiB
Name: ip-10-124-2-159
ID: 6HVT:TWH3:YP6T:GMZO:23TM:EUAA:F7XJ:ISII:QDE7:V2SN:XKFI:XPGZ
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
Insecure Registries:
 127.0.0.0/8

而且我不知道为什么只能同时运行4个任务,连ECS实例的资源都还可用,如何增加

你的问题是一个很常见的问题,当你经常启动和停止容器时,你刚才提到的 post 就是这样!他们明确表示:

"The Amazon EC2 Container Service Plugin can launch containers on your ECS cluster that automatically register themselves as Jenkins slaves, execute the appropriate Jenkins job on the container, and then automatically remove the container/build slave afterwards"

这个问题是,如果停止的容器没有被清理,你最终 运行 内存不足,正如你所经历的那样。如果您 ssh 进入实例并 运行 以下命令,您可以自己检查:

docker ps -a

如果您在 Jenkins 遇到麻烦时 运行 此命令,您应该会看到几乎无穷无尽的已停止容器列表。您可以通过 运行 执行以下命令将它们全部删除:

docker rm -f $(docker ps -a -f status-exited)

但是,经常手动执行此操作确实不是很方便,所以您真正想要做的是在启动时在您的 ECS 实例配置的 userData 参数中包含以下脚本:

ECS_ENGINE_TASK_CLEANUP_WAIT_DURATION=1m >> /etc/ecs/ecs.config
ECS_CLUSTER=<NAME_OF_CLUSTER> >> /etc/ecs/ecs.config
ECS_DISABLE_IMAGE_CLEANUP=false >> /etc/ecs/ecs.config
ECS_IMAGE_CLEANUP_INTERVAL=10m >> /etc/ecs/ecs.config
ECS_IMAGE_MINIMUM_CLEANUP_AGE=30m >> /etc/ecs/ecs.config

这将指示 ECS 代理启用清理守护进程,每 10 分钟(这是您可以设置的最短间隔)检查一次要删除的映像,在任务停止 1 分钟后删除容器,并删除映像已存在 30 分钟,并且不再被活动的任务定义引用。您可以了解有关这些变量的更多信息 here.

根据我的经验,如果您非常快速地启动和停止容器,此配置可能还不够,因此您可能需要为您的实例附加一个合适的卷,以确保您有足够的 space在守护进程清理停止的容器时继续。

感谢何塞的回答。

但是,这个命令在 Docker 1.12.*

中对我有用
docker rm $(docker ps -aqf "status=exited")

flag 'q' 从结果中过滤 containerIds 并将其删除。

如果您升级到最新的 AWS 客户端(或最新的 ECS AMI,amzn-ami-2017.09.d-amazon-ecs-optimized 或更高版本),那么您在您的 ecs 配置中为服务于集群的 EC 主机配置 ECS automated cleanup of defunct images, containers and volumes

这会在 node(label){} 子句之后进行清理,但不会在该构建期间执行 docker。

  • 节点容器及其卷 - 已清理
  • docker 由在该节点上执行的步骤生成的图像 - 未清理

ECS 对该节点上发生的事情视而不见。鉴于节点本身应该是最大的东西,ECS 自动清理应该将 运行 单独清理任务的需要减少到最低限度。