上周三 15:40,运维小周在企业微信里说测试环境更新后 web 容器起不来。宿主机 Ubuntu 22.04,Docker 24.0.7,compose v2.21.0。
$ docker compose ps
NAME IMAGE COMMAND SERVICE STATUS
proj-api-1 proj-api "/app/api" api Up 2 minutes (unhealthy)
proj-web-1 proj-web "/app/web" web Restarting (1) 4 seconds ago
看 web 日志。
$ docker compose logs --tail=6 web
proj-web-1 | 2024-11-13T15:41:02Z INF listening on :8080
proj-web-1 | Error: listen tcp4 0.0.0.0:8080: bind: address already in use
8080 被占了。宿主机上跑着一个 nginx,看了一眼它。
$ ss -lntp | grep :8080
LISTEN 0 4096 0.0.0.0:8080 0.0.0.0:* users:(("docker-proxy",pid=21734,fd=4))
LISTEN 0 4096 [::]:8080 [::]:* users:(("docker-proxy",pid=21734,fd=4))
pid 21734 是另一个项目的容器,compose 文件里写了 8080:8080。把 proj-web 的端口映射改成 8088:8080,up -d 之后 web 进了 Up。
api 还是 unhealthy。compose 里它的 healthcheck 写着:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 10s
retries: 3
inspect 看失败日志。
$ docker inspect --format '{{json .State.Health}}' proj-api-1
{"Status":"unhealthy","FailingStreak":3,"Log":[{"ExitCode":127,"Output":"OCI runtime exec failed: exec failed: unable to start container process: exec: \"curl\": executable file not found in $PATH: unknown\n"}]}
ExitCode 127,镜像里没有 curl。基础镜像从 debian 换到 alpine 之后包没跟着改,healthcheck 每次执行都失败,FailingStreak 攒到 3 就判 unhealthy。
想改 wget。busybox 的 wget 和 GNU 的参数不完全一样,`-q -O -` 能跑,但服务对 3xx 的处理不返回非零,healthcheck 还是判过,不行。往镜像里补 curl 要改 Dockerfile 重建,apk add 之后一次构建 3 分 40 秒,这个 api 镜像是 1.2G,重建成本不值当。
程序本身带子命令。把 test 改成:
test: ["CMD", "/app/api", "healthcheck"]
up -d api 重跑,状态变 healthy。
$ docker compose ps
NAME IMAGE COMMAND SERVICE STATUS
proj-api-1 proj-api "/app/api" api Up 32 seconds (healthy)
proj-web-1 proj-web "/app/web" web Up 3 minutes
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

评论(0)