Resources in Kubernetes are organized in a flat structure, with no hierarchical information or relationship between them. However, such resources and objects can be linked together and put in relationship through labels and annotations.
Info
For more information, see the Kubernetes documentation on annotations and labels.
In brief:
- An annotation is used to assign additional non-identifying information to resources with the goal of facilitating integration with external tools.
- A label is used to group objects and query them through the Kubernetes native selector capability.
You can select one or more labels or annotations to use in your EDB Postgres® AI for CloudNativePG™ Cluster deployments. Then you need to configure the operator so that when you define these labels or annotations in a cluster's metadata, they're inherited by all resources created by it (including pods).
Note
Label and annotation inheritance is the technique adopted by EDB Postgres® AI for CloudNativePG™ Cluster instead of alternative approaches such as pod templates.
Predefined labels
EDB Postgres® AI for CloudNativePG™ Cluster manages the following predefined labels:
k8s.enterprisedb.io/backupDateThe date of the backup in ISO 8601 format (
YYYYMMDD). This label is available only onVolumeSnapshotresources.k8s.enterprisedb.io/backupNameBackup identifier. This label is available only on
VolumeSnapshotresources.k8s.enterprisedb.io/backupMonthThe year/month when a backup was taken. This label is available only on
VolumeSnapshotresources.k8s.enterprisedb.io/backupTimelineThe timeline of the instance when a backup was taken. This label is available only on
VolumeSnapshotresources.k8s.enterprisedb.io/backupYearThe year a backup was taken. This label is available only on
VolumeSnapshotresources.k8s.enterprisedb.io/clusterName of the cluster.
k8s.enterprisedb.io/immediateBackupApplied to a
Backupresource if the backup is the first one created from aScheduledBackupobject havingimmediateset totrue.k8s.enterprisedb.io/instanceNameName of the PostgreSQL instance (replaces the old and deprecated
postgresqllabel).k8s.enterprisedb.io/jobRoleRole of the job (that is,
import,initdb,join, ...)k8s.enterprisedb.io/majorVersionInteger PostgreSQL major version of the backup's data directory (for example,
17). This label is available only onVolumeSnapshotresources.k8s.enterprisedb.io/onlineBackupWhether the backup is online (hot) or taken when Postgres is down (cold). This label is available only on
VolumeSnapshotresources.postgresqldeprecated, Name of the PostgreSQL instance. Use
k8s.enterprisedb.io/instanceNameinsteadk8s.enterprisedb.io/podRoleDistinguishes pods dedicated to pooler deployment from those used for database instances.
k8s.enterprisedb.io/poolerNameName of the PgBouncer pooler.
k8s.enterprisedb.io/pvcRolePurpose of the PVC, such as
PG_DATAorPG_WAL.k8s.enterprisedb.io/reloadAvailable on
ConfigMapandSecretresources. When set totrue, a change in the resource is automatically reloaded by the operator.k8s.enterprisedb.io/userTypeSpecifies the type of PostgreSQL user associated with the
Secret, eithersuperuser(Postgres superuser access) orapp(application-level user in EDB Postgres® AI for CloudNativePG™ Cluster terminology), and is limited to the default users created by EDB Postgres® AI for CloudNativePG™ Cluster (typicallypostgresandapp).role- deprecated****Role of the instance running in a pod:
primary,replica, orunhealthy. Theunhealthyvalue is transient: the operator sets it on the old primary during a failover or switchover and clears it automatically once the transition completes. This label is deprecated, you should usek8s.enterprisedb.io/instanceRoleinstead.k8s.enterprisedb.io/scheduled-backupWhen available, name of the
ScheduledBackupresource that created a givenBackupobject.k8s.enterprisedb.io/instanceRoleRole of the instance running in a pod:
primary,replica, orunhealthy. Theunhealthyvalue is transient: the operator sets it on the old primary during a failover or switchover and clears it automatically once the transition completes.app.kubernetes.io/managed-byName of the manager. It will always be
cloudnative-pg. Available across all EDB Postgres® AI for CloudNativePG™ Cluster managed resources.app.kubernetes.io/nameName of the application. It will always be
postgresql. Available on pods, jobs, deployments, services, persistentVolumeClaims, volumeSnapshots, podDisruptionBudgets, podMonitors.app.kubernetes.io/componentName of the component (
database,pooler, ...). Available on pods, jobs, deployments, services, persistentVolumeClaims, volumeSnapshots, podDisruptionBudgets, podMonitors.app.kubernetes.io/instanceName of the owning
Clusterresource. Available on pods, jobs, deployments, services, volumeSnapshots, podDisruptionBudgets, podMonitors.app.kubernetes.io/versionMajor version of PostgreSQL. Available on pods, jobs, services, volumeSnapshots, podDisruptionBudgets, podMonitors.
Predefined annotations
EDB Postgres® AI for CloudNativePG™ Cluster manages the following predefined annotations:
container.apparmor.security.beta.kubernetes.io/*Name of the AppArmor profile to apply to the named container. See AppArmor for details.
k8s.enterprisedb.io/backupEndTimeThe time a backup ended. This annotation is available only on
VolumeSnapshotresources.k8s.enterprisedb.io/backupEndWALThe WAL at the conclusion of a backup. This annotation is available only on
VolumeSnapshotresources.k8s.enterprisedb.io/backupStartTimeThe time a backup started.
k8s.enterprisedb.io/backupStartWALThe WAL at the start of a backup. This annotation is available only on
VolumeSnapshotresources.k8s.enterprisedb.io/coredumpFilterFilter to control the coredump of Postgres processes, expressed with a bitmask. By default it's set to
0x31to exclude shared memory segments from the dump. See PostgreSQL core dumps for more information.k8s.enterprisedb.io/clusterManifestManifest of the
Clusterowning this resource (such as a PVC). This label replaces the old, deprecatedk8s.enterprisedb.io/hibernateClusterManifestlabel.k8s.enterprisedb.io/fencedInstancesList of the instances that need to be fenced, expressed in JSON format. The whole cluster is fenced if the list contains the
*element.k8s.enterprisedb.io/forceLegacyBackupApplied to a
Clusterresource for testing purposes only, to simulate the behavior ofbarman-cloud-backupprior to version 3.4 (Jan 2023) when the--nameoption wasn't available.k8s.enterprisedb.io/hashThe hash value of the resource.
k8s.enterprisedb.io/hibernationApplied to a
Clusterresource to control the declarative hibernation feature. Allowed values areonandoff.k8s.enterprisedb.io/managedSecretsPull secrets managed by the operator and automatically set in the
ServiceAccountresources for each Postgres cluster.k8s.enterprisedb.io/nodeSerialOn a pod resource, identifies the serial number of the instance within the Postgres cluster.
k8s.enterprisedb.io/operatorVersionVersion of the operator.
k8s.enterprisedb.io/passwordPassthroughWhen set to
enabledon a basic-authSecretconsumed by the operator (superuser, application user, or a managed-role password secret), the operator forwards the password value verbatim in theCREATE/ALTER ROLEstatement instead of SCRAM-SHA-256 encoding it operator-side. PostgreSQL then encodes the value according to its ownpassword_encryptionsetting. See Opting out of operator-side encoding.k8s.enterprisedb.io/pgControldataOutput of the
pg_controldatacommand. This annotation replaces the old, deprecatedk8s.enterprisedb.io/hibernatePgControlDataannotation.k8s.enterprisedb.io/podEnvHashDeprecated, as the
k8s.enterprisedb.io/podSpecannotation now also contains the pod environment.k8s.enterprisedb.io/podPatchAnnotation can be applied on a
Clusterresource.When set to a JSON-patch formatted patch, the patch will be applied to the instance Pods. The patch can modify any field of the Pod specification, including security-sensitive fields. The operator validates only that the patch is syntactically correct and applicable.
As with all Cluster fields that affect Pod specifications, enforcement of security constraints is delegated to the Kubernetes admission control chain. See the Trust Model and Security Boundaries section for details.
⚠️ WARNING: This feature may introduce discrepancies between the operator's expectations and Kubernetes behavior. Use with caution and only as a last resort.
IMPORTANT: adding or changing this annotation won't trigger a rolling deployment of the generated Pods. The latter can be triggered manually by the user with
kubectl cnp restart.
k8s.enterprisedb.io/podSpecSnapshot of the
specof the pod generated by the operator. This annotation replaces the old, deprecatedk8s.enterprisedb.io/podEnvHashannotation.k8s.enterprisedb.io/poolerSpecHashHash of the pooler resource.
k8s.enterprisedb.io/pvcStatusCurrent status of the PVC:
initializing,ready, ordetached.k8s.enterprisedb.io/reconcilePodSpecAnnotation can be applied to a
ClusterorPoolerto prevent restarts.When set to
disabledon aCluster, the operator prevents instances from restarting due to changes in the PodSpec. This includes changes to:- Topology or affinity
- Scheduler
- Volumes or containers
When set to
disabledon aPooler, the operator restricts any modifications to the deployment specification, except for changes tospec.instances.
k8s.enterprisedb.io/reconciliationLoopWhen set to
disabledon aCluster, the operator prevents the reconciliation loop from running.k8s.enterprisedb.io/reloadedAtContains the latest cluster
reloadtime.reloadis triggered by the user through a plugin.k8s.enterprisedb.io/skipEmptyWalArchiveCheckWhen set to
enabledon aClusterresource, the operator disables the check that ensures that the WAL archive is empty before writing data. Use at your own risk.k8s.enterprisedb.io/skipWalArchivingWhen set to
enabledon aClusterresource, the operator disables WAL archiving. This will setarchive_modetooffand require a restart of all PostgreSQL instances. Use at your own risk.k8s.enterprisedb.io/snapshotStartTimeThe time a snapshot started.
k8s.enterprisedb.io/snapshotEndTimeThe time a snapshot was marked as ready to use.
k8s.enterprisedb.io/validationWhen set to
disabledon a EDB Postgres® AI for CloudNativePG™ Cluster-managed custom resource, the validation webhook allows all changes without restriction.⚠️ WARNING: Disabling validation may permit unsafe or destructive operations. Use this setting with caution and at your own risk.
k8s.enterprisedb.io/volumeSnapshotDeadlineApplied to
BackupandScheduledBackupresources, allows you to control how long the operator should retry recoverable errors before considering the volume snapshot backup failed. In minutes, defaulting to 10.kubectl.kubernetes.io/restartedAtWhen available, the time of last requested restart of a Postgres cluster.
alpha.k8s.enterprisedb.io/unrecoverableExperimental annotation applied to a
Podrunning a PostgreSQL instance. It instructs the operator to delete thePodand all its associated PVCs. The instance will then be recreated according to the configured join strategy. The annotation is honored regardless of the instance's state, so it also takes effect on aPodthat is Pending, Running but not ready, or Terminating. When a TerminatingPodhas passed its deletion deadline (the deletion request time plus its termination grace period), the operator force removes it so that its PVCs can be deleted and the instance recreated. This annotation can only be used on instances that are neither the current primary nor the designated target primary, which stay excluded even when marked unrecoverable.⚠️ WARNING: Force removing a
Podon an unreachable node does not stop any process that might still be running there, and whether the underlying volumes are detached depends on the storage driver. This is acceptable for this annotation, whose contract already forfeits the instance's data.
Prerequisites
By default, no label or annotation defined in the cluster's metadata is inherited by the associated resources. To enable label/annotation inheritance, follow the instructions provided in Operator configuration.
The following continues from that example and limits it to the following:
- Annotations:
categories - Labels:
app,environment, andworkload
Note
Feel free to select the names that most suit your context for both
annotations and labels. You can also use wildcards
in naming and adopt strategies like using mycompany/* for all labels
or setting annotations starting with mycompany/ to be inherited.
Defining cluster's metadata
When defining the cluster, before any resource is deployed, you can set the metadata as follows:
apiVersion: postgresql.k8s.enterprisedb.io/v1 kind: Cluster metadata: name: cluster-example annotations: categories: database labels: environment: production workload: database app: sso spec: # ... <snip>
Once the cluster is deployed, you can verify, for example, that the labels were correctly set in the pods:
kubectl get pods --show-labels
Current limitations
Currently, EDB Postgres® AI for CloudNativePG™ Cluster doesn't automatically propagate labels or annotations deletions. Therefore, when an annotation or label is removed from a cluster that was previously propagated to the underlying pods, the operator doesn't remove it on the associated resources.