- 云原生
- 后端
- 运维
【免费下载链接】Terminus
Open-Source Personal Cloud OS for Always-On Agents
在 Olares 中,PostgreSQL 是默认预装的基础数据库中间件。应用开发者无需关心数据库的部署与运维细节,只需在OlaresManifest.yaml中声明依赖,并在 Helm 模板里把系统注入的连接信息映射为容器环境变量,即可在应用中使用一套安全、隔离、由平台统一托管的 PostgreSQL 服务。本文将以 Olares 官方集成指南为主线,结合仓库源码逐层拆解完整的集成流程、配置参数与变量注入机制,帮助你快速上手。
集成原理:声明式中间件依赖如何生效
Olares 的中间件指位于应用与系统之间的基础设施服务,用于提供数据存储、消息通信等通用能力。PostgreSQL 的集成过程是声明式的:开发者只在OlaresManifest.yaml中描述"我需要什么数据库、哪些扩展、初始化时执行什么脚本",具体的资源申请、账号创建、数据库初始化、连接信息生成,均由 Olares 在部署阶段自动完成(参见中间件指南)。
整个集成链路可概括为三个步骤:
- 声明:在
OlaresManifest.yaml的middleware.postgres段声明用户名、数据库、扩展与初始化脚本; - 自动处理:部署时 Olares 应用运行时解析该声明,向中间件服务发起
MiddlewareRequest,创建数据库与账号并返回连接信息,随后将连接信息注入应用的values.yaml; - 映射:在应用的部署模板(如
deployment.yaml)中,将.Values.postgres.*映射为容器环境变量。
系统注入的变量是只读的、由平台统一管理,且属于 Helm values——它们不会自动进入容器,必须通过env:显式映射才能被应用进程读取(详见系统注入的运行时变量)。
配置OlaresManifest.yaml声明 PostgreSQL 依赖
在应用包的OlaresManifest.yaml中添加middleware.postgres配置段即可完成依赖声明:
- 使用
scripts字段指定数据库创建完成后需要执行的 SQL 脚本(按顺序执行); - 使用
extensions字段为数据库添加所需的扩展(如vectors、earthdistance、pg_trgm等); - 系统在执行脚本时会自动提供并替换两个变量:
$databasename(数据库名)和$dbusername(数据库用户名),由 Olares 应用运行时在脚本执行前注入。
官方文档给出的完整示例(以 Immich 应用申请向量数据库为例):
middleware: postgres: username: immich databases: - name: immich extensions: - vectors - earthdistance scripts: - BEGIN; - ALTER DATABASE $databasename SET search_path TO "$user", public, vectors; - ALTER SCHEMA vectors OWNER TO $dbusername; - COMMIT;上述示例的含义是:申请一个名为immich的数据库,为其安装vectors(向量检索)与earthdistance(地球距离计算,用于地理邻近查询)扩展,并执行三条 SQL:把数据库默认search_path调整为包含vectorsschema,再把vectorsschema 的所有者移交给当前用户,最终提交事务。
更完整的字段形态
从仓库中用于测试的完整 Manifest(framework/oac/testdata/full_manifest/OlaresManifest.yaml)可以看到middleware.postgres支持的全部字段:
middleware: postgres: username: pguser password: pgpass databases: - name: appdb extensions: - pg_trgm scripts: - init.sql distributed: true各字段说明:
| 字段 | 类型 | 说明 | | -- | -- | -- | |username| String | 申请的 PostgreSQL 用户名。实际生效的用户名会由平台进一步组合加工(见下文"源码实现"一节)。 | |password| String | 可选。若不填写,系统会生成随机密码并通过 Secret 注入。 | |databases[]| Array | 申请的数据库列表,可申请多个。 | |databases[].name| String | 数据库名称,需与后续环境变量映射中的 key 对应。 | |databases[].extensions| Array | 需要安装的 PostgreSQL 扩展名称列表。 | |databases[].scripts| Array | 数据库创建后按顺序执行的 SQL 脚本,支持$databasename、$dbusername两个自动替换变量。 | |databases[].distributed| Boolean | 是否为分布式数据库(Olares 的 PostgreSQL 基于 Citus 构建,可声明分布式表能力)。 |
这些字段对应的 Go 类型定义可在 framework/oac/internal/manifest/types.go 中确认:Middleware、Database、PostgresConfig等类型均以github.com/beclab/api/manifest中的共享定义为准,保证了 Manifest 解析、校验与应用运行时各模块操作的是同一套类型结构。
映射环境变量:把连接信息传入容器
在应用部署模板中,将系统注入的.Values.postgres.*字段映射为应用所需的环境变量:
containers: - name: my-app env: # 在 OlaresManifest 中配置的数据库名称, # 对应 middleware.postgres.databases[i].name # 注意:将 <dbname> 替换为 Manifest 中定义的实际名称(例如 immich) - name: DB_POSTGRESDB_DATABASE value: {{ .Values.postgres.databases.<dbname> }} # 主机地址 - name: DB_POSTGRESDB_HOST value: {{ .Values.postgres.host }} # 端口 - name: DB_POSTGRESDB_PORT value: "{{ .Values.postgres.port }}" # 用户名 - name: DB_POSTGRESDB_USER value: {{ .Values.postgres.username }} # 密码 - name: DB_POSTGRESDB_PASSWORD value: {{ .Values.postgres.password }}使用要点:
- 数据库名映射:
.Values.postgres.databases是一个以数据库名为键的 Map。申请了几个数据库,就对应几个 key。例如申请了immich,就用{{ .Values.postgres.databases.immich }}取值; - 端口字符串化:
.Values.postgres.port类型是 Number,映射到环境变量时必须加引号("{{ .Values.postgres.port }}"),否则 Helm 渲染后环境变量值可能不是字符串; - 与"系统注入的运行时变量"文档中的示例保持一致:
{{ .Values.postgres.host }}这类引用同样可以出现在任何 Helm 模板文件中,比如把数据库主机地址注入为DB_HOST(参见系统注入的运行时变量)。
PostgreSQL 变量参考
PostgreSQL 运行时变量会在部署过程中注入到values.yaml,由系统统一管理、用户无法自行修改:
| 变量 | 类型 | 说明 | | -- | -- | -- | |.Values.postgres.host| String | PostgreSQL 主机地址。 | |.Values.postgres.port| Number | PostgreSQL 端口。 | |.Values.postgres.username| String | PostgreSQL 用户名。 | |.Values.postgres.password| String | PostgreSQL 密码。 | |.Values.postgres.databases| Map<String,String> | 请求的数据库集合,按数据库名为键。例如,若申请的数据库名为app_db,可通过.Values.postgres.databases.app_db获取对应值。 |
源码视角:中间件请求如何被构造与注入
理解集成原理的最好方式是阅读应用安装器(app-service)中负责中间件编排的代码。核心逻辑位于 framework/app-service/pkg/tapr/middleware.go,其中Apply函数在应用部署时被调用:
- 构造用户名:PostgreSQL 的最终用户名并非直接使用 Manifest 中的
username,而是组合为{username}_{ownerName}_{appName},并把连字符替换为下划线(middleware.go#L146-L149)。这样既避免了不同用户/不同应用之间账号冲突,也符合 PostgreSQL 标识符规范; - 生成请求:
process函数通过 GenMiddleRequest 将 Manifest 中的 PostgreSQL 配置渲染为MiddlewareRequest自定义资源(CRD),请求体通过 Gotext/template生成(postgresRequest 模板),包含databases(含distributed、extensions、scripts)、password(显式值或secretKeyRef引用)、user等字段; - 密码处理:若 Manifest 未显式提供
password,安装器会调用CreateOrUpdateSecret创建同名密码 Secret({appName}-{namespace}-postgres-password),并在MiddlewareRequest中以valueFrom.secretKeyRef方式引用(middleware_request_tpl.go#L37-L45); - 获取连接信息并注入:安装器向
http://middleware-service.os-platform/middleware/v1/request/info发起带重试(404/429/5xx 自动重试 3 次)的查询,拿到返回的host、port、username、password、databases,最终写入vals["postgres"](middleware.go#L111-L164),这就是.Values.postgres.*系列变量的最终来源。
此外,Olares 的 CLI 脚手架还会在打包阶段进行中间件规范检查:如果应用把 PostgreSQL 之类的数据存储直接打进自身镜像并作为 Workload 运行,脚手架会给出提示,要求替换为 Olares 系统中间件并声明options.dependencies依赖(参见 cli/pkg/chart/scaffold.go 与 scaffold.go#L884)。这从工具链层面保证了"声明式集成中间件"是唯一受支持的数据库接入方式。
获取连接信息与数据验证
集成完成后,如需人工查看或管理数据库数据(例如验证初始化脚本是否生效、排查写入问题),可以按查看 PostgreSQL 数据指南操作:从控制面板左侧导航栏的"中间件 → Postgres"中获取主机、用户、密码(连接信息面板如下图所示),再选择通过 Olares 终端进入 PostgreSQL 容器(kubectl exec -it -n os-platform citus-0 -- sh)后用psql -h citus-0 -U olares连接,或通过 Bytebase 进行可视化管理。
小结
在 Olares 中集成 PostgreSQL 是一个"声明 + 自动注入 + 显式映射"的过程:在OlaresManifest.yaml里通过middleware.postgres声明数据库、扩展与初始化脚本,平台即自动完成账号创建、数据库初始化与连接信息生成,并通过.Values.postgres.*变量注入到应用;应用侧只需在部署模板中把对应值映射为环境变量即可。借助仓库源码(middleware.go、middleware_request_tpl.go)可以清晰看到从 Manifest 到MiddlewareRequest、再到values.yaml的完整调用链,帮助你在遇到连接异常或权限问题时快速定位原因。
- 云原生
- 后端
- 运维
【免费下载链接】Terminus
Open-Source Personal Cloud OS for Always-On Agents
相关推荐
Terminus(Olares)PostgreSQL 中间件集成指南:从 `OlaresManifest.yaml` 声明到应用连接信息注入
Terminus(Olares)PostgreSQL 中间件集成指南:从 OlaresManifest.yaml 声明到应用连接信息注入 在 Terminus(
云原生后端运维Olares 应用集成 Redis:通过 OlaresManifest 声明中间件依赖并映射连接变量
Olares 应用集成 Redis:通过 OlaresManifest 声明中间件依赖并映射连接变量 本文介绍如何在 Olares(开源个人云操作系统)中,通过
云原生后端运维Terminus(Olares)RabbitMQ 中间件集成实战:用 OlaresManifest.yaml 声明式接入消息队列
Terminus(Olares)RabbitMQ 中间件集成实战:用 OlaresManifest.yaml 声明式接入消息队列 本篇技术指南基于 Termin
云原生后端运维
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考