十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

Dozzle Agent 模式完全指南:跨主机安全连接 Docker 容器日志与操作

Dozzle Agent 模式完全指南:跨主机安全连接 Docker 容器日志与操作 Dozzle Agent 模式完全指南跨主机安全连接 Docker 容器日志与操作【免费下载链接】dozzleRealtime log viewer for containers. Supports Docker, Swarm and K8s.项目地址: https://gitcode.com/GitHub_Trending/do/dozzle本指南以 docs/fr/guide/agent.md与 docs/guide/agent.md 同源为主体讲解 Dozzle 的 Agent 模式如何将一台 Docker 主机的容器以加密通道暴露给另一台 Dozzle 实例实现远程日志实时查看、终端操作与多主机分组管理。读完本文你将掌握 Agent 的创建、连接、主机分组、健康检查、自定义证书与常见故障排查并理解其基于 gRPC 与 mTLS 的底层通信原理。Agent 模式是什么Dozzle 是一个针对容器的实时日志查看器Realtime log viewer for containers支持 Docker、Swarm 与 Kubernetes。在默认的 server 模式下Dozzle 通过本地 Docker socket 读取当前主机的容器而Agent 模式允许一台 Dozzle 实例作为代理把所在 Docker 主机的容器暴露给其他 Dozzle 实例即中心/hub端。所有通信都经过TLS 加密因此你可以在一台远程主机上部署 Dozzle Agent然后从本机连接的 Dozzle UI 上查看、操作那台主机的容器。从源码结构看Agent 通信建立在gRPC之上protos/cloud.proto与internal/agent/pb定义了AgentService服务契约internal/agent/server.go 实现服务端运行在 Agent 上internal/agent/client.go 实现客户端运行在 hub 上。双向 TLSmTLS确保两端互相验证证书。[!WARNING] 仅适用于 Docker Agent 模式仅支持 DockerBadge 明确标注 Docker uniquement。如果你使用Docker Swarm 模式则无需 Agent——Dozzle 会自动发现自身并基于 Swarm 模式组成集群详见 Swarm 模式。先理解安全边界Agent 只有其网络那样私密这是使用 Agent 前必须建立的认知。Dozzle 镜像内置了一套自签名证书它在每一份镜像拷贝中都是相同的由 internal/support/cli/certs.go 中的shared_cert.pem/shared_key.pem编译进二进制。这意味着它提供加密但不提供身份认证——证书无法证明连接的另一端是谁任何能触达端口7007的人都可以用自己那份相同的证书接上你的 Agent读取该主机上全部日志并在其容器内执行命令Agent不会检查DOZZLE_ENABLE_SHELL或DOZZLE_ENABLE_ACTIONS——这些开关只控制 hub 端 UI 展示什么对 Agent 的接入能力没有约束力。因此官方文档给出两条铁律将端口7007保持在私有网络内这是最基本的安全措施如果 Agent 从网络的其他任何地方可达就必须生成自己的证书让 Agent 只接受你自己的 hub。同样值得注意的是远程 Agent 之上不能再叠加 socket 代理。Dozzle Agent 本身就是替代 socket 代理的方案如果你更想用 socket 代理来控制权限请参考 远程主机 文档。创建 Agent创建 Agent 只需让 Dozzle 以agent子命令启动。官方示例docker run -v /var/run/docker.sock:/var/run/docker.sock -p 7007:7007 amir20/dozzle:latest agent对应的 docker-compose 方式services: dozzle-agent: image: amir20/dozzle:latest command: agent volumes: - /var/run/docker.sock:/var/run/docker.sock:ro ports: - 7007:7007启动后 Agent 监听7007端口。你可以在 Dozzle UI 中通过提供 Agent 的 IP 与端口来连接它Agent 只显示其所在主机上可用的容器。[!TIP] 更安全的部署方式 如果使用 Docker 网络同一网络内的容器互相访问无需暴露端口 7007。同一网络内的其他容器即可访问该 Agent——这是运行 Agent 最安全的方式因为网络之外的任何东西都无法触达它。从源码看Agent 监听地址并非写死agent子命令支持--agent-addr参数环境变量DOZZLE_AGENT_ADDR默认:7007见 internal/support/cli/agent_command.go 中的AgentCmd结构。Agent 启动后会创建本地 Docker 客户端、加载证书并通过agent.NewServer(...)启动 gRPC 服务。连接 Agent连接 Agent 同样简单提供 Agent 的地址与端口即可。docker run -p 8080:8080 amir20/dozzle:latest --remote-agent agent:7007docker-compose 方式services: dozzle: image: amir20/dozzle:latest environment: - DOZZLE_REMOTE_AGENTagent:7007 ports: - 8080:8080 # Dozzle UI 端口注意连接 Agent 时无需挂载本地 Docker socket此时 UI 只显示 Agent 上可用的容器。[!TIP]如果你还希望 UI 同时显示本机容器按快速上手示例挂载docker.sock即可可以通过多条DOZZLE_REMOTE_AGENT连接多个 Agent例如DOZZLE_REMOTE_AGENTagent1:7007,agent2:7007。--remote-agent参数与DOZZLE_REMOTE_AGENT环境变量在 internal/support/cli/args.go 中定义RemoteAgent []stringseparate表示支持逗号分隔多值并在解析时做TrimSpace处理避免两端空格造成解析失败。连接串的三种形态结合 internal/agent/client.go 的ParseEndpoint连接串被|拆分为最多三段address|name|group其中address必填、name与group可选。name覆盖展示名group用于分组解析后分别存入客户端的nameOverride与group字段。主机分组Host Groups当管理的 Agent 散布在不同环境时可以把每个 Agent 分配到命名分组。分组在侧边栏显示为可折叠区块每个分组有一个全部合并按钮用于查看该组所有主机的合并日志。连接串格式为endpoint|name|group三部分均可选格式结果agent:7007无自定义名称、无分组agent:7007\|web-1自定义名称、无分组agent:7007\|web-1\|Production自定义名称 分组agent:7007\|\|Production默认主机名 分组命令行示例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|Developmentdocker-compose 示例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 出现在下方点击分组名旁的合并图标会打开一个组合日志视图实时流式聚合该组所有主机的日志这个合并视图也可直接通过路由/host-group/group-name访问。未分组的 Agent 行为保持不变显示在分组区块之下。name覆盖与group在 internal/agent/client.go 的Host()方法中落地获取远端主机信息后若提供了nameOverride则用它替换显示名Group字段则始终来自连接串解析结果。常见问题Agent 不显示如果你在日志中看到An agent with an existing ID was found. Removing the duplicate host.说明有两个主机使用了相同的 Server ID。原理上Dozzle 通过 Docker API 收集主机信息每个 Agent 需要一个跨重启保持不变的唯一主机 ID用于身份识别。目前 Agent 使用 Docker 的系统 ID 或节点 ID来标识主机在 Swarm 环境中使用节点 ID如果发现并非所有主机都可见很可能是存在配置了相同主机 ID 的重复主机。解决办法删除系统上的/var/lib/docker/engine-id并重启 Docker。这会清除由重复主机 ID 引起的冲突。更多排查建议见 FAQ。高级选项配置健康检查与主 Dozzle 实例一样可以为 Agent 设置 healthcheck。在 Agent 模式下healthcheck 检查的是Agent 与 Docker 的连接如果 Docker 不可达Agent 会被标记为不健康unhealthy并且不再出现在 UI 中。使用healthcheck子命令对应 internal/support/cli/health_command.goservices: 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:7007从源码看healthcheck在 Agent 模式下会读取 Agent 启动时写入的地址文件/tmp/dozzle-agent.addr将其归一化后通过 internal/healthcheck/rpc.go 发起一次 gRPC RPC 请求来探活而在 server 模式下则回退为 HTTP 请求。因此该 healthcheck 在两种模式下均有效。修改 Agent 名称与普通 Dozzle 实例一致通过DOZZLE_HOSTNAME环境变量可修改 Agent 的展示名docker run -v /var/run/docker.sock:/var/run/docker.sock -p 7007:7007 amir20/dozzle:latest agent --hostname my-special-namedocker-compose 方式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 的名称将变为my-special-name在 UI 连接该 Agent 时会反映出来。--hostname与DOZZLE_HOSTNAME同样定义在 internal/support/cli/args.go由 Docker 客户端创建时传入并上报给 hub。配置过滤器Filters可以为 Agent 配置过滤器限制它能访问的容器。这些过滤器直接传递给 Docker从根本上收窄 Dozzle 可见范围services: dozzle-agent: image: amir20/dozzle:latest command: agent environment: - DOZZLE_FILTERlabelcolor volumes: - /var/run/docker.sock:/var/run/docker.sock:ro上面的配置会让 Agent 只显示带color标签的容器。注意这些过滤器会与 UI 层的过滤器叠加进一步缩小容器列表。关于不同过滤器类型的详细说明见过滤器文档。在 internal/support/cli/args.go 中DOZZLE_FILTER支持keyvalue形式也支持--filter旗标重复传递解析后以map[string][]string交给 Docker 客户端在 internal/support/cli/agent_command.go 中过滤器被传入NewDockerClientService(client, args.Filter)作为 Agent 侧容器列举的约束。自定义证书让加密同时变成认证再次强调Dozzle 内置的自签名证书被编译进二进制在所有安装中完全相同任何人都能从公开镜像中提取它。因此它只提供加密、不提供认证——Agent 无法区分你的 hub 与别人的 hub。在默认配置下阻止陌生人进入 Agent 的唯一屏障就是他们无法触达端口7007。[!WARNING] 何时必须使用自己的证书 如果端口7007能被任何你无法控制的对象触达——包括发布在具有公网 IP 的主机上——就必须生成自己的证书对。每一个这样做的部署都会获得一个他人不持有的凭据。用 generate-certs 生成唯一证书对运行generate-certs子命令即可写出唯一证书对实现见 internal/support/cli/generate_certs_command.go默认输出dozzle_cert.pem/dozzle_key.pem可用--force覆盖已存在文件docker run --rm -v $PWD:/out amir20/dozzle:latest generate-certs --cert-out /out/dozzle_cert.pem --key-out /out/dozzle_key.pem将两个文件复制到hub 和每一个 Agent。Dozzle 默认在/dozzle_cert.pem与/dozzle_key.pem查找对应 internal/support/cli/args.go 中CertPath/KeyPath的默认值dozzle_cert.pem/dozzle_key.pem因此把文件挂载到这两个路径即可也可以使用--cert/--key旗标或DOZZLE_CERT/DOZZLE_KEY环境变量放到其他位置。把私钥当作密码对待任何持有它的人都能连上你的 Agent而 Agent 会拒绝任何出示其他证书的 hub。因此 hub 与所有 Agent 必须使用同一对证书并一起重启。使用默认路径挂载推荐 Docker Secretsservices: 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.pemdocker-compose 方式services: agent: image: amir20/dozzle:latest command: agent --cert /certs/my-cert.pem --key /certs/my-key.pem volumes: - /var/run/docker.sock:/var/run/docker.sock - ./certs:/certs ports: - 7007:7007[!TIP] 提供证书时优先使用 Docker Secrets——可通过docker secret create命令创建也可如上面的 compose 示例一样定义。同样的证书必须同时提供给连接 Agent 的 Dozzle 实例。用 openssl 生成替代方案如果更愿意用 openssl 而不是generate-certs$ 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有趣的是Dozzle 的generate-certs实现internal/support/cli/generate_certs_command.go同样基于Ed25519密钥生成的证书自签、有效期 5 年KeyUsage同时包含数字签名与证书签名ExtKeyUsage同时声明 ServerAuth 与 ClientAuth并且IsCAtrue——这是因为两端既要把这份证书作为自己的身份出示又要把它当作 CA 来信任对方。证书与 mTLS 的底层原理为什么双方使用同一份证书就能工作看 internal/agent/server.go 的NewServer服务端把加载的证书放进tls.Certificates同时把同一份证书的解析结果加入ClientCAs证书池并设置ClientAuth: tls.RequireAndVerifyClientCert——即强制要求客户端出示证书并验证。而在 internal/agent/client.go 的NewClient中客户端把同一份证书既作为自己的Certificates又放入RootCAs同时InsecureSkipVerify: true因为证书的 Subject 不匹配主机名。两端各持同一份证书互相都能通过对方的校验——这正是hub 与 Agent 必须使用同一对证书的代码依据。Agent 的 gRPC 通道还有一些值得一提的实现细节同为 internal/agent/client.go默认启用gzip 压缩与 10MB 的接收消息上限grpc.MaxCallRecvMsgSize(10*1024*1024)客户端 keepalive 为 30 秒间隔、10 秒超时服务端强制策略最小 15 秒见 server.go 的grpc.KeepaliveEnforcementPolicy消息类型在protobuf层通过SingleMessage单条文本、GroupMessage多片段与ComplexMessageJSON 对象区分日志级别、流类型与原始消息都会随事件一并传输。Agent 与远程连接Remote Host的对比Agent 与远程连接Remote Host直连远端 Docker API看起来很相似但 Agent 在性能与安全上通常更优。官方对比功能Agent远程连接Remote Connection性能更好负载分布到各端较差集中在 UI 端安全性加密可自带证书不安全或依赖 Docker TLS易用性开箱即用需要暴露 Docker socket权限完全访问 Docker可通过 socket 代理控制重连自动重连需要重启 UI健康检查内置 healthcheck无 healthcheck过滤器支持过滤器不支持过滤器如果你确实打算使用远程连接务必使用Docker TLS 或反向代理来保护连接详见远程主机文档。更进一步Agent 的端到端行为连接、容器列举、日志流在 e2e/agent.spec.ts 中有 Playwright 集成测试覆盖可以作为部署验证的参考示例仓库提供了 examples/setup-remote-agent.sh 脚本展示如何在实际主机上编排远端 Agent 的启动流程Agent 模式与 Swarm 模式的关系、过滤器语法、远程主机接入等主题可继续阅读 Swarm 模式、过滤器、远程主机 与支持的配置参数。记住核心要点Agent 的安全强度取决于它的网络可达性——默认证书只加密、不认证一旦 Agent 暴露到不受控网络必须立即生成唯一证书对并让 hub 与所有 Agent 使用同一份凭据、一同重启。【免费下载链接】dozzleRealtime log viewer for containers. Supports Docker, Swarm and K8s.项目地址: https://gitcode.com/GitHub_Trending/do/dozzle创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表