ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

CloudNativePG 应用连接指南:通过 Kubernetes Services 与 Secrets 接入 PostgreSQL 集群

CloudNativePG 应用连接指南:通过 Kubernetes Services 与 Secrets 接入 PostgreSQL 集群 CloudNativePG 应用连接指南通过 Kubernetes Services 与 Secrets 接入 PostgreSQL 集群【免费下载链接】cloudnative-pgThe most popular Kubernetes Operator for PostgreSQL.项目地址: https://gitcode.com/GitHub_Trending/cl/cloudnative-pg本指南面向希望在 Kubernetes 集群内让应用接入 CloudNativePG 所管理 PostgreSQL 集群的开发者与运维人员系统讲解 Operator 为每个集群自动生成的服务发现机制DNS 解析与环境变量、凭据 Secrets 的字段结构以及如何遵循最佳实践安全、稳定地建立数据库连接。阅读本文后你将掌握rw/ro/r三类服务的选择方法、-app与-superuser两类凭据的正确使用场景并能基于仓库源码理解其底层实现在真实集群中直接落地可运行的连接配置。应用接入的核心原则通过 Operator 管理的服务而非直连实例CloudNativePG 假定应用与其托管的 PostgreSQL 集群位于同一个 Kubernetes 集群内并通过 Operator 为每个Cluster资源创建的标准 Kubernetes 网络服务Service来暴露数据库访问。官方文档明确建议强烈推荐在应用中使用这些服务避免直接连接某个具体的 PostgreSQL 实例因为实例尤其主节点在集群生命周期内会发生切换、滚动更新或故障恢复直连实例将导致连接中断与应用不可用。以 CloudNativePG 的集群pg-database为例其 Pod 名称形如pg-database-1、pg-database-2……如果应用硬编码连接pg-database-1一旦该实例因故障被替换、或因提升/降级改变角色应用将失去可用端点。而通过服务名连接Kubernetes 会持续将流量转发到当前满足条件的实例上。CloudNativePG 为集群创建的三类四类服务从仓库中的服务实现源码可以确认CloudNativePG 为每个集群默认创建以下服务见 pkg/specs/services.go 中的CreateClusterReadWriteService、CreateClusterReadOnlyService、CreateClusterReadService、CreateClusterAnyService四个构造函数服务名以集群pg-database为例作用底层 Selector 依据对应源码函数pg-database-rw指向集群主实例Primary支持读写roleprimary标签CreateClusterReadWriteServicepg-database-ro指向全部热备副本Replica只读rolereplica标签CreateClusterReadOnlyServicepg-database-r指向集群内任意一个实例含主实例只读roleinstance标签含主与备CreateClusterReadServicepg-database-any指向所有实例包括未就绪的 Podroleinstance标签且publishNotReadyAddresses: trueCreateClusterAnyService服务命名遵循CLUSTER_NAME-SERVICE_NAME约定该约定定义于 api/v1/cluster_types.go 的ServiceAnySuffix-any、ServiceReadSuffix-r、ServiceReadOnlySuffix-ro、ServiceReadWriteSuffix-rw并由 api/v1/cluster_funcs.go 中的GetServiceAnyName、GetServiceReadName、GetServiceReadOnlyName、GetServiceReadWriteName四个方法拼接生成。其中rw服务在保证 PostgreSQL 复制上不可或缺不能被禁用ro与r服务可通过managed.services.disabledDefaultServices选项关闭详见下文服务管理。上述默认服务名均被 CloudNativePG 保留用户自定义服务时不可占用。这些服务默认均为ClusterIP类型端口映射为postgres.ServerPort5432且-any服务设置了publishNotReadyAddresses: true确保实例在尚未就绪时也能被解析到——这对需要等待所有实例建立联系的运维工具很有用但对一般业务应用请使用rw/ro/r。服务在读写分离中的典型用法读写应用ORM、业务主流程连接pg-database-rw始终打到主实例保证写一致性。只读报表/分析查询连接pg-database-ro流量分散到各热备副本减轻主实例负载集群无副本时该服务不暴露端点。容忍读主节点如既想负载均衡又不介意主实例参与只读连接pg-database-r。服务发现方式一Kubernetes DNS 解析推荐Kubernetes 集群 DNS 是 CloudNativePG 正常运行所依赖的基础设施也是最推荐的发现方式。应用可通过服务名直接解析到对应 Service 的 ClusterIP同命名空间直接使用服务名例如pg-database-rw、pg-database-ro。跨命名空间使用完整限定名FQDN 短形式service-name.namespace-name例如pg-database-rw.apps。更进一步Kubernetes 会为每个 Service 生成形如pg-database-rw.default.svc.cluster.local的完整 DNS 名cluster.local为默认集群域。CloudNativePG 在生成凭据时使用的正是此类 FQDN细节见下文 Secrets 章节。在 Deployment 中通过 DNS 使用服务的示例apiVersion: apps/v1 kind: Deployment metadata: name: my-app spec: template: spec: containers: - name: app image: my-app:latest env: # 同命名空间直接使用服务名 - name: PGHOST value: pg-database-rw - name: PGPORT value: 5432服务发现方式二环境变量同命名空间如果应用与 PostgreSQL 集群部署在同一个命名空间Kubernetes 会自动为同命名空间内每个 Service 注入一组SERVICE_NAME相关的环境变量到应用 Pod 中。假设集群名为pg-database应用 Pod 中可直接使用环境变量指向的服务说明PG_DATABASE_R_SERVICE_HOSTpg-database-r指向集群全部 PostgreSQL 实例含主实例的只读服务 IPPG_DATABASE_RO_SERVICE_HOSTpg-database-ro指向全部热备副本的只读服务 IPPG_DATABASE_RW_SERVICE_HOSTpg-database-rw指向主实例的读写服务 IP这些变量名由 Kubernetes 依据服务名中的连字符替换为下划线 _SERVICE_HOST后缀的规则自动生成pg-database-rw→PG_DATABASE_RW_SERVICE_HOST。应用启动时读取这些变量即可获得对应服务的 ClusterIP无需硬编码地址。注意环境变量方式仅在同命名空间生效跨命名空间时请优先使用 DNS 解析。凭据管理Operator 自动生成的 basic-auth Secrets对于每个部署的 PostgreSQL 集群CloudNativePG 会生成最多两个kubernetes.io/basic-auth类型的 Secret用于携带连接凭据源码见 pkg/specs/secrets.go 的CreateSecret函数Secret 类型为corev1.SecretTypeBasicAuthcluster-name-app如pg-database-app应用连接使用的凭据对应用户是数据库的属主owner。除非通过.spec.bootstrap.initdb.secret.name指定了已存在的 Secret否则 Operator 一定会生成。cluster-name-superuser如pg-database-superuser仅用于管理目的的超级用户凭据对应postgres用户。仅在.spec.enableSuperuserAccess为true且未通过.spec.superuserSecret指定其他 Secret 时生成。重要默认情况下通过网络禁用超级用户访问.spec.enableSuperuserAccess默认关闭。应用应一律使用-app凭据-superuser凭据仅限管理员在需要时启用。Secret 的字段清单每个生成的 Secret 都包含以下字段对应 pkg/specs/secrets.go 中的StringData字段名内容说明username/user数据库用户名两个字段值相同兼容不同客户端读取习惯password数据库密码dbname数据库名称通常与集群名一致的默认数据库host主机名指向rw服务的短主机名不带端口port端口号即postgres.ServerPort5432pgpass.pgpass文件格式内容可直接写入~/.pgpass供 libpq 工具链使用uriPostgreSQL 连接 URIpostgresql://user:passhost:port/dbname形式主机为短名jdbc-uriJDBC 连接 URI供 Java/JVM 生态的 JDBC 驱动使用fqdn-uri基于 FQDN 的 PostgreSQL URI主机为完整域名fqdn-jdbc-uri基于 FQDN 的 JDBC URI主机为完整域名其中uri/jdbc-uri使用命名空间限定的主机名host.namespace:port而fqdn-uri/fqdn-jdbc-uri使用完整域名host.namespace.svc.cluster-domain:port。FQDN 与集群域配置Secret 中 FQDN 形式 URI 所使用的主机名依据 Kubernetes 集群域计算而来service.namespace.svc.kubernetes-cluster-domain。集群域通过 Operator 配置参数KUBERNETES_CLUSTER_DOMAIN指定环境变量同名其默认值为cluster.local定义于 internal/configuration/configuration.go 的DefaultKubernetesClusterDomain。非默认集群域如k8s.example.com的集群需调整该参数否则fqdn-*系列连接串无法解析。更多细节见 Operator 配置文档。在应用中挂载 Secret 的示例apiVersion: apps/v1 kind: Deployment metadata: name: my-app spec: template: spec: containers: - name: app image: my-app:latest env: - name: DB_USER valueFrom: secretKeyRef: name: pg-database-app key: username - name: DB_PASSWORD valueFrom: secretKeyRef: name: pg-database-app key: password - name: DB_NAME valueFrom: secretKeyRef: name: pg-database-app key: dbname # 也可直接使用完整连接串 - name: DATABASE_URL valueFrom: secretKeyRef: name: pg-database-app key: uri对于 Pythonpsycopg2/SQLAlchemy、Gopgx/lib/pq、Node.jspg等支持 libpq 连接串的驱动直接使用uri字段即可Java 应用则使用jdbc-uri需要走.pgpass的 CLI 工具链psql、pg_dump等可使用pgpass字段内容。高级话题服务管理、连接池与外部访问通过managed.services自定义服务CloudNativePG 在 服务管理文档 中提供了对服务的高级定制能力禁用默认服务通过managed.services.disabledDefaultServices可关闭ro与r服务但rw服务因承载复制关键路径而不可禁用。新增自定义服务通过managed.services.additional段以serviceTemplate定义任意 KubernetesService如LoadBalancer类型对外暴露通过selectorTyperw/ro/r指定其选中的实例角色updateStrategy控制更新策略默认patch直接修改replace则删除重建但会引发短暂中断。例如为数据库主实例创建一个对外LoadBalancer服务# snip managed: services: additional: - selectorType: rw serviceTemplate: metadata: name: mydb-lb labels: test-label: true annotations: test-annotation: true spec: type: LoadBalancer上述能力的实现位于 pkg/specs/services.go 的BuildManagedServices与buildDefaultService函数Operator 依据selectorType构造对应的默认服务再以用户的serviceTemplate覆盖元数据与 spec并强制写入由 Operator 管理的 Selector 与端口。连接池PgBouncer 接入层对于高并发应用CloudNativePG 支持通过 PgBouncer 构建连接池作为应用与 PostgreSQL 集群之间的访问层以降低连接开销并提升吞吐。详细的部署与配置方法参见 Connection Pooling 章节。将服务暴露到集群外的安全须知CloudNativePG 服务默认是集群内可见的ClusterIP。如需对外暴露如 DBaaS 场景、遗留虚拟机应用迁移需自行创建LoadBalancer或NodePort类型的服务。需要强调的是将数据库暴露到公网会使其面临恶意攻击风险请务必在对外暴露前完成数据库加固或确保 Kubernetes 集群仅从私有网络可达。小结推荐的连接组合综合上述内容一个遵循 CloudNativePG 最佳实践的应用连接方案是发现方式优先使用服务名进行 DNS 解析同命名空间直接用cluster-rw跨命名空间用cluster-rw.namespace让 Kubernetes 负责实例切换时的流量重定向凭据来源从cluster-appSecret 读取username、password、dbname、host/port或现成的uri/jdbc-uri/pgpass字段杜绝硬编码密码读写分离按需在rw、ro、r三类服务中选择合适的端点高并发场景引入 PgBouncer 连接池连接池文档对外暴露通过managed.services.additional自定义服务并做好安全加固。这样组合既保证了连接的稳定与高可用也让应用代码天然适配主备切换、滚动升级等运维动作充分发挥 CloudNativePG 的自动化能力。可进一步阅读 服务管理完整文档 与 Cluster CRD 参考 获取全部配置项。【免费下载链接】cloudnative-pgThe most popular Kubernetes Operator for PostgreSQL.项目地址: https://gitcode.com/GitHub_Trending/cl/cloudnative-pg创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表