Add docs for hugepages support

This commit is contained in:
Silas Della Contrada 2023-05-04 13:43:38 +02:00
parent 9ccc78af82
commit 5bb950a1b7
1 changed files with 109 additions and 76 deletions

View File

@ -5,7 +5,8 @@ Learn how to work with the Postgres Operator in a Kubernetes (K8s) environment.
## Create a manifest for a new PostgreSQL cluster
Make sure you have [set up](quickstart.md) the operator. Then you can create a
new Postgres cluster by applying manifest like this [minimal example](https://github.com/zalando/postgres-operator/blob/master/manifests/minimal-postgres-manifest.yaml):
new Postgres cluster by applying manifest like
this [minimal example](https://github.com/zalando/postgres-operator/blob/master/manifests/minimal-postgres-manifest.yaml):
```yaml
apiVersion: "acid.zalan.do/v1"
@ -20,8 +21,8 @@ spec:
users:
# database owner
zalando:
- superuser
- createdb
- superuser
- createdb
# role for application foo
foo_user: # or 'foo_user: []'
@ -107,7 +108,7 @@ kind: postgresql
metadata:
name: acid-minimal-cluster
spec:
[...]
[ ... ]
postgresql:
version: "15"
parameters:
@ -120,11 +121,11 @@ Postgres Operator allows defining roles to be created in the resulting database
cluster. It covers three use-cases:
* `manifest roles`: create application roles specific to the cluster described
in the manifest.
in the manifest.
* `infrastructure roles`: create application roles that should be automatically
created on every cluster managed by the operator.
created on every cluster managed by the operator.
* `teams API roles`: automatically create users for every member of the team
owning the database cluster.
owning the database cluster.
In the next sections, we will cover those use cases in more details. Note, that
the Postgres Operator can also create databases with pre-defined owner, reader
@ -141,7 +142,8 @@ Manifest roles are defined as a dictionary, with a role name as a key and a
list of role options as a value. For a role without any options it is best to
supply the empty list `[]`. It is also possible to leave this field empty as in
our example manifests. In certain cases such empty field may be missing later
removed by K8s [due to the `null` value it gets](https://kubernetes.io/docs/concepts/overview/object-management-kubectl/declarative-config/#how-apply-calculates-differences-and-merges-changes)
removed by
K8s [due to the `null` value it gets](https://kubernetes.io/docs/concepts/overview/object-management-kubectl/declarative-config/#how-apply-calculates-differences-and-merges-changes)
(`foobar_user:` is equivalent to `foobar_user: null`).
The operator accepts the following options: `superuser`, `inherit`, `login`,
@ -170,7 +172,7 @@ spec:
users:
# users with secret in different namespace
appspace.db_user:
- createdb
- createdb
databases:
# namespace notation is part of user name
app_db: appspace.db_user
@ -230,20 +232,21 @@ metadata:
configuration:
kubernetes:
infrastructure_roles_secrets:
- secretname: "postgresql-infrastructure-roles"
userkey: "user1"
passwordkey: "password1"
rolekey: "inrole1"
- secretname: "postgresql-infrastructure-roles"
userkey: "user2"
...
- secretname: "postgresql-infrastructure-roles"
userkey: "user1"
passwordkey: "password1"
rolekey: "inrole1"
- secretname: "postgresql-infrastructure-roles"
userkey: "user2"
...
```
Note, only the CRD-based configuration allows for referencing multiple secrets.
As of now, the ConfigMap is restricted to either one or the existing template
option with `infrastructure_roles_secret_name`. Please, refer to the example
manifests to understand how `infrastructure_roles_secrets` has to be configured
for the [configmap](https://github.com/zalando/postgres-operator/blob/master/manifests/configmap.yaml) or [CRD configuration](https://github.com/zalando/postgres-operator/blob/master/manifests/postgresql-operator-default-configuration.yaml).
for the [configmap](https://github.com/zalando/postgres-operator/blob/master/manifests/configmap.yaml)
or [CRD configuration](https://github.com/zalando/postgres-operator/blob/master/manifests/postgresql-operator-default-configuration.yaml).
If both `infrastructure_roles_secret_name` and `infrastructure_roles_secrets`
are defined the operator will create roles for both of them. So make sure,
@ -305,7 +308,8 @@ returns usernames. A minimal Teams API should work like this:
/.../<teamname> -> ["name","anothername"]
```
A ["fake" Teams API](https://github.com/zalando/postgres-operator/blob/master/manifests/fake-teams-api.yaml) deployment is provided
A ["fake" Teams API](https://github.com/zalando/postgres-operator/blob/master/manifests/fake-teams-api.yaml) deployment
is provided
in the manifests folder to set up a basic API around whatever services is used
for user management. The Teams API's URL is set in the operator's
[configuration](reference/operator_parameters.md#automatic-creation-of-human-users-in-the-database)
@ -320,12 +324,14 @@ Postgres clusters are associated with one team by providing the `teamID` in
the manifest. Additional superuser teams can be configured as mentioned in
the previous paragraph. However, this is a global setting. To assign
additional teams, superuser teams and single users to clusters of a given
team, use the [PostgresTeam CRD](https://github.com/zalando/postgres-operator/blob/master/manifests/postgresteam.crd.yaml).
team, use
the [PostgresTeam CRD](https://github.com/zalando/postgres-operator/blob/master/manifests/postgresteam.crd.yaml).
Note, by default the `PostgresTeam` support is disabled in the configuration.
Switch `enable_postgres_team_crd` flag to `true` and the operator will start to
watch for this CRD. Make sure, the cluster role is up to date and contains a
section for [PostgresTeam](https://github.com/zalando/postgres-operator/blob/master/manifests/operator-service-account-rbac.yaml#L30).
section
for [PostgresTeam](https://github.com/zalando/postgres-operator/blob/master/manifests/operator-service-account-rbac.yaml#L30).
#### Additional teams
@ -341,7 +347,7 @@ metadata:
spec:
additionalTeams:
a-team:
- "b-team"
- "b-team"
```
With the example above the operator will create login roles for all members
@ -352,9 +358,9 @@ for clusters of `b-team` in one manifest:
spec:
additionalTeams:
a-team:
- "b-team"
- "b-team"
b-team:
- "a-team"
- "a-team"
```
You see, the `PostgresTeam` CRD is a global team mapping and independent from
@ -367,10 +373,10 @@ users for their `additionalTeams`, e.g.:
spec:
additionalTeams:
a-team:
- "b-team"
- "c-team"
- "b-team"
- "c-team"
b-team:
- "a-team"
- "a-team"
```
This creates roles for members of the `c-team` team not only in all clusters
@ -390,12 +396,12 @@ it easier to map a group of teams to many other teams:
spec:
additionalTeams:
a-team:
- "virtual-team"
- "virtual-team"
b-team:
- "virtual-team"
- "virtual-team"
virtual-team:
- "c-team"
- "d-team"
- "c-team"
- "d-team"
```
This example would create roles for members of `c-team` and `d-team` plus
@ -412,7 +418,7 @@ could be reflected in a `PostgresTeam` mapping with just two lines:
spec:
additionalTeams:
a-team:
- "f-team"
- "f-team"
```
This is helpful, because Postgres cluster names are immutable and can not
@ -434,7 +440,7 @@ metadata:
spec:
additionalMembers:
a-team:
- "tia"
- "tia"
```
This will create the login role `tia` in every cluster owned by `a-team`.
@ -447,9 +453,9 @@ teams, e.g. for `virtual-team` we used above:
spec:
additionalMembers:
virtual-team:
- "flynch"
- "rdecker"
- "briggs"
- "flynch"
- "rdecker"
- "briggs"
```
#### Removed members
@ -489,7 +495,7 @@ called `data`.
```yaml
spec:
preparedDatabases: {}
preparedDatabases: { }
```
### Default NOLOGIN roles
@ -501,13 +507,13 @@ spec:
preparedDatabases:
foo:
schemas:
bar: {}
bar: { }
```
Postgres Operator will create the following NOLOGIN roles:
| Role name | Member of | Admin |
| -------------- | -------------- | ------------- |
|----------------|----------------|---------------|
| foo_owner | | admin |
| foo_reader | | foo_owner |
| foo_writer | foo_reader | foo_owner |
@ -517,7 +523,8 @@ Postgres Operator will create the following NOLOGIN roles:
The `<dbname>_owner` role is the database owner and should be used when creating
new database objects. All members of the `admin` role, e.g. teams API roles, can
become the owner with the `SET ROLE` command. [Default privileges](https://www.postgresql.org/docs/15/sql-alterdefaultprivileges.html)
become the owner with the `SET ROLE`
command. [Default privileges](https://www.postgresql.org/docs/15/sql-alterdefaultprivileges.html)
are configured for the owner role so that the `<dbname>_reader` role
automatically gets read-access (SELECT) to new tables and sequences and the
`<dbname>_writer` receives write-access (INSERT, UPDATE, DELETE on tables,
@ -552,7 +559,7 @@ counterparts. Therefore, you cannot have `defaultRoles` set to `false` and enabl
`defaultUsers` at the same time.
| Role name | Member of | Admin |
| ------------------- | -------------- | ------------- |
|---------------------|----------------|---------------|
| foo_owner_user | foo_owner | admin |
| foo_reader_user | foo_reader | foo_owner |
| foo_writer_user | foo_writer | foo_owner |
@ -656,7 +663,7 @@ spec:
preparedDatabases:
foo:
schemas:
my_existing_schema: {}
my_existing_schema: { }
```
Adding existing database schemas to the manifest to create roles for them as
@ -688,6 +695,25 @@ manifest the operator will raise the limits to the configured minimum values.
If no resources are defined in the manifest they will be obtained from the
configured [default requests](reference/operator_parameters.md#kubernetes-resource-requests).
### HugePages support
The operator supports [HugePages](https://www.postgresql.org/docs/15/kernel-resources.html#LINUX-HUGEPAGES). To enable
HugePages, set the matching resource requests and/or limits in the manifest:
```yaml
spec:
resources:
requests:
hugepages-2Mi: 250Mi
hugepages-1Gi: 1Gi
limits:
hugepages-2Mi: 500Mi
hugepages-1Gi: 2Gi
```
There are no minimums or maximums, but Kubernetes will not spin up the pod if the requested HugePages cannot be
allocated.
## Use taints, tolerations and node affinity for dedicated PostgreSQL nodes
To ensure Postgres pods are running on nodes without any other application pods,
@ -699,12 +725,13 @@ to apply for all Postgres clusters.
```yaml
spec:
tolerations:
- key: postgres
operator: Exists
effect: NoSchedule
- key: postgres
operator: Exists
effect: NoSchedule
```
If you need the pods to be scheduled on specific nodes you may use [node affinity](https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/)
If you need the pods to be scheduled on specific nodes you may
use [node affinity](https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/)
to specify a set of label(s), of which a prospective host node must have at least one. This could be used to
place nodes with certain hardware capabilities (e.g. SSD drives) in certain environments or network segments,
e.g. for PCI compliance.
@ -719,11 +746,11 @@ spec:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: environment
operator: In
values:
- pci
- matchExpressions:
- key: environment
operator: In
values:
- pci
```
If you need to define a `nodeAffinity` for all your Postgres clusters use the
@ -792,7 +819,6 @@ or [Azure](administrator.md#azure-setup)
it can only be set globally with [custom Pod environment variables](administrator.md#custom-pod-environment-variables)
or locally in the Postgres manifest's [`env`](administrator.md#via-postgres-cluster-manifest) section.
For non AWS S3 following settings can be set to support cloning from other S3
implementations:
@ -867,7 +893,8 @@ point you should restore.
## Setting up a standby cluster
Standby cluster is a [Patroni feature](https://github.com/zalando/patroni/blob/master/docs/replica_bootstrap.rst#standby-cluster)
Standby cluster is
a [Patroni feature](https://github.com/zalando/patroni/blob/master/docs/replica_bootstrap.rst#standby-cluster)
that first clones a database, and keeps replicating changes afterwards. It can
exist in a different location than its source database, but unlike cloning,
the PostgreSQL version between source and target cluster has to be the same.
@ -916,10 +943,10 @@ standby, postgres etc.) all have a password that does not match the credentials
stored in secrets which are created by the operator. You have two options:
a. Create secrets manually beforehand and paste the credentials of the source
cluster
cluster
b. Let the operator create the secrets when it bootstraps the standby cluster.
Patch the secrets with the credentials of the source cluster. Replace the
spilo pods.
Patch the secrets with the credentials of the source cluster. Replace the
spilo pods.
Otherwise, you will see errors in the Postgres logs saying users cannot log in
and the operator logs will complain about not being able to sync resources.
@ -951,7 +978,7 @@ standby_cluster:
- bootstrap_standby_with_wale
- basebackup_fast_xlog
restore_command: envdir "/home/postgres/etc/wal-e.d/env-standby" /scripts/restore_command.sh
"%f" "%p"
"%f" "%p"
```
Finally, remove the `standby` section from the postgres cluster manifest.
@ -992,10 +1019,10 @@ spec:
In addition to any environment variables you specify, the following environment
variables are always passed to sidecars:
- `POD_NAME` - field reference to `metadata.name`
- `POD_NAMESPACE` - field reference to `metadata.namespace`
- `POSTGRES_USER` - the superuser that can be used to connect to the database
- `POSTGRES_PASSWORD` - the password for the superuser
- `POD_NAME` - field reference to `metadata.name`
- `POD_NAMESPACE` - field reference to `metadata.namespace`
- `POSTGRES_USER` - the superuser that can be used to connect to the database
- `POSTGRES_PASSWORD` - the password for the superuser
The PostgreSQL volume is shared with sidecars and is mounted at
`/home/postgres/pgdata`.
@ -1004,7 +1031,8 @@ The PostgreSQL volume is shared with sidecars and is mounted at
specified but globally disabled in the configuration. The `enable_sidecars`
option must be set to `true`.
If you want to add a sidecar to every cluster managed by the operator, you can specify it in the [operator configuration](administrator.md#sidecars-for-postgres-clusters) instead.
If you want to add a sidecar to every cluster managed by the operator, you can specify it in
the [operator configuration](administrator.md#sidecars-for-postgres-clusters) instead.
### Accessing the PostgreSQL socket from sidecars
@ -1017,8 +1045,8 @@ container simply add a VolumeMount to this volume to your sidecar spec.
- name: "container-name"
image: "company/image:tag"
volumeMounts:
- mountPath: /var/run
name: postgresql-run
- mountPath: /var/run
name: postgresql-run
```
If you do not want to globally enable this feature and only use it for single
@ -1028,18 +1056,18 @@ the manifest:
```yaml
spec:
additionalVolumes:
- name: postgresql-run
mountPath: /var/run/postgresql
targetContainers:
- all
volumeSource:
emptyDir: {}
- name: postgresql-run
mountPath: /var/run/postgresql
targetContainers:
- all
volumeSource:
emptyDir: { }
sidecars:
- name: "container-name"
image: "company/image:tag"
volumeMounts:
- mountPath: /var/run
name: postgresql-run
- name: "container-name"
image: "company/image:tag"
volumeMounts:
- mountPath: /var/run
name: postgresql-run
```
## InitContainers Support
@ -1112,7 +1140,8 @@ spec:
```
The operator will create and sync a K8s cron job to do periodic logical backups
of this particular Postgres cluster. Due to the [limitation of K8s cron jobs](https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/#cron-job-limitations)
of this particular Postgres cluster. Due to
the [limitation of K8s cron jobs](https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/#cron-job-limitations)
it is highly advisable to set up additional monitoring for this feature; such
monitoring is outside the scope of operator responsibilities. See
[configuration reference](reference/cluster_manifest.md) and
@ -1201,11 +1230,13 @@ Therefore, instead of using a global `spilo_fsgroup` setting in operator
configuration or use the `spiloFSGroup` field per Postgres cluster manifest.
For testing purposes, you can generate a self-signed certificate with openssl:
```sh
openssl req -x509 -nodes -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=acid.zalan.do"
```
Upload the cert as a kubernetes secret:
```sh
kubectl create secret tls pg-tls \
--key tls.key \
@ -1213,6 +1244,7 @@ kubectl create secret tls pg-tls \
```
When doing client auth, CA can come optionally from the same secret:
```sh
kubectl create secret generic pg-tls \
--from-file=tls.crt=server.crt \
@ -1235,6 +1267,7 @@ spec:
```
Optionally, the CA can be provided by a different secret:
```sh
kubectl create secret generic pg-tls-ca --from-file=ca.crt=ca.crt
```