news 2026/9/16 21:52:46

CloudNativePG 标签与注解(Labels Annotations)完全指南:从预定义元数据到自定义继承机制

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CloudNativePG 标签与注解(Labels Annotations)完全指南:从预定义元数据到自定义继承机制

CloudNativePG 标签与注解(Labels & Annotations)完全指南:从预定义元数据到自定义继承机制

【免费下载链接】cloudnative-pgThe most popular Kubernetes Operator for PostgreSQL.项目地址: https://gitcode.com/GitHub_Trending/cl/cloudnative-pg

本文是 CloudNativePG(CNPG)Kubernetes Operator 中标签(Label)与注解(Annotation)体系的技术指南。Kubernetes 以扁平结构组织资源,而标签和注解正是将 Pod、PVC、Job、VolumeSnapshot 等资源与集群关联起来、供外部工具与运维流程识别的核心元数据。读完本文,你将掌握 CloudNativePG 全部预定义标签/注解的语义与适用资源,能够通过 operator 配置实现自定义标签/注解向所有衍生资源(包括 Pod)的自动继承,并了解该机制的当前局限。

为什么 CloudNativePG 选择元数据继承而非 Pod 模板

Kubernetes 中的资源没有天然的层次关系,但通过labelsannotations可以将对象关联起来:

  • 注解(Annotation):为资源附加非标识性的额外信息,主要用于与外部工具的集成;
  • 标签(Label):用于对对象分组,并通过 Kubernetes 原生的选择器(selector)能力进行查询。

在 Kubernetes 生态中,部分控制器通过"Pod 模板(pod template)"机制让用户直接定义 Pod 的元数据。CloudNativePG 则选择了另一条技术路线——标签与注解继承(label and annotation inheritance)。其核心思路是:用户先在 operator 配置中声明允许继承的标签/注解名称,之后在Cluster资源的 metadata 中定义这些标签/注解,operator 在创建所有衍生资源(包括 Pod)时自动将它们复制到目标资源上。这一机制避免了 Pod 模板带来的不可控性,同时保持了元数据注入的灵活性。

该继承逻辑的核心实现位于 pkg/utils/labels_annotations.go:InheritAnnotationsInheritLabels两个函数遍历源 metadata,并通过InheritanceController接口(IsAnnotationInherited/IsLabelInherited)判断某个名称是否应被继承,匹配成功即写入目标对象的 metadata。operator 配置对象Data正是该接口的实现者,见 internal/configuration/configuration.go。

InheritAnnotations / InheritLabels(pkg/utils/labels_annotations.go) │ ▼ InheritanceController.IsAnnotationInherited / IsLabelInherited │ ▼ configuration.Data(internal/configuration/configuration.go) │ 使用 path.Match 对 INHERITED_ANNOTATIONS / INHERITED_LABELS 做 glob 匹配

预定义标签(Predefined labels)

CloudNativePG 为自身管理的资源打上统一的预定义标签,常量定义与注释见 pkg/utils/labels_annotations.go。按功能可分为以下几类。

集群与实例标识

标签说明
cnpg.io/cluster所属Cluster资源的名称,由LabelClusterName函数写入,几乎覆盖所有衍生资源
cnpg.io/instanceNamePostgreSQL 实例名称,取代旧的postgresql标签
cnpg.io/nodeSerial(注解)实例在集群内的序号,用于实例与 Pod 的对应关系
cnpg.io/podRole区分 Pod 的用途:instance(数据库实例)或pooler(PgBouncer 连接池),枚举值见PodRoleInstance/PodRolePooler

实例角色标签:cnpg.io/instanceRole与已废弃的role

cnpg.io/instanceRole标记 Pod 中实例的运行角色,取值包括:

  • primary:主实例;
  • replica:副本实例;
  • unhealthy瞬态值,仅在故障转移(failover)或切换(switchover)期间由 operator 打在旧主实例上,转换完成后自动清除。

旧标签role已废弃,仅保留向后兼容。在源码中,SetInstanceRole会同时写入新旧两个标签,而GetInstanceRole读取时优先返回新标签值(见 pkg/utils/labels_annotations.go),这保证了运行中的旧版组件仍能识别角色,同时引导用户迁移到新标签。

备份与 VolumeSnapshot 系列标签

以下标签仅出现在VolumeSnapshot资源上,记录备份的时间与来源信息,常量定义于 pkg/utils/labels_annotations.go,实际写入逻辑见 pkg/reconciler/backup/volumesnapshot/reconciler.go(例如backupDate使用20060102格式):

标签含义
cnpg.io/backupDate备份日期,ISO 8601 风格YYYYMMDD
cnpg.io/backupYear/cnpg.io/backupMonth备份发生的年份 / 年月
cnpg.io/backupTimeline备份时实例所处的 timeline
cnpg.io/backupName备份标识
cnpg.io/majorVersion备份数据目录对应的 PostgreSQL 主版本整数,如17
cnpg.io/onlineBackup备份是否为在线热备(hot)还是离线冷备(cold)

Backup / ScheduledBackup 关联标签

  • cnpg.io/scheduled-backup:创建该Backup对象的ScheduledBackup资源名称(常量ParentScheduledBackupLabelName);
  • cnpg.io/immediateBackup:当ScheduledBackupimmediatetrue时,打在由其创建的第一个Backup上。

Job 与 PVC 角色标签

  • cnpg.io/jobRole:Job 的角色,例如major-upgrade(大版本升级 Job);
  • cnpg.io/pvcRole:PVC 的用途,取值PG_DATAPG_WALPG_TABLESPACE(见PVCRole枚举);
  • cnpg.io/poolerName:PgBouncer pooler 的名称;
  • cnpg.io/reload:出现在ConfigMapSecret上,值为true时表示资源变更会被 operator 自动重载到运行中的实例;
  • cnpg.io/userType:标注Secret对应的 PostgreSQL 用户类型,superuser(超级用户,典型为postgres)或app(应用级用户,典型为app),仅用于 CloudNativePG 默认创建的用户;
  • cnpg.io/tablespaceName:PVC 所承载的表空间名称(源码中额外定义)。

Kubernetes 推荐标签(app.kubernetes.io/*)

CloudNativePG 遵循 [Kubernetes 推荐标签]规范,在 Pod、Job、Deployment、Service、PVC、VolumeSnapshot、PodDisruptionBudget、PodMonitor 等资源上打上app.kubernetes.io域标签(常量定义见 pkg/utils/labels_annotations.go,应用示例见 pkg/specs/jobs.go 与 pkg/specs/pgbouncer/deployments.go):

标签可用资源
app.kubernetes.io/managed-by恒为cloudnative-pg所有由 CloudNativePG 管理的资源
app.kubernetes.io/name恒为postgresqlpods、jobs、deployments、services、persistentVolumeClaims、volumeSnapshots、podDisruptionBudgets、podMonitors
app.kubernetes.io/component组件名(databasepooler等)同上
app.kubernetes.io/instance所属Cluster资源名pods、jobs、deployments、services、volumeSnapshots、podDisruptionBudgets、podMonitors
app.kubernetes.io/versionPostgreSQL 主版本pods、jobs、services、volumeSnapshots、podDisruptionBudgets、podMonitors

这些标签使外部工具(如监控、成本分析、备份系统)无需理解 CloudNativePG 内部结构,即可通过标准 Kubernetes 选择器发现和聚合所有 PostgreSQL 相关资源。

预定义注解(Predefined annotations)

预定义注解的常量定义同样集中在 pkg/utils/labels_annotations.go。按使用场景分类如下。

备份时间与 WAL 位置

  • cnpg.io/backupStartTime/cnpg.io/backupEndTime:备份开始 / 结束时间;
  • cnpg.io/backupStartWAL/cnpg.io/backupEndWAL:备份开始 / 结束时对应的 WAL 位置;
  • cnpg.io/snapshotStartTime:快照开始时间;
  • cnpg.io/snapshotEndTime:快照被标记为可用的时间;
  • cnpg.io/backupLabelFile/cnpg.io/backupTablespaceMapFile:备份的backup_labeltablespace_map文件内容(源码中定义,供恢复流程使用)。

其中backupStartTime位于VolumeSnapshot资源,backupStartWALbackupEndWALbackupEndTime仅出现在VolumeSnapshot上。

资源同步与哈希校验

  • cnpg.io/hash:资源的哈希值,用于检测配置漂移;
  • cnpg.io/podSpec:operator 生成的 Podspec快照,取代已废弃的cnpg.io/podEnvHash(旧的podEnvHash注解仅保留兼容,因环境变量差异已并入podSpec快照);
  • cnpg.io/poolerSpecHash:Pooler 资源的哈希值;
  • cnpg.io/clusterManifest:所属Cluster的完整 manifest(用于 PVC 等资源),取代已废弃的cnpg.io/hibernateClusterManifest
  • cnpg.io/pgControldatapg_controldata命令的输出,取代已废弃的cnpg.io/hibernatePgControlData
  • cnpg.io/operatorVersion:生成该对象的 operator 版本,由SetOperatorVersion写入。

运行时控制类注解

  • cnpg.io/hibernation:取值on/off,控制声明式休眠(declarative hibernation)特性(见 docs/src/declarative_hibernation.md);
  • cnpg.io/fencedInstances:需要被隔离(fencing)的实例列表,JSON 数组格式,若包含*元素则隔离整个集群(常量FencedInstanceAnnotation);
  • cnpg.io/reconcilePodSpec:取值为disabled时阻止实例因 PodSpec 变更(拓扑/亲和性、调度器、卷与容器等)而重启;作用于Pooler时则限制 Deployment 除spec.instances外的任何修改;
  • cnpg.io/reconciliationLoop:取值为disabled时停止该Cluster的协调循环(对应IsReconciliationDisabled判定,见 pkg/utils/labels_annotations.go);
  • cnpg.io/reloadedAt:最近一次集群 reload 的时间,由用户通过kubectl cnpg插件触发;
  • kubectl.kubernetes.io/restartedAt:最近一次请求重启 PostgreSQL 集群的时间;
  • cnpg.io/pvcStatus:PVC 当前状态:initializingreadydetached
  • cnpg.io/nodeSerial:Pod 上实例在集群内的序号;
  • cnpg.io/managedSecrets:operator 管理的 pull secrets,自动注入每个集群对应的ServiceAccount

WAL 与备份行为开关

  • cnpg.io/skipWalArchivingenabled时关闭 WAL 归档(archive_mode设为off,需要重启所有 PostgreSQL 实例)——高风险选项,自担风险;
  • cnpg.io/skipEmptyWalArchiveCheckenabled时跳过写入数据前对 WAL 归档是否为空的检查——高风险选项,自担风险;
  • cnpg.io/volumeSnapshotDeadline:作用于Backup/ScheduledBackup,控制 operator 在判定卷快照备份失败前重试可恢复错误的时长(分钟),默认 10;
  • cnpg.io/forceLegacyBackup:仅测试用途,模拟barman-cloud-backup3.4 之前(2023 年 1 月)无--name参数时的行为。

安全与合规相关

  • container.apparmor.security.beta.kubernetes.io/*:为指定容器设置 AppArmor profile。源码中getAnnotationAppArmor会校验注解中提到的容器名确实存在于 Pod 的普通或 init 容器中,避免无效注解(见 pkg/utils/labels_annotations.go)。更多细节参见 docs/src/security.md;
  • cnpg.io/coredumpFilter:控制 Postgres 进程 coredump 的位掩码,默认0x31(排除共享内存段),相关排障见 docs/src/troubleshooting.md;
  • cnpg.io/passwordPassthrough:取值enabled时,operator 在CREATE/ALTER ROLE语句中原样转发基础认证 Secret 中的密码,而不再由 operator 侧做 SCRAM-SHA-256 编码,由 PostgreSQL 依据自身的password_encryption设置完成编码(对应IsPasswordPassthroughEnabled判定与 docs/src/declarative_role_management.md 中的相关章节);
  • cnpg.io/validation:取值disabled时,validation webhook 放行该自定义资源的一切变更——警告:这可能允许不安全甚至破坏性的操作,请谨慎使用

实验性注解(alpha.cnpg.io 域)

实验性注解使用独立的alpha.cnpg.io命名空间(常量AlphaMetadataNamespace),包括:

  • alpha.cnpg.io/unrecoverable:作用于运行 PostgreSQL 实例的 Pod,指示 operator 删除该 Pod 及其所有关联 PVC 并按配置的 join 策略重建实例。该注解对任何状态的 Pod(Pending、Running 未就绪、Terminating)均生效;当 Terminating Pod 超过删除宽限期时,operator 会强制删除以便回收 PVC。它只能用于既非当前主实例也非指定目标主实例的实例上。警告:在不可达节点上强制删除 Pod 无法停止其上仍可能运行着的进程,卷是否真正分离取决于存储驱动——该注解的契约本身就意味着放弃实例数据;
  • alpha.cnpg.io/livenessPinger:实例管理器中存活探针的配置;
  • alpha.cnpg.io/failoverQuorum:启用同步仲裁故障转移保护;
  • alpha.cnpg.io/enableInstancePprof:接受true/false,控制实例是否启用 pprof 服务。

Pod 动态修补注解cnpg.io/podPatch

该注解作用于Cluster资源,接受 JSON-patch 格式的补丁,将应用到实例 Pod 上。它能够修改 Pod 规格的任意字段,包括安全敏感字段;operator 仅验证补丁语法正确且可应用。与所有影响 Pod 规格的 Cluster 字段一样,安全约束的强制执行委托给 Kubernetes 的准入控制链(见 docs/src/security.md 中 Trust Model 章节)。

使用时有两点必须注意:

  • ⚠️ 警告:该特性可能造成 operator 预期与 Kubernetes 实际行为之间的偏差,应作为最后手段谨慎使用;
  • 重要:新增或修改该注解不会触发 Pod 滚动更新,用户需通过kubectl cnpg restart手动触发。

启用自定义标签与注解的继承

前提:operator 配置

默认情况下,Clustermetadata 中的标签和注解不会被任何衍生资源继承。要启用继承,需要在 operator 配置(cnpg-controller-manager-configConfigMap 或 Secret)中设置两个环境变量,详见 docs/src/operator_conf.md:

环境变量作用
INHERITED_ANNOTATIONS注解名列表,出现在Clustermetadata 中时被所有衍生资源(含 Pod)继承
INHERITED_LABELS标签名列表,同上

两个变量的值都支持路径式通配符(glob):例如example.com/*同时匹配example.com/oneexample.com/two。这是实现"我公司所有标签都继承"这类策略的推荐方式,例如用mycompany/*匹配所有mycompany/前缀的标签,或让所有mycompany/前缀的注解都被继承。

底层的匹配逻辑使用 Gopath.Match逐模式比对,遇到非法 glob 模式时会记录日志并跳过该模式而不中断整体匹配(见 internal/configuration/configuration.go),对应的行为测试见 internal/configuration/configuration_test.go。

一个最小化的 operator 配置示例(放在 operator 命名空间cnpg-system中):

apiVersion: v1 kind: ConfigMap metadata: name: cnpg-controller-manager-config namespace: cnpg-system data: INHERITED_ANNOTATIONS: categories INHERITED_LABELS: environment, workload, app

沿用该示例并加以限定后,本文后续将只继承:

  • 注解categories
  • 标签appenvironmentworkload

在 Cluster 中定义 metadata

在创建Cluster资源时(在部署任何衍生资源之前),在其 metadata 中设置上述标签和注解:

apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: name: cluster-example annotations: categories: database labels: environment: production workload: database app: sso spec: # ... <snip>

验证继承结果

部署完成后,可通过以下命令验证标签是否正确传播到了 Pod:

kubectl get pods --show-labels

在输出中,每个实例 Pod 除了携带cnpg.io/clustercnpg.io/instanceNamecnpg.io/instanceRoleapp.kubernetes.io/*等预定义标签外,还应看到environment=productionworkload=databaseapp=sso三个自定义标签。

继承机制在源码中的落点

自定义元数据继承并非只作用于 Pod,而是贯穿于 operator 生成的所有资源。从源码看,utils.InheritAnnotationsutils.InheritLabels被以下资源生成路径调用:

  • 实例 Pod:pkg/reconciler/instance/metadata.go,同时传入cluster.GetFixedInheritedLabels()作为固定标签;
  • PVC:pkg/reconciler/persistentvolumeclaim/metadata.go;
  • 大版本升级 Job:pkg/reconciler/majorupgrade/reconciler.go,Job 本体及其 Pod 模板都参与继承。

InheritLabels实现中的一个关键细节:它先写入fixedLabels(operator 固定的预定义标签),再遍历源标签并在IsLabelInherited返回 true 时写入自定义标签。因此即便用户自定义标签与预定义标签同名,预定义值也不会被覆盖。相应的单元测试见 pkg/utils/labels_annotations_test.go。

当前局限:删除不会反向传播

CloudNativePG 目前不会自动传播标签或注解的删除。也就是说,当一个此前已传播到 Pod 等衍生资源上的注解或标签从Cluster上移除时,operator不会在关联资源上同步删除它。这意味着旧标签/注解会残留在历史资源上,用户在清理元数据时需自行处理,或通过重建资源(如滚动更新)让新元数据生效。

总结与最佳实践

  1. 优先使用标准app.kubernetes.io/*标签与外部工具集成,保证跨平台可移植性;
  2. 通过INHERITED_ANNOTATIONS/INHERITED_LABELS结合company/*通配符,建立公司级统一的元数据规范,避免在每个Cluster上重复定义;
  3. 角色相关判断请使用cnpg.io/instanceRole而非已废弃的role标签;
  4. 谨慎使用cnpg.io/podPatchcnpg.io/validationcnpg.io/skipWalArchiving等高风险开关,并在变更后通过kubectl cnpg restart触发预期行为;
  5. 时刻牢记删除不回传的局限,设计元数据生命周期时应考虑通过重建资源完成清理。

如需进一步了解所有标签/注解的完整权威清单,可直接阅读仓库中的 docs/src/labels_annotations.md 原文,以及常量定义所在的 pkg/utils/labels_annotations.go。

【免费下载链接】cloudnative-pgThe most popular Kubernetes Operator for PostgreSQL.项目地址: https://gitcode.com/GitHub_Trending/cl/cloudnative-pg

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

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

LivePortrait 上手教程:把静态照片变成会动的人像动画

LivePortrait 上手教程&#xff1a;把静态照片变成会动的人像动画 【免费下载链接】LivePortrait Bring portraits to life! 项目地址: https://gitcode.com/GitHub_Trending/li/LivePortrait 你相册里堆着一堆静态照片&#xff0c;却只能干放着。如果一段视频就能让照片…

作者头像 李华
网站建设 2026/9/16 21:51:55

C++ TCP服务器开发与自定义协议粘包处理实践

1. 项目背景与核心挑战在嵌入式系统和网络编程领域&#xff0c;TCP服务器的开发一直是基础且关键的技术。不同于HTTP等高层协议&#xff0c;直接基于TCP实现自定义协议能获得更高的灵活性和性能优势&#xff0c;但同时也带来了粘包问题的挑战。我最近在开发一个工业设备监控系统…

作者头像 李华
网站建设 2026/9/16 21:50:56

FastAPI异步调用同步方法的高效实践

1. FastAPI异步方法调用同步方法的实战指南在FastAPI开发中&#xff0c;我们经常会遇到一个典型场景&#xff1a;如何在异步方法中调用同步的阻塞代码&#xff1f;这个问题看似简单&#xff0c;但处理不当会导致整个应用的性能急剧下降。我最近在一个高并发API项目中就踩过这个…

作者头像 李华
网站建设 2026/9/16 21:49:04

Chrome JavaScript黑白名单配置全攻略:从原生设置到企业策略

上个月我在处理一台旧笔记本时&#xff0c;实在被各种网页拖垮了性能——打开一个门户首页CPU就直接顶到100%&#xff0c;风扇像飞机起飞。排查了半天&#xff0c;真正的“凶手”其实是满屏的JavaScript脚本、广告SDK、埋点统计和自动播放组件。当时我就在想&#xff0c;要是能…

作者头像 李华
网站建设 2026/9/16 21:49:00

WSA 安装失败?按这三步自查,Windows 安卓子系统一次跑通

WSA 安装失败&#xff1f;按这三步自查&#xff0c;Windows 安卓子系统一次跑通 【免费下载链接】WSABuilds Run Windows Subsystem For Android on your Windows 10 and Windows 11 PC using prebuilt binaries with Google Play Store (MindTheGapps) and/or Magisk or Kerne…

作者头像 李华