首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >nginx集装箱码头健康检查

nginx集装箱码头健康检查
EN

Stack Overflow用户
提问于 2018-02-13 21:36:21
回答 4查看 18.9K关注 0票数 18

我有一个项目使用正式的nginx码头容器从码头集线器,启动通过码头组成。我在Docker中为我的每个容器配置了健康检查,最近对这个nginx容器的健康检查表现得很奇怪;在使用docker-compose up -d启动时,我的所有容器都启动并开始运行健康检查,但是nginx容器看起来从未运行过健康检查。如果我将docker exec放入容器中,我可以手动运行脚本,如果重新启动容器,则健康检查将正常运行。

来自docker ps的示例输出

代码语言:javascript
复制
CONTAINER ID        IMAGE                     COMMAND                  CREATED             STATUS                            PORTS                                                                       NAMES
458a55ae8971        my_custom_image           "/tini -- /usr/local…"   7 minutes ago       Up 7 minutes (healthy)                                                                                        project_worker_1
5024781b1a73        redis:3.2                 "docker-entrypoint.s…"   7 minutes ago       Up 7 minutes (healthy)            127.0.0.1:6379->6379/tcp                                                    project_redis_1
bd405dde8ce7        postgres:9.6              "docker-entrypoint.s…"   7 minutes ago       Up 7 minutes (healthy)            127.0.0.1:15432->5432/tcp                                                   project_postgres_1
93e15c18d879        nginx:mainline            "nginx -g 'daemon of…"   7 minutes ago       Up 7 minutes (health: starting)   127.0.0.1:80->80/tcp, 127.0.0.1:443->443/tcp                                nginx

docker inspect nginx输出的示例(部分,为了简洁)

代码语言:javascript
复制
    "State": {
        "Status": "running",
        "Running": true,
        "Paused": false,
        "Restarting": false,
        "OOMKilled": false,
        "Dead": false,
        "Pid": 11568,
        "ExitCode": 0,
        "Error": "",
        "StartedAt": "2018-02-13T21:04:22.904241169Z",
        "FinishedAt": "0001-01-01T00:00:00Z",
        "Health": {
            "Status": "unhealthy",
            "FailingStreak": 0,
            "Log": []
        }
    },

docker-compose.yml中定义nginx容器的部分:

代码语言:javascript
复制
nginx:
  image: nginx:mainline
  # using container_name means there will only ever be one nginx container!
  container_name: nginx
  restart: always
  networks:
    - proxynet
  volumes:
    - /etc/nginx/conf.d
    - /etc/nginx/vhost.d
    - /usr/share/nginx/html
    - tlsdata:/etc/nginx/certs:ro
    - attachdata:/usr/share/nginx/html/uploads:ro
    - staticdata:/usr/share/nginx/html/static:ro
    - ./nginx/healthcheck.sh:/bin/healthcheck.sh
  healthcheck:
    test: ['CMD', '/bin/healthcheck.sh']
    interval: 1m
    timeout: 5s
    retries: 3
  ports:
    # Make the http/https ports available on the Docker host IPv4 loopback interface
    - '127.0.0.1:80:80'
    - '127.0.0.1:443:443'

我作为卷加载的healthcheck.sh

代码语言:javascript
复制
#!/bin/bash

service nginx status || exit 1

看起来这个问题只是一个问题,当容器最初启动时,systemd永远不会从状态检查返回,同时配置的健康检查超时不会触发。其他功能都正常,nginx已经启动和响应,但是健康检查能够正常运行,而无需每次启动时都需要手动重新启动。

我的配置中是否缺少了什么,或者更好地检查我是否可以运行?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2019-07-27 20:57:55

一年多后,我找到了解决办法。首先,对环境、我认为正在发生的事情以及对Docker引擎可能出现的bug的猜测进行了进一步的澄清。

我现在使用的撰写文件是启动一个经过轻微修改的“官方”Alpine映像版本,该版本使用COPY加载健康检查脚本,并在映像中显式地添加HEALTHCHECK。此映像用于nginx服务,并与运行奇装异彩的映像一起使用来自Docker的容器元数据生成NGINX配置文件。这个容器作为一个名为nginx-gen的服务运行。当容器更改时,重新生成配置,如果有任何更改,则将SIGHUP发送到nginx服务。

我发现如下:

  • 如果所有服务一起启动,nginx服务就不会运行健康检查;
  • 如果nginx服务在启动后立即重新启动,健康检查将正常完成;
  • 如果nginx服务自行启动,健康检查将正常完成;
  • 如果nginx-gen以外的所有服务一起启动,健康检查将正常完成;
  • 如果所有的服务都一起启动,但是在做任何事情之前,nginx-gen被修改为sleep 60,那么健康检查就会正常完成;

因此,似乎与信号处理、Docker和NGINX之间存在着一些模糊的交互作用。如果在容器中运行第一次健康检查之前,SIGHUP被发送到容器中的NGINX进程,则不会运行任何健康检查。

我最后提出的迭代修改了nginx-gen容器,以轮询nginx容器的健康状况。它使用简短的sleep查找循环中具有定义标签的容器的健康状态。一旦nginx容器报告正常,nginx-gen就开始生成配置文件。我还将通知方法更改为docker exec脚本,以显式测试和重新加载nginx容器中的配置,而不是依赖于SIGHUP

最终结果:我可以docker-compose up -d,而且所有的东西最终都报告了healthy,而没有进一步的干预。成功!

票数 4
EN

Stack Overflow用户

发布于 2019-01-07 15:05:11

在这种情况下,我认为没有必要使用自定义脚本。

试着改变你的健康检查测试

代码语言:javascript
复制
test: ["CMD", "service", "nginx", "status"]

对我来说挺好的。

尝试使用"而不是',以防万一:)

编辑

如果您真的想强制使用exit 1,如果发生故障,可以使用:

代码语言:javascript
复制
test: service nginx status || exit 1
票数 16
EN

Stack Overflow用户

发布于 2020-06-03 16:43:55

对于正式的高寒nginx图像,您也可以这样做:

代码语言:javascript
复制
healthcheck:
      test: ["CMD-SHELL", "wget -O /dev/null http://localhost || exit 1"]
      timeout: 10s

wget是标准图像的一部分。这样做是将index.html/php/任何东西下载到任何地方(/dev/null),否则就会超时和失败。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48776044

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档