Installation and upgrades v1

OpenShift

For instructions on how to install Cloud Native PostgreSQL on Red Hat OpenShift Container Platform, please refer to the "OpenShift" section.

Warning

OLM (via operatorhub.io is no longer supported as an installation method for EDB Postgres for Kubernetes.

Installation on Kubernetes

Obtaining an EDB subscription token

Important

You must obtain an EDB subscription token to install EDB Postgres for Kubernetes. You can only access the EDB private software repositories if you have a token.

Installing EDB Postgres for Kubernetes requires an EDB Repos 2.0 token to gain access to the EDB private software repositories.

You can obtain the token by visiting your EDB Account Profile. You must sign in if you're not already logged in.

Your account profile page displays the token to use next to the Repos 2.0 Token label. By default, the token is obscured. Select Show (the eye icon) to reveal it.

Your token entitles you to access one of two repositories: standard or enterprise.

  • standard Includes the operator and the EDB Postgres Extended operand images.
  • enterprise Includes the operator and the EDB Postgres Advanced and EDB Postgres Extended operand images.

Set the relevant value, determined by your subscription, as an environment variable EDB_SUBSCRIPTION_PLAN:

EDB_SUBSCRIPTION_PLAN=enterprise

Then set the Repos 2.0 token to an environment variable EDB_SUBSCRIPTION_TOKEN:

EDB_SUBSCRIPTION_TOKEN=<your-token>
Warning

The token is sensitive information. Ensure that you don't expose it to unauthorized users.

You can now proceed with the installation.

Using the Helm chart

The operator can be installed using the provided Helm chart.

Directly using the operator manifest

The operator can be installed like any other resource in Kubernetes, through a YAML manifest applied via kubectl.

Install the EDB pull secret

Before installing EDB Postgres for Kubernetes, you need to create a pull secret for EDB software in the postgresql-operator-system namespace. The pull secret needs to be saved in the namespace where the operator will reside.

Create the postgresql-operator-system namespace:

kubectl create namespace postgresql-operator-system

Create the pull secret:

kubectl create secret -n postgresql-operator-system docker-registry edb-pull-secret \
  --docker-server=docker.enterprisedb.com \
  --docker-username=k8s_$EDB_SUBSCRIPTION_PLAN \
  --docker-password=$EDB_SUBSCRIPTION_TOKEN

Install the operator

Now that the pull secret has been added to the namespace, the operator can be installed like any other resource in Kubernetes, through a YAML manifest applied via kubectl.

Two different manifests are available, depending on your subscription plan:

You can install the manifest for the latest version of the operator by running: You can install the latest operator manifest for this minor release as follows:

kubectl apply --server-side -f \
   https://get.enterprisedb.io/pg4k/pg4k-$EDB_SUBSCRIPTION_PLAN-1.24.1.yaml

You can verify that with:

kubectl get deployment -n postgresql-operator-system postgresql-operator-controller-manager

Using the cnp plugin for kubectl

You can use the cnp plugin to override the default configuration options that are in the static manifests.

For example, to generate the default latest manifest but change the watch namespaces to only be a specific namespace, you could run:

kubectl cnp install generate \
  --watch-namespace "specific-namespace" \
  > cnp_for_specific_namespace.yaml

See the "cnp plugin" documentation for a more comprehensive example.

Warning

If you are deploying EDB Postgres for Kubernetes on GKE and get an error (... failed to call webhook...), be aware that by default traffic between worker nodes and control plane is blocked by the firewall except for a few specific ports, as explained in the official docs and by this issue. You'll need to either change the targetPort in the webhook service, to be one of the allowed ones, or open the webhooks' port (9443) on the firewall.

Details about the deployment

In Kubernetes, the operator is by default installed in the postgresql-operator-system namespace as a Kubernetes Deployment. The name of this deployment depends on the installation method. When installed through the manifest or the cnp plugin, by default, it is called postgresql-operator-controller-manager. When installed via Helm, by default, the deployment name is derived from the helm release name, appended with the suffix -edb-postgres-for-kubernetes (e.g., <name>-edb-postgres-for-kubernetes).

Note

With Helm you can customize the name of the deployment via the fullnameOverride field in the "values.yaml" file.

You can get more information using the describe command in kubectl:

$ kubectl get deployments -n postgresql-operator-system
NAME                READY   UP-TO-DATE   AVAILABLE   AGE
<deployment-name>   1/1     1            1           18m
kubectl describe deploy \
  -n postgresql-operator-system \
  <deployment-name>

As with any Deployment, it sits on top of a ReplicaSet and supports rolling upgrades. The default configuration of the EDB Postgres for Kubernetes operator comes with a Deployment of a single replica, which is suitable for most installations. In case the node where the pod is running is not reachable anymore, the pod will be rescheduled on another node.

If you require high availability at the operator level, it is possible to specify multiple replicas in the Deployment configuration - given that the operator supports leader election. Also, you can take advantage of taints and tolerations to make sure that the operator does not run on the same nodes where the actual PostgreSQL clusters are running (this might even include the control plane for self-managed Kubernetes installations).

Operator configuration

You can change the default behavior of the operator by overriding some default options. For more information, please refer to the "Operator configuration" section.

Upgrades

Important

Please carefully read the release notes before performing an upgrade as some versions might require extra steps.

Upgrading EDB Postgres for Kubernetes operator is a two-step process:

  1. upgrade the controller and the related Kubernetes resources
  2. upgrade the instance manager running in every PostgreSQL pod

Unless differently stated in the release notes, the first step is normally done by applying the manifest of the newer version for plain Kubernetes installations, or using the native package manager of the used distribution (please follow the instructions in the above sections).

The second step is automatically executed after having updated the controller, by default triggering a rolling update of every deployed PostgreSQL instance to use the new instance manager. The rolling update procedure culminates with a switchover, which is controlled by the primaryUpdateStrategy option, by default set to unsupervised. When set to supervised, users need to complete the rolling update by manually promoting a new instance through the cnp plugin for kubectl.

Rolling updates

This process is discussed in-depth on the Rolling Updates page.

Important

In case primaryUpdateStrategy is set to the default value of unsupervised, an upgrade of the operator will trigger a switchover on your PostgreSQL cluster, causing a (normally negligible) downtime.

The default rolling update behavior can be replaced with in-place updates of the instance manager. This approach does not require a restart of the PostgreSQL instance, thereby avoiding a switchover within the cluster. This feature, which is disabled by default, is described in detail below.

In-place updates of the instance manager

By default, EDB Postgres for Kubernetes issues a rolling update of the cluster every time the operator is updated. The new instance manager shipped with the operator is added to each PostgreSQL pod via an init container.

However, this behavior can be changed via configuration to enable in-place updates of the instance manager, which is the PID 1 process that keeps the container alive.

Internally, each instance manager in EDB Postgres for Kubernetes supports the injection of a new executable that replaces the existing one after successfully completing an integrity verification phase and gracefully terminating all internal processes. Upon restarting with the new binary, the instance manager seamlessly adopts the already running postmaster.

As a result, the PostgreSQL process is unaffected by the update, refraining from the need to perform a switchover. The other side of the coin, is that the Pod is changed after the start, breaking the pure concept of immutability.

You can enable this feature by setting the ENABLE_INSTANCE_MANAGER_INPLACE_UPDATES environment variable to 'true' in the operator configuration.

The in-place upgrade process will not change the init container image inside the Pods. Therefore, the Pod definition will not reflect the current version of the operator.

Compatibility among versions

EDB Postgres for Kubernetes follows semantic versioning. Every release of the operator within the same API version is compatible with the previous one. The current API version is v1, corresponding to versions 1.x.y of the operator.

In addition to new features, new versions of the operator contain bug fixes and stability enhancements. Because of this, we strongly encourage users to upgrade to the latest version of the operator, as each version is released in order to maintain the most secure and stable Postgres environment.

EDB Postgres for Kubernetes currently releases new versions of the operator at least monthly. If you are unable to apply updates as each version becomes available, we recommend upgrading through each version in sequential order to come current periodically and not skipping versions.

The release notes page contains a detailed list of the changes introduced in every released version of EDB Postgres for Kubernetes, and it must be read before upgrading to a newer version of the software.

Most versions are directly upgradable and in that case, applying the newer manifest for plain Kubernetes installations or using the native package manager of the chosen distribution is enough.

When versions are not directly upgradable, the old version needs to be removed before installing the new one. This won't affect user data but only the operator itself.

Upgrading to 1.24 from a previous minor version

Warning

Every time you are upgrading to a higher minor release, make sure you go through the release notes and upgrade instructions of all the intermediate minor releases. For example, if you want to move from 1.22.x to 1.24, make sure you go through the release notes and upgrade instructions for 1.23 and 1.24.

From Replica Clusters to Distributed Topology

One of the key enhancements in EDB Postgres for Kubernetes 1.24.0 is the upgrade of the replica cluster feature.

The former replica cluster feature, now referred to as the "Standalone Replica Cluster," is no longer recommended for Disaster Recovery (DR) and High Availability (HA) scenarios that span multiple Kubernetes clusters. Standalone replica clusters are best suited for read-only workloads, such as reporting, OLAP, or creating development environments with test data.

For DR and HA purposes, EDB Postgres for Kubernetes now introduces the Distributed Topology strategy for replica clusters. This new strategy allows you to build PostgreSQL clusters across private, public, hybrid, and multi-cloud environments, spanning multiple regions and potentially different cloud providers. It also provides an API to control the switchover operation, ensuring that only one cluster acts as the primary at any given time.

This Distributed Topology strategy enhances resilience and scalability, making it a robust solution for modern, distributed applications that require high availability and disaster recovery capabilities across diverse infrastructure setups.

You can seamlessly transition from a previous replica cluster configuration to a distributed topology by modifying all the Cluster resources involved in the distributed PostgreSQL setup. Ensure the following steps are taken:

  • Configure the externalClusters section to include all the clusters involved in the distributed topology. We strongly suggest using the same configuration across all Cluster resources for maintainability and consistency.
  • Configure the primary and source fields in the .spec.replica stanza to reflect the distributed topology. The primary field should contain the name of the current primary cluster in the distributed topology, while the source field should contain the name of the cluster each Cluster resource is replicating from. It is important to note that the enabled field, which was previously set to true or false, should now be unset (default).

For more information, please refer to the "Distributed Topology" section for replica clusters.

Upgrading to 1.23 from a previous minor version

User defined replication slots

EDB Postgres for Kubernetes now offers automated synchronization of all replication slots defined on the primary to any standby within the High Availability (HA) cluster.

If you manually manage replication slots on a standby, it is essential to exclude those replication slots from synchronization. Failure to do so may result in EDB Postgres for Kubernetes removing them from the standby. To implement this exclusion, utilize the following YAML configuration. In this example, replication slots with a name starting with 'foo' are prevented from synchronization:

...
  replicationSlots:
    synchronizeReplicas:
      enabled: true
      excludePatterns:
      - "^foo"

Alternatively, if you prefer to disable the synchronization mechanism entirely, use the following configuration:

...
  replicationSlots:
    synchronizeReplicas:
      enabled: false

Server-side apply of manifests

To ensure compatibility with Kubernetes 1.29 and upcoming versions, EDB Postgres for Kubernetes now mandates the utilization of "Server-side apply" when deploying the operator manifest.

While employing this installation method poses no challenges for new deployments, updating existing operator manifests using the --server-side option may result in errors resembling the example below:

Apply failed with 1 conflict: conflict with "kubectl-client-side-apply" using..

If such errors arise, they can be resolved by explicitly specifying the --force-conflicts option to enforce conflict resolution:

kubectl apply --server-side --force-conflicts -f <OPERATOR_MANIFEST>

Henceforth, kube-apiserver will be automatically acknowledged as a recognized manager for the CRDs, eliminating the need for any further manual intervention on this matter.