Quickstart

Can't wait to try out Crunchy Postgres for Kubernetes? Let us show you the quickest possible path to getting up and running.

Prerequisites

Please be sure you have the following utilities installed on your host machine:

  • kubectl
  • git

Installation

Step 1: Download the Examples

First, go to GitHub and fork the Postgres Operator examples repository:

https://github.com/CrunchyData/postgres-operator-examples/fork

Once you have forked this repo, you can download it to your working environment with a command similar to this:

YOUR_GITHUB_UN="$YOUR_GITHUB_USERNAME"
git clone --depth 1 "git@github.com:${YOUR_GITHUB_UN}/postgres-operator-examples.git"
cd postgres-operator-examples

Step 2: Install PGO, the Postgres Operator

You can install PGO, the Postgres Operator from Crunchy Data, using the command below:

kubectl apply -k kustomize/install/namespace
kubectl apply --server-side -k kustomize/install/default

This will create a namespace called postgres-operator and create all of the objects required to deploy PGO.

To check on the status of your installation, you can run the following command:

kubectl -n postgres-operator get pods \
  --selector=postgres-operator.crunchydata.com/control-plane=postgres-operator \
  --field-selector=status.phase=Running

If the PGO Pod is healthy, you should see output similar to:

NAME                                READY   STATUS    RESTARTS   AGE
postgres-operator-9dd545d64-t4h8d   1/1     Running   0          3s

Create a Postgres Cluster

Let's create a simple Postgres cluster. You can do this by executing the following command:

kubectl apply -k kustomize/postgres

This will create a Postgres cluster named hippo in the postgres-operator namespace. You can track the progress of your cluster using the following command:

kubectl -n postgres-operator describe postgresclusters.postgres-operator.crunchydata.com hippo

Connect to the Postgres cluster

As part of creating a Postgres cluster, the Postgres Operator creates a PostgreSQL user account. The credentials for this account are stored in a Secret that has the name <clusterName>-pguser-<userName>.

Within this Secret are attributes that provide information to let you log into the PostgreSQL cluster. These include:

  • user: The name of the user account.
  • password: The password for the user account.
  • dbname: The name of the database that the user has access to by default.
  • host: The name of the host of the database. This references the Service of the primary Postgres instance.
  • port: The port that the database is listening on.
  • uri: A PostgreSQL connection URI that provides all the information for logging into the Postgres database.
  • jdbc-uri: A PostgreSQL JDBC connection URI that provides all the information for logging into the Postgres database via the JDBC driver.

If you deploy your Postgres cluster with the PgBouncer connection pooler, there are additional values that are populated in the user Secret, including:

  • pgbouncer-host: The name of the host of the PgBouncer connection pooler. This references the Service of the PgBouncer connection pooler.
  • pgbouncer-port: The port that the PgBouncer connection pooler is listening on.
  • pgbouncer-uri: A PostgreSQL connection URI that provides all the information for logging into the Postgres database via the PgBouncer connection pooler.
  • pgbouncer-jdbc-uri: A PostgreSQL JDBC connection URI that provides all the information for logging into the Postgres database via the PgBouncer connection pooler using the JDBC driver.

Note that all connections use TLS. PGO sets up a public key infrastructure (PKI) for your Postgres clusters. You can also choose to bring your own PKI / certificate authority; this is covered later in the documentation.

Connect via psql in the Terminal

Connect Directly

If you are on the same network as your PostgreSQL cluster, you can connect directly to it using the following command:

psql $(kubectl -n postgres-operator get secrets hippo-pguser-hippo -o go-template='{{.data.uri | base64decode}}')

Connect Using a Port-Forward

In a new terminal, create a port forward:

PG_CLUSTER_PRIMARY_POD=$(kubectl get pod -n postgres-operator -o name \
  -l postgres-operator.crunchydata.com/cluster=hippo,postgres-operator.crunchydata.com/role=master)
kubectl -n postgres-operator port-forward "${PG_CLUSTER_PRIMARY_POD}" 5432:5432

Establish a connection to the PostgreSQL cluster.

PG_CLUSTER_USER_SECRET_NAME=hippo-pguser-hippo

PGPASSWORD=$(kubectl get secrets -n postgres-operator "${PG_CLUSTER_USER_SECRET_NAME}" -o go-template='{{.data.password | base64decode}}') \
PGUSER=$(kubectl get secrets -n postgres-operator "${PG_CLUSTER_USER_SECRET_NAME}" -o go-template='{{.data.user | base64decode}}') \
PGDATABASE=$(kubectl get secrets -n postgres-operator "${PG_CLUSTER_USER_SECRET_NAME}" -o go-template='{{.data.dbname | base64decode}}') \
psql -h localhost

Create a user schema

Starting in Postgres 15, PUBLIC creation permission on the public schema have been removed, but there is a simple way forward to allow you to start writing queries. As described in our helpful blog post on the subject, after connecting via psql as the hippo user, just execute

CREATE SCHEMA hippo AUTHORIZATION hippo;

and you will be able to create tables in the hippo schema without any additional steps or permissions.

Connect an Application

The information provided in the user Secret will allow you to connect an application directly to your PostgreSQL database.

For example, let's connect Keycloak. Keycloak is a popular open source identity management tool that is backed by a PostgreSQL database. Using the hippo cluster we created, we can deploy the following manifest file:

cat <<EOF >> keycloak.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: keycloak
  namespace: postgres-operator
  labels:
    app.kubernetes.io/name: keycloak
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: keycloak
  template:
    metadata:
      labels:
        app.kubernetes.io/name: keycloak
    spec:
      containers:
      - image: quay.io/keycloak/keycloak:latest
        args: ["start-dev"]
        name: keycloak
        env:
        - name: DB_VENDOR
          value: "postgres"
        - name: DB_ADDR
          valueFrom: { secretKeyRef: { name: hippo-pguser-hippo, key: host } }
        - name: DB_PORT
          valueFrom: { secretKeyRef: { name: hippo-pguser-hippo, key: port } }
        - name: DB_DATABASE
          valueFrom: { secretKeyRef: { name: hippo-pguser-hippo, key: dbname } }
        - name: DB_USER
          valueFrom: { secretKeyRef: { name: hippo-pguser-hippo, key: user } }
        - name: DB_PASSWORD
          valueFrom: { secretKeyRef: { name: hippo-pguser-hippo, key: password } }
        - name: KEYCLOAK_ADMIN
          value: "admin"
        - name: KEYCLOAK_ADMIN_PASSWORD
          value: "admin"
        - name: KC_PROXY
          value: "edge"
        ports:
        - name: http
          containerPort: 8080
        - name: https
          containerPort: 8443
        readinessProbe:
          httpGet:
            path: /realms/master
            port: 8080
      restartPolicy: Always

EOF

kubectl apply -f keycloak.yaml

There is a full example for how to deploy Keycloak with the Postgres Operator in the kustomize/keycloak folder.

Next Steps

Congratulations, you've got your Postgres cluster up and running, perhaps with an application connected to it!

You can find out more about the postgresclusters custom resource definition through the documentation and through kubectl explain, i.e.:

kubectl explain postgresclusters

You’ve seen how easy it is to get a Postgres database up and running and connected to your applications using Crunchy Postgres for Kubernetes. In the next section we will take a closer look at CPK and how its different components work together to provide everything you need for a production-ready Postgres cluster.