|
| 1 | +--- |
| 2 | +title: "Customize a Postgres Cluster" |
| 3 | +draft: false |
| 4 | +weight: 130 |
| 5 | +--- |
| 6 | + |
| 7 | +The PostgreSQL Operator makes it very easy and quick to [create a cluster]({{< relref "tutorial/create-cluster.md" >}}), but there are possibly more customizations you want to make to your cluster. These include: |
| 8 | + |
| 9 | +- Resource allocations (e.g. Memory, CPU, PVC size) |
| 10 | +- Sidecars (e.g. [Monitoring]({{< relref "architecture/monitoring.md" >}}), pgBouncer, [pgAdmin 4]({{< relref "architecture/pgadmin4.md" >}})) |
| 11 | +- High Availability (e.g. adding replicas) |
| 12 | +- Specifying specific PostgreSQL images (e.g. one with PostGIS) |
| 13 | +- Specifying a [Pod anti-affinity and Node affinity](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/) |
| 14 | +- Enable and/or require TLS for all connections |
| 15 | +- [Custom PostgreSQL configurations]({{< relref "advanced/custom-configuration.md" >}}) |
| 16 | + |
| 17 | +and more. |
| 18 | + |
| 19 | +There are an abundance of ways to customize your PostgreSQL clusters with the PostgreSQL Operator. You can read about all of these options in the [`pgo create cluster`]({{< relref "pgo-client/reference/pgo_create_cluster.md" >}}) reference. |
| 20 | + |
| 21 | +The goal of this section is to present a few of the common actions that can be taken to help create the PostgreSQL cluster of your choice. Later sections of the tutorial will cover other topics, such as creating a cluster with TLS or tablespaces. |
| 22 | + |
| 23 | +## Create a PostgreSQL Cluster With Monitoring |
| 24 | + |
| 25 | +The [PostgreSQL Operator Monitoring]({{< relref "architecture/monitoring.md" >}}) stack provides a convenient way to gain insights into the availabilty and performance of your PostgreSQL clusters. In order to collect metrics from your PostgreSQL clusters, you have to enable the `crunchy-postgres-exporter` sidecar alongside your PostgreSQL cluster. You can do this with the `--metrics` flag on [`pgo create cluster`]({{< relref "pgo-client/reference/pgo_create_cluster.md" >}}): |
| 26 | + |
| 27 | +``` |
| 28 | +pgo create cluster hippo --metrics |
| 29 | +``` |
| 30 | + |
| 31 | +Note that the `--metrics` flag just enables a sidecar that can be scraped. You will need to install the [monitoring stack]({{< relref "installation/metrics/_index.md" >}}) separately, or tie it into your existing monitoring infrastructure. |
| 32 | + |
| 33 | +## Customize PVC Size |
| 34 | + |
| 35 | +Databases come in all different sizes, and those sizes can certainly change over time. As such, it is helpful to be able to specify what size PVC you want to store your PostgreSQL data. |
| 36 | + |
| 37 | +### Customize PVC Size for PostgreSQL |
| 38 | + |
| 39 | +The PostgreSQL Operator lets you choose the size of your "PostgreSQL data directory" (aka "PGDATA" directory) using the `--pvc-size` flag. The PVC size should be selected using standard [Kubernetes resource units](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#resource-units-in-kubernetes), e.g. `20Gi`. |
| 40 | + |
| 41 | +For example, to create a PostgreSQL cluster that has a data directory that is `20Gi` in size: |
| 42 | + |
| 43 | +``` |
| 44 | +pgo create cluster hippo --pvc-size=20Gi |
| 45 | +``` |
| 46 | + |
| 47 | +### Customize PVC Size for pgBackRest |
| 48 | + |
| 49 | +You can also specify the PVC size for the [pgBackRest repository]({{< relref "architecture/disaster-recovery.md" >}}) with the `--pgbackrest-pvc-size`. [pgBackRest](https://pgbackrest.org/) is used to store all of your backups, so you want to size it so that you can meet your backup retention policy. |
| 50 | + |
| 51 | +For example, to create a pgBackRest repository that has a PVC sized to `100Gi` in size: |
| 52 | + |
| 53 | +``` |
| 54 | +pgo create cluster hippo --pgbackrest-pvc-size=100Gi |
| 55 | +``` |
| 56 | + |
| 57 | +## Customize CPU / Memory |
| 58 | + |
| 59 | +Databases have different CPU and memory requirements, often which is dictated by the amount of data in your working set (i.e. actively accessed data). Kubernetes provides several ways for Pods to [manage CPU and memory resources](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/): |
| 60 | + |
| 61 | +- CPU & Memory Requests |
| 62 | +- CPU & Memory Limits |
| 63 | + |
| 64 | +A CPU or Memory Request tells Kubernetes to ensure that there is _at least_ that amount of resource available on the Node to schedule a Pod to. |
| 65 | + |
| 66 | +A CPU Limit tells Kubernetes to not let a Pod exceed utilizing that amount of CPU. A Pod will only be allowed to use that maximum amount of CPU. Similarly, a Memory limit tells Kubernetes to not let a Pod exceed a certain amount of Memory. In this case, if Kubernetes detects that a Pod has exceed a Memory limit, it will try to terminate any processes that are causing the limit to be exceed. We mention this as, prior to cgroups v2, Memory limits can potentially affect PostgreSQL availability and we advise to use them carefully. |
| 67 | + |
| 68 | +The below goes into how you can customize the CPU and memory resources that are made available to the core deployment Pods with your PostgreSQL cluster. Customizing CPU and memory does add more resources to your PostgreSQL cluster, but to fully take advantage of additional resources, you will need to [customize your PostgreSQL configuration](#customize-postgresql-configuration) and tune parameters such as `shared_buffers` and others. |
| 69 | + |
| 70 | +### Customize CPU / Memory for PostgreSQL |
| 71 | + |
| 72 | +The PostgreSQL Operator provides several flags for [`pgo create cluster`]({{< relref "pgo-client/reference/pgo_create_cluster.md" >}}) to help manage resources for a PostgreSQL instance: |
| 73 | + |
| 74 | +- `--cpu`: Specify the CPU Request for a PostgreSQL instance |
| 75 | +- `--cpu-limit`: Specify the CPU Limit for a PostgreSQL instance |
| 76 | +- `--memory`: Specify the Memory Request for a PostgreSQL instance |
| 77 | +- `--memory-limit`: Specify the Memory Limit for a PostgreSQL instance |
| 78 | + |
| 79 | +For example, to create a PostgreSQL cluster that makes a CPU Request of 2.0 with a CPU Limit of 4.0 and a Memory Request of 4Gi with a Memory Limit of 6Gi: |
| 80 | + |
| 81 | +``` |
| 82 | +pgo create cluster hippo \ |
| 83 | + --cpu=2.0 --cpu-limit=4.0 \ |
| 84 | + --memory=4Gi --memory-limit=6Gi |
| 85 | +``` |
| 86 | + |
| 87 | +### Customize CPU / Memory for Crunchy PostgreSQL Exporter Sidecar |
| 88 | + |
| 89 | +If you deploy your [PostgreSQL cluster with monitoring](#create-a-postgresql-cluster-with-monitoring), you may want to adjust the resources of the `crunchy-postgres-exporter` sidecar that runs next to each PostgreSQL instnace. You can do this with the following flags: |
| 90 | + |
| 91 | +- `--exporter-cpu`: Specify the CPU Request for a `crunchy-postgres-exporter` sidecar |
| 92 | +- `--exporter-cpu-limit`: Specify the CPU Limit for a `crunchy-postgres-exporter` sidecar |
| 93 | +- `--exporter-memory`: Specify the Memory Request for a `crunchy-postgres-exporter` sidecar |
| 94 | +- `--exporter-memory-limit`: Specify the Memory Limit for a `crunchy-postgres-exporter` sidecar |
| 95 | + |
| 96 | +For example, to create a PostgreSQL cluster with a metrics sidecar with custom CPU and memory requests + limits, you could do the following: |
| 97 | + |
| 98 | +``` |
| 99 | +pgo create cluster hippo --metrics \ |
| 100 | + --exporter-cpu=0.5 --exporter-cpu-limit=1.0 \ |
| 101 | + --exporter-memory=256Mi --exporter-memory-limit=1Gi |
| 102 | +``` |
| 103 | + |
| 104 | +### Customize CPU / Memory for pgBackRest |
| 105 | + |
| 106 | +You can also customize the CPU and memory requests and limits for pgBackRest with the following flags: |
| 107 | + |
| 108 | +- `--pgbackrest-cpu`: Specify the CPU Request for pgBackRest |
| 109 | +- `--pgbackrest-cpu-limit`: Specify the CPU Limit for pgBackRest |
| 110 | +- `--pgbackrest-memory`: Specify the Memory Request for pgBackRest |
| 111 | +- `--pgbackrest-memory-limit`: Specify the Memory Limit for pgBackRest |
| 112 | + |
| 113 | +For example, to create a PostgreSQL cluster with custom CPU and memory requests + limits for pgBackRest, you could do the following: |
| 114 | + |
| 115 | +``` |
| 116 | +pgo create cluster hippo \ |
| 117 | + --pgbackrest-cpu=0.5 --pgbackrest-cpu-limit=1.0 \ |
| 118 | + --pgbackrest-memory=256Mi --pgbackrest-memory-limit=1Gi |
| 119 | +``` |
| 120 | + |
| 121 | +## Create a High Availability PostgreSQL Cluster |
| 122 | + |
| 123 | +[High availability]({{< relref "architecture/high-availability/_index.md" >}}) allows you to deploy PostgreSQL clusters with redundancy that allows them to be accessible by your applications even if there is a downtime event to your primary instance. The PostgreSQL clusters use the distributed consensus storage system that comes with Kubernetes so that availability is tied to that of your Kubenretes clusters. For an in-depth discussion of the topic, please read the [high availability]({{< relref "architecture/high-availability/_index.md" >}}) section of the documentation. |
| 124 | + |
| 125 | +To create a high availability PostgreSQL cluster with one replica, you can run the following command: |
| 126 | + |
| 127 | +``` |
| 128 | +pgo create cluster hippo --replica-count=1 |
| 129 | +``` |
| 130 | + |
| 131 | +You can scale up and down your PostgreSQL cluster with the [`pgo scale`]({{< relref "pgo-client/reference/pgo_scale.md" >}}) and [`pgo scaledown`]({{< relref "pgo-client/reference/pgo_scaledown.md" >}}) commands. |
| 132 | + |
| 133 | +## Customize PostgreSQL Configuration |
| 134 | + |
| 135 | +PostgreSQL provides a lot of different knobs that can be used to fine tune the [configuration](https://www.postgresql.org/docs/current/runtime-config.html) for your workload. While you can [customize your PostgreSQL configuration]({{< relref "advanced/custom-configuration.md" >}}) after your cluster has been deployed, you may also want to load in your custom configuration during initialization. |
| 136 | + |
| 137 | +The PostgreSQL Operator uses [Patroni](https://patroni.readthedocs.io/) to help manage cluster initialization and high availability. To understand how to build out a configuration file to be used to customize your PostgreSQL cluster, please review the [Patroni documentation](https://patroni.readthedocs.io/en/latest/SETTINGS.html). |
| 138 | + |
| 139 | +For example, let's say we want to create a PostgreSQL cluster with `shared_buffers` set to `2GB`, `max_connections` set to `30` and `password_encryption` set to `scram-sha-256`. We would create a configuration file that looks similar to: |
| 140 | + |
| 141 | +``` |
| 142 | +--- |
| 143 | +bootstrap: |
| 144 | + dcs: |
| 145 | + postgresql: |
| 146 | + parameters: |
| 147 | + max_connections: 30 |
| 148 | + shared_buffers: 2GB |
| 149 | + password_encryption: scram-sha-256 |
| 150 | +``` |
| 151 | + |
| 152 | +Save this configuration in a file called `postgres-ha.yaml`. |
| 153 | + |
| 154 | +Next, create a [`ConfigMap`](https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/) called `hippo-custom-config` like so: |
| 155 | + |
| 156 | +``` |
| 157 | +kubectl -n pgo create configmap hippo-custom-config --from-file=postgres-ha.yaml |
| 158 | +``` |
| 159 | + |
| 160 | +You can then have you new PostgreSQL cluster use `hippo-custom-config` as part of its cluster initialization by using the `--custom-config` flag of `pgo create cluster`: |
| 161 | + |
| 162 | +``` |
| 163 | +pgo create cluster hippo --custom-config=hippo-custom-config |
| 164 | +``` |
| 165 | + |
| 166 | +After your cluster is initialized, [connect to your cluster]({{< relref "tutorial/connect-cluster.md" >}}) and confirm that your settings have been applied: |
| 167 | + |
| 168 | +``` |
| 169 | +SHOW shared_buffers; |
| 170 | +
|
| 171 | + shared_buffers |
| 172 | +---------------- |
| 173 | + 2GB |
| 174 | +``` |
| 175 | + |
| 176 | +## Troubleshooting |
| 177 | + |
| 178 | +### PostgreSQL Pod Can't Be Scheduled |
| 179 | + |
| 180 | +There are many reasons why a PostgreSQL Pod may not be scheduled: |
| 181 | + |
| 182 | +- **Resources are unavailable**. Ensure that you have a Kubernetes [Node](https://kubernetes.io/docs/concepts/architecture/nodes/) with enough resources to satisfy your memory or CPU Request. |
| 183 | +- **PVC cannot be provisioned**. Ensure that you request a PVC size that is available, or that your PVC storage class is set up correctly. |
| 184 | +- **Node affinity rules cannot be satisfied**. If you assigned a node label, ensure that the Nodes with that label are available for scheduling. If they are, ensure that there are enough resources available. |
| 185 | +- **Pod anti-affinity rules cannot be satisfied**. This most likely happens when [pod anti-affinity]({{< relref "architecture/high-availability/_index.md" >}}#how-the-crunchy-postgresql-operator-uses-pod-anti-affinity) is set to `required` and there are not enough Nodes available for scheduling. Consider adding more Nodes or relaxing your anti-affinity rules. |
| 186 | + |
| 187 | +## Next Steps |
| 188 | + |
| 189 | +As mentioned at the beginning, there are a lot more customizations that you can make to your PostgreSQL cluster, and we will cover those as the tutorial progresses! This section was to get you familiar with some of the most common customizations, and to explore how many options `pgo create cluster` has! |
| 190 | + |
| 191 | +Now you have your PostgreSQL cluster up and running and using the resources as you see fit. What if you want to make changes to the cluster? We'll explore some of the commands that can be used to update your PostgreSQL cluster! |
0 commit comments