跳到主要内容

对象存储接入(MinIO / COS)

日志(Loki)和链路(Tempo)默认存本地卷。数据量大或要跨节点共享时,可以改存对象存储。

先看哪些组件需要
  • 单机部署:只有**日志(Loki)**需要考虑对象存储。单机不具备链路追踪能力、不产生链路数据,ops-tempo 无需也不建议配置对象存储。
  • 集群部署:日志和链路都可以用对象存储,且必须用两个不同的桶

一、准备 MinIO

已有 MinIO 或云对象存储可跳到第二步

docker run -d --name minio \
-p 9000:9000 -p 9001:9001 \
-e MINIO_ROOT_USER=minioadmin \
-e MINIO_ROOT_PASSWORD='<强随机密码>' \
-v /data/minio:/data \
--restart always \
minio/minio server /data --console-address ":9001"
  • 9000 是 S3 API 端口(平台连的是这个),9001 是 Web 控制台。
  • 生产请把 MINIO_ROOT_PASSWORD 换成强随机串,并只在内网暴露 9000。

浏览器打开 http://MinIO主机IP:9001,用上面的账号密码登录。

二、建桶

Loki 和 Tempo 必须用不同的桶,共用会互相覆盖元数据。

控制台 Buckets → Create Bucket,或用命令行:

docker run --rm --network host --entrypoint sh minio/mc -c "
mc alias set local http://<MinIO主机IP>:9000 minioadmin '<密码>' &&
mc mb local/mdis-loki &&
mc mb local/mdis-tempo &&
mc ls local"

命名没有强制要求,本文用 mdis-loki / mdis-tempo

三、创建访问密钥(AK/SK)

不要直接用 root 账号。控制台 Access Keys → Create access key,保存生成的 Access Key 与 Secret Key(Secret Key 只显示一次)。

命令行方式(建一个专用用户并授权到这两个桶):

docker run --rm --network host --entrypoint sh minio/mc -c "
mc alias set local http://<MinIO主机IP>:9000 minioadmin '<密码>' &&
mc admin user add local mdis '<SK,8位以上>' &&
mc admin policy attach local readwrite --user mdis"

四、填写配置

单机(ops.yaml

只给 ops-loki 服务加环境变量:

ops-loki:
environment:
ENV_S3_ENDPOINT: 192.168.1.10:9000 # MinIO 的 S3 API 地址,填 host:port,别带 http://
ENV_S3_BUCKET_LOKI: mdis-loki # 需提前在 MinIO 里建好这个桶
ENV_S3_ACCESS_KEY: mdis
ENV_S3_SECRET_KEY: '<SK>'
ENV_S3_FORCE_PATH_STYLE: 'true'

改完 docker compose -f ops.yaml up -d ops-loki 重建该容器。

集群(10-secret.yaml

stringData:
ENV_S3_ENDPOINT: "minio.default.svc.cluster.local:9000"
ENV_S3_ACCESS_KEY: "mdis"
ENV_S3_SECRET_KEY: "<SK>"
ENV_S3_FORCE_PATH_STYLE: "true"
桶名不在 Secret 里,而且两个组件各用各的

30-stateful.yaml 里给 ops-lokiENV_S3_BUCKET_LOKI、给 ops-tempoENV_S3_BUCKET_TEMPO两个桶必须不同

不要把桶名写进共用的 Secret,也不要用旧的通用变量 ENV_S3_BUCKET——它会同时喂给两个 组件,Loki 先写入占了目录结构后,Tempo 初始化就会失败、进入 CrashLoopBackOff。 (ENV_S3_BUCKET 仅为兼容存量部署保留。)

⚠️ 两个桶都要在部署前先建好。桶不存在时 Loki 报 NoSuchBucket 直接反复重启。

五、连接地址怎么填(最容易出错的一步)

ENV_S3_ENDPOINT 填的是 MinIO 的 S3 API 地址,不是控制台地址,形如 192.168.1.10:9000http://192.168.1.10:9000——带不带 http:// 都可以:Tempo 用的 minio-go 只接受 host:port,平台会在启动 Tempo 时自动剥掉 scheme;Loki 侧固定按 HTTP 连接(配置里写死 insecure: true)。⚠️ 也正因如此,目前不支持只提供 HTTPS 的对象存储

部署关系endpoint 应该填
MinIO 与平台在同一个 compose 网络容器名,如 minio:9000
MinIO 在另一套 compose 或装在宿主机上宿主机 IP + 宿主机映射端口,如 192.168.1.10:9011
MinIO 在同一个 K8s 集群Service DNS,如 minio.default.svc.cluster.local:9000
云对象存储厂商给的 endpoint 域名
跨 stack 时不能填对方的容器名

不在同一个 compose 网络里,容器名是解析不到的,ops-loki 会起不来并报:

dial tcp: lookup minio: no such host

这时必须用宿主机 IP。注意宿主机映射端口未必是 9000——以 docker ps 实际显示的为准 (例如映射成了 9011:9000,那就填 9011)。

路径风格

对象存储ENV_S3_FORCE_PATH_STYLE
MinIOtrue
腾讯云 COSfalse(只支持 virtual-hosted 风格,填 true 必然失败)
UCloud US3true

六、验证

重建容器后看日志和桶:

# 1. 容器起来了,且没有 S3 报错
docker logs <loki 容器> 2>&1 | grep -iE "error|fail" | head

# 2. 触发一些日志后,桶里应出现对象
docker run --rm --network host --entrypoint sh minio/mc -c "
mc alias set local http://<MinIO主机IP>:9000 mdis '<SK>' &&
mc ls -r local/mdis-loki | head"

桶里出现 fake/index/ 开头的对象即为成功。刚配好时可能要等几分钟——Loki 攒够一批才上传。

七、常见报错

日志里的报错原因
dial tcp: lookup xxx: no such hostendpoint 用了容器网络里解析不到的名字,见第五步
connection refused端口写错,以 docker ps 实际映射为准
SignatureDoesNotMatchAK/SK 不对
AccessDeniedAK/SK 对但没有该桶的权限,检查用户策略
NoSuchBucket桶没建,或桶名拼错
切换存储后旧日志不会迁移

Loki 切换后端不会搬运既有数据,旧日志仍在原来的本地卷里。切换后需要重新产生日志才能在新后端看到内容, 这属于正常现象,不是配置失败。