ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Dozzle Agent 模式实战:用 TLS 加密的 gRPC 通道把多台 Docker 主机接入统一日志面板

Dozzle Agent 模式实战:用 TLS 加密的 gRPC 通道把多台 Docker 主机接入统一日志面板 Dozzle Agent 模式实战用 TLS 加密的 gRPC 通道把多台 Docker 主机接入统一日志面板【免费下载链接】dozzleRealtime log viewer for containers. Supports Docker, Swarm and K8s.项目地址: https://gitcode.com/GitHub_Trending/do/dozzleDozzle 支持以 Agent 模式运行将某个 Docker 主机上的容器日志、事件与指标暴露给其他 Dozzle 实例所有通信都走带双向 TLS 认证的私有 gRPC 通道。读完本文你将掌握如何部署 Agent、通过DOZZLE_REMOTE_AGENT连接单个或多个 Agent、用endpoint|name|group连接串做主机分组以及配置 Healthcheck、容器过滤与自定义证书等进阶选项并能定位“Agent 不出现/重复主机 ID”这类常见问题。适用前提Agent 模式仅适用于 Docker 环境。如果你使用 Docker Swarm则不需要 Agent——Dozzle 在 Swarm 模式下会自动发现节点并组建成集群见 Swarm 模式文档。从源码看Swarm 模式启动时同样会在:7007上拉起一个 agent gRPC 服务供 Swarm 内节点互联见 main.go。1. 什么是 Agent 模式Agent 模式的核心思路是在远端主机上再跑一个 Dozzle 容器但它不启动 Web 界面只启动一个 gRPC 服务端监听默认端口7007。本地Hub 端的 Dozzle 实例通过--remote-agent参数连接到它Hub 的 UI 里就会多出一个对应的主机节点展示该主机上的全部容器。从源码结构看这条链路由 internal/agent/server.goAgent 端服务端与 internal/agent/client.goHub 端客户端实现接口定义来自 protos/rpc.proto生成的 protobuf/gRPC 代码位于 internal/agent/pb/。Agent 服务对外暴露的能力覆盖容器列表与查询ListContainers/FindContainer、实时日志流StreamLogs、按时间区间取日志LogsBetweenDates、原始字节流StreamRawBytes、事件流StreamEvents、统计流StreamStats、主机信息HostInfo、容器启停删ContainerAction、镜像更新UpdateContainer/CheckImageUpdate以及终端 attach/exec 等参见 internal/agent/server.go。一个重要的安全约束不要把 Socket Proxy 叠加在 Agent 之上。使用远端 Agent 时不能再在前面套一层 Docker socket proxyDozzle Agent 本身就是对 proxy 的替代如果你想用的还是 socket proxy 方案请参考 Remote Hosts 文档。2. 创建一个 Agent创建 Agent 的方式是在启动 Dozzle 时附加agent子命令该子命令在 internal/support/cli/args.go 中声明。最小示例如下docker run -v /var/run/docker.sock:/var/run/docker.sock -p 7007:7007 amir20/dozzle:latest agent或 docker-compose 写法# docker-compose.yml services: dozzle-agent: image: amir20/dozzle:latest command: agent volumes: - /var/run/docker.sock:/var/run/docker.sock:ro ports: - 7007:7007要点说明Agent 需要挂载本机的docker.sock才能读取容器信息示例中使用只读挂载:ro是推荐做法启动后 Agent 监听7007端口它只会暴露自己所处主机上可见的容器如果 Agent 与 Hub 处于同一个 Docker 网络中无需向宿主机映射7007网络内的其他容器可以直接通过服务名/网络内 IP 访问它。仓库提供了可直接参考的 compose 示例 examples/docker.agents.yml其内容就是在 Swarm 中以deploy.mode: global部署 Agent并开启DOZZLE_LEVELdebug便于排查。另外examples/setup-remote-agent.sh 是一个一键脚本用于在远端主机上完成“创建网络、准备证书、部署 Agent”的整套准备流程适合作为批量部署远端 Agent 的操作模板。3. 连接 AgentHub 端通过--remote-agent参数或环境变量DOZZLE_REMOTE_AGENT声明要连接的 Agent 地址。两者等价参数在 internal/support/cli/args.go 中同时注册为 flag 与环境变量支持“separate”多值写法解析时还会对每个值做TrimSpace处理args.go。docker run -p 8080:8080 amir20/dozzle:latest --remote-agent agent:7007# docker-compose.yml services: dozzle: image: amir20/dozzle:latest environment: - DOZZLE_REMOTE_AGENTagent:7007 ports: - 8080:8080 # Dozzle UI 端口几个实用细节无需挂载本地 docker.sock。只连 Agent 时Hub 的 UI 只会显示各 Agent 上可用的容器如果同时想看本机容器再按 Getting Started 中的方式挂载docker.sock即可本机与远端 Agent 会并列显示连接多个 Agent通过逗号分隔写在同一个变量里或提供多个值例如DOZZLE_REMOTE_AGENTagent1:7007,agent2:7007。在传输层Agent 客户端的初始化internal/agent/client.go体现了几个工程细节使用 TLS 传输凭证并将自身证书同时作为 CA 加入RootCAs因为自签证书需要双向信任默认启用 gzip 压缩grpc.UseCompressor(gzip.Name)并允许最大 10MB 的接收消息grpc.MaxCallRecvMsgSize(10*1024*1024)以适配大日志消息客户端 keepalive 参数为Time: 30s / Timeout: 10s服务端 keepalive 强制策略MinTime: 15sserver.go用于及时发现并断开僵死连接这正是 Agent 模式“断线自动重连”能力的底层保障之一。4. 主机分组Host Groups当 Agent 数量较多、跨多套环境时可以把每个 Agent 指派到一个命名分组。分组在侧边栏中显示为可折叠的区块每个分组都有一个“合并全部”按钮用于查看该组内所有主机日志合并后的视图合并视图也可以直接通过路由/host-group/group-name访问对应前端页面 assets/pages/host-group/。连接串的格式为endpoint|name|group三个部分均为可选格式效果agent:7007不覆盖名称、不分组agent:7007\|web-1覆盖名称、不分组agent:7007\|web-1\|Production覆盖名称 分组agent:7007\|\|Production保留默认主机名 分组解析逻辑就在 internal/agent/client.go 的ParseEndpoint函数中按|切分最多三段地址段必填且不能为空否则报错invalid agent endpoint。名称覆盖nameOverride在 client.go 的 Host() 方法 中生效——当 Agent 提供了主机名但连接串指定了名称覆盖时UI 上显示的是覆盖名分组字段则原样写入container.Host.Group供侧边栏渲染分组。多 Agent 分组的完整示例docker run -p 8080:8080 amir20/dozzle:latest \ --remote-agent agent1:7007|web-1|Production \ --remote-agent agent2:7007|web-2|Production \ --remote-agent agent3:7007|dev-1|Development# docker-compose.yml services: dozzle: image: amir20/dozzle:latest environment: - DOZZLE_REMOTE_AGENTagent1:7007|web-1|Production,agent2:7007|web-2|Production,agent3:7007|dev-1|Development ports: - 8080:8080此时侧边栏呈现为▾ Production web-1 web-2 ▾ Development dev-1 ungrouped-host ← 未分组的 Agent 显示在分组区块下方未分组的 Agent 行为与以往完全一致会显示在分组区块之后因此该功能是向后兼容的。5. 进阶选项5.1 为 Agent 配置 Healthcheck与主实例一样Agent 也可以配置容器 healthcheck。区别在于Agent 模式下的 healthcheck 检查的是Agent 与 Docker 引擎之间的连通性——如果 Docker 不可达Agent 会被标记为不健康从而不再出现在 Hub 的 UI 中。实现上healthcheck子命令在 Agent 模式走 gRPC 探测internal/healthcheck/rpc.go 中的RPCRequest会用当前证书创建一个 agent 客户端并调用ListContainers只要该调用成功即视为健康对比之下普通 server 模式走的是 HTTP 探测见 internal/healthcheck/http.go。示例配置services: dozzle-agent: image: amir20/dozzle:latest command: agent healthcheck: test: [CMD, /dozzle, healthcheck] interval: 5s retries: 5 start_period: 5s start_interval: 5s volumes: - /var/run/docker.sock:/var/run/docker.sock:ro ports: - 7007:70075.2 修改 Agent 显示名称与 Dozzle 主实例相同Agent 的名称可以通过环境变量DOZZLE_HOSTNAME或命令行--hostname修改定义见 internal/support/cli/args.godocker run -v /var/run/docker.sock:/var/run/docker.sock -p 7007:7007 amir20/dozzle:latest agent --hostname my-special-name# docker-compose.yml services: dozzle-agent: image: amir20/dozzle:latest command: agent environment: - DOZZLE_HOSTNAMEmy-special-name volumes: - /var/run/docker.sock:/var/run/docker.sock:ro ports: - 7007:7007设置后 Agent 在 Hub 界面中显示为my-special-name。注意它与连接串中的name覆盖第 4 节是两层机制Agent 侧DOZZLE_HOSTNAME决定主机上报的默认名Hub 侧连接串的|name段可以在消费端再次覆盖。5.3 为 Agent 配置过滤Filters你可以给 Agent 配置过滤器来限制它可访问的容器。这些过滤条件会直接透传给 Docker API限制 Dozzle 能看到的内容services: dozzle-agent: image: amir20/dozzle:latest command: agent environment: - DOZZLE_FILTERlabelcolor volumes: - /var/run/docker.sock:/var/run/docker.sock:ro这样 Agent 只会展示带colorlabel 的容器。需要留意的是Agent 侧的过滤器会与 UI 侧的过滤器叠加生效进一步收窄范围各类过滤语法的完整说明见 Filters 文档。参数层面DOZZLE_FILTER--filter以keyvalue形式解析为 label 过滤映射args.go随后作为container.ContainerLabels传入容器客户端例如 gRPC 端的ListContainers/FindContainer请求都会携带该 label 过滤条件server.go。5.4 使用自定义证书mTLS默认情况下Dozzle 使用自签名证书进行 Agent 间通信。这是一个仅在 Dozzle 实例之间有效的私有证书安全且适用于大多数场景。但风险在于如果 Agent 端口对外暴露且攻击者恰好知道该端口他也可以搭一个 Dozzle 实例连接到你的 Agent。要杜绝这一点可以提供自己的证书。从源码看这不是普通的 TLS而是双向认证mTLS服务端在 internal/agent/server.go 的NewServer中显式设置ClientAuth: tls.RequireAndVerifyClientCert即每个连接方Hub 实例必须出示与 Agent 服务端相同的证书/密钥对才能握手成功。这也是为什么自定义证书必须同时提供给 Agent 和与之连接的 Hub 实例。证书默认查找路径为/dozzle_cert.pem与/dozzle_key.pem可通过--cert/--key参数或DOZZLE_CERT/DOZZLE_KEY环境变量调整args.go。以下按三种提供方式给出完整示例。方式一Docker Secrets 注入到默认路径推荐与 examples/docker.agents-with-certs.yml 一致services: agent: image: amir20/dozzle:latest command: agent volumes: - /var/run/docker.sock:/var/run/docker.sock secrets: - source: cert target: /dozzle_cert.pem - source: key target: /dozzle_key.pem ports: - 7007:7007 secrets: cert: file: ./cert.pem key: file: ./key.pem方式二环境变量指定自定义路径services: agent: image: amir20/dozzle:latest command: agent environment: - DOZZLE_CERT/certs/my-cert.pem - DOZZLE_KEY/certs/my-key.pem volumes: - /var/run/docker.sock:/var/run/docker.sock - ./certs:/certs ports: - 7007:7007方式三命令行参数docker run -v /var/run/docker.sock:/var/run/docker.sock -v ./certs:/certs -p 7007:7007 \ amir20/dozzle:latest agent --cert /certs/my-cert.pem --key /certs/my-key.pem证书可以用如下命令生成Ed25519 自签证书有效期 365 天$ openssl genpkey -algorithm Ed25519 -out key.pem $ openssl req -new -key key.pem -out request.csr -subj /CUS/STCalifornia/LSan Francisco/OMy Company $ openssl x509 -req -in request.csr -signkey key.pem -out cert.pem -days 365生成后把同一份cert.pem/key.pem同时挂载给 Agent 与 Hub 两侧即可。另外CLI 还提供agent-test子命令args.go用于在部署前测试一个 Agent 是否可连通可用于验证证书与网络配置是否正确。6. 常见问题排查Agent 不出现 / 重复主机 ID如果在日志中看到类似提示An agent with an existing ID was found. Removing the duplicate host.说明存在两个使用了相同主机 IDServer ID的主机。Dozzle 依赖 Docker API 收集主机信息每个 Agent 必须拥有一个跨重启保持稳定且全局唯一的 Host ID才能被正确识别。当前 Agent 的主机识别优先级为Swarm 环境优先使用 Swarm Node ID每个 Swarm 节点都以它被其他节点引用天然稳定普通 Docker使用 Docker 写入/var/lib/docker/engine-id的 System ID。这一优先级在 internal/container/host_id.go 的DerivedHostID.Resolve中可以得到印证解析顺序是SwarmNodeID优先Podman 场景下退化为由主机名与存储根路径派生的 UUIDv5最后才是EngineID。当两台机器由于克隆镜像、迁移等原因共享了相同的engine-id时Hub 端的可重试客户端管理器就会把后注册的一个当作重复主机剔除。修复办法在冲突的主机上删除/var/lib/docker/engine-id文件并重启 Docker或重启 Agent 容器让引擎重新生成一个新的 ID重复即可消除。更完整的排查思路见 FAQ 中的 “duplicate hosts” 一节。此外如果派生 ID 确实发生冲突且无法通过重建 engine-id 解决还可以用--host-id/DOZZLE_HOST_ID参数args.go手动指定一个静态 Host ID 作为最终手段。7. Agent 与 Remote Connection 的选型对比Agent 与远端直连Remote Connection解决的是同一类问题但 Agent 在性能与安全上通常更优。官方文档给出的对比如下特性Agent远端连接Remote Connection性能分布式负载更好UI 端体验较差安全性私有 SSLmTLS不安全或依赖 Docker TLS易用性开箱即用需要暴露 Docker Socket权限对 Docker 完全访问可通过 Proxy 精细控制重连自动重连需要重启 UIHealthcheck内置无过滤器支持不支持可以推断Agent 模式“自动重连”的表现来自 4 节提到的 gRPC keepalive 机制与 Hub 端可重试客户端管理器RetriableClientManager见 internal/support/docker/retriable_client_manager.go而远端连接一旦断开往往需要重启界面进程才能恢复。如果你出于特殊原因仍选择远端连接方案请务必用 Docker TLS 或反向代理保护连接不要把 Docker Socket 裸奔暴露到网络中。综合来看多主机场景优先使用 Agent它用 mTLS 私有通道替代了暴露 Docker Socket 的做法同时天然获得过滤、健康检查与自动重连能力。参考路径本文档对应仓库内 docs/guide/agent.md英文原文Agent 服务端/客户端实现internal/agent/server.go、internal/agent/client.gogRPC 接口定义protos/rpc.proto、生成代码 internal/agent/pb/CLI 参数定义internal/support/cli/args.goHealthcheck 实现internal/healthcheck/rpc.go、internal/healthcheck/http.go主机 ID 解析internal/container/host_id.go部署示例examples/docker.agents.yml、examples/docker.agents-with-certs.yml、examples/setup-remote-agent.sh相关文档Remote Hosts、Swarm Mode、Filters、FAQ【免费下载链接】dozzleRealtime log viewer for containers. Supports Docker, Swarm and K8s.项目地址: https://gitcode.com/GitHub_Trending/do/dozzle创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表