简体   繁体   English

Docker 容器健康检查停止不健康的容器

[英]Docker container healthcheck stop unhealthy container

I have a docker container that has a healthcheck running every 1 min.我有一个 docker 容器,每 1 分钟运行一次健康检查。 I read that appending "|| kill 1" to the healthcheck in dockerfile can stop the container after healthcheck fails, but it does not seem to be working for me and I cannot find an example that works.我读到在 dockerfile 中将“|| kill 1”附加到 healthcheck 可以在 healthcheck 失败后停止容器,但它似乎对我不起作用,我找不到一个有效的例子。

Does anybody know how I can stop the container after marked as unhealthy?有人知道标记为不健康后如何停止容器吗? I currently have this in my dockerfile:我目前在我的 dockerfile 中有这个:

HEALTHCHECK --start-period=30s --timeout=5s --interval=1m --retries=2 CMD bash /expressvpn/healthcheck.sh || kill 1

EDIT 1编辑 1
Dockerfile Dockerfile

FROM debian:buster-slim

ENV CODE="code"
ENV SERVER="smart"

ARG VERSION="expressvpn_2.6.0.32-1_armhf.deb"

COPY files/ /expressvpn/

 RUN apt-get update && apt-get install -y --no-install-recommends \
expect curl ca-certificates iproute2 wget jq \
&& wget -q https://download.expressvpn.xyz/clients/linux/${VERSION} -O /expressvpn/${VERSION} \
&& dpkg -i /expressvpn/${VERSION} \
&& rm -rf /expressvpn/*.deb \
&& rm -rf /var/lib/apt/lists/* \
&& apt-get purge --autoremove -y wget \
&& rm -rf /var/log/*.log

HEALTHCHECK --start-period=30s --timeout=5s --interval=1m --retries=2 CMD bash /expressvpn/healthcheck.sh || exit 1

ENTRYPOINT ["/bin/bash", "/expressvpn/start.sh"]

healthcheck.sh健康检查.sh

if [[ ! -z $DDNS ]];
then
    checkIP=$(getent hosts $DDNS | awk '{ print $1 }')
else
    checkIP=$IP
fi

if [[ ! -z $checkIP ]];
then
    ipinfo=$(curl -s -H "Authorization: Bearer $BEARER" 'ipinfo.io' | jq -r '.')
    currentIP=$(jq -r '.ip' <<< "$ipinfo")
    hostname=$(jq -r '.hostname' <<< "$ipinfo")
    if [[ $checkIP = $currentIP ]];
    then
        if [[ ! -z $HEALTHCHECK ]];
        then
            curl https://hc-ping.com/$HEALTHCHECK/fail
            expressvpn disconnect
            expressvpn connect $SERVER
            exit 1
        else
            expressvpn disconnect
            expressvpn connect $SERVER
            exit 1
       fi
    else
        if [[ ! -z $HOSTNAME_PART && ! -z $hostname && $hostname != *"$HOSTNAME_PART"* ]];
        then
            #THIS IS WHERE THE CONTAINER SHOULD STOP <------------
            kill 1
        fi

        if [[ ! -z $HEALTHCHECK ]];
        then
            curl https://hc-ping.com/$HEALTHCHECK
            exit 0
        else
            exit 0
        fi
    fi
else
    exit 0
fi

start.sh开始.sh

#!/usr/bin/bash
cp /etc/resolv.conf /etc/resolv.conf.bak
umount /etc/resolv.conf
cp /etc/resolv.conf.bak /etc/resolv.conf
rm /etc/resolv.conf.bak
service expressvpn restart
expect /expressvpn/activate.sh
expressvpn connect $SERVER

touch /var/log/temp.log
tail -f /var/log/temp.log

exec "$@"

Try Changing from kill to exit 1尝试从kill更改为exit 1

HEALTHCHECK --start-period=30s --timeout=5s --interval=1m --retries=2 \
CMD bash /expressvpn/healthcheck.sh || exit 1

Reference from docker docs 参考自 docker 文档

Edit 1:编辑 1:

After some testing if you want to kill the container on unhealthy status you need to do it in the health check script /expressvpn/healthcheck.sh or by script on the host.经过一些测试,如果你想在unhealthy状态下杀死容器,你需要在健康检查脚本/expressvpn/healthcheck.sh或主机上的脚本中进行。

The following example the container status is healthy:以下示例容器状态为健康:

HEALTHCHECK --start-period=30s --timeout=5s --interval=10s --retries=2 CMD bash -c 'echo "0" || kill 1' || exit 1

The following example the container stops since the command ech not exit then the kill 1 is executed and the container got killed:以下示例容器停止,因为命令ech not exit 然后kill 1被执行并且容器被杀死:

HEALTHCHECK --start-period=30s --timeout=5s --interval=10s --retries=2 CMD bash -c 'ech "0" || kill 1' || exit 1

Edit 2:编辑 2:

Well after a bit of digging i understood something that i saw in some dockerfiles:好吧,经过一番挖掘,我明白了一些我在一些 dockerfiles 中看到的东西:

RUN apt update -y && apt install tini -y

ENTRYPOINT ["tini", "--"]
CMD ["./echo.sh"]

From what i got docker keeps the pid 1 = entrypoint process from getting killed by SIGTERM so for this you have tini small util that helps with this (still not sure what exactly the purpose of this i will keep it for next time i will be in the mood..).从我得到的 docker 可以防止pid 1 = entrypoint进程被SIGTERM杀死所以为此你有 tini 小实用程序可以帮助解决这个问题(仍然不确定我将保留它的确切目的是为了下次我会在情绪..)。
Anyway after adding tini the container got killed with kill 1无论如何,在添加 tini 之后,容器被kill 1

Thank you for the question.感谢你的提问。

please check the output of your health check.请查看健康检查的output。 You'll have to ensure that your healthcheck actually fails 2 consecutive times.您必须确保您的健康检查实际上连续失败了 2 次。

 docker inspect --format "{{json.State.Health }}" <container name> | jq

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM