opsx
|
46e73d3d17
|
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)
|
2026-10-26 19:32:38 +00:00 |
|
opsx
|
004375e0ce
|
fix(ns): 命名空间固定 log —— 平台/Loki 实例/Promtail 全部收敛到 log
按需求:所有 lokistack 相关资源(管理平台副本、Loki 实例、Promtail 采集器)
固定使用 log 命名空间,不提供覆盖开关。
改动:
1. 后端 services/deployment.go Create():k8s-yaml 模式下 namespace 为空时
兜底为 "log",前端漏传也不会跑偏。
2. 前端 DeploymentCard.tsx:命名空间展示 fallback 'loki' → 'log'
3. 前端 DeploymentFormDialog.tsx:输入框 placeholder 'loki' → 'log'
(form-schema.ts 的 DEFAULT_VALUES.namespace 原本已是 'log')
未动:
kubernetes/install.sh 的 NS="log" 早就是固定值
collector_deployer.go 已自动跟随 loki.Namespace(collector.Namespace 为空时)
资源名不冲突:
平台 lokistack / lokistack-data / lokistack-secrets / lokistack-nodeport
Loki 实例 loki / loki-config / loki-data / loki-headless / loki-storage-credentials
Promtail promtail-* (DaemonSet)
镜像:lghost/lokistack:latest + v0.1 = sha256:9d15b7ffbb3d
|
2026-10-26 18:55:06 +00:00 |
|
opsx
|
cfe1ccd154
|
fix(storage): 按 endpoint 形态解析响应 + 凭据解密返回 + 无建桶权限友好提示
【真实根因】COS 桶明明存在却报"桶不存在/创建失败"
用户配置:endpoint=loki-log-1394668510.cos.ap-hongkong.myqcloud.com(虚拟主机式,已含桶名)
旧代码:始终 GET / 并按 ListBuckets 的 <Buckets><Bucket><Name> 解析。
但在虚拟主机式 endpoint 下,GET / 返回的是 ListObjects(<ListBucketResult>)——
桶内对象列表,不是桶列表。解析必然找不到桶名 → 误判"桶不存在"
→ 触发建桶 PUT → 用户的 AK 无 cos:PutBucket 权限 → 403
→ 最终报"创建后校验失败"。
【实测确认(用该 AK 直连 COS)】
GET / (vhost) → 200 <ListBucketResult> 桶存在,能列对象
GET / (区域端点) → 200 <ListAllMyBucketsResult> AK 有 cos:GetService
HEAD / → 403 AK 无 cos:HeadBucket
PUT / (CreateBucket) → 403 AK 无 cos:PutBucket
即 QcloudCOSDataFullControl = 数据面全控(读写/列桶),不含管控面(建桶/HeadBucket)。
【修复】
1. 探测统一用 GET /,再按 endpoint 形态解释响应:
- 虚拟主机式 → 按 ListObjects(<ListBucketResult>)判断,200 即桶存在
- 区域端点 → 按 ListBuckets(<Buckets><Bucket><Name>)匹配桶名
桶存在就直接返回"桶已存在",不再走建桶流程。
2. 建桶二次校验同样改用 GET /(不再用 HEAD,避免 HeadBucket 403 误判)。
3. 建桶返回 403 时给出明确友好提示:
"当前 Access Key 无建桶权限。腾讯云 QcloudCOSDataFullControl 只授予数据读写/列出,
不含 CreateBucket。请到 COS 控制台手动创建桶,或在 CAM 追加 cos:PutBucket"
4. models/storage.go Sanitized() 用 crypto.DecryptField 解密后再返回 AK/SK
(原来直接返回 ENC:xxx 密文,前端编辑框显示密文)。
5. 前端访问地址输入框补充说明:推荐填区域端点(不带桶名)。
镜像:lghost/lokistack:latest + v0.1 = sha256:350478003870
|
2026-10-26 18:38:00 +00:00 |
|
opsx
|
ff69ea2ce8
|
fix(storage): 凭证明文返回便于编辑测试 + 建桶后二次校验防"假成功"
问题(log.astx.club/storage):
1. 编辑存储时 Access Key / Secret Key 都是空的,点「测试连接」提示
请先填写 Bucket 与 Access Key / Secret Key,无法测试也无法保存;
2. 提示"桶不存在,已自动创建"但疑似没有真正创建;
3. 测试失败提示用 toast 弹到右下角,不在弹框内。
修复:
1. models/storage.go Sanitized() 返回 accessKey / secretKey 明文
(内网运维工具,管理员需要在编辑弹框里看到并测试连接;脱敏会导致
编辑时字段为空、校验失败)
2. 前端 StorageConfig 类型补 accessKey / secretKey 字段;
编辑弹框打开时回填这两个字段(原来只有 secretKey 且强制置空);
Secret Key 标签去掉「留空保持不变」
3. services/storage_check.go 建桶后二次 ListBuckets 校验:
不同对象存储 CreateBucket 语义不同(腾讯云 COS 要求桶名放 Host、
路径为 /),直接 PUT /<bucket> 可能返回 200 但未真正创建。
现在创建后重新列举桶,找不到就报"创建后校验失败"并提示检查
Endpoint / Region / 桶名(COS 需带 APPID)
4. 前端「请先填写 Bucket 与 Access Key / Secret Key」改为在弹框内
testResult 区域显示(原来 toast 弹右下角)
镜像:lghost/lokistack:latest + v0.1 = sha256:6b6cc9769e79
|
2026-10-26 18:30:47 +00:00 |
|
opsx
|
d0b9b6b71d
|
fix(ui): 前端用户可见文案 opsx-loki → lokistack
修正用户能看到/会复制走的旧名(你反馈的 K8s 示例 token 命令在内):
1. 界面标题(4 处)
App.tsx 浏览器标题栏
Layout.tsx 侧边栏 logo / 页面标题 fallback / 移动端导航
login/index.tsx 登录页大标题
settings/index.tsx 「关于 lokistack」
2. 集群接入示例(用户直接复制到集群执行,5 处)
ClusterFormDialog.tsx:
Role / ServiceAccount 名: opsx-loki → lokistack
token Secret 名: opsx-loki-token → lokistack-token
取 token 命令: get secret opsx-loki-token → lokistack-token
3. 文档
docs/deployment/README.md, host-nginx.md 旧名全量修正
README.md 迁移章节之外的示例命令修正;
迁移章节(从 opsx-loki 升级)保留旧名作历史对照
【刻意不改】
a) localStorage key(9 个)
opsxloki.auth.{token,refresh-token,user}
opsxloki.theme.mode / layout.collapsed / chunk-reloaded
opsxloki.logs.{query-history,range-history}
原因:改了所有在线用户立即掉登录,主题/折叠/查询历史全丢。
要改必须配套迁移(参考 main.tsx 中 lokideploy.* → opsxloki.* 的写法)。
b) 数据文件名 opsxloki.json(后端硬编码,改了读不到 DB)
c) Go module 路径 opsxloki/...(159 处 import)
属编译期内部标识,最终用户不可见;改名需全仓重构 + go.mod 变更。
|
2026-10-26 17:30:30 +00:00 |
|
opsx
|
3c9388658b
|
refactor: 资源名 opsx-loki/opsxloki → lokistack(线上已迁移完成)
【已在线完成,零数据丢失】
K8s ns=log 资源全部改名:
Deployment opsx-loki → lokistack
Service opsx-loki → lokistack
Service opsx-loki-nodeport → lokistack-nodeport
PVC opsxloki-data → lokistack-data
Secret opsxloki-secrets → lokistack-secrets
Label app: opsx-loki → app: lokistack
Ingress log.astx.club 后端 → lokistack-nodeport:8080
镜像 lghost/opsxloki → lghost/lokistack
docker-compose 卷/容器名同步更名
【保留不变(改了会出事)】
namespace: log
数据文件名 opsxloki.json(代码硬编码)
容器内路径 /app/data
【迁移过程】
1. 备份 PVC 数据(32KB) + Secret 原值 + 旧 yaml → /root/lokistack-migration-backup-20261026-171141
2. scale 旧 Deployment → 0,等 Pod 消失
3. 复制 Secret(JWT sha256 校验一致)
4. 新建 PVC lokistack-data(Bound 30Gi cbs)
5. 临时 Pod 恢复数据(chown 1000:1000,opsxloki.json 保留 0600)
6. apply 新 Deployment → 1/1 Running
7. 修复 Ingress 后端(TKE qcloud 要求 NodePort)→ CLB 恢复 200
8. 删除旧 Deployment / 失效 Service
【验证】
lokistack 1/1,0 重启,镜像 lghost/lokistack:latest(statically linked)
/api/v1/health → {"status":"ok","version":"2.0.0"}
/app/data/opsxloki.json 610B 完整(admin 用户 + 配置)
http://log.astx.club/ → HTTP 200
镜像加固:admin123=0、/app/backend/=0、initial-admin-password.txt 存在
【回滚兜底(建议 7 天后删)】
pvc/opsxloki-data、secret/opsxloki-secrets
【文档】
README 新增「从 opsx-loki 升级」章节:
K8s 七步迁移脚本 + docker-compose 卷迁移命令
|
2026-10-26 17:16:15 +00:00 |
|
opsx
|
b65dcc9677
|
refactor: 镜像名 lghost/opsxloki → lghost/lokistack(跟随项目更名)
只改镜像引用(8 处),K8s 资源名一律不动 —— 改了会丢数据/断服务:
改:
kubernetes/deployment.yaml image
docker-compose.yml image
docker-compose.prod.yml image ×2
kubernetes/README.md 文档 ×2
docs/deployment/kubernetes.md 文档 ×2
不改(重要):
opsxloki-secrets K8s Secret —— 改名会导致 JWT_SECRET/ENCRYPTION_KEY 重置,
历史加密的实例密码无法解密
opsxloki-data PVC —— 改名 = 新建空卷,数据全丢
container_name docker 容器名 —— 改名会让 docker exec/logs 命令失效
app: opsx-loki Pod label —— 改名要同步改 Service selector
deployment 名称 opsx-loki —— 改名要重建 Deployment
⚠️ 部署顺序(本提交只改代码,尚未 apply 到 K8s):
1) 推镜像 lghost/lokistack:latest 到 Docker Hub
2) kubectl apply -f kubernetes/deployment.yaml
3) 等 Pod 1/1 就绪
4) 才能删除 lghost/opsxloki
顺序颠倒会因 imagePullPolicy: Always 拉到不存在的镜像导致服务中断
|
2026-10-26 17:09:47 +00:00 |
|
opsx
|
ec759cd36b
|
build: Dockerfile 编译加 -trimpath(抹除源码绝对路径)
加固前:二进制内可 strings 出 66 处 /app/backend/controllers/*.go 等源码路径,
泄露完整目录结构与文件名。
加固后:路径被 trimpath 抹除,命中数 0。
注:build.sh / run.sh 已在上个提交加过 -trimpath,本次补上实际部署用的
Dockerfile 构建路径(K8s / docker-compose 走的就是这里)。
|
2026-10-26 17:05:11 +00:00 |
|
opsx
|
3c27e58a73
|
feat(security): 移除 admin123 硬编码默认密码 + 编译加 -trimpath
安全加固(降低二进制泄露/逆向的信息面):
1. 初始密码随机化
- 首次启动生成 16 位随机密码(大小写+数字,排除 0/O/1/l/I 易混淆字符)
- 写入数据卷 initial-admin-password.txt(0600)并打印到首次启动日志
- admin 首次改密后自动删除该文件(seed.CleanupInitPassword)
- 支持 ADMIN_INIT_PASSWORD 环境变量指定(自动化部署 / 固定密码场景)
- 生成失败直接 Fatal 退出,不再降级到公开默认口令
2. 移除硬编码 admin123
- main.go 不再打印 "Default login: admin / admin123"
- 二进制内 admin123 命中:2 → 0
3. -trimpath
- build.sh / run.sh 编译加 -trimpath
- 二进制内 /app/backend/ 源码路径命中:66 → 0
4. 文档
- README 新增「第 4 步:获取管理员初始密码」
(docker compose exec / logs / docker cp / named volume 四种方式 + K8s 对应命令)
- .env.example 补 ADMIN_INIT_PASSWORD
- kubernetes/deployment.yaml 加 env 注释说明
验证(strings 对比加固前后二进制):
admin123 2 → 0
/app/backend/ 66 → 0
initial-admin-password.txt / ADMIN_INIT_PASSWORD / CleanupInitPassword 均存在
|
2026-10-26 17:01:09 +00:00 |
|
opsx
|
9a46a955d4
|
feat(k8s): 一键部署脚本 + 跨云适配 + 云相关清单拆分到 examples
新增 kubernetes/install.sh(一条命令部署):
- 云平台识别:读节点 providerID,识别 TKE / EKS / ACK / CCE / GKE / AKS / K3s / 自建
- StorageClass 三级探测:显式 STORAGE_CLASS → is-default-class 注解 → 集群唯一 SC
- 自建集群兜底:无任何 SC 时自动创建静态 local PV
(hostPath + DirectoryOrCreate + nodeAffinity + WaitForFirstConsumer + Retain)
- Secret 幂等生成:已存在则跳过,绝不覆盖(避免密钥轮换导致历史凭证无法解密)
- 失败分类诊断:ImagePullBackOff / CreateContainerConfigError / PVC Pending
按云给出对应仓库格式与推荐 SC 名
- 环境变量:WITH_NODEPORT / STORAGE_CLASS / LOCAL_STORAGE / NODE_NAME / PV_PATH / PV_SIZE
云相关清单拆到 kubernetes/examples/:
- ingress.yaml(阿里云 alb)、ingress-tke.yaml(腾讯云 qcloud)、secret.example.yaml
- 原因:留在根目录会导致 kubectl apply -f kubernetes/ 时 ingress 同名互相覆盖,
且 secret.example.yaml 的占位符会把真实密钥顶掉
README 重写:
- 全部用法速查 + 环境变量一览
- 自建 K8s 存储方案选型(local PV / local-path-provisioner / OpenEBS / Longhorn / NFS)
- hostPath 数据运维:定位、热备份、跨节点迁移、卸载保留、常见坑
|
2026-10-26 14:03:39 +00:00 |
|