news 2026/10/14 17:07:54

Olares 应用接入 MySQL 中间件:OlaresManifest 声明、值注入与环境变量映射全解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Olares 应用接入 MySQL 中间件:OlaresManifest 声明、值注入与环境变量映射全解
  • 云原生
  • 后端
  • 运维

【免费下载链接】Terminus

Open-Source Personal Cloud OS for Always-On Agents

项目地址:https://gitcode.com/gh_mirrors/terminus2/Terminus
点击查看免费下载

在 Olares 上开发或上架应用时,关系型数据库的接入方式与普通 K8s 环境不同:你不需要在 chart 里自带 MySQL、手写凭据,只需要在OlaresManifest.yaml中声明middleware.mysql需求,平台安装流程就会自动创建中间件请求、生成账号密码,并把host/port/username/password/databases等连接值注入 Helmvalues.yaml,再由你在模板里映射成容器环境变量。读完本文,你可以独立完成三件事:配置 MySQL 中间件声明、把注入值正确映射为应用环境变量、读懂.Values.mysql.*各字段的类型与语义,并能结合仓库源码理解整条“声明 → 申请 → 注入”链路的底层实现。

前置步骤:从 Market 安装 MySQL 服务

MySQL 中间件服务不是系统自带的,需要先从 Market 安装:

  1. 在 Launchpad 中打开Market,搜索 “MySQL”;
  2. 点击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.hostStringMySQL 服务主机地址
.Values.mysql.portNumberMySQL 端口
.Values.mysql.usernameStringMySQL 用户名
.Values.mysql.passwordStringMySQL 密码
.Values.mysql.databasesMap<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

项目地址:https://gitcode.com/gh_mirrors/terminus2/Terminus
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/14 17:07:41

上海莘庄壁挂炉维修|松下壁挂炉故障维修|主板失灵无法启动上门排查|欧米到家报修热线

&#x1f525; 壁挂炉是家庭中冬季24小时不间断供暖与供热水的核心设备&#xff0c;一旦突发不点火、不加热、漏水异响或显示屏报错&#xff0c;全家取暖和热水往往立刻受影响。上海家庭使用的壁挂炉品牌繁多&#xff0c;电控逻辑和燃烧结构差异较大。本文系统梳理上海地区壁挂…

作者头像 李华
网站建设 2026/10/14 17:06:40

MQTT遗嘱消息LWT与离线判定:从幽灵在线到精准状态管理

1. 从一次"幽灵在线"事故说起设备明明已经拔了电源&#xff0c;平台上的在线状态却还亮着绿灯&#xff0c;刷新页面、重启服务端都无济于事&#xff0c;直到几分钟甚至几十分钟后才姗姗来迟地变成离线。这种"幽灵在线"的现象&#xff0c;做物联网平台的人几…

作者头像 李华
网站建设 2026/10/14 17:04:37

Pandas DataFrame.to_html() 生成HTML表格与CSS美化实战指南

做数据分析的人&#xff0c;谁还没为“把表格弄到网页上”这件事折腾过几回&#xff1f;报表系统里要展示一个带样式的数据表格&#xff0c;往往绕不开前后端联调、接口对接一堆杂事。其实最省事的路子一直都很朴素——让 Pandas 直接把 DataFrame 转成 HTML。今天要聊的DataFr…

作者头像 李华
网站建设 2026/10/14 17:04:30

插件加载失败排查全解析:从did not activate到插件协议四件套

先说个结论&#xff1a;99% 的“插件加载失败”报错&#xff0c;不是因为插件本身有多脆弱&#xff0c;而是因为我们把“插件”这两个字想得太简单了。前几天我处理了一个特别典型的问题&#xff0c;启动日志里刷着harness failed to load plugins web boot: 2 entries did not…

作者头像 李华
网站建设 2026/10/14 17:04:06

SpringApplication启动流程源码解析

从main方法的SpringApplication.run()开始&#xff0c;这里是使用类名调用静态方法&#xff0c;这是启动的入口contrlb进入源码&#xff0c;看到这个run方法&#xff0c;在这里面这个静态run方法的实现分为两步骤&#xff0c;第一先初始化实例SpringApplication,然后再调用Spri…

作者头像 李华
网站建设 2026/10/14 17:04:02

CAN总线通信原理与STM32 bxCAN外设开发实战

以前一直觉得&#xff0c;搞懂 CAN 总线是个“早晚要做但不着急”的事。真正被逼着去弄明白&#xff0c;是某个项目里两块主控板之间需要用一根线传状态&#xff0c;板子距离两三米&#xff0c;线还从电机旁边走&#xff0c;UART 直接废掉&#xff0c;I2C 更是想都别想。换成 C…

作者头像 李华