我正在一台具有 32GB RAM 的 AWS EC2 主机上部署一个包含 5 个应用程序的 docker-compose 堆栈。其中包括:2 个 Java 容器、2 个 Rails 容器、1 个 Elasticsearch/Logstash/Kibana (ELK) 容器(来自https://hub.docker.com/r/sebp/elk/)。
当我第一次启动堆栈时,所有容器都会启动。ELK 容器大约需要 3 分钟才能启动。其他容器会立即启动。
但是 ELK 容器在大约 5 分钟后退出。我从日志中看到 elasticsearch 服务无法启动。日志消息表明内存限制错误。
但是,当我拆除所有东西并再次启动时,所有容器(包括 ELK 容器)都会立即启动,并且一切都保持稳定。只有当我第一次在新的 EC2 实例上启动堆栈时才会出现此问题。
我可以从 docker 统计数据中看到,ELK 容器仅使用了实例上可用的 32GB RAM 中的 2-3GB。
ELK容器配置如下:
elk:
image: sebp/elk
hostname: elk
container_name: elk
volumes:
- ./pipeline/:/etc/logstash/conf.d/
tty: true
expose:
- "12201/udp"
network_mode: host
ports:
- "5601:5601"
- "9200:9200"
- "12201:12201"
ulimits:
nofile:
soft: 65536
hard: 65536
启动时容器之间没有依赖关系。
elasticsearch 首次运行时发生什么情况导致容器启动失败?
答案1
这里的问题是 sebp/elb 图像包含一个超时参数,该参数在 elasticsearch 启动之前就已过期。
由 ES_CONNECT_RETRY 环境变量控制,默认设置为 30 秒。Elasticsearch 首次启动所需的时间比这要长,因此当我将其设置为 300 秒时,它就成功了。您可以在 docker-compose 清单中将其添加为 elk 容器的环境变量。
elk:
image: sebp/elk
hostname: elk
container_name: elk
environment:
- ES_CONNECT_RETRY=300
除此之外,您还需要在运行 docker-compose 之前设置 COMPOSE_HTTP_TIMEOUT 环境变量,否则,docker-compose 将在 elasticsearch 启动之前超时。您应该将该值设置为大于您为 ES_CONNECT_RETRY 设置的值,例如
COMPOSE_HTTP_TIMEOUT=360
这可能是因为我使用的是较大的 Ec2 实例 (32GB RAM)。在较小的实例上可能不是问题。