Kubernetes (Helm) 部署
如果准备把 Luna DevOps 长期运行在 Kubernetes 中,推荐使用 Helm。Chart 会一起部署 API、Worker、PostgreSQL 和 Redis,也可以改为连接已有的外部数据库与 Redis。
本文命令以标准 Kubernetes 为基准,也兼容满足兼容范围的 K3s 和其他 Kubernetes 发行版;发行版特有的存储、Ingress 或安全策略需要由集群管理员适配。
开始前准备
你需要:
- 一个可用的 Kubernetes 或 K3s 集群。
- 本机已经配置好
kubectl 和 helm。
- 集群能拉取 DockerHub 镜像。
- 默认 StorageClass 可用,用来保存 PostgreSQL 和 Redis 数据。
安装
数据库全新时,先把首个管理员配置保存到 Kubernetes Secret。下面的文件应设置为仅当前用户可读,用完后安全删除;名称和语言键可以省略,API 会分别回退为邮箱和 zh-CN:
initial-admin.env
initial-admin-email=admin@example.com
initial-admin-password=请替换为8至72字节的强密码
然后在仓库根目录执行:
kubectl create namespace luna-devops
kubectl -n luna-devops create secret generic luna-devops-initial-admin \
--from-env-file=initial-admin.env
helm install luna-devops ./charts/luna-devops \
--namespace luna-devops \
--set api.initialAdmin.existingSecret=luna-devops-initial-admin
默认会同时安装 API、Worker、PostgreSQL 和 Redis。管理员 Secret 只注入 API;API 仅在全新数据库中创建首个管理员,不会在升级或重启时覆盖已有账号。已有有效管理员的数据库可以不设置 api.initialAdmin,Chart 仍能正常安装或升级。AI 助手默认关闭;启用时设置 ai.enabled=true,并通过 ai.existingSecret 提供稳定的 ai-internal-secret。
确认可以登录后,可以让 API 脱离初始化 Secret,再删除它:
helm upgrade luna-devops ./charts/luna-devops \
--namespace luna-devops \
--reuse-values \
--set-string api.initialAdmin.existingSecret=
kubectl -n luna-devops delete secret luna-devops-initial-admin
四个 Secret 键引用都是可选的;existingSecret 为空时,Chart 不会创建或引用初始管理员 Secret。首管密码只允许通过外部 Secret 提供,不进入 Helm values 或 release history。
打开控制台
先把 API Service 转发到本机:
kubectl -n luna-devops port-forward svc/luna-devops-api 8088:80
然后访问:
http://localhost:8088/login
使用固定版本
helm upgrade --install luna-devops ./charts/luna-devops \
--namespace luna-devops \
--create-namespace \
--set api.initialAdmin.existingSecret=luna-devops-initial-admin \
--set api.image.tag=v0.1.0-rc.1 \
--set worker.image.tag=v0.1.0-rc.1 \
--set ai.agent.image.tag=v0.1.0-rc.1
通过公网域名访问
如果通过 Ingress 暴露控制台,把 app.publicBaseUrl 改成用户真实访问的地址:
helm upgrade --install luna-devops ./charts/luna-devops \
--namespace luna-devops \
--create-namespace \
--set api.initialAdmin.existingSecret=luna-devops-initial-admin \
--set app.publicBaseUrl=https://devops.example.com \
--set-string app.trustedProxyCidrs=10.42.0.0/16 \
--set ingress.enabled=true \
--set ingress.className=nginx \
--set ingress.hosts[0].host=devops.example.com
app.publicBaseUrl 会影响 OIDC 回调、Webhook 回调和浏览器跨域校验,不要写成集群内 Service 地址。示例中的 10.42.0.0/16 仅表示专用的 Ingress/反向代理来源网段;请替换为 API 实际看到的来源及可信转发链代理出口。只有网络隔离能阻止其他 Pod 直连 API 时,才能使用整段 Pod CIDR。Chart 在启用 Ingress 且未显式设置该边界时会拒绝渲染,并始终拒绝 0.0.0.0/0 和 ::/0。
使用外部 PostgreSQL 或 Redis
内置数据库适合快速启动。生产环境已经有托管 PostgreSQL 或 Redis 时,可以关闭对应内置组件:
postgresql:
enabled: false
externalDatabase:
url: postgres://devops:password@postgres.example.com:5432/devops?sslmode=disable
redis:
enabled: false
externalRedis:
url: redis://default:replace-with-a-strong-password@redis.example.com:6379/0
外部 Redis 可以使用连接 URI 或现有 Secret;TLS 连接使用 rediss://。生产环境请通过 Kubernetes Secret 提供凭据,不要把密码直接提交到 values 文件。
然后安装:
helm upgrade --install luna-devops ./charts/luna-devops \
--namespace luna-devops \
--create-namespace \
-f values-prod.yaml
配置浏览器 Trace Relay 鉴权
API 会代理浏览器 Trace。若这个 Relay 使用与 API、Worker、Agent 通用 Collector 不同的鉴权,先把完整的 OTEL_EXPORTER_OTLP_TRACES_HEADERS 值保存到独立 Kubernetes Secret。下面的本地文件只应由当前用户读取,创建 Secret 后请安全删除;空格等特殊字符需按 URL 编码,例如 %20:
browser-trace-headers.txt
Authorization=Bearer%20请替换为Relay令牌
kubectl -n luna-devops create secret generic luna-devops-browser-trace-auth \
--from-file=otlp-traces-headers=browser-trace-headers.txt
在生产 values 中只保存 Secret 名称和键名,不要写入 Header 凭据。独立 Relay 地址不是密钥,可以通过 API 专属 extraEnv 配置;省略该地址时,浏览器 Trace 仍使用通用 OTLP 地址,但改用这里的 API 专属鉴权:
api:
browserTrace:
existingSecret: luna-devops-browser-trace-auth
headersKey: otlp-traces-headers
extraEnv:
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: https://trace-relay.example.com/v1/traces
若浏览器 Trace 与通用 Collector 使用相同鉴权,请让 api.browserTrace.existingSecret 保持为空,API 会继续回退到 observability.existingSecret。专属 Secret 只注入 API,不会进入 Worker 或 Agent;Chart 也会拒绝通过 api.extraEnv.OTEL_EXPORTER_OTLP_TRACES_HEADERS 写入明文凭据。
配置 Agent 网络策略
Chart 默认启用 API 到 Agent 的入站隔离,但不默认限制 Agent 出站。Agent 需要访问模型 Provider、
OpenTelemetry Collector 和 PostgreSQL;其中动态域名无法由原生 Kubernetes NetworkPolicy 可靠表达。
只有列全实际目的地后才启用出站隔离,例如:
ai:
agent:
networkPolicy:
egress:
enabled: true
additionalCIDRs:
- 203.0.113.10/32
additionalRules:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: observability
ports:
- protocol: TCP
port: 4318
模型 Provider 使用动态地址时,请改用支持 FQDN 策略的 CNI 或稳定出口代理,不要把未覆盖真实目的地
的 deny-all 规则当作可用配置。Agent 的非 root 用户、只读根文件系统和禁用 ServiceAccount Token
不受此开关影响。
常用配置
卸载
helm uninstall luna-devops -n luna-devops
PVC 默认会保留,避免误删数据。确认不再需要这些数据后,再手动清理:
kubectl -n luna-devops delete pvc -l app.kubernetes.io/instance=luna-devops