Service Management
A PostgreSQL cluster should only be accessed via standard Kubernetes network services directly managed by CloudNativePG. For more details, refer to the "Service" page of the Kubernetes Documentation.
CloudNativePG defines three types of services for each Cluster
resource:
rw
: Points to the primary instance of the cluster (read/write).ro
: Points to the replicas, where available (read-only).r
: Points to any PostgreSQL instance in the cluster (read).
By default, CloudNativePG creates all the above services for a Cluster
resource, with the following conventions:
- The name of the service follows this format:
<CLUSTER_NAME>-<SERVICE_NAME>
. - All services are of type
ClusterIP
.
Important
Default service names are reserved for CloudNativePG usage.
While this setup covers most use cases for accessing PostgreSQL within the same Kubernetes cluster, CloudNativePG offers flexibility to:
- Disable the creation of the
ro
and/orr
default services. - Define your own services using the standard
Service
API provided by Kubernetes.
You can mix these two options.
A common scenario arises when using CloudNativePG in database-as-a-service
(DBaaS) contexts, where access to the database from outside the Kubernetes
cluster is required. In such cases, you can create your own service of type
LoadBalancer
, if available in your Kubernetes environment.
Disabling Default Services
You can disable any or all of the ro
and r
default services through the
managed.services.disabledDefaultServices
option.
Important
The rw
service is essential and cannot be disabled because CloudNativePG
relies on it to ensure PostgreSQL replication.
For example, if you want to remove both the ro
(read-only) and r
(read)
services, you can use this configuration:
# <snip>
managed:
services:
disabledDefaultServices: ["ro", "r"]
Adding Your Own Services
Important
When defining your own services, you cannot use any of the default reserved
service names that follow the convention <CLUSTER_NAME>-<SERVICE_NAME>
. It is
your responsibility to pick a unique name for the service in the Kubernetes
namespace.
You can define a list of additional services through the
managed.services.additional
stanza
by specifying the service type (e.g., rw
) in the selectorType
field
and optionally the updateStrategy
.
The serviceTemplate
field gives you access to the standard Kubernetes API for
the network Service
resource, allowing you to define both the metadata
and
the spec
sections as you like.
You must provide a name
to the service and avoid defining the selector
field, as it is managed by the operator.
Warning
Service templates give you unlimited possibilities in terms of configuring network access to your PostgreSQL database. This translates into greater responsibility on your end to ensure that services work as expected. CloudNativePG has no control over the service configuration, except honoring the selector.
The updateStrategy
field allows you to control how the operator
updates a service definition. By default, the operator uses the patch
strategy, applying changes directly to the service.
Alternatively, the recreate
strategy deletes the existing service and
recreates it from the template.
Warning
The recreate
strategy will cause a service disruption with every
change. However, it may be necessary for modifying certain
parameters that can only be set during service creation.
For example, if you want to have a single LoadBalancer
service for your
PostgreSQL database primary, you can use the following excerpt:
# <snip>
managed:
services:
additional:
- selectorType: rw
serviceTemplate:
metadata:
name: "mydb-lb"
labels:
test-label: "true"
annotations:
test-annotation: "true"
spec:
type: LoadBalancer
The above example also shows how to set metadata such as annotations and labels for the created service.
About Exposing Postgres Services
There are primarily three use cases for exposing your PostgreSQL service outside your Kubernetes cluster:
- Temporarily, for testing.
- Permanently, for DBaaS purposes.
- Prolonged period/permanently, for legacy applications that cannot be easily or sustainably containerized and need to reside in a virtual machine or physical machine outside Kubernetes. This use case is very similar to DBaaS.
Be aware that allowing access to a database from the public network could expose your database to potential attacks from malicious users.
Warning
Ensure you secure your database before granting external access, or make sure your Kubernetes cluster is only reachable from a private network.