CNP-I v1.27.0
The CloudNativePG Interface (CNPG-I) is a standard way to extend and customize EDB Postgres® AI for CloudNativePG™ Cluster without modifying its core codebase.
Why CNP-I?
EDB Postgres® AI for CloudNativePG™ Cluster supports a wide range of use cases, but sometimes its built-in functionality isn’t enough, or adding certain features directly to the main project isn’t practical.
Before CNP-I, users had two main options:
- Fork the project to add custom behavior, or
- Extend the upstream codebase by writing custom components on top of it.
Both approaches created maintenance overhead, slowed upgrades, and delayed delivery of critical features.
CNP-I solves these problems by providing a stable, gRPC-based integration point for extending EDB Postgres® AI for CloudNativePG™ Cluster at key points in a cluster’s lifecycle —such as backups, recovery, and sub-resource reconciliation— without disrupting the core project.
CNP-I can extend:
- The operator, and/or
- The instance manager running inside PostgreSQL pods.
Registering a plugin
CNP-I is inspired by the Kubernetes Container Storage Interface (CSI). The operator communicates with registered plugins using gRPC, following the CNPG-I protocol.
EDB Postgres® AI for CloudNativePG™ Cluster discovers plugins at startup. You can register them in one of two ways:
- Sidecar container – run the plugin inside the operator’s Deployment
- Standalone Deployment – run the plugin as a separate workload in the same namespace
In both cases, the plugin must be packaged as a container image.
Sidecar Container
When running as a sidecar, the plugin must expose its gRPC server via a Unix
domain socket. This socket must be placed in a directory shared with the
operator container, mounted at the path set in PLUGIN_SOCKET_DIR
(default:
/plugin
).
Example:
apiVersion: apps/v1 kind: Deployment metadata: name: controller-manager spec: template: spec: containers: - image: cloudnative-pg:latest [...] name: manager volumeMounts: - mountPath: /plugins name: cnpg-i-plugins - image: cnpg-i-plugin-example:latest name: cnpg-i-plugin-example volumeMounts: - mountPath: /plugins name: cnpg-i-plugins volumes: - name: cnpg-i-plugins emptyDir: {}
Standalone Deployment (recommended)
Running a plugin as its own Deployment decouples its lifecycle from the operator’s and allows independent scaling. In this setup, the plugin exposes a TCP gRPC endpoint behind a Service, with mTLS for secure communication.
Warning
EDB Postgres® AI for CloudNativePG™ Cluster does not discover plugins dynamically. If you deploy a new plugin, you must restart the operator to detect it.
Example Deployment:
apiVersion: apps/v1 kind: Deployment metadata: name: cnpg-i-plugin-example spec: template: [...] spec: containers: - name: cnpg-i-plugin-example image: cnpg-i-plugin-example:latest ports: - containerPort: 9090 protocol: TCP
The related Service for the plugin must include:
- The label
k8s.enterprisedb.io/plugin: <plugin-name>
— required for EDB Postgres® AI for CloudNativePG™ Cluster to discover the plugin - The annotation
k8s.enterprisedb.io/pluginPort: <port>
— specifies the port where the plugin’s gRPC server is exposed
Example Service:
apiVersion: v1 kind: Service metadata: annotations: k8s.enterprisedb.io/pluginPort: "9090" labels: k8s.enterprisedb.io/pluginName: cnpg-i-plugin-example.my-org.io name: cnpg-i-plugin-example spec: ports: - port: 9090 protocol: TCP targetPort: 9090 selector: app: cnpg-i-plugin-example
Configuring TLS Certificates
When a plugin runs as a Deployment
, communication with EDB Postgres® AI for CloudNativePG™ Cluster happens
over the network. To secure it, mTLS is enforced, requiring TLS
certificates for both sides.
Certificates must be stored as Kubernetes TLS Secrets
and referenced in the plugin’s Service annotations
(k8s.enterprisedb.io/pluginClientSecret
and k8s.enterprisedb.io/pluginServerSecret
):
apiVersion: v1 kind: Service metadata: annotations: k8s.enterprisedb.io/pluginClientSecret: cnpg-i-plugin-example-client-tls k8s.enterprisedb.io/pluginServerSecret: cnpg-i-plugin-example-server-tls k8s.enterprisedb.io/pluginPort: "9090" name: barman-cloud namespace: postgresql-operator-system spec: [...]
Note
You can provide your own certificate bundles, but the recommended method is to use Cert-manager.
Using a plugin
To enable a plugin, configure the .spec.plugins
section in your Cluster
resource. Refer to the EDB Postgres® AI for CloudNativePG™ Cluster API Reference for the full
PluginConfiguration
specification.
Example:
apiVersion: postgresql.k8s.enterprisedb.io/v1 kind: Cluster metadata: name: cluster-with-plugins spec: instances: 1 storage: size: 1Gi plugins: - name: cnpg-i-plugin-example.my-org.io enabled: true parameters: key1: value1 key2: value2
Each plugin may have its own parameters—check the plugin’s documentation for
details. The name
field in spec.plugins
depends on how the plugin is
deployed:
- Sidecar container: use the Unix socket file name
- Deployment: use the value from the Service’s
k8s.enterprisedb.io/pluginName
label
Community plugins
The CNP-I protocol has quickly become a proven and reliable pattern for extending EDB Postgres® AI for CloudNativePG™ Cluster while keeping the core project maintainable. Over time, the community has built and shared plugins that address real-world needs and serve as examples for developers.
For a complete and up-to-date list of plugins built with CNP-I, please refer to the CNPG-I GitHub page.