- 云原生
- 后端
- 运维
【免费下载链接】Terminus
Open-Source Personal Cloud OS for Always-On Agents
在 Olares 上开发或上架应用时,关系型数据库的接入方式与普通 K8s 环境不同:你不需要在 chart 里自带 MySQL、手写凭据,只需要在OlaresManifest.yaml中声明middleware.mysql需求,平台安装流程就会自动创建中间件请求、生成账号密码,并把host/port/username/password/databases等连接值注入 Helmvalues.yaml,再由你在模板里映射成容器环境变量。读完本文,你可以独立完成三件事:配置 MySQL 中间件声明、把注入值正确映射为应用环境变量、读懂.Values.mysql.*各字段的类型与语义,并能结合仓库源码理解整条“声明 → 申请 → 注入”链路的底层实现。
前置步骤:从 Market 安装 MySQL 服务
MySQL 中间件服务不是系统自带的,需要先从 Market 安装:
- 在 Launchpad 中打开Market,搜索 “MySQL”;
- 点击Get,再点击Install,等待安装完成。
安装完成后,该服务及其连接详情会出现在Control Hub的Middleware列表中。这一步是后续所有配置的前提——源码层面的依据是:安装/升级应用时,平台会先校验名为mysql-middleware-mysql的ApplicationManager资源是否存在且Status.State == "running",不满足则判定 MySQL 中间件需求未就绪(见 CheckMiddlewareRequirement)。
在 OlaresManifest.yaml 中声明 MySQL 需求
应用的中间件需求统一声明在OlaresManifest.yaml的middleware段下,MySQL 对应middleware.mysql:
username:指定 MySQL 数据库用户名的基础前缀;databases:请求一个或多个数据库。每个数据库名会作为 key 出现在注入值.Values.mysql.databases中;password(可选):在 manifest 中未提供时,平台会在集群中自动创建 Secret 并随机生成密码(见后文“原理”部分)。
最小可用示例:
middleware: mysql: username: mysqlclient databases: - name: aaa一个带显式密码、多数据库的完整写法(与仓库测试夹具中的用法一致,参考 OlaresManifest.yaml 测试夹具):
middleware: mysql: username: mysqluser password: mysqlpass databases: - name: mysqlapp - name: analytics注意:middleware段是通用结构,同一应用中可以并行声明 postgres、redis、mongodb、minio、mariadb、clickhouse 等多种中间件,每个子段的字段各不相同。以 MySQL 为例,databases是一个仅含name的列表;而 postgres 还支持extensions、scripts、distributed等 MySQL 不具备的字段(完整对照见上述测试夹具的 middleware 段)。
将注入值映射到容器环境变量
声明只是“申请”,真正让应用连上数据库,还需要在 chart 的部署模板(deployment YAML)中,把平台注入的.Values.mysql.*字段映射到你的应用需要的容器环境变量:
containers: - name: my-app # For MySQL, the corresponding values are as follows env: - name: MDB_HOST value: "{{ .Values.mysql.host }}" - name: MDB_PORT value: "{{ .Values.mysql.port }}" - name: MDB_USER value: "{{ .Values.mysql.username }}" - name: MDB_PASSWORD value: "{{ .Values.mysql.password }}" # Database name # The database name configured in OlaresManifest (e.g., aaa) - name: MDB_DB value: "{{ .Values.mysql.databases.aaa }}"要点说明:
- 环境变量名(如
MDB_HOST)由你的应用自行约定,模板里映射的值才是平台保证的; - 数据库名必须写成
.Values.mysql.databases.<数据库名>,其中<数据库名>就是你在OlaresManifest.yaml里声明的databases[].name(示例中为aaa); - 如果声明了多个数据库,可以映射多个变量,例如
MDB_DB_2: "{{ .Values.mysql.databases.analytics }}"。
.Values.mysql.*值参考
MySQL 的 values 是部署期间注入values.yaml的预定义运行时值,由系统管理、不可在 values 文件中手工编辑。完整字段如下:
| Value | 类型 | 说明 |
|---|---|---|
.Values.mysql.host | String | MySQL 服务主机地址 |
.Values.mysql.port | Number | MySQL 端口 |
.Values.mysql.username | String | MySQL 用户名 |
.Values.mysql.password | String | MySQL 密码 |
.Values.mysql.databases | Map<String,String> | 请求的数据库映射,key 为数据库名。例如请求了app_db,则位于.Values.mysql.databases.app_db |
从源码结构看,mysql键是所有应用 chart 的 values 脚手架的一部分:BuildValues 会预置"mysql": {"databases": {}}空骨架,并有测试 TestBuildValues_HasStableScaffold 强制校验mysql等所有中间件 key 必须存在,保证 chart 模板可以安全地引用这些路径。
原理深潜:一次 MySQL 中间件申请在集群里发生了什么
以上配置背后的执行逻辑集中在 tapr.Apply(由应用安装器 HelmOps.TaprApply 在安装/升级流程中调用)。当检测到middleware.mysql非空时,流程分四步:
1. 组合真实用户名。manifest 里的username只是前缀,实际用户名按manifestUsername-ownerName-appName拼接:
username := fmt.Sprintf("%s-%s-%s", middleware.MySQL.Username, ownerName, appName)(见 middleware.go#L303-L309)。也就是说,即便两个应用声明了相同的username,最终也各自拥有独立的 MySQL 账号,天然隔离。
2. 生成并下发 MiddlewareRequest 资源。genMysqlRequest 使用内置模板渲染出一个MiddlewareRequest(apiVersion: apr.bytetrade.io/v1alpha1),核心内容如下(渲染结果结构):
apiVersion: apr.bytetrade.io/v1alpha1 kind: MiddlewareRequest metadata: name: <appName>-mysql namespace: <namespace> spec: app: <appName> appNamespace: <appNamespace> middleware: mysql mysql: databases: - name: aaa password: value: <显式密码> # 未指定密码时改为 valueFrom 指向 Secret user: <组合后的用户名>模板原文见 mysqlRequest 模板。这里体现了一个关键细节:password字段支持value(显式指定)或valueFrom.secretKeyRef(引用 Secret)两种形态;当 manifest 未提供密码时,process函数会先调用 CreateOrUpdateSecret 创建名为<appName>-<namespace>-mysql-password的 Secret 并生成随机密码,模板随后引用它。这样凭据不落盘在 chart 里。
3. 轮询中间件服务获取连接信息。请求提交后,getMiddlewareRequest向http://middleware-service.os-platform/middleware/v1/request/infoPOST 请求(带 BFL token 与用户名头,1 秒超时,404/429/5xx 自动重试 3 次),响应体MiddlewareRequestResp包含Host、Port、UserName、Password以及Databases(map[string]string,key 为请求的数据库名)。
4. 回填 Helm values。拿到响应后,代码把连接信息整体写入values["mysql"]:
vals["mysql"] = map[string]interface{}{ "host": resp.Host, "port": resp.Port, "username": resp.UserName, "password": resp.Password, "databases": resp.Databases, }这一步与上文 values 参考表一一对应——.Values.mysql.databases.aaa之所以可用,正是因为Databases是以数据库名为 key 的 map。
验证与排障建议
- 应用安装失败且日志提示中间件相关错误时,先确认 Control Hub 的 Middleware 列表中 MySQL 服务状态为运行中(对应源码检查的
mysql-middleware-mysqlApplicationManager 是否running,见 validate.go#L646-L656); - 应用 Pod 已起来但连不上数据库时,优先核对环境变量映射是否写对了数据库 key:
.Values.mysql.databases.<name>中的<name>必须与OlaresManifest.yaml里的databases[].name完全一致; - 修改数据库列表(增删
databases条目)属于 manifest 变更,应在应用升级时重新触发中间件请求流程,而不是手工改 Secret。
小结
Olares 的 MySQL 接入模型可以概括为三步:Market 安装服务 →OlaresManifest.yaml声明middleware.mysql(username + databases)→ chart 模板中把.Values.mysql.*映射为容器环境变量。平台负责账号隔离、凭据安全存储与连接信息注入,应用侧只消费五个确定性的注入值。理解了 tapr 包 中“组合用户名 → 下发 MiddlewareRequest → 轮询 request/info → 回填 values”这条链路,你就能把同一套模式平移到 MariaDB、ClickHouse、PostgreSQL 等其他关系型中间件上(它们的 values 结构与 MySQL 几乎同构,仅数据库条目支持的扩展字段不同)。
- 云原生
- 后端
- 运维
【免费下载链接】Terminus
Open-Source Personal Cloud OS for Always-On Agents
相关推荐
Terminus(Olares)应用集成 Elasticsearch 中间件:OlaresManifest 声明、values 注入与环境变量映射
Terminus(Olares)应用集成 Elasticsearch 中间件:OlaresManifest 声明、values 注入与环境变量映射 本篇基于 T
云原生后端运维在 Olares(Terminus)中声明式接入 MinIO:从 OlaresManifest.yaml 到容器环境变量映射
在 Olares(Terminus)中声明式接入 MinIO:从 OlaresManifest.yaml 到容器环境变量映射 本篇基于 Terminus 仓库的
云原生后端运维Terminus (Olares) 应用环境变量机制详解:`.Values.olaresEnv` 声明式注入与系统运行时值
Terminus Olares 应用环境变量机制详解: .Values.olaresEnv 声明式注入与系统运行时值 本篇技术指南基于 Olares(Termi
云原生后端运维
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考