我有一个使用HealthCheck的Nginx Dockerimage,这样:
HEALTHCHECK --interval=3s --timeout=1s \
CMD nc -vz -w1 127.0.0.1 8080 || exit 1
出于安全原因,我也想删除shell,但是HealthCheck在此之后停止工作。我试图完全删除BusyBox (alpine-basilayout),单独删除/bin/sh的符号链接,用微小的等。
如何正确执行此操作,以免破坏容器中的应用程序并保存健康检查?
分析解答
CMD
指令有两种形式。当您写这篇文章时:
CMD nc -vz -w1 127.0.0.1 8080 || exit 1
它被翻译成sh -c 'nc -vz -w1 127.0.0.1 8080 || exit 1
。您可以通过使用"exec"形式CMD
指令避免执行该shell执行,例如:
CMD ["nc", "-vz", "-w1", "127.0.0.1", "8080"]
这将直接执行nc
,而无需涉及shell。请注意,您现有的HealthCheck使用shell语法(|| exit 1
)部分明确进行了;如果您不使用shell,那将不起作用。
例如,使用此Dockerfile建造的容器永远不会健康:
FROM alpine
RUN apk add darkhttpd curl
RUN rm -f /bin/sh
ENTRYPOINT ["darkhttpd"]
CMD ["/var/www/localhost/htdocs", "--port", "8080"]
HEALTHCHECK --interval=3s --timeout=1s \
CMD nc -vz -w1 127.0.0.1 8080
但是,这是根据需要起作用的:
FROM alpine
RUN apk add darkhttpd curl
RUN rm -f /bin/sh
ENTRYPOINT ["darkhttpd"]
CMD ["/var/www/localhost/htdocs", "--port", "8080"]
HEALTHCHECK --interval=3s --timeout=1s \
CMD ["nc", "-vz", "-w1", "127.0.0.1", "8080"]