fix(loki): COS 存储全链路修复 —— Secret 生成/env 注入/凭据解密/endpoint 规范化

API 端到端跑通中暴露 4 个串联问题(腾讯云 COS + K8s 场景):

1. loki_manifest.go: switch 缺少 cos / obs
   → 不生成 loki-storage-credentials Secret、不注入 LOKI_STORAGE_* 环境变量、
     也不给 Loki 加 -config.expand-env=true
   → 配置里 ${LOKI_STORAGE_ACCESS_KEY} 无法展开 → AK 为空
   → COS 返回 403 InvalidAccessKeyId(ruler 每分钟报错)
   修复:case 补上 cos / obs

2. loki_manifest.go: 生成 Secret 时用了 ENC: 密文原始值
   → Secret data 里是 ENC:xxx 而非真实 AK/SK
   修复:crypto.DecryptField 解密后再 base64

3. loki_config.go: host-docker 模式同样把密文写进配置
   修复:解密后返回

4. loki_config.go: cos/oss/obs 的 endpoint 未剥离桶名前缀
   → 用户填虚拟主机式 endpoint(mybucket-1250000000.cos.<region>...)时,
     Loki 的 S3 客户端又拼一次 bucketnames,变成 <bucket>.<bucket>.cos...
   → TLS 证书校验失败(x509: certificate is valid for ... not <bucket>.<bucket>.cos...)
   修复:新增 stripBucketPrefix,s3/cos/oss/obs/minio 分支统一剥离桶名前缀

验证(log namespace,API 端到端):
  - Loki statefulset 1/1 Running,ruler 无 InvalidAccessKeyId/x509
  - 写入 + 查询日志成功(持久化到 COS)
  - Promtail DaemonSet 12/12 全节点就绪
  - collector status=active

运维侧附加动作(非代码,见部署文档):
  - 存储配置改用有效 AK/SK + 区域端点 cos.ap-hongkong.myqcloud.com
  - 平台 ServiceAccount log:lokistack 绑定 cluster-admin
    (否则无法创建 Promtail 所需的 ClusterRole/ClusterRoleBinding)
This commit is contained in:
opsx committed 2026-10-26 19:32:38 +00:00
1 parent 004375e0ce
commit 46e73d3d17
3 files changed
+47 -6

No files matched your search

+9 -3
View File
@@ -5,6 +5,8 @@ import (
"crypto/sha256"
"encoding/base64"
"fmt"
"opsxloki/pkg/crypto"
)
func (d *LokiDeployer) generateManifest(ns string) string {
@@ -34,7 +36,11 @@ func (d *LokiDeployer) generateManifest(ns string) string {
storageEnvBlock := ""
if sc := d.deployment.StorageConfig; sc != nil {
switch sc.StorageType {
case "s3", "oss", "minio", "azure":
// 注意:必须包含 cos / obs —— 腾讯云 COS、华为 OBS 同样走 S3 兼容协议,
// 也需要生成 loki-storage-credentials Secret、注入 LOKI_STORAGE_* 环境变量、
// 并给 Loki 加 -config.expand-env=true,否则配置里的 ${LOKI_STORAGE_ACCESS_KEY}
// 无法展开 → AK 为空 → 对象存储 403 InvalidAccessKeyId。
case "s3", "oss", "cos", "obs", "minio", "azure":
secretManifest = fmt.Sprintf(`---
apiVersion: v1
kind: Secret
@@ -45,8 +51,8 @@ type: Opaque
data:
accessKey: %s
secretKey: %s`, ns,
base64.StdEncoding.EncodeToString([]byte(sc.AccessKey)),
base64.StdEncoding.EncodeToString([]byte(sc.SecretKey)))
base64.StdEncoding.EncodeToString([]byte(crypto.DecryptField(sc.AccessKey))),
base64.StdEncoding.EncodeToString([]byte(crypto.DecryptField(sc.SecretKey))))
configExpandArg = "\n - -config.expand-env=true"
storageEnvBlock = `
env: