CloudNativePG PostgreSQL 配置完全指南:postgresql.conf、pg_hba.conf 与 pg_ident.conf 的声明式管理
CloudNativePG PostgreSQL 配置完全指南postgresql.conf、pg_hba.conf 与 pg_ident.conf 的声明式管理【免费下载链接】cloudnative-pgThe most popular Kubernetes Operator for PostgreSQL.项目地址: https://gitcode.com/GitHub_Trending/cl/cloudnative-pgCloudNativePG 遵循声明式配置与容器不可变原则不允许用户直接修改 Pod 内的 PostgreSQL 配置文件而是通过Cluster资源中的postgresql字段以声明式方式统一管理postgresql.conf、pg_hba.conf和pg_ident.conf三大核心配置。本文将以官方文档 docs/src/postgresql_conf.md 为主线结合仓库源码如 pkg/management/postgres/configuration.go、pkg/postgres/configuration.go、api/v1/cluster_types.go深入剖析各配置项的生成逻辑、固定参数约束与实操示例帮助读者掌握在 CloudNativePG 上安全、正确地配置 PostgreSQL 实例的完整方法。为什么不能直接修改配置文件熟悉 PostgreSQL 的读者都知道一个实例通常由三个文件决定其行为postgresql.confPostgreSQL 主运行时配置文件pg_hba.conf客户端认证Host Based Authentication文件pg_ident.conf外部系统用户到数据库用户的映射文件但在 CloudNativePG 中由于声明式配置和PostgreSQL 容器不可变两大设计原则用户被禁止直接触碰这些文件。所有配置都必须通过Cluster资源定义中的postgresql字段来完成具体对应三个键parameters自定义postgresql.conf参数pg_hba自定义pg_hba.conf规则pg_ident自定义pg_ident.conf映射规则这些设置会应用到集群内的所有实例确保配置的一致性。警告禁止使用ALTER SYSTEM强制修改配置不要用ALTER SYSTEM命令以命令式方式修改 PostgreSQL 实例配置。修改某些由 operator 控制的参数可能导致集群进入不可预测/不可恢复的状态而且ALTER SYSTEM的修改不会在集群内复制。如需启用见下文「启用ALTER SYSTEM」章节。一个完整的自定义配置参考示例见仓库中的 docs/src/samples/cluster-example-custom.yaml。postgresql配置段的生成机制Pod 内的 PostgreSQL 实例以默认的postgresql.conf启动operator 会自动在文件末尾追加以下两行listen_addresses * include custom.conf其中custom.conf就是承载用户自定义配置的文件。例如# ... postgresql: parameters: shared_buffers: 1GB # ...关于 PostgreSQL GUCGUCGrand Unified Configuration是 PostgreSQL 对运行时参数的统称更多可用参数可参考 PostgreSQL 官方文档。需要注意的是CloudNativePG 的parameters只接受字符串类型的值即map[string]string见 api/v1/cluster_types.go 中PostgresConfiguration.Parameters字段定义。custom.conf的内容由 operator 自动生成并维护应用顺序如下全局默认参数Global default parameters依赖 PostgreSQL 大版本号的默认参数major-version defaults用户提供的参数User-provided parameters固定参数Fixed parameters全局默认参数custom.conf中的全局默认参数如下与 pkg/postgres/configuration.go 中CnpgConfigurationSettings.GlobalDefaultSettings的定义完全一致archive_timeout 5min dynamic_shared_memory_type posix full_page_writes on logging_collector on log_destination csvlog log_directory /controller/log log_filename postgres log_rotation_age 0 log_rotation_size 0 log_truncate_on_rotation false max_parallel_workers 32 max_replication_slots 32 max_worker_processes 32 shared_memory_type mmap shared_preload_libraries ssl_max_protocol_version TLSv1.3 ssl_min_protocol_version TLSv1.3 wal_keep_size 512MB wal_level logical wal_log_hints on wal_sender_timeout 5s wal_receiver_timeout 5s警告WAL 段保留策略是用户的责任你需要根据预期和实际负载为集群规划 WAL 段的保留策略并正确配置wal_keep_size或旧版本上的wal_keep_segments。如果集群中唯一的流复制客户端只是 HA 集群内的副本实例则可以利用复制槽特性replicationSlots.highAvailability选项详见 docs/src/replication.md在集群层面管理复制槽。在没有复制槽也没有持续备份的情况下配置wal_keep_size或wal_keep_segments是防止 standby 掉出同步的唯一手段。standby 一旦掉出同步会产生类似could not receive data from WAL stream: ERROR: requested WAL segment ************************ has already been removed的错误此时需要从PGDATA或 WAL 卷中预留一部分空间来保留旧的 WAL 段供流复制使用。固定参数Fixed parameters以下参数是固定的完全由 operator 独占控制archive_command /controller/manager wal-archive %p hot_standby true listen_addresses * port 5432 restart_after_crash false ssl on ssl_ca_file /controller/certificates/client-ca.crt ssl_cert_file /controller/certificates/server.crt ssl_key_file /controller/certificates/server.key unix_socket_directories /controller/run由于固定参数被追加在最后用户无法通过 YAML 配置覆盖它们。这些参数是 WAL 归档和复制正确运行的必要条件。值得注意的是operator 还维护了一个更长的禁止用户设置参数清单见下文「固定参数与禁止覆盖清单」并通过webhook 拦截用户对这些参数的设置。从实现上看配置文件的生成与写入集中在 pkg/management/postgres/configuration.gocreatePostgresqlConfiguration函数组装ConfigurationInfo包含全局默认、用户参数、额外共享库、同步备用名、临时表空间、扩展等最终由postgres.CreatePostgresqlConfFile生成配置文本与其 SHA-256 校验和再由InstallPgDataFileContent写入PGDATA下的custom.conf文件名常量定义于 pkg/management/postgres/constants/constants.go。该函数只有在内容真正变化时才返回变更标志供实例管理器决定是否需要 reload 或滚动重启。Write-Ahead Log LevelWAL 级别PostgreSQL 的wal_level决定写入 WAL 的信息量可选值如下minimal仅写入崩溃恢复所需的信息replica额外支持 WAL 归档和流复制包括在 standby 上运行只读查询logical包含replica的全部信息并额外支持逻辑解码和逻辑复制上游 PostgreSQL 默认wal_level为replica而CloudNativePG 默认将其设为logical以便开箱即用地支持逻辑复制例如从外部 PostgreSQL 服务器迁移数据。如果集群不需要逻辑复制建议将wal_level设为replica以减少 WAL 体积和开销只有单实例集群且禁用 WAL 归档时才允许将wal_level设为minimal。复制相关设置Replication Settingsprimary_conninfo、restore_command、recovery_target_timeline由 operator 根据实例在集群中的角色自动管理仅在实例作为副本运行时生效primary_conninfo hostPRIMARY userpostgres dbnamepostgres tcp_user_timeout5000 recovery_target_timeline latest重要tcp_user_timeout默认情况下每个 standby 都将tcp_user_timeout设为5 秒。该参数定义在 TCP 连接被强制关闭前已传输数据允许保持未确认的最长时间决定了 standby 对网络问题的反应速度。如果默认值不满足需求可通过 operator 配置项STANDBY_TCP_USER_TIMEOUT统一覆盖所有 standby详见 docs/src/operator_conf.md。从源码看这些复制参数写入的是override.conf另一份由 operator 维护的文件pkg/management/postgres/configuration.go 中的writePostgresOverrideConfFile函数会写入restore_command、recovery_target_timeline latest、primary_conninfo并在启用复制槽时追加primary_slot_name同时createStandbySignal会创建standby.signal文件以标记实例进入 standby 模式。在导入数据库等场景中operator 还会向override.conf写入archive_modeoff、fsyncoff、wal_levelminimal等临时优化参数见configurePostgresForImport。日志控制设置Log control settingsoperator 要求 PostgreSQL 以CSV 格式输出日志实例管理器会自动解析 CSV 并转换为 JSON 格式输出。因此postgresql.conf中的相关日志设置如logging_collector、log_destination、log_directory、log_filename、log_rotation_age/size、log_truncate_on_rotation等是固定的、不可修改。更多细节见 docs/src/logging.md。共享预加载库Shared Preload Librariesshared_preload_libraries用于指定在服务器启动时预加载的一个或多个共享库逗号分隔列表典型用途是加载需要在整个系统中大多数数据库会话可用的扩展例如pg_stat_statements。在 CloudNativePG 中shared_preload_libraries默认为空。虽然可以覆盖其内容但官方只建议 PostgreSQL 专家用户这样做。重要如果指定的库未找到服务器将无法启动从而阻断 CloudNativePG 的一切自愈尝试需要人工干预。请务必在直接管理shared_preload_libraries内容时先测试好扩展及其设置。CloudNativePG 能够对若干最常用的扩展自动管理shared_preload_libraries的内容见下节「受管扩展」一旦 operator 发现某个配置参数需要某个受管库就会自动把该库加入列表当没有任何实际参数需要它时又会自动移除。重要请始终牢记从shared_preload_libraries中移除库需要重启集群中所有实例才能生效。此外用户还可以通过.spec.postgresql.shared_preload_libraries以字符串列表形式提供额外的预加载库operator 会将其与自动管理的库合并对应 api/v1/cluster_types.go 中PostgresConfiguration.AdditionalLibraries字段其 JSON 键为shared_preload_libraries。受管扩展Managed ExtensionsCloudNativePG 会自动管理以下扩展在shared_preload_libraries中的条目auto_explainpg_stat_statementspgauditpg_failover_slots其中部分库还需要在数据库内创建额外对象通常通过CREATE EXTENSION创建视图/函数DROP EXTENSION移除。对于这些库CloudNativePG 会在集群中所有允许连接的数据库由以下查询识别中自动处理扩展的创建与移除SELECT datname FROM pg_database WHERE datallowconn注意上述查询结果包含template1等模板数据库。重要随着 Database CRD 声明式扩展管理 的引入受管扩展特性可能在 CloudNativePG 未来版本中发生重大变化部分功能可能被弃用。启用auto_explainauto_explain自动记录慢语句的执行计划无需手动执行EXPLAIN有助于排查未优化的查询。只要配置中出现以auto_explain.开头的参数即可启用。以下示例会自动记录执行时间超过 10 秒的查询执行计划# ... postgresql: parameters: auto_explain.log_min_duration: 10s # ...注意启用 auto_explain 可能导致性能问题请参考 PostgreSQL 官方文档。启用pg_stat_statementspg_stat_statements是 PostgreSQL 实现查询实时监控最重要的能力之一。配置以pg_stat_statements.开头的参数即可启用# ... postgresql: parameters: pg_stat_statements.max: 10000 pg_stat_statements.track: all # ...如前所述operator 会自动将pg_stat_statements加入shared_preload_libraries并在每个数据库上执行CREATE EXTENSION IF NOT EXISTS pg_stat_statements之后即可对pg_stat_statements视图执行查询。启用pgauditpgaudit通过标准 PostgreSQL 日志设施提供详细的会话级和/或对象级审计日志。CloudNativePG 对 PostgreSQL 集群上的 PGAudit 提供透明、原生支持详见 docs/src/logging.md。配置以pgaudit.开头的参数即可启用postgresql: parameters: pgaudit.log: all, -misc pgaudit.log_catalog: off pgaudit.log_parameter: on pgaudit.log_relation: on在源码层面实例管理器的日志管道专门实现了 pgaudit 的 CSV 解析支持见 pkg/management/postgres/logpipe/pgaudit.gopgaudit类型的日志记录会以logger: pgaudit的 JSON 字段输出便于日志采集与检索。启用pg_failover_slotsEDB 的pg_failover_slots扩展确保逻辑复制槽能够在故障转移场景下存活CloudNativePG 的故障转移正是基于物理流复制实现的。配置以pg_failover_slots.开头的参数即可启用operator 会透明地管理其在shared_preload_libraries中的条目。此外对于每个打算配合pg_failover_slots使用的数据库你需要在pg_hba段中添加一条允许各副本连接主库的规则。例如要在app数据库上使用pg_failover_slotspostgresql: pg_hba: - hostssl app streaming_replica all certpg_hba段主机认证规则pg_hba是用于生成 Pod 内pg_hba.conf的 PostgreSQL Host Based Authentication 规则列表对应PostgresConfiguration.PgHBA字段类型为[]string。重要pg_hba.conf的更多信息请参考 PostgreSQL 官方文档。由于 PostgreSQL 采用第一条匹配规则进行认证operator 生成的pg_hba.conf可以看作由四个部分拼接而成固定规则Fixed rules用户自定义规则User-defined rules可选的 LDAP 段Optional LDAP section默认规则Default rules固定规则local all all peer hostssl postgres streaming_replica all cert mapcnpg_streaming_replica hostssl replication streaming_replica all cert mapcnpg_streaming_replica hostssl all cnpg_pooler_pgbouncer all cert mapcnpg_pooler_pgbouncer默认规则host all all all default-authentication-method从 PostgreSQL 14 起password_encryption数据库参数的默认值改为scram-sha-256因此PostgreSQL 14 及以上版本的默认认证方式为scram-sha-256PostgreSQL 13 及更早版本默认使用md5。这一逻辑在源码中也有体现pkg/management/postgres/configuration.go 的GeneratePostgresqlHBA函数根据majorVersion 14决定默认认证方式为md5或scram-sha-256。最终生成的pg_hba.conf大致如下local all all peer hostssl postgres streaming_replica all cert mapcnpg_streaming_replica hostssl replication streaming_replica all cert mapcnpg_streaming_replica hostssl all cnpg_pooler_pgbouncer all cert mapcnpg_pooler_pgbouncer user defined rules user defined LDAP host all all all scram-sha-256 # (or md5 for PostgreSQL version 13)在集群清单中pg_hba规则以列表项形式写在.spec.postgresql.pg_hba下例如postgresql: pg_hba: - hostssl app app 10.244.0.0/16 md5上述示例通过安全通道hostssl为app用户访问app数据库启用了 MD5 密码认证也可改用scram-sha-256。生成 HBA 文件的实际调用链为RefreshPGHBA → GeneratePostgresqlHBA → postgres.CreateHBARules其中会注入固定规则、LDAP 配置、podSelector 展开后的 IP 以及默认认证方式。使用podSelectorRefs动态解析地址在 Kubernetes 中Pod IP 是临时的。每当客户端 Pod 重启就手动更新pg_hba规则是不可持续的。.spec.podSelectorRefs选项将其自动化允许你定义命名标签选择器operator 将其解析为最新的 IP 地址。工作原理定义选择器将友好的名称映射到标准的 Kubernetes podlabelSelector引用选择器在pg_hba规则中使用${podselector:NAME}占位符自动展开operator 解析匹配的 Pod IP实例管理器把每个引用展开为pg_hba.conf中的独立 CIDR 条目IPv4 为/32IPv6 为/128配置示例以下片段定义了应用 Pod 与监控 Pod 的选择器并将其应用到 PostgreSQL 访问规则podSelectorRefs: - name: app-pods selector: matchLabels: app: myapp - name: monitoring selector: matchLabels: role: monitoring postgresql: pg_hba: - hostssl mydb myuser ${podselector:app-pods} scram-sha-256 - hostssl postgres monitor ${podselector:monitoring} scram-sha-256IP 展开映射如果 operator 检测到应用 Pod 的 IP 为10.0.0.5、10.0.0.12监控 Pod 的 IP 为10.0.1.3实例管理器会将模板转换为# Expanded from: hostssl mydb myuser ${podselector:app-pods} scram-sha-256 hostssl mydb myuser 10.0.0.5/32 scram-sha-256 hostssl mydb myuser 10.0.0.12/32 scram-sha-256 # Expanded from: hostssl postgres monitor ${podselector:monitoring} scram-sha-256 hostssl postgres monitor 10.0.1.3/32 scram-sha-256关键约束与行为作用域出于安全考虑选择器仅限 Cluster 所在的同一个 namespace不支持跨 namespace 查找。位置限制${podselector:NAME}语法仅可出现在host类型条目host、hostssl、hostnossl、hostgssenc、hostnogssenc的地址字段中。响应性operator 监听 Pod 生命周期事件创建、删除或 IP 更新触发配置自动重新生成并执行 PostgreSQLreload。校验选择器名称必须匹配^[a-z](https://link.gitcode.com/i/5ae28c8836d19f07ff3acdcfabf12d9f)?$模式且pg_hba规则中每个${podselector:NAME}引用都必须对应podSelectorRefs中已定义的条目webhook 会校验这两项约束。对应的 Go 类型PodSelectorRef定义见 api/v1/cluster_types.go其中Name字段带有相同的正则校验注解。警告当某个选择器匹配到零个 Pod 时引用它的pg_hba行会从pg_hba.conf中省略。请确保你的默认规则提供了适当的兜底访问。完整示例见 docs/src/samples/cluster-example-pod-selector-refs.yaml。LDAP 配置在集群 spec 的postgres段下还有一个可选的ldap段用于定义将被转换为pg_hba.conf中一条规则host all all 0.0.0.0/0 ldap ...的 LDAP 配置支持两种模式simple bind 模式需要在 LDAP 段中指定server、prefix和suffixsearchbind 模式需要指定server、baseDN、bindDN以及包含 LDAP 密码的 SecretbindPassword此外可选用searchFilter或searchAttribute指定搜索方式若未指定searchAttribute默认使用uid两种模式都允许通过scheme指定 LDAP scheme如ldaps见 api/v1/cluster_types.go 中的LDAPSchemeLDAP/LDAPSchemeLDAPS常量以及port指定端口但两者均非必填。searchbind 模式的完整示例postgresql: ldap: server: openldap.default.svc.cluster.local bindSearchAuth: baseDN: ouorg,dcexample,dccom bindDN: cnadmin,dcexample,dccom bindPassword: name: ldapBindPassword key: data searchAttribute: uidLDAP 规则的实际构造逻辑在 pkg/management/postgres/configuration.go 的buildLDAPConfigString函数中它会依据配置依次追加ldapserver、ldapport、ldapscheme、ldaptls1当TLS为 true 时、simple bind 的ldapprefix/ldapsuffix或 searchbind 的ldapbasedn/ldapbinddn/ldapbindpasswd以及可选的ldapsearchfilter/ldapsearchattribute所有值都会按照pg_hba.conf的规则进行引号转义quoteHbaLiteral。pg_ident段用户名映射pg_ident是 PostgreSQL User Name Maps 的列表CloudNativePG 用它生成并维护数据目录中的 ident 映射文件pg_ident.conf对应PostgresConfiguration.PgIdent字段。重要pg_ident.conf的更多信息请参考 PostgreSQL 官方文档。operator 写入的pg_ident.conf由两部分组成固定规则Fixed rules用户自定义规则User-defined rules目前唯一由 operator 自动生成的固定规则是local postgres system user postgres实例管理器会检测运行 PostgreSQL 实例的系统用户并自动添加一条规则将其映射到数据库中的postgres用户。如果容器内postgres用户未被正确配置实例管理器将允许任何本地用户连接并记录类似下面的警告Unable to identify the current user. Falling back to insecure mapping.最终生成的pg_ident.conf类似local postgres system user postgres user defined lines在集群清单中pg_ident规则以列表项形式写在.spec.postgresql.pg_ident下例如postgresql: pg_ident: - mymap /^(.*)mydomain\\.com$ \\1写入逻辑对应 pkg/management/postgres/configuration.go 的RefreshPGIdent → generatePostgresqlIdent → postgres.CreateIdentRules其中固定映射来自getCurrentUserOrDefaultToInsecureMapping()即检测系统用户失败时退化为不安全映射。变更配置与滚动更新应用配置变更只需编辑Cluster资源的postgresql段变更后集群实例会立即 reload 配置以应用改动如果变更涉及需要重启的参数operator 将执行滚动升级rolling upgrade来逐个替换实例。启用ALTER SYSTEMCloudNativePG 强烈主张以 Cluster 清单作为修改 PostgreSQL 集群配置的唯一方式以保证整个高可用集群的配置一致并符合 Infrastructure-as-Code 的最佳实践。默认情况下CloudNativePG禁用新建 PostgreSQL 集群上的ALTER SYSTEM。若需启用显式设置.spec.postgresql.enableAlterSystem为true即可对应 api/v1/cluster_types.go 中PostgresConfiguration.EnableAlterSystem字段默认false注释明确说明仅应用于调试和故障排查。警告使用ALTER SYSTEM需格外谨慎该命令只作用于当前连接的实例不会被复制。CloudNativePG 对部分固定参数负有责任并完全控制其余参数务必三思。PostgreSQL 17 及以后.spec.postgresql.enableAlterSystem直接控制 PostgreSQL 的allow_alter_systemGUC该特性正是由 CloudNativePG 社区贡献给 PostgreSQL 的PostgreSQL 17 之前当enableAlterSystem为false时postgresql.auto.conf文件会被设为只读任何ALTER SYSTEM尝试都会报错错误信息类似ERROR: could not open file postgresql.auto.conf: Permission denied动态共享内存设置PostgreSQL 通过dynamic_shared_memory_type支持多种动态共享内存实现。在 CloudNativePG 中官方建议只使用以下两种取值posix基于shm_open分配的 POSIX 共享内存默认设置sysv基于shmget分配的 System V 共享内存该设置对并行查询的内存分配尤为重要。POSIX 共享内存默认的posix设置在大多数场景下已足够因为 operator 会自动挂载一个名为shm的内存型EmptyDir卷到/dev/shm。可在运行中的 Postgres 容器内用以下命令验证其大小mount | grep shm输出大致如下shm on /dev/shm type tmpfs (rw,nosuid,nodev,noexec,relatime,size******)如需为shm卷设置最大大小可通过Cluster资源中的.spec.ephemeralVolumesSizeLimit.shm字段实现spec: ephemeralVolumesSizeLimit: shm: 1GiSystem V 共享内存如果 Kubernetes 节点的SHMMAX与SHMALL值足够高也可以设置dynamic_shared_memory_type: sysv在 PostgreSQL 容器内运行以下命令查看SHMMAX/SHMALLipcs -lm例如------ Shared Memory Limits -------- max number of segments 4096 max seg size (kbytes) 18014398509465599 max total shared memory (kbytes) 18014398509481980 min seg size (bytes) 1可以看到max total shared memory数值非常高此时建议将dynamic_shared_memory_type设为sysv。另一种查看方式cat /proc/sys/kernel/shmall cat /proc/sys/kernel/shmmax固定参数与禁止覆盖清单部分 PostgreSQL 配置参数只能由 operator 管理。operator 通过 webhook 阻止用户设置它们。以下参数不允许出现在postgresql段的parameters中allow_alter_system allow_system_table_mods archive_cleanup_command archive_command archive_mode bonjour bonjour_name cluster_name config_file data_directory data_sync_retry event_source external_pid_file hba_file hot_standby ident_file jit_provider listen_addresses log_destination log_directory log_file_mode log_filename log_rotation_age log_rotation_size log_truncate_on_rotation logging_collector port primary_conninfo primary_slot_name promote_trigger_file recovery_end_command recovery_min_apply_delay recovery_target recovery_target_action recovery_target_inclusive recovery_target_lsn recovery_target_name recovery_target_time recovery_target_timeline recovery_target_xid restart_after_crash restore_command shared_preload_libraries ssl ssl_ca_file ssl_cert_file ssl_crl_file ssl_dh_params_file ssl_key_file ssl_passphrase_command ssl_passphrase_command_supports_reload ssl_prefer_server_ciphers stats_temp_directory synchronous_standby_names syslog_facility syslog_ident syslog_sequence_numbers syslog_split_messages unix_socket_directories unix_socket_group unix_socket_permissions这些参数涉及归档、复制、SSL、监听地址、恢复目标等 operator 必须完全掌控的领域。用户自定义配置只能在其之外的安全范围内进行任何越界尝试都会被 webhook 拒绝从而保证高可用集群不会因为错误的配置而陷入不可恢复的状态。总结CloudNativePG 通过Cluster资源的postgresql段将 PostgreSQL 三大配置文件postgresql.conf、pg_hba.conf、pg_ident.conf全面纳入声明式管理parameters支持用户参数但受固定参数与 webhook 双重约束pg_hba支持固定规则、用户规则、LDAP 与podSelectorRefs动态 IP 展开pg_ident负责系统用户到数据库用户的映射而enableAlterSystem提供了在需要时安全启用命令式修改的开关。理解 operator 在 pkg/management/postgres/configuration.go 与 pkg/postgres/configuration.go 中的文件生成与维护机制是安全使用这些配置能力、避免集群进入不可恢复状态的关键。【免费下载链接】cloudnative-pgThe most popular Kubernetes Operator for PostgreSQL.项目地址: https://gitcode.com/GitHub_Trending/cl/cloudnative-pg创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考