ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

Dozzle 内置健康检查:`dozzle healthcheck` 子命令的启用、原理与退出码详解

Dozzle 内置健康检查:`dozzle healthcheck` 子命令的启用、原理与退出码详解 Dozzle 内置健康检查dozzle healthcheck子命令的启用、原理与退出码详解【免费下载链接】dozzleRealtime log viewer for containers. Supports Docker, Swarm and K8s.项目地址: https://gitcode.com/GitHub_Trending/do/dozzleDozzle 自带dozzle healthcheck子命令用于为容器日志查看器本身提供 Docker 原生健康检查能力。本文以官方 Healthcheck 指南 为主线结合仓库源码internal/support/cli/health_command.go、internal/web/healthcheck.go等讲解如何在 docker-compose 中启用、服务端与 Agent 两种模式各自检查什么、退出码含义以及--addr/--base自定义端口与路径的处理逻辑。读完本文你可以直接为自己的 Dozzle 部署配置一套可落地的健康检查并理解其底层实现原理。为什么要为 Dozzle 启用健康检查Dozzle 是运行在 Docker、Swarm、K8s 等容器环境中的实时日志查看器。当容器编排平台如 Swarm 的deploy.healthcheck、K8s 的 livenessProbe、或第三方监控工具需要判断 Dozzle 是否存活时就需要一个可靠的探活手段。Dozzle 在镜像中内置了dozzle healthcheck子命令。值得注意的是该命令默认并未写入镜像——原因在官方文档中明确说明它会给容器增加少量 CPU 开销docs/guide/healthcheck.md原文It is not wired into the image by default because it adds a small amount of CPU overhead。因此需要用户在 compose 文件中显式启用。从源码看/dozzle正是二进制入口。Dockerfile 中ENTRYPOINT [/dozzle]Dockerfile而 CLI 子命令在 internal/support/cli/args.go 中注册Healthcheck *HealthcheckCmd arg:subcommand:healthcheck help:checks if the server is running即容器启动参数/dozzle healthcheck会解析到HealthcheckCmd并执行健康检查逻辑。在 docker-compose 中启用 healthcheck官方文档给出的完整 compose 配置如下原样继承可直接复制使用services: dozzle: image: amir20/dozzle:latest volumes: - /var/run/docker.sock:/var/run/docker.sock ports: - 8080:8080 healthcheck: test: [CMD, /dozzle, healthcheck] interval: 3s timeout: 30s retries: 5 start_period: 30s各字段含义Docker Compose 标准语义字段值说明test[CMD, /dozzle, healthcheck]在容器内执行/dozzle healthcheck命令以其退出码判定健康状态interval3s两次健康检查之间的间隔timeout30s单次检查允许的最大执行时间超时视为失败retries5连续失败达到该次数后标记容器为 unhealthystart_period30s容器启动后的宽限期期间失败不计入 retries便于 Dozzle 完成启动提示若你的 Dozzle 通过环境变量自定义了监听地址或基础路径见下文--addr/--base此 healthcheck 仍无需额外配置即可正常工作。服务端模式下检查什么/healthcheck端点当以服务端模式运行时即常规的 Dozzle 主进程未配置 agentdozzle healthcheck会向自身发送一个 HTTPGET请求到/healthcheck端点。该端点路由在 internal/web/routes.go 中注册r.Get(/healthcheck, h.healthcheck)端点实现位于 internal/web/healthcheck.go其判定逻辑与官方文档描述完全一致获取所有本地Docker 客户端h.hostService.LocalClients()若本地客户端为空len(clients) 0只要存在已知的远程 agent 主机len(h.hostService.Hosts()) 0返回200 OK否则返回500 Internal Server Error若存在本地客户端则并发对每个客户端执行client.Ping(ctx)每个客户端的 ping 超时上限为 3 秒context.WithTimeout(r.Context(), 3*time.Second)只要至少一个本地客户端 ping 成功就返回200 OK全部失败则返回500。对应官方文档的结论可以严格对上200 OK—— 至少一个本地 Docker 客户端正常响应或本地客户端为空但已知至少一个远程 agent 主机500 Internal Server Error—— 所有本地客户端均失败且没有任何已知的 agent 主机。从实现细节看这个端点有两点值得注意并发探活多个本地客户端通过sync.WaitGroupatomic.Bool并行 ping而不是串行等待因此多 Docker 客户端场景下总耗时不会线性累加宽容策略只要有一个客户端存活即判定健康避免单客户端抖动导致整个 Dozzle 被标记为 unhealthy。远程 Agent 被有意排除在服务端检查之外官方文档特别强调远程 agent故意不参与服务端的健康检查——一个不可达的 agent 不应让主 Dozzle 进程被判为不健康。这与上面第 2 步的逻辑互为印证即使配置了 agent 主机服务端也不向它们发起任何 ping仅在本机无 Docker 客户端时把它们作为降级通过的依据。每个 agent 可以暴露自己的健康检查参见 Agent 健康检查配置。Agent 模式RPC 健康检查除了服务端模式dozzle healthcheck还会自动识别当前进程是否是 agent并切换检查方式。入口实现位于 internal/support/cli/health_command.goconst agentAddrFile /tmp/dozzle-agent.addr if data, err : os.ReadFile(agentAddrFile); err nil { // 读到 agent 地址文件 → 走 RPC 检查 ... return healthcheck.RPCRequest(ctx, agentAddress, certs) } else { // 否则 → 走 HTTP 检查 return healthcheck.HttpRequest(args.Addr, args.Base) }逻辑为若容器内存在 agent 地址文件/tmp/dozzle-agent.addr则说明当前进程运行在 agent 模式此时会对该地址发起 gRPC 请求否则执行服务端 HTTP 检查。地址规范化方面若 agent 地址的主机部分为空、::或0.0.0.0会被替换为127.0.0.1以确保从本机可达。RPC 检查实现在 internal/healthcheck/rpc.go通过agent.NewClient(addr, certs)建立客户端然后调用client.ListContainers(ctx, ...)验证 agent 是否正常响应。注意它需要 TLS 证书ReadCertificates(embeddedCerts, args.CertPath, args.KeyPath)并受 CLI 的--timeout环境变量DOZZLE_TIMEOUT默认10s见 internal/support/cli/args.go约束。退出码与输出dozzle healthcheck的退出码规则官方文档0—— 健康对应 HTTP 200非零 —— 不健康包括网络错误或非 200 响应。HTTP 请求的底层实现在 internal/healthcheck/http.gofunc HttpRequest(addr string, base string) error { if strings.HasPrefix(addr, :) { addr localhost addr } if base / { base } url : fmt.Sprintf(%s%s/healthcheck, addr, base) if !strings.HasPrefix(url, http) { url http:// url } log.Info().Str(url, url).Msg(performing healthcheck) resp, err : http.Get(url) if err ! nil { return err } defer resp.Body.Close() if resp.StatusCode 200 { return nil } return fmt.Errorf(healthcheck failed with status code %d, resp.StatusCode) }请求失败连接错误等直接返回err进程以非零退出响应非 200 时错误信息中包含失败的状态码并通过 zerolog 写入 stdout与文档中失败 URL 和状态写入 stdout的描述对应成功200返回nil进程以 0 退出。该行为有对应的单元测试覆盖internal/healthcheck/http_test.go 构造了始终返回 200 和始终返回 500 的两个测试服务器分别断言HttpRequest返回nil和错误验证了200 视为健康、500 视为失败的判定。兼容--addr与--base自定义端口和基础路径官方文档明确该命令遵守--addr和--base因此在自定义端口或基础路径下无需额外配置。源码印证了这一点HttpRequest接收的args.Addr、args.Base直接参与 URL 构造当addr以:开头如默认值:8080时自动补全为localhost:8080当base为/默认值时按空串处理避免产生//healthcheck之类的畸形路径若 URL 不以http开头自动补http://前缀。对应参数定义见 internal/support/cli/args.goAddr string arg:env:DOZZLE_ADDR default::8080 help:sets host:port to bind for server... Base string arg:env:DOZZLE_BASE default:/ help:sets the base for http router.因此无论是默认的:8080、/还是通过DOZZLE_ADDR/DOZZLE_BASE修改过的监听地址与基础路径例如在反向代理后挂在/dozzle路径下healthcheck 命令都能正确构造出指向自身的健康检查 URL无需在 compose 中额外传参。已知限制不要与--health-cmd一起使用官方文档给出了一条重要警告Warning由于 Docker 自身的一个 bughealthcheck命令无法与--health-cmd标志配合使用。请使用如上所示的docker-compose.yml中的healthcheck块即docker-compose的healthcheck.test指令而不要通过dozzle --health-cmd ...的方式传递。相关细节可参阅 Docker CLI 的 issue docker/cli#3719。换句话说健康检查命令必须通过 compose 的healthcheck块声明如本文第一节的配置而不是通过 Dozzle 的--health-cmd参数注入。小结一条命令、两种模式、三类判定总结dozzle healthcheck的完整行为运行模式检查方式判定依据服务端无/tmp/dozzle-agent.addrHTTP GET 自身/healthcheck至少一个本地 Docker 客户端 ping 成功或本地无客户端但有 agent 主机Agent存在地址文件gRPCListContainers探活agent 能否正常响应容器列表请求失败场景——全部本地客户端失败且无 agent 主机 → HTTP 500 → 进程非零退出启用健康检查的成本只是微量的 CPU 开销换来的却是编排平台对 Dozzle 存活状态的准确感知。按照本文第一节的 compose 配置复制到你的部署文件中即可立即获得这项能力。【免费下载链接】dozzleRealtime log viewer for containers. Supports Docker, Swarm and K8s.项目地址: https://gitcode.com/GitHub_Trending/do/dozzle创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表