资讯动态

Loki Docker 日志驱动(Docker Logging Driver)完整指南:安装、配置与源码原理

发布时间:2026/9/10 14:43:23 来源:尧图企业网站定制
Loki Docker 日志驱动Docker Logging Driver完整指南安装、配置与源码原理【免费下载链接】lokiLike Prometheus, but for logs.项目地址: https://gitcode.com/GitHub_Trending/lok/loki导读Loki 提供了一个 Docker 日志驱动插件grafana/loki-docker-driver它扩展了 Docker 的日志采集能力将容器日志直接发送到自建的 Loki 实例或 Grafana Cloud实现像 Prometheus 收集指标一样收集日志。本文以仓库中的 docker-driver README 及其配套文档安装与维护、配置详解为主体结合clients/cmd/docker-driver/下的源码实现完整讲解该驱动的安装、升级、卸载、四种配置方式、标签体系、Pipeline 阶段、Relabeling、全部log-opt参数以及已知问题排查读完你可以在生产环境中独立部署并精细调优这一日志采集链路。说明Docker 插件目前不支持 Windows详见 Docker Engine 扩展文档。该驱动由 Loki 项目维护但被列为 Loki 的第三方客户端之一其支持承诺与 Grafana Alloy 不完全相同。一、驱动架构与运行原理1.1 插件形态Docker 托管插件Loki 的 Docker 驱动是一个Docker managed plugin以 Unix Socket 的方式与 Docker 守护进程通信。从 config.json 可以看到插件声明entrypoint为/bin/docker-driver声明实现 Docker 的docker.logdriver/1.0接口socket 名为loki.sock使用 host 网络模式访问 Loki暴露两个可配置环境变量LOG_LEVEL插件自身日志级别默认info和PPROF_PORT可选的 pprof 调试端口便于排查性能问题。驱动进程通过 main.go 启动读取LOG_LEVEL环境变量默认info用sdk.NewHandler({Implements: [LoggingDriver]})注册日志驱动接口然后监听/run/docker/plugins/loki.sock提供 RPC 服务。注意插件日志必须输出到stdout才会进入 Docker daemon 日志。1.2 数据通路FIFO → Loki 与 JSON 文件双写从源码结构看驱动的核心数据通路如下Docker daemon 将容器日志写入一个 FIFO 管道驱动通过fifo.OpenFifo以只读方式打开见 driver.go 的StartLoggingconsumeLog协程用logdriver.NewLogEntryDecoder解码每条日志构造logger.Message含时间戳、来源、部分日志元数据Loki 先行调用lf.lokil.Log(msg)推送给 Loki随后再写本地 JSON 文件lf.jsonl.Log保证docker logs仍然可用——这正是文档中Loki 驱动仍会组合使用 json-log 驱动的实现依据ReadLogs通过 JSON 文件回放日志实现docker logs读取能力Capabilities接口声明了ReadLogs: true见 http.go。驱动维护两个索引logs按日志文件路径与idx按容器 ID并在容器停止时根据keep-file配置决定是否删除/var/log/docker/containerID/目录下的 JSON 日志。1.3 从容器日志到 Loki Entrydriver.go 中的StartLogging会重新设定logCtx.LogPath /var/log/docker/containerID/json.log。在 loki.go 中loki.Log方法把logger.Message转为logproto.Entry时间戳 日志行合并标签后投递到内部 channel若启用了 Pipeline 阶段则先经stages.NewPipeline包装再进入客户端最终由clients/pkg/util中的客户端按批batch发送到 Loki 的 push 接口。二、安装、升级与卸载2.1 安装插件插件必须安装到每个需要采集日志的 Docker 主机上。安装命令可替换版本号amd64与arm64目前均受支持docker plugin install grafana/loki-docker-driver:3.6.0-amd64 --alias loki --grant-all-permissionsARM64 主机请把镜像 tag 改为-arm64后缀如3.6.0-arm64--alias loki为插件创建短别名后续--log-driverloki即引用它--grant-all-permissions一次性授予插件所需权限。用docker plugin ls检查安装结果成功启动的插件状态为enabledID NAME DESCRIPTION ENABLED ac720b8fcfdb loki Loki Logging Driver true2.2 升级插件升级流程为停用旧插件 → 升级按需变更版本与架构→ 重新启用 → 重启 Dockerdocker plugin disable loki --force docker plugin upgrade loki grafana/loki-docker-driver:3.6.0-arm64 --grant-all-permissions docker plugin enable loki systemctl restart docker请按实际版本号替换命令中的版本号。2.3 卸载插件干净卸载需要先禁用再删除docker plugin disable loki --force docker plugin rm loki2.4 从源码自行构建可选仓库 README 说明了贡献与构建方式需要 Docker、Makefile可选 Go 工具链。使用根目录 Makefile 中预定义的目标见Makefile第 489–539 行附近make docker-driver构建驱动并创建插件镜像make docker-driver-enable启用构建出的插件make docker-driver-clean禁用并删除插件。Makefile 中LOKI_DOCKER_DRIVER、PLUGIN_TAG、PLUGIN_ARCH变量可覆盖镜像名、tag 与架构后缀其构建流程为用 Dockerfile 编译静态二进制CGO_ENABLED0 go build导出为 rootfs再用docker plugin create打包成插件。三、配置驱动四种方式Docker 守护进程有一个默认日志驱动每个容器默认继承它除非单独配置。3.1 为单个容器指定docker run--log-driver指定驱动--log-opt NAMEVALUE传递驱动选项可重复传入多次。下面的命令把 Grafana 容器日志发送到 Grafana Cloud批大小 400000 字节、发送失败最多重试 5 次docker run --log-driverloki \ --log-opt loki-urlhttps://user_id:passwordlogs-us-west1.grafana.net/loki/api/v1/push \ --log-opt loki-retries5 \ --log-opt loki-batch-size400000 \ grafana/grafana注意Loki 驱动仍会结合 json-log 驱动工作主要是为了保持docker logs可用。可用max-size、max-file调整文件大小与轮转其默认值不取自 json-log 配置设置no-filetrue可完全禁用 JSON 文件创建但同时也使该容器的docker logs失效。3.2 设为守护进程默认驱动daemon.json编辑 Linux 下位于/etc/docker/的daemon.json把log-driver设为loki{ debug: true, log-driver: loki }驱动选项通过log-opts一并配置{ debug: true, log-driver: loki, log-opts: { loki-url: https://user_id:passwordlogs-us-west1.grafana.net/loki/api/v1/push, loki-batch-size: 400000 } }daemon.json 中的log-opts值必须是字符串布尔与数值如上例的loki-batch-size也要加引号。修改后重启 Docker daemon 生效此后该主机上所有新建容器都会通过此驱动把日志发往 Loki。3.3 Swarm 服务 / Compose 配置在 compose 文件中直接为服务声明日志驱动同时适用于docker stack deploy与docker-composeversion: 3.7 services: logger: image: grafana/grafana logging: driver: loki options: loki-url: https://user_id:passwordlogs-prod-us-central1.grafana.net/loki/api/v1/push部署docker stack deploy my_stack_name --compose-file docker-compose.yaml # 或 docker-compose -f docker-compose.yaml up部署后 Grafana 服务即自动把日志发往 Loki。Swarm 的栈名/服务名、Compose 的项目名/服务名会被自动发现并作为 Loki 标签下发方便在 Grafana 中按这些维度过滤。3.4 选项解析的源码支撑在 config.go 中validateDriverOpt校验所有log-opt键名非法选项会直接报错wrong log-opt而loki-url是必填项缺失即拒绝启动loki: loki-url is required in the config。parseConfig则依次完成 URL 解析、时长解析time.ParseDuration、整数解析strconv.Atoi、TLS 与代理配置、租户 ID、外部标签、Swarm/Compose 自动标签、host/filename 标签、Relabel 配置以及 Pipeline 解析最终组装成config{labels, clientConfig, pipeline}。这些常量cfgExternalLabelsKey、cfgTimeoutKey等与下文表格中的选项一一对应。四、标签体系与 LogQL 检索Loki 使用标签索引日志条目配合 LogQL 流选择器 查询日志。驱动默认给每条日志添加以下标签filename日志在磁盘上的写入路径host产生日志的主机名源码中由os.Hostname()取得见 config.goswarm_stack、swarm_serviceDocker Swarm 部署时自动添加compose_project、compose_serviceDocker Compose 部署时自动添加。Swarm/Compose 标签来自容器标签com.docker.swarm.service.name、com.docker.stack.namespace、com.docker.compose.service、com.docker.compose.project源码常量见 config.go。自定义标签可通过loki-external-labels、loki-pipeline-stages、loki-pipeline-stage-file、labels、env、env-regex添加详见下文选项表。需要特别注意loki-external-labels的默认值是container_name{{.Name}}。一旦你自定义了该选项默认值即被替换——除非显式补回container_name否则不会再有该标签。例如loki-external-labels: jobdocker,container_name{{.Name}}标签值支持 Docker tag 模板展开如{{.Name}}、{{.ID}}源码中由expandLabelValue借助 Docker 的templates.NewParse渲染见 config.go。五、Pipeline 阶段解析日志行提取标签5.1 两种注入方式Pipeline 阶段在每条日志的最后执行。由于把配置文件挂载进驱动的 rootfs 比较麻烦驱动提供了内联选项loki-pipeline-stagesloki-pipeline-stage-file则指向配置文件参考 pipeline-example.yaml。二者同时提供会报错源码中parsePipeline显式校验见 config.go。仓库自带的 docker-compose.yaml 示例配置了两个阶段先用regex提取 level 值再用labels将其设为标签version: 3 services: grafana: image: grafana/grafana logging: driver: loki options: loki-url: http://host.docker.internal:3100/loki/api/v1/push loki-pipeline-stages: | - regex: expression: (level|lvl|severity)(?Plevel\w) - labels: level: ports: - 3000:3000注意loki-pipeline-stages: |块状标量语法可保持 YAML 缩进正确。5.2 docker run 传字符串docker run时需把阶段列表作为字符串传入注意转义 bash 特殊字符\\\w表示正则中的\wread -d stages EOF - regex: expression: (level|lvl|severity)(?Plevel\\\w) - labels: level: EOF docker run --log-driverloki \ --log-opt loki-urlhttp://host.docker.internal:3100/loki/api/v1/push \ --log-opt loki-pipeline-stages$stages \ -p 3000:3000 grafana/grafana5.3 底层实现loki.go 中New()先构建客户端util.Client若检测到cfg.pipeline.PipelineStages非空则调用stages.NewPipeline创建处理管线并用pipeline.Wrap(c)包裹客户端使每条日志先经过阶段处理再进入发送队列。Pipelines 复用了 Loki 客户端侧的clients/pkg/logentry/stages实现其能力与 Loki 生态的loki.process组件一致。六、Relabeling容器元数据重打标签可以使用 Prometheus relabeling 配置修改驱动发现的标签。配置同样以 YAML 字符串传入loki-relabel-config。Relabel 阶段每个容器只执行一次作用于容器启动时的元数据——因此适合重命名仅启动时可见的标签如swarm_stack而日志行上的标签请用 Pipeline 阶段。例如把swarm_stack、swarm_service分别改名为namespace、serviceversion: 3 services: grafana: image: grafana/grafana logging: driver: loki options: loki-url: http://host.docker.internal:3100/loki/api/v1/push loki-relabel-config: | - action: labelmap regex: swarm_stack replacement: namespace - action: labelmap regex: swarm_(service) ports: - 3000:3000源码中relabelConfigconfig.go使用 Prometheus 的relabel.ProcessBuilder处理标签集并通过rc.Validate(model.UTF8Validation)校验配置合法性。七、全部 log-opt 选项速查表使用--log-opt NAMEVALUECompose 中用options:指定以下选项选项必填默认值说明loki-url是—Loki HTTP push 端点loki-external-labels否container_name{{.Name}}附加标签键值对逗号分隔值支持 Docker tag 模板如container_name{{.ID}}.{{.Name}},clusterprodloki-timeout否10s发送日志到 Loki 的超时单位ns/us/ms/s/m/hloki-batch-wait否1s攒批等待时间无论批是否攒满都最多等这么久再发送loki-batch-size否1048576单批日志的最大字节数loki-min-backoff否500ms重试前最小等待时间loki-max-backoff否5m重试前最大等待时间loki-retries否10单批日志最大重试次数设为0表示无限重试loki-pipeline-stage-file否—Pipeline 阶段配置文件路径示例见 pipeline-example.yaml可解析日志行提取更多标签loki-pipeline-stages否—以字符串内联的 Pipeline 阶段配置loki-relabel-config否—Prometheus relabeling 配置用于重命名标签loki-tenant-id否—发送时设置租户 IDHTTP 头X-Scope-OrgID可被 Pipeline 阶段覆盖loki-tls-ca-file否—自定义 CA 证书路径loki-tls-cert-file否—客户端证书路径loki-tls-key-file否—客户端私钥路径loki-tls-server-name否—校验服务器证书时使用的名称loki-tls-insecure-skip-verify否false*是否跳过 TLS 校验loki-proxy-url否—访问 Loki 使用的代理 URLno-file否false*默认创建每个容器的本地 JSON 日志文件保证docker logs可用true则完全不创建不占磁盘但docker logs失效keep-file否false*默认容器停止后删除 JSON 日志文件true则保留。no-filetrue时无效max-size否-1日志轮转前的大小上限正整数加单位修饰符k/m/g-1表示不限供 json-log 保持docker logs使用max-file否1最多保留的日志文件数超限时删除最旧文件仅在设置max-size时生效labels否—逗号分隔的容器标签键列表命中则并入日志标签env否—逗号分隔的环境变量键列表命中则并入日志标签env-regex否—匹配日志相关环境变量的正则与labels/env键冲突时env 值优先两者都为日志消息增加标签字段带*的布尔值在配置文件中只接受字符串形式true接受1,t,T,true,TRUE,Truefalse接受0,f,F,false,FALSE,False。这也解释了为什么 daemon.json 中的布尔/数值必须加引号。no-file 与 keep-file 的交互矩阵no-filekeep-file创建 JSON 日志文件容器停止时删除docker logs可用falsefalse是是是falsetrue是否是true任意否不适用否这些选项在源码中由parseBoolean解析并体现在 driver.go 的StartLogging/StopLogging逻辑中no-filetrue时跳过jsonfilelog.New与目录创建容器停止时仅当keepFile为假才删除/var/log/docker/containerID/目录。八、已知问题Docker Daemon 死锁与规避方案驱动会把所有日志保存在内存中当 Loki 不可达且超过loki-retries次数时日志条目会被丢弃。相关参数含义与规避策略loki-retries0无限重试驱动会一直重试直到 Loki 恢复从而避免丢日志。但无限重试有副作用——Docker daemon 会等待驱动处理完容器全部日志才允许移除容器如果容器卡住daemon 可能永久等待。收紧重试窗口设置loki-retries2、loki-max-backoff800ms、loki-timeout1s、keep-filetrue可将 daemon 被锁定的时间缩短Loki 客户端无法重连时 JSON 日志文件仍保留在磁盘上。使用非阻塞模式在 docker-compose 中设置services.logger.logging.options.modenon-blocking。非阻塞意味着写日志不会阻塞应用主流程日志先缓冲再异步发送Loki 不可用时消息暂存于缓冲恢复后继续发送。但缓冲溢出或 Loki 长时间不可用仍可能导致日志丢失。要彻底规避此问题文档还建议改用 Alloy 的loki.source.docker组件或discovery.docker做 Docker 服务发现采集。九、故障排查插件日志位于 Docker daemon 日志中启用 debug 模式请参考 Docker daemon 文档。插件的stdout会重定向到 Docker 日志条目以plugin为前缀。用docker plugin ls查看 Loki 驱动的插件 ID。Docker daemon 日志的存放位置因系统而异请查阅 Docker daemon 文档中你所在平台的日志路径。十、实践建议小结先安装插件注意架构后缀-amd64/-arm64用docker plugin ls确认ENABLEDtrue按场景选择配置方式单容器--log-opt、全局daemon.json、Swarm/Composelogging.driver利用loki-external-labels预设jobdocker等业务维度标签Swarm/Compose 部署会自动获得栈/服务标签日志行内的结构化字段用 Pipeline 阶段regexlabels提取容器级元数据改名用 Relabeling高可用场景优先设置合理的loki-batch-size/loki-batch-wait平衡吞吐与延迟并显式配置loki-retries、keep-file或modenon-blocking防止 daemon 死锁与日志丢失需要docker logs则保留默认的 JSON 文件双写磁盘敏感场景可权衡no-filetrue的取舍。【免费下载链接】lokiLike Prometheus, but for logs.项目地址: https://gitcode.com/GitHub_Trending/lok/loki创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价