内网环境下如何在 Docker 中运行 Fluentd?
内网运行 Fluentd Docker 容器的关键点:离线镜像准备(save/load)、插件离线安装(gem 本地安装进自建镜像)、端口与日志目录挂载。本文给出无外网环境的完整部署方案。
内网部署的核心是解决"镜像和插件从哪来":在外网机器拉好镜像 docker save 导出,内网 docker load 导入;需要的插件在打镜像时用 gem 本地安装进去,之后运行与普通容器无异。
1. 离线准备镜像
外网机器:
docker pull fluent/fluentd:v1.16-debian-1
docker save fluent/fluentd:v1.16-debian-1 -o fluentd.tar
拷贝到内网后 docker load -i fluentd.tar。
2. 插件离线安装(自建镜像)
Fluentd 输出到 ES/Kafka 等常需插件,一并打进镜像:
FROM fluent/fluentd:v1.16-debian-1
USER root
COPY gems/ /tmp/gems/
RUN gem install --local /tmp/gems/fluent-plugin-elasticsearch-*.gem
USER fluent
单个 gem fetch/download 不会自动保证完整传递依赖和 native 构建依赖。更稳妥是在联网的目标架构环境构建、测试完整自定义镜像,再 docker save/load;离线 gem 方式须准备锁定版本的全部依赖。
3. 运行
docker run -d --name fluentd \
-v /opt/fluentd/conf:/fluentd/etc \
-v /var/log:/var/log:ro \
-v fluentd-state:/fluentd/state \
-p 24224:24224 \
fluentd-custom:latest \
fluentd -c /fluentd/etc/fluent.conf
注意挂载:配置目录、要采集的日志目录(只读)、接收 forward 协议的端口;pos_file 和 buffer path 应设在另挂的持久可写目录(示例为 /fluentd/state,须按镜像 UID/GID 准备权限),不能放入上面的只读 /var/log。发送方使用 Docker logging driver 时地址从 daemon 网络解析,不是应用容器的网络。
常见问题(FAQ)
Q:怎么确认插件依赖齐了? 外网机器上实际运行一遍 fluentd -c xxx --dry-run,可发现部分加载/配置问题,但不证明下游连通、TLS、读写权限和交付正常,还须发送实际测试事件验证。
Q:内网时间不同步会影响日志吗? 会——日志时间戳错乱,内网也要配 NTP。