CNPG-I ====== .. raw:: html The **CloudNativePG Interface** ( `CNPG-I `_ ) is a standard way to extend and customize CloudNativePG without modifying its core codebase. Why CNPG-I? ----------- CloudNativePG 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 CNPG-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. CNPG-I solves these problems by providing a stable, gRPC-based integration point for extending CloudNativePG at key points in a cluster’s lifecycle —such as backups, recovery, and sub-resource reconciliation— without disrupting the core project. CNPG-I can extend: - The operator, and/or - The instance manager running inside PostgreSQL pods. Registering a plugin -------------------- CNPG-I is inspired by the Kubernetes `Container Storage Interface (CSI) `_ . The operator communicates with registered plugins using **gRPC**, following the `CNPG-I protocol `_ . CloudNativePG 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: .. code:: yaml 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:: CloudNativePG does **not** discover plugins dynamically. If you deploy a new plugin, you must **restart the operator** to detect it.   Example Deployment: .. code:: yaml 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 ``cnpg.io/plugin: `` — required for CloudNativePG to discover the plugin - The annotation ``cnpg.io/pluginPort: `` — specifies the port where the plugin’s gRPC server is exposed Example Service: .. code:: yaml apiVersion: v1 kind: Service metadata: annotations: cnpg.io/pluginPort: "9090" labels: cnpg.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 CloudNativePG 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 (``cnpg.io/pluginClientSecret`` and ``cnpg.io/pluginServerSecret`` ): .. code:: yaml apiVersion: v1 kind: Service metadata: annotations: cnpg.io/pluginClientSecret: cnpg-i-plugin-example-client-tls cnpg.io/pluginServerSecret: cnpg-i-plugin-example-server-tls cnpg.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 `_ .   Customizing the Certificate DNS Name ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ By default, CloudNativePG uses the Service name as the server name for TLS verification when connecting to the plugin. If your environment requires the certificate to have a different DNS name (e.g., ``barman-cloud.svc`` ), you can customize it using the ``cnpg.io/pluginServerName`` annotation: .. code:: yaml apiVersion: v1 kind: Service metadata: annotations: cnpg.io/pluginClientSecret: cnpg-i-plugin-example-client-tls cnpg.io/pluginServerSecret: cnpg-i-plugin-example-server-tls cnpg.io/pluginPort: "9090" cnpg.io/pluginServerName: barman-cloud.svc name: barman-cloud namespace: postgresql-operator-system spec: [...] This allows the operator to verify the plugin’s certificate against the specified DNS name instead of the default Service name. The server certificate must include this DNS name in its Subject Alternative Names (SAN). Using a plugin -------------- To enable a plugin, configure the ``.spec.plugins`` section in your ``Cluster`` resource. Refer to the CloudNativePG API Reference for the full `PluginConfiguration `_ specification. Example: .. code:: yaml apiVersion: postgresql.cnpg.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 ``cnpg.io/pluginName`` label Community plugins ----------------- The CNPG-I protocol has quickly become a proven and reliable pattern for extending CloudNativePG 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 CNPG-I, please refer to the `CNPG-I GitHub page `_ .