Feast Operator 实战:在 Kubernetes 上以 PostgreSQL TLS 模式部署带加密数据库连接的 Feast
2026/9/17 7:32:13 网站建设 项目流程

Feast Operator 实战:在 Kubernetes 上以 PostgreSQL TLS 模式部署带加密数据库连接的 Feast

【免费下载链接】feastThe Open Source Feature Store for AI/ML项目地址: https://gitcode.com/GitHub_Trending/fe/feast

本系列示例(examples/operator-postgres-tls-demo)演示了如何基于 Feast Operator 在 Kubernetes 集群上部署 Feast,并让 Feast 的 registry、online store、offline store 通过 TLS 加密连接 PostgreSQL。与常见的 Feast on K8s 示例不同,它的重点是:如何把 TLS 证书通过 Kubernetes 的 Volume / volumeMounts 机制挂载进 Feast Pod,并在 FeatureStore CR 与feature_store.yaml中正确配置sslrootcertsslcertsslkey等连接参数。读完本篇后,你将能够独立完成"自签证书生成 → Helm 部署 TLS PostgreSQL → 用 FeatureStore CR 挂载证书并部署 Feast → 验证 → 清理"的完整流程。

一、演示目标与前置条件

示例目录说明(README)的核心目标有两条:

  1. Feast 连接一个以 TLS 模式运行的 PostgreSQL 数据库,保证服务间通信安全;
  2. 演示 Feast 应用如何通过 Kubernetes Volume 和 volumeMount 引用 TLS 证书。虽然示例聚焦于挂载 TLS 证书,但同一机制同样适用于挂载 Kubernetes 支持的任何其他资源。

前置条件(Prerequisites):

  • 一个资源充足的 Kubernetes 集群(README 在 Troubleshooting 中特别强调,部署前先确认集群资源足够同时支撑 PostgreSQL 和 Feast);
  • 已安装并配置好的 Helm;
  • 用于管理 Feast 部署的 Feast Operator(源码位于 infra/feast-operator);
  • 运行 Notebooks 所用的 Jupyter Notebook / JupyterLab;
  • 对 Kubernetes、Helm 与 TLS 概念有基本了解。

集群侧还需要kubectlhelmCLI,开始前可执行以下命令确认:

kubectl version --client helm version

二、Notebook 流程总览与运行方式

演示由 3 个 Jupyter Notebook 按顺序构成:

  1. 01-Install-postgres-tls-using-helm.ipynb:使用 Helm 图表以 TLS 模式安装 PostgreSQL;
  2. 02-Install-feast.ipynb:使用 Feast Operator 部署 Feast;
  3. 03-Uninstall.ipynb:卸载 Feast、Feast Operator 与本演示创建的全部 PostgreSQL 资源。

运行方式:克隆 Feast 仓库后进入examples/operator-postgres-tls-demo,从仓库根目录启动 Jupyter(jupyter notebook),然后按上述编号顺序执行各 Notebook,每个 Notebook 内都包含分步说明与部署、测试、清理代码。

注意:01 号 Notebook 开头的红字提示说明,其中的 PostgreSQL 配置仅为演示 Feast Operator 配置 TLS PostgreSQL 的能力;生产环境的 Postgres 运维应参考官方 Bitnami Helm 文档。

三、Notebook 01:以 TLS 模式部署 PostgreSQL

3.1 创建命名空间

kubectl create ns feast kubectl config set-context --current --namespace feast

3.2 生成自签 TLS 证书

生产环境建议使用托管证书服务(如 Let's Encrypt),本演示使用自签证书,并需要把证书生成命令中的CN替换为实际域名。若非首次运行,先删除旧证书目录(rm -rf postgres-tls-certs),再执行:

mkdir -p postgres-tls-certs # 1) 生成 CA 证书 openssl req -new -x509 -days 365 -nodes \ -out postgres-tls-certs/ca.crt \ -keyout postgres-tls-certs/ca.key \ -subj "/CN=PostgreSQL CA" # 2) 生成服务器证书(CN 为集群内 Service DNS 名) openssl req -new -nodes \ -out postgres-tls-certs/server.csr \ -keyout postgres-tls-certs/server.key \ -subj "/CN=postgresql.feast.svc.cluster.local" openssl x509 -req -in postgres-tls-certs/server.csr -days 365 \ -CA postgres-tls-certs/ca.crt -CAkey postgres-tls-certs/ca.key \ -CAcreateserial -out postgres-tls-certs/server.crt # 3) 生成客户端证书(CN=admin,用于 mTLS 客户端身份) openssl req -new -nodes \ -out postgres-tls-certs/client.csr \ -keyout postgres-tls-certs/client.key \ -subj "/CN=admin" openssl x509 -req -in postgres-tls-certs/client.csr -days 365 \ -CA postgres-tls-certs/ca.crt -CAkey postgres-tls-certs/ca.key \ -CAcreateserial -out postgres-tls-certs/client.crt

三组文件的用途:

文件用途
ca.crt/ca.key自签 CA,用于签发并校验服务端/客户端证书
server.crt/server.keyPostgreSQL 服务端 TLS 证书(CN 为集群内 DNS 名)
client.crt/client.keyFeast 客户端使用的 mTLS 证书

3.3 创建两个 Kubernetes Secret

证书需要拆成两个 Secret 分别供服务端与客户端使用(两者都包含ca.crt):

# 服务端证书 Secret:供 PostgreSQL Server 使用 kubectl create secret generic postgresql-server-certs \ --from-file=ca.crt=./postgres-tls-certs/ca.crt \ --from-file=tls.crt=./postgres-tls-certs/server.crt \ --from-file=tls.key=./postgres-tls-certs/server.key # 客户端证书 Secret:供 Feast 应用使用 kubectl create secret generic postgresql-client-certs \ --from-file=ca.crt=./postgres-tls-certs/ca.crt \ --from-file=tls.crt=./postgres-tls-certs/client.crt \ --from-file=tls.key=./postgres-tls-certs/client.key

tls.crt/tls.key/ca.crt这三个键名是有意为之——后续 Bitnami PostgreSQL 图表通过certFilenamecertKeyFilenamecertCAFilename按这些文件名读取证书。

3.4 用 Helm 安装 TLS 模式的 PostgreSQL

将如下 values 写入values.yaml并执行helm install postgresql bitnami/postgresql --version 16.4.9 -f values.yaml -n feast

tls: enabled: true certificatesSecret: "postgresql-server-certs" # 引用 3.3 创建的服务端 Secret certFilename: "tls.crt" certKeyFilename: "tls.key" certCAFilename: "ca.crt" volumePermissions: enabled: true # 固定 PostgreSQL 凭证(后续 Feast 连接要用到) global: postgresql: auth: username: admin password: password database: feast

关键点:tls.certificatesSecret指向服务端 Secret,global.postgresql.auth固定了用户名admin、密码password、库名feast,与后面 FeatureStore CR 中postgres-secret的值一一对应。

3.5 验证 TLS 部署

kubectl wait --for=condition=Ready pod -l app.kubernetes.io/name=postgresql --timeout=60s kubectl get pods -l app.kubernetes.io/name=postgresql # 确认 postgresql.conf 中 ssl 已开启且证书路径正确 kubectl exec postgresql-0 -- cat /opt/bitnami/postgresql/conf/postgresql.conf | grep ssl # 通过集群内连接确认库已创建 kubectl exec postgresql-0 -- env PGPASSWORD=password psql -U admin -d feast -c '\l'

Notebook 的实际输出可以确认ssl = 'on'ssl_ca_file = '/opt/bitnami/postgresql/certs/ca.crt'ssl_cert_file = '/opt/bitnami/postgresql/certs/tls.crt'ssl_key_file = '/opt/bitnami/postgresql/certs/tls.key',且\l列出的库中包含 owner 为adminfeast

如果还需要从集群外用 Python 测试连接(Notebook 的 Step 8/9),需在独立终端执行端口转发(Jupyter 不支持在后台线程中保持该进程):

kubectl port-forward svc/postgresql 5432:5432

然后用 SQLAlchemy 建立带 TLS 参数的连接:

DATABASE_URL = ( f"postgresql+psycopg://{DB_USER}:{DB_PASSWORD}@{DB_HOST}:{DB_PORT}/{DB_NAME}?" f"sslmode=verify-ca&sslrootcert={SSL_ROOT_CERT}&sslcert={SSL_CERT}&sslkey={SSL_KEY}" ) engine = create_engine(DATABASE_URL) with engine.connect() as connection: print("Connected successfully!")

Notebook 中同时设置了环境变量os.environ["FEAST_CA_CERT_FILE_PATH"] = "postgres-tls-certs/ca.crt"——这正是后面 Option 2 部署方案在 Feast SDK 内部起作用的同一个变量,说明该环境变量是 Feast 识别 CA 证书的通用入口。

四、Notebook 02:用 Feast Operator 部署 Feast

4.1 安装 Feast Operator

# 从 release 分支构建的安装清单 kubectl apply -f ../../infra/feast-operator/dist/install.yaml # 等待 controller-manager 就绪 kubectl wait --for=condition=available --timeout=5m \ deployment/feast-operator-controller-manager -n feast-operator-system

该命令会创建featurestores.feast.devCRD、feast-operator-system命名空间、RBAC 与feast-operator-controller-managerDeployment。也可以改用make -C infra/feast-operator install deploy IMG=... FS_IMG=...从 master 分支构建最新镜像部署。Operator 对服务自身 TLS 的处理逻辑见 tls.go(含 OpenShift 路由证书等场景)。

4.2 核心机制:FeatureStore CR 的 Volumes 与 volumeMounts

这是整个演示的灵魂。Feast Operator 支持在 FeatureStore CR 中声明volumesvolumeMounts,把 TLS 证书文件挂载进 Pod,且底层支持 Secret、ConfigMap、PersistentVolume 等多种 Kubernetes 资源类型。相关的控制器行为与断言可在 featurestore_controller_volume_volumemount_test.go 中查阅。

在理解挂载机制之前,先理解 PostgreSQL TLS 连接 URL 中的三个关键参数(Notebook 原文):

  • sslrootcert:CA 证书路径,用于校验受信任的服务器证书;
  • sslcert:客户端证书,用于双向 TLS(mTLS)
  • sslkey:客户端证书对应的私钥。

若不要求 mTLS,可以省略sslcertsslkey,但sslrootcert仍然必要,用于验证服务器证书。

4.3 Option 1:在连接 URL 中直接写死 CA 证书路径

完整 CR 见 v1_featurestore_postgres_db_volumes_tls.yaml,其结构可拆解为三段:

① 两个 Secretpostgres-secret存放POSTGRES_DB/USER/PASSWORD/HOST四个连接变量;feast-data-stores以 YAML 文本形式存放三份数据源配置(sqlregistry、postgresoffline/online store):

stringData: sql: | path: postgresql+psycopg://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:5432/${POSTGRES_DB}?sslmode=verify-full&sslrootcert=/var/lib/postgresql/certs/ca.crt&sslcert=/var/lib/postgresql/certs/tls.crt&sslkey=/var/lib/postgresql/certs/tls.key cache_ttl_seconds: 60 sqlalchemy_config_kwargs: echo: false pool_pre_ping: true postgres: | host: ${POSTGRES_HOST} port: 5432 database: ${POSTGRES_DB} db_schema: public user: ${POSTGRES_USER} password: ${POSTGRES_PASSWORD} sslmode: verify-full sslkey_path: /var/lib/postgresql/certs/tls.key sslcert_path: /var/lib/postgresql/certs/tls.crt sslrootcert_path: /var/lib/postgresql/certs/ca.crt

② FeatureStore CR 中的证书挂载(Option 1 的要点是把sslrootcert直接指向挂载路径):

spec: feastProject: postgres_tls_sample services: volumes: - name: postgres-certs secret: secretName: postgresql-client-certs # 引用 01 中创建的客户端证书 Secret items: - key: ca.crt path: ca.crt mode: 0644 # CA 证书需要全局可读 - key: tls.crt path: tls.crt mode: 0644 # 客户端证书 - key: tls.key path: tls.key mode: 0640 # 私钥收敛权限 onlineStore: server: volumeMounts: - name: postgres-certs mountPath: /var/lib/postgresql/certs readOnly: true envFrom: - secretRef: name: postgres-secret

③ 三份数据源均通过secretRef引用feast-data-stores,registry 使用type: sql本地持久化,offline/online store 均使用type: postgres

注意items中对私钥tls.key显式设置了mode: 0640而证书为0644,这是该 CR 示例给出的权限最小化示范。部署命令:

kubectl apply -f infra/feast-operator/config/samples/v1_featurestore_postgres_db_volumes_tls.yaml --namespace=feast

4.4 Option 2:用环境变量指定 CA 证书路径

完整 CR 见 v1_featurestore_postgres_tls_volumes_ca_env.yaml。与 Option 1 的差异只有两处:

  1. postgres-secret额外增加了一个变量:FEAST_CA_CERT_FILE_PATH: /var/lib/postgresql/certs/ca.crt
  2. 数据源配置中的 CA 来源改为sslrootcert=system/sslrootcert_path: system,即不再在 URL 里写死 CA 路径,而是让 Feast SDK 从环境变量取。
FEAST_CA_CERT_FILE_PATH=<path-to-ca-cert>

这个环境变量的作用在 SDK 源码中可以印证:ssl_ca_trust_store_setup.py 中的configure_ca_trust_store_env_variables()会读取FEAST_CA_CERT_FILE_PATH,并把它同步设置到SSL_CERT_FILEREQUESTS_CA_BUNDLE,使 Python 标准库、requests 等依赖 CA bundle 的组件都能找到同一份 CA 证书。因此 Option 2 更适合需要让"非 SQLAlchemy 连接字符串"的组件(如 HTTP 客户端、gRPC)也共享同一 CA 信任链的场景。

两个 Option 只能二选一部署(Notebook 中红字强调,避免后续步骤冲突):

# Option 1 kubectl apply -f infra/feast-operator/config/samples/v1_featurestore_postgres_db_volumes_tls.yaml --namespace=feast # Option 2 kubectl apply -f infra/feast-operator/config/samples/v1_featurestore_postgres_tls_volumes_ca_env.yaml --namespace=feast

4.5 验证部署

kubectl wait --for=condition=available --timeout=8m deployment/feast-sample-db-ssl -n feast kubectl get all kubectl get feast # 期望输出:sample-db-ssl STATUS=Ready

CR 进入Ready后,进一步验证数据库与 Feast 注册内容:

# 1) 确认 registry 表已建立(feast_metadata、feature_views、feature_services 等) kubectl exec postgresql-0 -- env PGPASSWORD=password psql -U admin -d feast -c '\dt' # 2) 查看容器内渲染后的 feature_store.yaml,确认 TLS 参数注入正确 kubectl exec deploy/feast-sample-db-ssl -c online -- cat feature_store.yaml # 3) 执行 feast apply 注册示例特征仓库 kubectl exec deploy/feast-sample-db-ssl -c online -- feast apply # 4) 列出项目与特征视图 kubectl exec deploy/feast-sample-db-ssl -c online -- feast projects list kubectl exec deploy/feast-sample-db-ssl -c online -- feast feature-views list # 5) 查看 Feast 版本 kubectl exec deployment/feast-sample-db-ssl -c online -- feast version

Notebook 实际运行结果中,Option 2(postgres_tls_sample_env_ca项目)渲染出的feature_store.yaml展示了模板变量的最终形态,值得注意的三个细节:

  • offline_store / online_store 均为sslmode: verify-fullsslrootcert_path: system
  • registry 的path是完整 SQLAlchemy URL,携带sslmode=verify-full&sslrootcert=system&sslcert=...&sslkey=...
  • registry 同时配置了registry_type: sqlcache_ttl_seconds: 60sqlalchemy_config_kwargsecho: falsepool_pre_ping: true,后者保证连接池探活,避免 TLS 长连接被服务端掐断后出现坏连接)。

feast apply完成后,\dt中可以看到 registry 的 14 张表(feast_metadatafeature_viewsfeature_servicesentitiesdata_sourcespermissionsprojects等)以及示例特征视图落库的postgres_tls_sample_env_ca_driver_hourly_stats等表;feast feature-views list则列出driver_hourly_statsdriver_hourly_stats_fresh两个 FeatureView 与transformed_conv_rate等 OnDemandFeatureView。

五、Notebook 03:清理环境

# 按之前选择的 Option 删除 FeatureStore CR 与两个 Secret kubectl delete -f infra/feast-operator/config/samples/v1_featurestore_postgres_db_volumes_tls.yaml # 或 kubectl delete -f infra/feast-operator/config/samples/v1_featurestore_postgres_tls_volumes_ca_env.yaml # 卸载 Helm 发布的 PostgreSQL,并删除证书 Secret 与本地证书目录 helm uninstall postgresql kubectl delete secret postgresql-server-certs kubectl delete secret postgresql-client-certs rm -rf postgres-tls-certs # 兜底清理 PV/PVC(Notebook 注释说明:二者有时不会自动删除,可能残留引发问题) kubectl delete pvc --all kubectl delete pv --all # 确认命名空间已清空 kubectl get all # 期望:No resources found in feast namespace.

六、故障排查要点

继承 README 的 Troubleshooting 部分并结合本示例补充:

  • 集群资源:开始前确认集群有足够资源同时承载 PostgreSQL 与 Feast(Helm 安装输出中也会警告未设置primary.resourcesresources字段不适合生产)。
  • 日志诊断:遇到问题时优先查看 PostgreSQL 与 Feast Pod 的日志,可定位 TLS 配置错误(如证书路径不存在、CA 不匹配、verify-full下 CN 与主机名不一致)与资源不足两类最常见故障。
  • 密码残留:若之前删除过 Helm release 但保留了 PVC,旧 PVC 中的密码会导致新配置失效,需删除持久卷才能生效(Helm NOTES 中的明确警告)。
  • 集群外连接失败:确认kubectl port-forward是否在独立终端中保持运行(Jupyter 中无法常驻该进程)。

七、小结

本演示串起了一条完整的"加密数据库链路":openssl自签 CA/服务器/客户端三套证书 → 两个 Secret 分别喂给 PostgreSQL 与 Feast → Bitnami 图表开启tls.enabled→ FeatureStore CR 通过volumes/volumeMounts把客户端证书挂到/var/lib/postgresql/certs→ 数据源配置以sslmode: verify-full强制双向校验。两种 CA 注入方式(URL 内sslrootcert=<path>FEAST_CA_CERT_FILE_PATH环境变量 +sslrootcert=system)分别对应"仅 SQLAlchemy 链路需要 CA"与"全组件共享信任链"两类需求,而 SDK 侧 ssl_ca_trust_store_setup.py 负责把环境变量扩散到SSL_CERT_FILEREQUESTS_CA_BUNDLE,Operator 侧控制器负责把 CR 声明转化为实际 Pod spec,两者配合构成了 Feast on K8s 中 TLS 部署的完整闭环。生产环境只需把自签证书替换为托管证书(并同步更新 CN/SAN),其余部署结构均可复用。

【免费下载链接】feastThe Open Source Feature Store for AI/ML项目地址: https://gitcode.com/GitHub_Trending/fe/feast

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询