参考 lokistack 的实现:
1. 首次启动生成 16 位随机密码(大小写+数字,排除 0/O/1/l/I 易混淆字符)
- 4 个默认账号共用:admin / dba / auditor / developer
- 写入数据目录 initial-admin-password.txt(0600)
- 打印到启动日志(含账号列表、密码、文件路径、docker/kubectl 获取命令)
2. 支持 ADMIN_INIT_PASSWORD 环境变量覆盖(自动化部署 / 需要固定密码时)
3. 生成失败直接 log.Fatalf 退出,不降级到公开默认口令
4. 批量导入用户 BatchImportUsers:空密码不再默认 admin123,
改为随机 14 位(新增 genPassword),保证每个导入用户密码不可预测
5. 幂等:已存在的账号不重建、不改密码;只有缺失的账号才创建
6. imagePullPolicy: IfNotPresent → Always
原因:latest tag 配 IfNotPresent 会导致节点一直复用缓存的旧镜像,
新 push 的镜像不生效(本次实测踩到:Pod imageID 仍是旧 digest)
7. 文档
- README 新增「首次部署获取默认账号密码」章节(含 4 账号角色表 + 3 种获取方式)
- docker-compose.yml 加 ADMIN_INIT_PASSWORD 环境变量
- kubernetes/deployment.yaml 加 env 注释
验证(清空 DB 后全新 seed):
镜像 sha256:eaf0affd8d93
/app/data/initial-admin-password.txt 199B 权限 0600
内容含 "适用账号: [admin dba auditor developer]" + 随机密码
启动日志完整打印获取方式
登录实测:admin / dba / developer 用新密码均返回 access_token;
admin123 登录失败(已失效)
二进制 strings:admin123 命中 0
opsxsql 部署到 Kubernetes
文件
| 文件 | 说明 |
|---|---|
install.sh |
一键部署(推荐):云探测/SC 探测/本地 PV 兜底/密钥/清单渲染/失败诊断 |
namespace.yaml |
opsxsql 命名空间 |
pvc.yaml |
数据卷(默认 10Gi,集群默认 StorageClass) |
deployment.yaml |
平台本体,单副本 + Recreate |
service.yaml |
ClusterIP opsxsql:80 |
service-nodeport.yaml |
可选 NodePort 入口(:30900) |
ingress.yaml |
可选,通用 nginx Ingress |
examples/ |
跨云模板:阿里 ALB / 腾讯 qcloud Ingress、Secret 模板 |
一键部署(自动跨云适配)
install.sh 自动探测云平台(阿里 ACK / 腾讯 TKE / AWS EKS / 华为 CCE / GCP GKE / Azure AKS / K3s / 自建)
与 StorageClass(显式指定 > default 注解 > 唯一 SC);自建集群无 SC 时自动创建零依赖的节点本地 PV
(hostPath + nodeAffinity 锁节点 + Retain,无需 local-path-provisioner 镜像);部署失败时按云平台给出
镜像仓库/SC 定制诊断。幂等:重复执行不覆盖密钥、不重建数据卷。
# 默认(镜像 opsxsql:latest)
bash kubernetes/install.sh
# 指定镜像 + NodePort 入口
IMAGE=registry.example.com/opsxsql:v1.0.0 bash kubernetes/install.sh --nodeport
# 指定镜像 + 通用 nginx Ingress 域名(其他云模板见 examples/)
IMAGE=registry.example.com/opsxsql:v1.1.0 bash kubernetes/install.sh --ingress opsxsql.example.com
# 自定义命名空间 / 卷大小 / 手动指定 StorageClass / 强制本地存储
NS=sql-audit PVC_SIZE=20Gi bash kubernetes/install.sh
STORAGE_CLASS=alicloud-disk-essd bash kubernetes/install.sh
LOCAL_STORAGE=force NODE_NAME=node1 bash kubernetes/install.sh # 数据固定 node1:/var/lib/opsxsql-data
| 环境变量 | 默认 | 说明 |
|---|---|---|
IMAGE |
opsxsql:latest |
镜像(构建:仓库根 docker compose build 或 docker build .) |
NS |
opsxsql |
命名空间 |
STORAGE_CLASS |
自动探测 | 指定 StorageClass |
PVC_SIZE |
10Gi |
数据卷容量 |
WITH_NODEPORT / --nodeport |
0 |
附带 NodePort :30900 入口 |
LOCAL_STORAGE |
auto |
无 SC 时:auto 自动建本地 PV / off 仅提示 / force 强制本地 |
NODE_NAME / PV_PATH |
自动 / /var/lib/opsxsql-data |
本地存储落点 |
分步部署(等价于 install.sh)
# 1) 密钥(只生成一次;SECRET_KEY 丢失会导致已加密的实例/LDAP 密码无法解密)
kubectl -n opsxsql create secret generic opsxsql-secrets \
--from-literal=SECRET_KEY="$(openssl rand -hex 32)" \
--from-literal=JWT_SECRET="$(openssl rand -hex 32)"
# 2) 清单(先把 deployment.yaml 里的 image 改成实际仓库地址)
kubectl apply -f kubernetes/namespace.yaml
kubectl apply -f kubernetes/pvc.yaml
kubectl apply -f kubernetes/deployment.yaml
kubectl apply -f kubernetes/service.yaml
# 3) 可选入口
kubectl apply -f kubernetes/service-nodeport.yaml # 或 ingress.yaml
持久化(重要)
/app/data挂 PVC,保存 SQLite 数据库与持久化 JWT 密钥。- 必须
replicas: 1+strategy: Recreate:SQLite 是单写者,滚动更新时两个 Pod 同时挂同一 RWO PVC 会互相覆盖(install.sh 已内置该约束)。 - 备份(冷备一条命令):
kubectl -n opsxsql exec deploy/opsxsql -- sqlite3 /app/data/sqlite3.db '.backup /app/data/backup-$(date +%F).db'
kubectl -n opsxsql cp deploy/opsxsql:/app/data/backup-$(date +%F).db ./backup.db
- 云盘快照走 CSI VolumeSnapshot(AWS EBS / 腾讯 CBS / 华为 EVS / 阿里 ESSD 同一套 API):
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
name: opsxsql-data-20261026
namespace: sql
spec:
volumeSnapshotClassName: <集群的 snapshotClass>
source:
persistentVolumeClaimName: opsxsql-data
多云兼容
| 项 | 做法 |
|---|---|
| 存储类 | pvc.yaml 不写 storageClassName 用默认 SC;无默认 SC 时填云厂名(AWS gp3 / 腾讯 cbs / 华为 csi-disk / 阿里 alicloud-disk-essd) |
| 镜像仓库 | deployment.yaml 的 image 填目标云可拉的仓库(Harbor / ACR / TCR / SWR),或本仓库根 Dockerfile 自行构建 |
| gh-ost | 镜像内置(在线大表 DDL 用);不用该功能可忽略,无需外置依赖 |
升级 / 卸载
# 升级:换镜像 tag 重新 install(Recreate 策略自动重建,数据卷不动)
IMAGE=registry.example.com/opsxsql:v1.1.0 bash kubernetes/install.sh --nodeport
# 卸载(数据卷保留;需要连数据一起删加 --include-data)
kubectl -n opsxsql delete deploy,svc,ingress opsxsql opsxsql-nodeport 2>/dev/null
kubectl delete ns opsxsql # 会连 PVC 一起删,谨慎