Pull changes from upstream repository
This commit is contained in:
parent
228023ff21
commit
75b0dc0932
46 changed files with 5661 additions and 0 deletions
2
test/examples/custom-config/README
Normal file
2
test/examples/custom-config/README
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
Bind-mount this directory under /opt/app-root/src in container, and all the
|
||||
*.conf files from postgresql-cfg/ files will be included to postgresql.conf.
|
||||
|
|
@ -0,0 +1 @@
|
|||
shared_buffers = 111MB
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
log_destination = 'stderr'
|
||||
logging_collector = on
|
||||
log_directory = 'pg_log'
|
||||
log_filename = 'postgresql.log'
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
#!/bin/bash
|
||||
|
||||
# postgresql image encrypts user passwords at service start
|
||||
# the functionality can be disabled by providing this file (postgresql-start-hook/set_passwords.sh) in s2i build
|
||||
253
test/examples/postgresql-ephemeral-template.json
Normal file
253
test/examples/postgresql-ephemeral-template.json
Normal file
|
|
@ -0,0 +1,253 @@
|
|||
{
|
||||
"kind": "Template",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {
|
||||
"name": "postgresql-ephemeral",
|
||||
"annotations": {
|
||||
"openshift.io/display-name": "PostgreSQL (Ephemeral)",
|
||||
"description": "PostgreSQL database service, without persistent storage. For more information about using this template, including OpenShift considerations, see https://github.com/sclorg/postgresql-container/.\n\nWARNING: Any data stored will be lost upon pod destruction. Only use this template for testing",
|
||||
"iconClass": "icon-postgresql",
|
||||
"tags": "database,postgresql",
|
||||
"openshift.io/long-description": "This template provides a standalone PostgreSQL server with a database created. The database is not stored on persistent storage, so any restart of the service will result in all data being lost. The database name, username, and password are chosen via parameters when provisioning this service.",
|
||||
"openshift.io/provider-display-name": "Red Hat, Inc.",
|
||||
"openshift.io/documentation-url": "https://docs.okd.io/latest/using_images/db_images/postgresql.html",
|
||||
"openshift.io/support-url": "https://access.redhat.com"
|
||||
}
|
||||
},
|
||||
"message": "The following service(s) have been created in your project: ${DATABASE_SERVICE_NAME}.\n\n Username: ${POSTGRESQL_USER}\n Password: ${POSTGRESQL_PASSWORD}\n Database Name: ${POSTGRESQL_DATABASE}\n Connection URL: postgresql://${DATABASE_SERVICE_NAME}:5432/\n\nFor more information about using this template, including OpenShift considerations, see https://github.com/sclorg/postgresql-container/.",
|
||||
"labels": {
|
||||
"template": "postgresql-ephemeral-template"
|
||||
},
|
||||
"objects": [
|
||||
{
|
||||
"kind": "Secret",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {
|
||||
"name": "${DATABASE_SERVICE_NAME}",
|
||||
"annotations": {
|
||||
"template.openshift.io/expose-username": "{.data['database-user']}",
|
||||
"template.openshift.io/expose-password": "{.data['database-password']}",
|
||||
"template.openshift.io/expose-database_name": "{.data['database-name']}"
|
||||
}
|
||||
},
|
||||
"stringData" : {
|
||||
"database-user" : "${POSTGRESQL_USER}",
|
||||
"database-password" : "${POSTGRESQL_PASSWORD}",
|
||||
"database-name" : "${POSTGRESQL_DATABASE}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "Service",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {
|
||||
"name": "${DATABASE_SERVICE_NAME}",
|
||||
"annotations": {
|
||||
"template.openshift.io/expose-uri": "postgres://{.spec.clusterIP}:{.spec.ports[?(.name==\"postgresql\")].port}"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"ports": [
|
||||
{
|
||||
"name": "postgresql",
|
||||
"protocol": "TCP",
|
||||
"port": 5432,
|
||||
"targetPort": 5432,
|
||||
"nodePort": 0
|
||||
}
|
||||
],
|
||||
"selector": {
|
||||
"name": "${DATABASE_SERVICE_NAME}"
|
||||
},
|
||||
"type": "ClusterIP",
|
||||
"sessionAffinity": "None"
|
||||
},
|
||||
"status": {
|
||||
"loadBalancer": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "DeploymentConfig",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {
|
||||
"name": "${DATABASE_SERVICE_NAME}",
|
||||
"annotations": {
|
||||
"template.alpha.openshift.io/wait-for-ready": "true"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"strategy": {
|
||||
"type": "Recreate"
|
||||
},
|
||||
"triggers": [
|
||||
{
|
||||
"type": "ImageChange",
|
||||
"imageChangeParams": {
|
||||
"automatic": true,
|
||||
"containerNames": [
|
||||
"postgresql"
|
||||
],
|
||||
"from": {
|
||||
"kind": "ImageStreamTag",
|
||||
"name": "postgresql:${POSTGRESQL_VERSION}",
|
||||
"namespace": "${NAMESPACE}"
|
||||
},
|
||||
"lastTriggeredImage": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "ConfigChange"
|
||||
}
|
||||
],
|
||||
"replicas": 1,
|
||||
"selector": {
|
||||
"name": "${DATABASE_SERVICE_NAME}"
|
||||
},
|
||||
"template": {
|
||||
"metadata": {
|
||||
"labels": {
|
||||
"name": "${DATABASE_SERVICE_NAME}"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"name": "postgresql",
|
||||
"image": " ",
|
||||
"ports": [
|
||||
{
|
||||
"containerPort": 5432,
|
||||
"protocol": "TCP"
|
||||
}
|
||||
],
|
||||
"readinessProbe": {
|
||||
"timeoutSeconds": 1,
|
||||
"initialDelaySeconds": 5,
|
||||
"exec": {
|
||||
"command": [ "/usr/libexec/check-container" ]
|
||||
}
|
||||
},
|
||||
"livenessProbe": {
|
||||
"timeoutSeconds": 10,
|
||||
"initialDelaySeconds": 120,
|
||||
"exec": {
|
||||
"command": [ "/usr/libexec/check-container", "--live" ]
|
||||
}
|
||||
},
|
||||
"env": [
|
||||
{
|
||||
"name": "POSTGRESQL_USER",
|
||||
"valueFrom": {
|
||||
"secretKeyRef" : {
|
||||
"name" : "${DATABASE_SERVICE_NAME}",
|
||||
"key" : "database-user"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "POSTGRESQL_PASSWORD",
|
||||
"valueFrom": {
|
||||
"secretKeyRef" : {
|
||||
"name" : "${DATABASE_SERVICE_NAME}",
|
||||
"key" : "database-password"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "POSTGRESQL_DATABASE",
|
||||
"valueFrom": {
|
||||
"secretKeyRef" : {
|
||||
"name" : "${DATABASE_SERVICE_NAME}",
|
||||
"key" : "database-name"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"resources": {
|
||||
"limits": {
|
||||
"memory": "${MEMORY_LIMIT}"
|
||||
}
|
||||
},
|
||||
"volumeMounts": [
|
||||
{
|
||||
"name": "${DATABASE_SERVICE_NAME}-data",
|
||||
"mountPath": "/var/lib/pgsql/data"
|
||||
}
|
||||
],
|
||||
"terminationMessagePath": "/dev/termination-log",
|
||||
"imagePullPolicy": "IfNotPresent",
|
||||
"capabilities": {},
|
||||
"securityContext": {
|
||||
"capabilities": {},
|
||||
"privileged": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"volumes": [
|
||||
{
|
||||
"name": "${DATABASE_SERVICE_NAME}-data",
|
||||
"emptyDir": {
|
||||
"medium": ""
|
||||
}
|
||||
}
|
||||
],
|
||||
"restartPolicy": "Always",
|
||||
"dnsPolicy": "ClusterFirst"
|
||||
}
|
||||
}
|
||||
},
|
||||
"status": {}
|
||||
}
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "MEMORY_LIMIT",
|
||||
"displayName": "Memory Limit",
|
||||
"description": "Maximum amount of memory the container can use.",
|
||||
"value": "512Mi",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "NAMESPACE",
|
||||
"displayName": "Namespace",
|
||||
"description": "The OpenShift Namespace where the ImageStream resides.",
|
||||
"value": "openshift"
|
||||
},
|
||||
{
|
||||
"name": "DATABASE_SERVICE_NAME",
|
||||
"displayName": "Database Service Name",
|
||||
"description": "The name of the OpenShift Service exposed for the database.",
|
||||
"value": "postgresql",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "POSTGRESQL_USER",
|
||||
"displayName": "PostgreSQL Connection Username",
|
||||
"description": "Username for PostgreSQL user that will be used for accessing the database.",
|
||||
"generate": "expression",
|
||||
"from": "user[A-Z0-9]{3}",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "POSTGRESQL_PASSWORD",
|
||||
"displayName": "PostgreSQL Connection Password",
|
||||
"description": "Password for the PostgreSQL connection user.",
|
||||
"generate": "expression",
|
||||
"from": "[a-zA-Z0-9]{16}",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "POSTGRESQL_DATABASE",
|
||||
"displayName": "PostgreSQL Database Name",
|
||||
"description": "Name of the PostgreSQL database accessed.",
|
||||
"value": "sampledb",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "POSTGRESQL_VERSION",
|
||||
"displayName": "Version of PostgreSQL Image",
|
||||
"description": "Version of PostgreSQL image to be used (10 or latest).",
|
||||
"value": "10",
|
||||
"required": true
|
||||
}
|
||||
]
|
||||
}
|
||||
277
test/examples/postgresql-persistent-template.json
Normal file
277
test/examples/postgresql-persistent-template.json
Normal file
|
|
@ -0,0 +1,277 @@
|
|||
{
|
||||
"kind": "Template",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {
|
||||
"name": "postgresql-persistent",
|
||||
"annotations": {
|
||||
"openshift.io/display-name": "PostgreSQL",
|
||||
"description": "PostgreSQL database service, with persistent storage. For more information about using this template, including OpenShift considerations, see https://github.com/sclorg/postgresql-container/.\n\nNOTE: Scaling to more than one replica is not supported. You must have persistent volumes available in your cluster to use this template.",
|
||||
"iconClass": "icon-postgresql",
|
||||
"tags": "database,postgresql",
|
||||
"openshift.io/long-description": "This template provides a standalone PostgreSQL server with a database created. The database is stored on persistent storage. The database name, username, and password are chosen via parameters when provisioning this service.",
|
||||
"openshift.io/provider-display-name": "Red Hat, Inc.",
|
||||
"openshift.io/documentation-url": "https://docs.okd.io/latest/using_images/db_images/postgresql.html",
|
||||
"openshift.io/support-url": "https://access.redhat.com"
|
||||
}
|
||||
},
|
||||
"message": "The following service(s) have been created in your project: ${DATABASE_SERVICE_NAME}.\n\n Username: ${POSTGRESQL_USER}\n Password: ${POSTGRESQL_PASSWORD}\n Database Name: ${POSTGRESQL_DATABASE}\n Connection URL: postgresql://${DATABASE_SERVICE_NAME}:5432/\n\nFor more information about using this template, including OpenShift considerations, see https://github.com/sclorg/postgresql-container/.",
|
||||
"labels": {
|
||||
"template": "postgresql-persistent-template"
|
||||
},
|
||||
"objects": [
|
||||
{
|
||||
"kind": "Secret",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {
|
||||
"name": "${DATABASE_SERVICE_NAME}",
|
||||
"annotations": {
|
||||
"template.openshift.io/expose-username": "{.data['database-user']}",
|
||||
"template.openshift.io/expose-password": "{.data['database-password']}",
|
||||
"template.openshift.io/expose-database_name": "{.data['database-name']}"
|
||||
}
|
||||
},
|
||||
"stringData" : {
|
||||
"database-user" : "${POSTGRESQL_USER}",
|
||||
"database-password" : "${POSTGRESQL_PASSWORD}",
|
||||
"database-name" : "${POSTGRESQL_DATABASE}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "Service",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {
|
||||
"name": "${DATABASE_SERVICE_NAME}",
|
||||
"annotations": {
|
||||
"template.openshift.io/expose-uri": "postgres://{.spec.clusterIP}:{.spec.ports[?(.name==\"postgresql\")].port}"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"ports": [
|
||||
{
|
||||
"name": "postgresql",
|
||||
"protocol": "TCP",
|
||||
"port": 5432,
|
||||
"targetPort": 5432,
|
||||
"nodePort": 0
|
||||
}
|
||||
],
|
||||
"selector": {
|
||||
"name": "${DATABASE_SERVICE_NAME}"
|
||||
},
|
||||
"type": "ClusterIP",
|
||||
"sessionAffinity": "None"
|
||||
},
|
||||
"status": {
|
||||
"loadBalancer": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "PersistentVolumeClaim",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {
|
||||
"name": "${DATABASE_SERVICE_NAME}"
|
||||
},
|
||||
"spec": {
|
||||
"accessModes": [
|
||||
"ReadWriteOnce"
|
||||
],
|
||||
"resources": {
|
||||
"requests": {
|
||||
"storage": "${VOLUME_CAPACITY}"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "DeploymentConfig",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {
|
||||
"name": "${DATABASE_SERVICE_NAME}",
|
||||
"annotations": {
|
||||
"template.alpha.openshift.io/wait-for-ready": "true"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"strategy": {
|
||||
"type": "Recreate"
|
||||
},
|
||||
"triggers": [
|
||||
{
|
||||
"type": "ImageChange",
|
||||
"imageChangeParams": {
|
||||
"automatic": true,
|
||||
"containerNames": [
|
||||
"postgresql"
|
||||
],
|
||||
"from": {
|
||||
"kind": "ImageStreamTag",
|
||||
"name": "postgresql:${POSTGRESQL_VERSION}",
|
||||
"namespace": "${NAMESPACE}"
|
||||
},
|
||||
"lastTriggeredImage": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "ConfigChange"
|
||||
}
|
||||
],
|
||||
"replicas": 1,
|
||||
"selector": {
|
||||
"name": "${DATABASE_SERVICE_NAME}"
|
||||
},
|
||||
"template": {
|
||||
"metadata": {
|
||||
"labels": {
|
||||
"name": "${DATABASE_SERVICE_NAME}"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"name": "postgresql",
|
||||
"image": " ",
|
||||
"ports": [
|
||||
{
|
||||
"containerPort": 5432,
|
||||
"protocol": "TCP"
|
||||
}
|
||||
],
|
||||
"readinessProbe": {
|
||||
"timeoutSeconds": 1,
|
||||
"initialDelaySeconds": 5,
|
||||
"exec": {
|
||||
"command": [ "/usr/libexec/check-container" ]
|
||||
}
|
||||
},
|
||||
"livenessProbe": {
|
||||
"timeoutSeconds": 10,
|
||||
"initialDelaySeconds": 120,
|
||||
"exec": {
|
||||
"command": [ "/usr/libexec/check-container", "--live" ]
|
||||
}
|
||||
},
|
||||
"env": [
|
||||
{
|
||||
"name": "POSTGRESQL_USER",
|
||||
"valueFrom": {
|
||||
"secretKeyRef" : {
|
||||
"name" : "${DATABASE_SERVICE_NAME}",
|
||||
"key" : "database-user"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "POSTGRESQL_PASSWORD",
|
||||
"valueFrom": {
|
||||
"secretKeyRef" : {
|
||||
"name" : "${DATABASE_SERVICE_NAME}",
|
||||
"key" : "database-password"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "POSTGRESQL_DATABASE",
|
||||
"valueFrom": {
|
||||
"secretKeyRef" : {
|
||||
"name" : "${DATABASE_SERVICE_NAME}",
|
||||
"key" : "database-name"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"resources": {
|
||||
"limits": {
|
||||
"memory": "${MEMORY_LIMIT}"
|
||||
}
|
||||
},
|
||||
"volumeMounts": [
|
||||
{
|
||||
"name": "${DATABASE_SERVICE_NAME}-data",
|
||||
"mountPath": "/var/lib/pgsql/data"
|
||||
}
|
||||
],
|
||||
"terminationMessagePath": "/dev/termination-log",
|
||||
"imagePullPolicy": "IfNotPresent",
|
||||
"capabilities": {},
|
||||
"securityContext": {
|
||||
"capabilities": {},
|
||||
"privileged": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"volumes": [
|
||||
{
|
||||
"name": "${DATABASE_SERVICE_NAME}-data",
|
||||
"persistentVolumeClaim": {
|
||||
"claimName": "${DATABASE_SERVICE_NAME}"
|
||||
}
|
||||
}
|
||||
],
|
||||
"restartPolicy": "Always",
|
||||
"dnsPolicy": "ClusterFirst"
|
||||
}
|
||||
}
|
||||
},
|
||||
"status": {}
|
||||
}
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "MEMORY_LIMIT",
|
||||
"displayName": "Memory Limit",
|
||||
"description": "Maximum amount of memory the container can use.",
|
||||
"value": "512Mi",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "NAMESPACE",
|
||||
"displayName": "Namespace",
|
||||
"description": "The OpenShift Namespace where the ImageStream resides.",
|
||||
"value": "openshift"
|
||||
},
|
||||
{
|
||||
"name": "DATABASE_SERVICE_NAME",
|
||||
"displayName": "Database Service Name",
|
||||
"description": "The name of the OpenShift Service exposed for the database.",
|
||||
"value": "postgresql",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "POSTGRESQL_USER",
|
||||
"displayName": "PostgreSQL Connection Username",
|
||||
"description": "Username for PostgreSQL user that will be used for accessing the database.",
|
||||
"generate": "expression",
|
||||
"from": "user[A-Z0-9]{3}",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "POSTGRESQL_PASSWORD",
|
||||
"displayName": "PostgreSQL Connection Password",
|
||||
"description": "Password for the PostgreSQL connection user.",
|
||||
"generate": "expression",
|
||||
"from": "[a-zA-Z0-9]{16}",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "POSTGRESQL_DATABASE",
|
||||
"displayName": "PostgreSQL Database Name",
|
||||
"description": "Name of the PostgreSQL database accessed.",
|
||||
"value": "sampledb",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "VOLUME_CAPACITY",
|
||||
"displayName": "Volume Capacity",
|
||||
"description": "Volume space available for data, e.g. 512Mi, 2Gi.",
|
||||
"value": "1Gi",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "POSTGRESQL_VERSION",
|
||||
"displayName": "Version of PostgreSQL Image",
|
||||
"description": "Version of PostgreSQL image to be used (10 or latest).",
|
||||
"value": "10",
|
||||
"required": true
|
||||
}
|
||||
]
|
||||
}
|
||||
240
test/examples/replica/README.md
Normal file
240
test/examples/replica/README.md
Normal file
|
|
@ -0,0 +1,240 @@
|
|||
# PostgreSQL Replication Example
|
||||
|
||||
**WARNING: This is only a Proof-Of-Concept example and it is not meant to be used in
|
||||
production. Use at your own risk.**
|
||||
|
||||
## What is PostgreSQL replication?
|
||||
|
||||
Replication enables data from one database server (master, or primary) to be
|
||||
replicated to one or more servers (slaves, or standby servers).
|
||||
|
||||
PostgreSQL has [different replication solutions](http://www.postgresql.org/docs/9.2/static/different-replication-solutions.html),
|
||||
each with its own pros and cons.
|
||||
This example uses PostgreSQL's native support for [streaming replication](http://www.postgresql.org/docs/9.2/static/warm-standby.html).
|
||||
In this configuration, the primary server operates in continuous archiving mode,
|
||||
while each standby server operates in continuous recovery mode, streaming over
|
||||
the network the write-ahead log (WAL) records from the primary as they're
|
||||
generated.
|
||||
|
||||
This configuration can be used to create a high availability (HA) cluster
|
||||
configuration and has relatively low performance impact on the primary server.
|
||||
|
||||
A standby server can also be used for read-only queries.
|
||||
|
||||
## Deployment
|
||||
|
||||
This example uses a [PersistentVolumeClaim](https://docs.okd.io/latest/architecture/additional_concepts/storage.html#persistent-volume-claims)
|
||||
to request persistent storage for the primary PostgreSQL server.
|
||||
|
||||
You need to have persistent volumes configured and available in your project in
|
||||
order to continue. For trying out this example in a single node testing
|
||||
environment, you can create a temporary volume with:
|
||||
|
||||
```
|
||||
$ oc create -f - <<EOF
|
||||
{
|
||||
"kind": "PersistentVolume",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {
|
||||
"name": "postgres-data-volume"
|
||||
},
|
||||
"spec": {
|
||||
"capacity": {
|
||||
"storage": "512Mi"
|
||||
},
|
||||
"hostPath": {
|
||||
"path": "`mktemp -d --tmpdir pg-data.XXXXX | tee >(xargs chmod a+rwx)`"
|
||||
},
|
||||
"accessModes": [
|
||||
"ReadWriteOnce"
|
||||
]
|
||||
}
|
||||
}
|
||||
EOF
|
||||
```
|
||||
|
||||
It is recommended, however, that you use other [type of PersistentVolume](https://docs.okd.io/latest/architecture/additional_concepts/storage.html#types-of-persistent-volumes)
|
||||
such as NFS.
|
||||
|
||||
Now you can create a new database deployment:
|
||||
|
||||
```
|
||||
$ oc new-app examples/replica/postgresql_replica.json
|
||||
```
|
||||
|
||||
## How does this example work?
|
||||
|
||||
### Services 'postgresql-master' and 'postgresql-slave'
|
||||
|
||||
These services are the entry point for connecting to, respectively, the primary
|
||||
database server and any of the standby servers.
|
||||
|
||||
In your application, connect to the `postgresql-master` service for write operations, and to `postgresql-master` or `postgresql-slave` for reads.
|
||||
Keep in mind that reading from a slave might return slightly outdated data.
|
||||
|
||||
To get a list of endpoints for the read-only standby servers, you can do a DNS
|
||||
query. From a container in the same OpenShift project:
|
||||
|
||||
```
|
||||
$ dig postgresql-slave A +search +short
|
||||
```
|
||||
|
||||
### DeploymentConfig 'postgresql-master'
|
||||
|
||||
This resource defines a [deployment configuration](https://docs.okd.io/latest/architecture/core_concepts/deployments.html#deployments-and-deployment-configurations)
|
||||
to spawn the PostgreSQL primary database server, or master.
|
||||
|
||||
Once the master is started, it works as a standalone database server, fully
|
||||
independent of the slaves.
|
||||
|
||||
### DeploymentConfig 'postgresql-slave'
|
||||
|
||||
This resource defines a [deployment configuration](https://docs.okd.io/latest/architecture/core_concepts/deployments.html#deployments-and-deployment-configurations)
|
||||
to spawn PostgreSQL standby servers, the slaves.
|
||||
|
||||
Upon startup, each slave waits for the master server to become available (via
|
||||
DNS lookup). Once that happens, the slave connects to the master and starts
|
||||
streaming the WAL.
|
||||
|
||||
To check that the slave is connected and streaming changes from the master,
|
||||
you can issue the following commands:
|
||||
|
||||
```
|
||||
$ master_name=`oc get pods -l name=postgresql-master -t '{{ (index .items 0).metadata.name }}'`
|
||||
$ oc exec $master_name -- bash -c 'psql -c "select client_addr, state from pg_stat_replication;"'
|
||||
```
|
||||
|
||||
After a successful deployment, you should get an output similar to:
|
||||
|
||||
```
|
||||
client_addr | state
|
||||
--------------+-----------
|
||||
172.17.0.227 | streaming
|
||||
(1 row)
|
||||
```
|
||||
|
||||
## Scaling
|
||||
|
||||
By default, the provided template creates one primary and one standby server.
|
||||
Scaling in this setup means increasing the number of standby servers,
|
||||
consequently increasing data redundancy and concurrent read throughput (if
|
||||
reading from slaves).
|
||||
|
||||
You can add more slaves using `oc scale`:
|
||||
|
||||
```
|
||||
$ oc scale dc postgresql-slave --replicas=2
|
||||
```
|
||||
|
||||
Using `oc scale` with `postgresql-master` is not supported.
|
||||
|
||||
After scaling, you can verify that all slaves are streaming changes from the
|
||||
master with:
|
||||
|
||||
```
|
||||
$ oc exec $master_name -- bash -c 'psql -c "select client_addr, state from pg_stat_replication;"'
|
||||
client_addr | state
|
||||
--------------+-----------
|
||||
172.17.0.227 | streaming
|
||||
172.17.0.229 | streaming
|
||||
(2 rows)
|
||||
```
|
||||
|
||||
There should be one row per slave (number of replicas defined via `oc scale`).
|
||||
|
||||
## Changing passwords
|
||||
|
||||
You can change the passwords for the database user and admin, as well as the
|
||||
password used for replication, by changing the appropriate environment variables
|
||||
in the deployment configurations described earlier.
|
||||
No other method is supported.
|
||||
|
||||
On every deploy, passwords are reset to match the values in the environment
|
||||
variables of the DeploymentConfig 'postgresql-master'.
|
||||
|
||||
### POSTGRESQL_PASSWORD and POSTGRESQL_ADMIN_PASSWORD
|
||||
|
||||
These are, respectively, the passwords for the regular database user defined
|
||||
by `POSTGRESQL_USER` and the admin user 'postgres'.
|
||||
|
||||
You can change these passwords with:
|
||||
|
||||
```
|
||||
$ oc env dc postgresql-master POSTGRESQL_PASSWORD=NewPassword POSTGRESQL_ADMIN_PASSWORD=NewAdminPassword
|
||||
deploymentconfigs/postgresql-master
|
||||
```
|
||||
|
||||
This will trigger the redeployment of the primary server.
|
||||
Note that you can change one password but not the other by simply omitting one
|
||||
of the arguments to `oc env` above.
|
||||
|
||||
You can verify that the new password is in effect with:
|
||||
|
||||
```
|
||||
$ oc exec $master_name -- bash -c 'PGPASSWORD=NewPassword psql -h postgresql-master $POSTGRESQL_DATABASE $POSTGRESQL_USER -c "select * from (select inet_server_addr()) ra cross join (select current_database()) cdb cross join (select current_user) cu"'
|
||||
inet_server_addr | current_database | current_user
|
||||
------------------+------------------+--------------
|
||||
172.17.1.38 | userdb | user
|
||||
(1 row)
|
||||
```
|
||||
|
||||
You should also be able to connect to a slave using the new password:
|
||||
|
||||
```
|
||||
$ oc exec $master_name -- bash -c 'PGPASSWORD=NewPassword psql -h postgresql-slave $POSTGRESQL_DATABASE $POSTGRESQL_USER -c "select * from (select inet_server_addr()) ra cross join (select current_database()) cdb cross join (select current_user) cu"'
|
||||
inet_server_addr | current_database | current_user
|
||||
------------------+------------------+--------------
|
||||
172.17.1.35 | userdb | user
|
||||
(1 row)
|
||||
```
|
||||
|
||||
For completeness, here's how to verify the new admin password:
|
||||
|
||||
```
|
||||
$ oc exec $master_name -- bash -c 'PGPASSWORD=NewAdminPassword psql -h postgresql-master $POSTGRESQL_DATABASE -c "select * from (select inet_server_addr()) ra cross join (select current_database()) cdb cross join (select current_user) cu"'
|
||||
inet_server_addr | current_database | current_user
|
||||
------------------+------------------+--------------
|
||||
172.17.1.38 | userdb | postgres
|
||||
(1 row)
|
||||
```
|
||||
|
||||
```
|
||||
$ oc exec $master_name -- bash -c 'PGPASSWORD=NewAdminPassword psql -h postgresql-slave $POSTGRESQL_DATABASE -c "select * from (select inet_server_addr()) ra cross join (select current_database()) cdb cross join (select current_user) cu"'
|
||||
inet_server_addr | current_database | current_user
|
||||
------------------+------------------+--------------
|
||||
172.17.1.35 | userdb | postgres
|
||||
(1 row)
|
||||
```
|
||||
|
||||
### POSTGRESQL_MASTER_PASSWORD
|
||||
|
||||
This password is used by standby servers to connect to the primary. Both
|
||||
deployment configurations in this example setup need to agree on the value of
|
||||
this password to have replication working correctly.
|
||||
|
||||
You can change the environment variable with the password on both deployment
|
||||
configurations at once:
|
||||
|
||||
```
|
||||
$ oc env dc postgresql-master postgresql-slave POSTGRESQL_MASTER_PASSWORD=NewReplicationPassword
|
||||
deploymentconfigs/postgresql-master
|
||||
deploymentconfigs/postgresql-slave
|
||||
```
|
||||
|
||||
This will trigger the redeployment of both primary and standby servers.
|
||||
|
||||
Note that, as a current limitation in this example, the standby servers store
|
||||
replicated data in an an ephemeral [emptyDir](https://docs.okd.io/latest/dev_guide/volumes.html).
|
||||
This means that redeploying a standby server will cause it to start replicating
|
||||
again from scratch.
|
||||
|
||||
After the primary and standby servers are ready, you can verify that the standby
|
||||
servers are successfully connected to the primary:
|
||||
|
||||
```
|
||||
$ oc exec $master_name -- bash -c 'psql -c "select client_addr, state from pg_stat_replication;"'
|
||||
client_addr | state
|
||||
-------------+-----------
|
||||
172.17.1.35 | streaming
|
||||
(1 row)
|
||||
```
|
||||
370
test/examples/replica/postgresql_replica.json
Normal file
370
test/examples/replica/postgresql_replica.json
Normal file
|
|
@ -0,0 +1,370 @@
|
|||
{
|
||||
"kind": "Template",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {
|
||||
"name": "pg-replica-example",
|
||||
"annotations": {
|
||||
"description": "PostgreSQL Replication Example",
|
||||
"iconClass": "icon-database",
|
||||
"tags": "database,postgresql,replication"
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "POSTGRESQL_MASTER_USER",
|
||||
"description": "The username used for master-slave replication",
|
||||
"value": "master",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "POSTGRESQL_MASTER_PASSWORD",
|
||||
"description": "The password for the PostgreSQL replication user",
|
||||
"generate": "expression",
|
||||
"from": "[a-zA-Z0-9]{12}",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "POSTGRESQL_USER",
|
||||
"description": "The username that clients will use to connect to PostgreSQL server",
|
||||
"value": "user",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "POSTGRESQL_PASSWORD",
|
||||
"description": "The password for the PostgreSQL master user",
|
||||
"generate": "expression",
|
||||
"from": "[a-zA-Z0-9]{12}",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "POSTGRESQL_DATABASE",
|
||||
"description": "The name of the database that will be created",
|
||||
"value": "userdb",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "POSTGRESQL_ADMIN_PASSWORD",
|
||||
"description": "The password for the PostgreSQL administrator",
|
||||
"generate": "expression",
|
||||
"from": "[a-zA-Z0-9]{12}",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"name": "POSTGRESQL_MASTER_SERVICE_NAME",
|
||||
"description": "The name of the PostgreSQL Service (used to DNS lookup, default: 'postgresql-master')",
|
||||
"value": "postgresql-master",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "POSTGRESQL_SLAVE_SERVICE_NAME",
|
||||
"description": "The name of the PostgreSQL Service (used to DNS lookup, default: 'postgresql-slave')",
|
||||
"value": "postgresql-slave",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "VOLUME_CAPACITY",
|
||||
"description": "Volume space available for data, e.g. 512Mi, 2Gi",
|
||||
"value": "512Mi",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "IMAGESTREAMTAG",
|
||||
"displayName": "ImageStreamTag",
|
||||
"description": "The OpenShift ImageStreamTag to use for PostgreSQL.",
|
||||
"value": "postgresql:9.6"
|
||||
},
|
||||
{
|
||||
"name": "NAMESPACE",
|
||||
"displayName": "Namespace",
|
||||
"description": "The OpenShift Namespace where the ImageStream resides.",
|
||||
"value": "openshift"
|
||||
}
|
||||
],
|
||||
"objects": [
|
||||
{
|
||||
"kind": "PersistentVolumeClaim",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {
|
||||
"name": "postgresql-data-claim"
|
||||
},
|
||||
"spec": {
|
||||
"accessModes": [
|
||||
"ReadWriteOnce"
|
||||
],
|
||||
"resources": {
|
||||
"requests": {
|
||||
"storage": "${VOLUME_CAPACITY}"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "Service",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {
|
||||
"name": "${POSTGRESQL_MASTER_SERVICE_NAME}",
|
||||
"labels": {
|
||||
"name": "${POSTGRESQL_MASTER_SERVICE_NAME}"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"ports": [
|
||||
{
|
||||
"port": 5432,
|
||||
"targetPort": 5432
|
||||
}
|
||||
],
|
||||
"selector": {
|
||||
"name": "${POSTGRESQL_MASTER_SERVICE_NAME}"
|
||||
},
|
||||
"clusterIP": "None"
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "Service",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {
|
||||
"name": "${POSTGRESQL_SLAVE_SERVICE_NAME}",
|
||||
"labels": {
|
||||
"name": "${POSTGRESQL_SLAVE_SERVICE_NAME}"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"ports": [
|
||||
{
|
||||
"port": 5432,
|
||||
"targetPort": 5432
|
||||
}
|
||||
],
|
||||
"selector": {
|
||||
"name": "${POSTGRESQL_SLAVE_SERVICE_NAME}"
|
||||
},
|
||||
"clusterIP": "None"
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "DeploymentConfig",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {
|
||||
"name": "${POSTGRESQL_MASTER_SERVICE_NAME}"
|
||||
},
|
||||
"spec": {
|
||||
"strategy": {
|
||||
"type": "Recreate"
|
||||
},
|
||||
"triggers": [
|
||||
{
|
||||
"type": "ImageChange",
|
||||
"imageChangeParams": {
|
||||
"automatic": true,
|
||||
"containerNames": [
|
||||
"postgresql-master"
|
||||
],
|
||||
"from": {
|
||||
"kind": "ImageStreamTag",
|
||||
"name": "${IMAGESTREAMTAG}",
|
||||
"namespace": "${NAMESPACE}"
|
||||
},
|
||||
"lastTriggeredImage": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "ConfigChange"
|
||||
}
|
||||
],
|
||||
"replicas": 1,
|
||||
"selector": {
|
||||
"name": "${POSTGRESQL_MASTER_SERVICE_NAME}"
|
||||
},
|
||||
"template": {
|
||||
"metadata": {
|
||||
"labels": {
|
||||
"name": "${POSTGRESQL_MASTER_SERVICE_NAME}"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"volumes": [
|
||||
{
|
||||
"name": "postgresql-data",
|
||||
"persistentVolumeClaim": {
|
||||
"claimName": "postgresql-data-claim"
|
||||
}
|
||||
}
|
||||
],
|
||||
"containers": [
|
||||
{
|
||||
"name": "postgresql-master",
|
||||
"image": " ",
|
||||
"args": [
|
||||
"run-postgresql-master"
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"containerPort": 5432
|
||||
}
|
||||
],
|
||||
"readinessProbe": {
|
||||
"timeoutSeconds": 1,
|
||||
"initialDelaySeconds": 5,
|
||||
"exec": {
|
||||
"command": [ "/usr/libexec/check-container" ]
|
||||
}
|
||||
},
|
||||
"livenessProbe": {
|
||||
"timeoutSeconds": 10,
|
||||
"initialDelaySeconds": 120,
|
||||
"exec": {
|
||||
"command": [ "/usr/libexec/check-container", "--live" ]
|
||||
}
|
||||
},
|
||||
"env": [
|
||||
{
|
||||
"name": "POSTGRESQL_MASTER_USER",
|
||||
"value": "${POSTGRESQL_MASTER_USER}"
|
||||
},
|
||||
{
|
||||
"name": "POSTGRESQL_MASTER_PASSWORD",
|
||||
"value": "${POSTGRESQL_MASTER_PASSWORD}"
|
||||
},
|
||||
{
|
||||
"name": "POSTGRESQL_USER",
|
||||
"value": "${POSTGRESQL_USER}"
|
||||
},
|
||||
{
|
||||
"name": "POSTGRESQL_PASSWORD",
|
||||
"value": "${POSTGRESQL_PASSWORD}"
|
||||
},
|
||||
{
|
||||
"name": "POSTGRESQL_DATABASE",
|
||||
"value": "${POSTGRESQL_DATABASE}"
|
||||
},
|
||||
{
|
||||
"name": "POSTGRESQL_ADMIN_PASSWORD",
|
||||
"value": "${POSTGRESQL_ADMIN_PASSWORD}"
|
||||
}
|
||||
],
|
||||
"volumeMounts": [
|
||||
{
|
||||
"name": "postgresql-data",
|
||||
"mountPath": "/var/lib/pgsql/data"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"kind": "DeploymentConfig",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {
|
||||
"name": "${POSTGRESQL_SLAVE_SERVICE_NAME}"
|
||||
},
|
||||
"spec": {
|
||||
"strategy": {
|
||||
"type": "Recreate"
|
||||
},
|
||||
"triggers": [
|
||||
{
|
||||
"type": "ImageChange",
|
||||
"imageChangeParams": {
|
||||
"automatic": true,
|
||||
"containerNames": [
|
||||
"postgresql-slave"
|
||||
],
|
||||
"from": {
|
||||
"kind": "ImageStreamTag",
|
||||
"name": "${IMAGESTREAMTAG}",
|
||||
"namespace": "${NAMESPACE}"
|
||||
},
|
||||
"lastTriggeredImage": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "ConfigChange"
|
||||
}
|
||||
],
|
||||
"replicas": 1,
|
||||
"selector": {
|
||||
"name": "${POSTGRESQL_SLAVE_SERVICE_NAME}"
|
||||
},
|
||||
"template": {
|
||||
"metadata": {
|
||||
"labels": {
|
||||
"name": "${POSTGRESQL_SLAVE_SERVICE_NAME}"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"volumes": [
|
||||
{
|
||||
"name": "postgresql-data",
|
||||
"emptyDir": {}
|
||||
}
|
||||
],
|
||||
"containers": [
|
||||
{
|
||||
"name": "postgresql-slave",
|
||||
"image": " ",
|
||||
"args": [
|
||||
"run-postgresql-slave"
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"containerPort": 5432
|
||||
}
|
||||
],
|
||||
"readinessProbe": {
|
||||
"timeoutSeconds": 1,
|
||||
"initialDelaySeconds": 5,
|
||||
"exec": {
|
||||
"command": [ "/usr/libexec/check-container" ]
|
||||
}
|
||||
},
|
||||
"livenessProbe": {
|
||||
"timeoutSeconds": 10,
|
||||
"initialDelaySeconds": 120,
|
||||
"exec": {
|
||||
"command": [ "/usr/libexec/check-container", "--live" ]
|
||||
}
|
||||
},
|
||||
"env": [
|
||||
{
|
||||
"name": "POSTGRESQL_MASTER_SERVICE_NAME",
|
||||
"value": "${POSTGRESQL_MASTER_SERVICE_NAME}"
|
||||
},
|
||||
{
|
||||
"name": "POSTGRESQL_MASTER_USER",
|
||||
"value": "${POSTGRESQL_MASTER_USER}"
|
||||
},
|
||||
{
|
||||
"name": "POSTGRESQL_MASTER_PASSWORD",
|
||||
"value": "${POSTGRESQL_MASTER_PASSWORD}"
|
||||
},
|
||||
{
|
||||
"name": "POSTGRESQL_USER",
|
||||
"value": "${POSTGRESQL_USER}"
|
||||
},
|
||||
{
|
||||
"name": "POSTGRESQL_PASSWORD",
|
||||
"value": "${POSTGRESQL_PASSWORD}"
|
||||
},
|
||||
{
|
||||
"name": "POSTGRESQL_DATABASE",
|
||||
"value": "${POSTGRESQL_DATABASE}"
|
||||
}
|
||||
],
|
||||
"volumeMounts": [
|
||||
{
|
||||
"name": "postgresql-data",
|
||||
"mountPath": "/var/lib/pgsql/data"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
36
test/examples/s2i-dump-data/.s2i/bin/assemble
Executable file
36
test/examples/s2i-dump-data/.s2i/bin/assemble
Executable file
|
|
@ -0,0 +1,36 @@
|
|||
#! /usr/bin/bash -x
|
||||
|
||||
# fail early
|
||||
set -e
|
||||
|
||||
# source the convenience tooling
|
||||
source "${CONTAINER_SCRIPTS_PATH}/common.sh"
|
||||
|
||||
# set $PGDATA variable
|
||||
set_pgdata
|
||||
|
||||
# assert uninitialized data
|
||||
test ! -f "$PGDATA/postgresql.conf"
|
||||
|
||||
# empty config file is needed after 'initialize_database' call
|
||||
touch "$POSTGRESQL_CONFIG_FILE"
|
||||
|
||||
initialize_database
|
||||
|
||||
# start local PostgreSQL server (wait with '-w')
|
||||
pg_ctl -w start -o "-h ''"
|
||||
|
||||
# load all sql files
|
||||
shopt -s nullglob
|
||||
for file in /tmp/src/init/*.sql; do
|
||||
psql -f "$file"
|
||||
done
|
||||
|
||||
pg_ctl stop
|
||||
|
||||
# dump the data into $PWD (in-image storage)
|
||||
tar caf data.tar.xz -C "$PGDATA" .
|
||||
rm -rf "$PGDATA"
|
||||
|
||||
# install pre-start hook
|
||||
cp -r /tmp/src/postgresql-pre-start .
|
||||
2
test/examples/s2i-dump-data/init/init.sql
Normal file
2
test/examples/s2i-dump-data/init/init.sql
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
CREATE TABLE test (sth TEXT);
|
||||
INSERT INTO test VALUES ('hello world');
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
if test ! -f "$PGDATA/postgresql.conf"; then
|
||||
tar xf "$APP_DATA"/src/data.tar.xz -C "$PGDATA"
|
||||
fi
|
||||
Loading…
Add table
Add a link
Reference in a new issue