Installing a Tanzu Postgres Operator

This topic describes how to install Tanzu Postgres using two different methods.

Install Tanzu Operator via the Tanzu Network Registry

This topic describes how to access the resources, and deploy the Tanzu Postgres Operator using the Tanzu Network Registry.

Prerequisites

To run Tanzu Postgres you need:

  • Access to Tanzu Network and Tanzu Network Registry. You can use the same credentials for both sites.

  • Docker running and configured on your local computer, to access the Kubernetes cluster and Docker registry.

  • A running Kubernetes cluster - Google Kubernetes Engine (GKE), VMware Enterprise TKGi) or Minikube - and the kubectl command-line tool, configured and authenticated to communicate with your Kubernetes cluster. If you are using GKE, install the gcloud command-line tool on your local client.

  • The Helm v3 command-line tool installed. For more information, see Installing Helm from the Helm documentation.

  • cluster-admin ClusterRole access to the Kubernetes cluster. For more information, see the Kubernetes documentation.

  • review the Network Policies Configuration topic if you have any network plugins (for example Network Plugin) in your Kubernetes cluster.

  • Cert Manager installed on the Kubernetes cluster.

    IMPORTANT: TKGm users need to upgrade the TKGm packaged cert-manager to a version above 1.0.

    Install cert-manager by running these commands from your local client:

    $ kubectl create namespace cert-manager
    $ helm repo add jetstack https://charts.jetstack.io
    $ helm repo update
    $ helm install cert-manager jetstack/cert-manager --namespace cert-manager  --version <1.latest> --set installCRDs=true
    

    where:

    • --namespace cert-manager is the namespace used for cert manager in the Kubernetes cluster
    • --version <1.latest> is the latest cert-manager version available (minimum above 1.0.2)
    • --set installCRDs=true ensures cert manager installs all types necessary to create certificates

    To verify the installation run:

    $ kubectl get all --namespace=cert-manager
    

    The output should be similar to:

    NAME                                           READY   STATUS    RESTARTS   AGE
    pod/cert-manager-57b65b7fc-x8vjt               1/1     Running   5          4d19h
    pod/cert-manager-cainjector-5f988f74c6-tgk25   1/1     Running   15         4d19h
    pod/cert-manager-webhook-7cf554f879-b5ss9      1/1     Running   4          4d19h
    
    NAME                           TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
    service/cert-manager           ClusterIP   10.106.253.7    <none>        9402/TCP   4d19h
    service/cert-manager-webhook   ClusterIP   10.108.17.113   <none>        443/TCP    4d19h
    
    NAME                                      READY   UP-TO-DATE   AVAILABLE   AGE
    deployment.apps/cert-manager              1/1     1            1           4d19h
    deployment.apps/cert-manager-cainjector   1/1     1            1           4d19h
    deployment.apps/cert-manager-webhook      1/1     1            1           4d19h
    
    NAME                                                 DESIRED   CURRENT   READY   AGE
    replicaset.apps/cert-manager-57b65b7fc               1         1         1       4d19h
    replicaset.apps/cert-manager-cainjector-5f988f74c6   1         1         1       4d19h
    replicaset.apps/cert-manager-webhook-7cf554f879      1         1         1       4d19h
    

    For more advanced security scenarios, see Configuring TLS for Tanzu Postgres Instances.

Access the Resources

  1. Set the environment variable to enable Open Container Initiative (OCI) support in the Helm v3 client by running:

    $ export HELM_EXPERIMENTAL_OCI=1
    

    If you skip this step, the following error message might appear:

    Error: this feature has been marked as experimental and is not enabled by default.
    
  2. Use Helm to log in to the Tanzu Network Registry by running:

    $ helm registry login registry.pivotal.io \
           --username=<USERNAME> \
           --password=<PASSWORD>
    

    Follow the prompts to enter the email address and password for your Tanzu Network account.

  3. Pull the Helm chart and images from the Tanzu registry into the local docker container registry:

    $ helm chart pull registry.pivotal.io/tanzu-sql-postgres/postgres-operator-chart:v1.2.0
    
  4. Export the artifacts into a local /tmp/ directory:

    $ helm chart export registry.pivotal.io/tanzu-sql-postgres/postgres-operator-chart:v1.2.0  --destination=/tmp/
    
  5. View the file operator/values.yaml in the Tanzu Postgres directory that specifies the location of the Postgres Operator and instance images. By default it contains the following values:

    $ cat /tmp/postgres-operator/values.yaml
    

    which returns:

    ---
    # specify the url for the docker image for the operator, e.g. gcr.io/<my_project>/postgres-operator
    operatorImageRepository: registry.pivotal.io/tanzu-sql-postgres/postgres-operator
    operatorImageTag: v1.2.0
    # specify the docker image for postgres instance, e.g. gcr.io/<my_project>/postgres-instance
    postgresImageRepository: registry.pivotal.io/tanzu-sql-postgres/postgres-instance
    postgresImageTag: v1.2.0
    # specify the name of the docker-registry secret to allow the cluster to authenticate with the container registry for pulling images
    dockerRegistrySecretName: regsecret
    # override the default self-signed cert-manager cluster issuer
    certManagerClusterIssuerName:
    
  6. Create a operator-values-overrides.yaml (choose your own file name) configuration file under the same location to specify the custom container registry and secret. Edit this file also when you enable TLS security (see Configuring TLS for Tanzu Postgres Instances) and need to enter a value for certManagerClusterIssuerName.

Note: The dockerRegistrySecretName is currently hard set to regsecret and cannot be changed in the overrides file.

For manual changes using the command line kubectl, you may also set individual parameters using the --set flag.

Create a Kubernetes Access Secret

Create a secret named regsecretby running:

$ kubectl create secret docker-registry regsecret \
    --docker-server=https://registry.pivotal.io/ \
    --docker-username='USERNAME' \
    --docker-password='PASSWD'

Where the USERNAME and password PASSWD credentials have permission to access VMware Tanzu Network. Surround both the USERNAME and the PASSWD by single quote marks to handle any special characters within those values.

IMPORTANT: The command above creates the secret in the default namespace. Only pods created in the same default namespace can reference the secret. To create a secret in a different namespace, use the --namespace flag.

Install the Operator

The Postgres Operator is the controller for Postgres instances resources. You install the Postgres Operator using the Helm package manager.

  1. Verify you don’t have previously installed instance CRDs in your cluster. Use a command similar to:

    $ kubectl get crd postgres.sql.tanzu.vmware.com
    

    If this is a brand new Operator installation, the result should be similar to:

    Error from server (NotFound): customresourcedefinitions.apiextensions.k8s.io "postgres.sql.tanzu.vmware.com" not found
    

    If the result is similar to:

    NAME                            CREATED AT
    postgres.sql.tanzu.vmware.com   2021-06-09T06:04:45Z
    

    there are older instances running in the cluster, from a previous Operator deployment. When deploying the Operator, you need to refresh this CRD in order to apply the new updated Operator version (see step 4).

  2. Install the Tanzu Postgres Operator by running one of the following:

    • If you created a custom operator-values-overrides.yaml run the following helm command:

      helm install --wait --values=/<your-path>/operator-values-overrides.yaml my-postgres-operator /tmp/postgres-operator/
      
    • If you did not create an operator-values-overrides.yaml configuration file (as in the case with Minikube) run:

      helm install --wait my-postgres-operator /tmp/postgres-operator/
      

      Helm begins installing the Operator into the Kubernetes namespace specified in the current Kubernetes context. Throughout this documentation we have used the default namespace. If you want to install into a different namespace, include the --namespace option in the helm command.

    Installing the Operator creates a new service account named postgres-operator-service-account. It is for internal use, but it is visible if you use the kubectl get serviceaccount command:

    $ kubectl get serviceaccount
    
    NAME                                 SECRETS   AGE
    default                              1         12m
    postgres-operator-service-account    1         8m56s
    
  3. Confirm that your Operator has installed successfully by running:

    $ kubectl get all
    

    The Tanzu Postgres Operator has finished installing when the value of the STATUS column for the Tanzu Postgres Operator Pod is Running and the value of the READY column is 1/1. See an example output:

    $ kubectl get all
    
    NAME                                             READY   STATUS        RESTARTS   AGE
    pod/my-postgres-operator-84d76dfb77-lq5mb        1/1     Running       0          21s
    
    NAME                                             TYPE       CLUSTER-IP          EXTERNAL-IP   PORT(S)    AGE
    service/kubernetes                               ClusterIP  10.96.0.1           <none>        443/TCP    13s
    service/my-postgres-operator-webhook-service     ClusterIP  10.106.202.247      <none>        443/TCP    16s
    
    NAME                                             READY   UP-TO-DATE   AVAILABLE   AGE
    deployment.apps/my-postgres-operator             1/1     1            0           23s
    
    NAME                                             DESIRED   CURRENT   READY   AGE
    replicaset.apps/my-postgres-operator-84d76dfb77  1         1         1       16s
    

    Note: You can only have one Tanzu Postgres Operator installed in a Kubernetes cluster.

    To fully describe the serviceaccount use:

    $ kubectl describe serviceaccount postgres-operator-service-account
    
    Name:                postgres-operator-service-account
    Namespace:           default
    Labels:              app=postgres-operator
                         app.kubernetes.io/managed-by=Helm
    Annotations:         meta.helm.sh/release-name: postgres-operator
                         meta.helm.sh/release-namespace: default
    Image pull secrets:  <none>
    Mountable secrets:   postgres-operator-service-account-token-49c22
    Tokens:              postgres-operator-service-account-token-49c22
    Events:              <none>
    

    You may also check the logs to confirm the Operator is running properly:

    $ kubectl logs -l app=postgres-operator
    

    Use the label app=postgres-operator to search across resources created by the Postgres Operator Helm chart:

    $ kubectl get all -l app=postgres-operator 
    

    If your namespace is different than the default, use the -n <your-namaspace> to specify your namespace. The output would be similar to:

    NAME                                           READY       STATUS           RESTARTS      AGE
    pod/postgres-operator-69765b8b74-rtms7         1/1         Running          0             3d19h
    NAME                                           TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
    service/postgres-operator-webhook-service      ClusterIP   10.108.211.126   <none>        443/TCP   3d19h
    NAME                                           READY       UP-TO-DATE       AVAILABLE     AGE
    deployment.apps/postgres-operator              1/1         1                1             3d19h
    NAME                                           DESIRED     CURRENT          READY         AGE
    replicaset.apps/postgres-operator-69765b8b74   1           1                1             3d19h
    
  4. If you have existing Postgres instances running from a previous Operator deployment (see step 1), re-apply the instance CRD, using a command similar to:

    $ cd /tmp/postgres-for-kubernetes-v1.2.0/
    
    $ kubectl apply -f operator/crds/postgres-instance.yaml
    

Install Tanzu Operator via a Downloaded Archive File

Choose this method if:

  • The installation destination (for example an air-gapped network) cannot access the VMware Tanzu Network.
  • Or you wish to load the Operator and instance images to private Docker registry.

This topic covers:

  • Downloading and unpacking the Tanzu Postgres distribution from VMware Tanzu Network
  • Loading the images to a local Docker registry
  • Pushing the images from the local Docker registry to a Private container registry
  • Configuring a Kubernetes secret for accessing the Private container registry
  • Deploying the Postgres Operator

Note that this procedure also installs the psql and ODBC driver client components to the Kubernetes cluster.

Prerequisites

Before you deploy the Tanzu Postgres Operator, review the list of Prerequisites that apply to both installation methods.

Download and unpack the Tanzu Postgres distribution

  1. Download the Tanzu Postgres distribution from VMware Tanzu Network. The Tanzu Postgres download filename has the format: postgres-for-kubernetes-v<version>.tar.gz

  2. Unpack the downloaded software:

    $ cd ~/Downloads
    $ tar xzf postgres-for-kubernetes-v<version>.tar.gz
    

    This command unpacks the distribution into a new directory named postgres-for-kubernetes-v<version>, for example postgres-for-kubernetes-v1.2.0.

  3. Change to the new postgres-for-kubernetes-v<version> directory.

    $ cd ./postgres-for-kubernetes-v*
    

Load the Images to a local Docker Registry

  1. Load the Postgres instance image to the Docker registry.

    $ docker load -i ./images/postgres-instance
    cc967c529ced: Loading layer [==================================================>]  65.57MB/65.57MB
    2c6ac8e5063e: Loading layer [==================================================>]  991.2kB/991.2kB
    6c01b5a53aac: Loading layer [==================================================>]  15.87kB/15.87kB
    e0b3afb09dc3: Loading layer [==================================================>]  3.072kB/3.072kB
    faee4b69eae8: Loading layer [==================================================>]  29.74MB/29.74MB
    6bc08b5f8a06: Loading layer [==================================================>]  4.096kB/4.096kB
    3bfb028071fa: Loading layer [==================================================>]  331.4MB/331.4MB
    6ef1a056590e: Loading layer [==================================================>]  57.86kB/57.86kB
    Loaded image: postgres-instance:v1.2.0
    
  2. Load the Postgres operator image to the Docker registry.

    $ docker load -i ./images/postgres-operator
    0d1435bd79e4: Loading layer [==================================================>]  3.062MB/3.062MB
    b50265a0f809: Loading layer [==================================================>]  40.87MB/40.87MB
    Loaded image: postgres-operator:v1.2.0
    
  3. Verify that the two Docker images are now available.

    $ docker images "postgres-*"
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    postgres-operator   v1.2.0              09f3bfbf93fb        10 days ago         42.7MB
    postgres-instance   v1.2.0              f28858b60d1f        10 days ago         413MB
    

Push the Images from the local Docker Registry to a Private Container Registry

Push the Tanzu Postgres Docker images to the container registry of your choice. Set each image’s project and image repo name, tag the images, and then push them using the Docker command docker push.

This example tags and pushes the images to the Google Cloud Registry, using the default (core) project name for the example Google Cloud account.

$ gcloud auth configure-docker

$ PROJECT=$(gcloud config list core/project --format='value(core.project)')
$ REGISTRY="gcr.io/${PROJECT}"

$ INSTANCE_IMAGE_NAME="${REGISTRY}/postgres-instance:$(cat ./images/postgres-instance-tag)"
$ docker tag $(cat ./images/postgres-instance-id) ${INSTANCE_IMAGE_NAME}
$ docker push ${INSTANCE_IMAGE_NAME}

$ OPERATOR_IMAGE_NAME="${REGISTRY}/postgres-operator:$(cat ./images/postgres-operator-tag)"
$ docker tag $(cat ./images/postgres-operator-id) ${OPERATOR_IMAGE_NAME}
$ docker push ${OPERATOR_IMAGE_NAME}

Configure a Kubernetes secret for accessing the Private container registry

Create a docker-registry type secret to allow the Kubernetes cluster to authenticate with the private container registry so it can pull images. These examples create a secret named regsecret using Harbor, Google Cloud Registry (GCR), and Amazon Elastic Container Registry (ECR).

IMPORTANT: The commands below create the secret in the default namespace. Only pods created in the same default namespace can reference the secret. To create a secret in a different namespace, use the --namespace flag.

Harbor

$ kubectl create secret docker-registry regsecret \
    --docker-server=${HARBOR_URL} \
    --docker-username=${HARBOR_USER} \
    --docker-password="${HARBOR_PASSWORD}"

GCR

$ kubectl create secret  docker-registry  regsecret \
        --docker-server=https://gcr.io \
        --docker-username=_json_key \
        --docker-password="$(cat ~/key.json)"

For information about how to obtain the key.json service account file, see Kubernetes Service Account

ECR

$ TOKEN=`aws ecr --region=$REGION get-authorization-token --output text --query authorizationData[].authorizationToken | base64 -d | cut -d: -f2`
$ kubectl create secret docker-registry regsecret \
    --docker-server=https://${ACCOUNT}.dkr.ecr.${REGION}.amazonaws.com \
    --docker-username=AWS \
    --docker-password="${TOKEN}"

Next follow Deploying a Postgres Operator. The Postgres Operator will use this secret to allow the Kubernetes cluster to authenticate with the container registry to pull images.

Deploy the Postgres Operator

The Postgres Operator is the controller for Postgres instances resources. You install the Postgres Operator using the Helm package manager.

Edit the Operator Configuration

  1. Go to the directory where you unpacked the Tanzu Postgres distribution.

    $ cd postgres-v*
    

    The file operator/values.yaml in the Tanzu Postgres directory specifies the location of the Postgres Operator and instance images. By default it contains the following values:

    ---
    # specify the url for the docker image for the operator, e.g. gcr.io/<my_project>/postgres-operator
    operatorImageRepository: registry.pivotal.io/tanzu-sql-postgres/postgres-operator
    operatorImageTag: v1.2.0
    # specify the docker image for postgres instance, e.g. gcr.io/<my_project>/postgres-instance
    postgresImageRepository: registry.pivotal.io/tanzu-sql-postgres/postgres-instance
    postgresImageTag: v1.2.0
    # specify the name of the docker-registry secret to allow the cluster to authenticate with the container registry for pulling images
    dockerRegistrySecretName: regsecret
    # override the default self-signed cert-manager cluster issuer
    certManagerClusterIssuerName:
    
  2. Create a operator-values-overrides.yaml (choose your own name) configuration file under the same location to specify the custom container registry and secret. For manual changes, you may also set individual parameters using the --set flag on the command line.

    See Helm Values Files in the Helm documentation for more information.

    If you are using a single node Minikube environment, it is not necessary to override the operator/values.yaml file because Minikube pulls the images from its local Docker registry.

    Determine which values in the values.yaml file need to be changed for your environment. Use the table below as a guide.

    Key Value Type Description
    operatorImageRepository URI Reference to the Tanzu Postgres Operator image. Change this reference to show the URI of your private registry where you uploaded the Operator image.
    instanceImageRepository URI Reference to the Tanzu Postgres image. Change this reference to show the URI of your private registry where you uploaded the instance image.
    dockerRegistrySecretName String Name of image secret. This value must match the name of the Kubernetes secret you created in Create a Kubernetes Access Secret above.
    certManagerClusterIssuerName String Name of TLS issuer. Change this field to match your custom CA issuer if you’re using TLS. See Configuring TLS for Tanzu Postgres Instances.


    An example values-overrides.yaml file could contain the following lines, replacing ${REGISTRY} with your private container registry name:

      operatorImageRepository: ${REGISTRY}/postgres-operator
      postgresImageRepository: ${REGISTRY}/postgres-instance
    
  3. Save the operator-values-overrides.yaml file in a location of your choice or the same directory as the values.yaml file.

Create the Postgres Operator

  1. Verify if you have previously installed instance CRDs in your cluster. Use a command similar to:

    $ kubectl get crd postgres.sql.tanzu.vmware.com
    

    If this is a brand new Operator installation, the result should be similar to:

    Error from server (NotFound): customresourcedefinitions.apiextensions.k8s.io "postgres.sql.tanzu.vmware.co" not found
    

    If the result is similar to:

    NAME                            CREATED AT
    postgres.sql.tanzu.vmware.com   2021-06-09T06:04:45Z
    

    there are older instances running in the cluster, from a previous Operator deployment. When deploying the Operator, you need to refresh this CRD in order to apply the new updated Operator version (see step 4).

  2. Use Helm to install the Postgres Operator in your Kubernetes cluster.

    $ helm install --wait my-postgres-operator operator/
    

    where:

    • --wait flag waits for the Operator deployment to complete before any image installation starts
    • my-postgres-operator is the custom name you provide for your Postgres Operator
    • operator/ is the location of the Postgres Operator helm chart

    or

    $ helm install --wait my-postgres-operator -f operator/operator-values-overrides.yaml operator/
    

    Replace operator/operator-values-overrides.yaml with your custom location.

    To create the Operator in a namespace different that the default, use:

    $ helm install --wait my-postgres-operator operator/ \
      --namespace=${OPERATOR_NAMESPACE} \
      --create-namespace \   
    

    Helm installs the new release into the Kubernetes namespace specified in the current Kubernetes context. The command displays a message similar to:

    NAME: my-postgres-operator
    LAST DEPLOYED: Wed Jun 16 13:28:05 2021
    NAMESPACE: default
    STATUS: deployed
    REVISION: 1
    TEST SUITE: None
    

    Note: The secret namespace in step Create a Kubernetes Access Secret must match the Operator namespace.

  3. Use watch kubectl get all to monitor the progress of the deployment. The deployment is complete when the Postgres Operator pod status changes to Running.

    $ watch kubectl get all
    
    Every 2.0s: kubectl get all
    
    NAME                                             READY   STATUS    RESTARTS   AGE
    pod/my-postgres-operator-58b6746b66-v2tn7        1/1     Running   0          2m57s
    
    NAME                                             TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
    service/kubernetes                               ClusterIP   10.8.0.1     <none>        443/TCP   30m
    service/my-postgres-operator-webhook-service     ClusterIP   10.8.14.56   <none>        443/TCP   2m57s
    
    NAME                                             READY   UP-TO-DATE   AVAILABLE   AGE
    deployment.apps/my-postgres-operator             1/1     1            1           2m58s
    
    NAME                                             DESIRED   CURRENT   READY   AGE
    replicaset.apps/my-postgres-operator-58b6746b66  1         1         1       2m58s
    

    Installing the Operator creates a new service account named postgres-operator-service-account. It is for internal use, but it is visible if you use the kubectl get serviceaccount command:

    $ kubectl get serviceaccount
    
    NAME                                 SECRETS   AGE
    default                              1         12m
    postgres-operator-service-account    1         8m56s
    

    To fully describe the serviceaccount use:

    $ kubectl describe serviceaccount postgres-operator-service-account
    
    Name:                postgres-operator-service-account
    Namespace:           default
    Labels:              app=postgres-operator
                         app.kubernetes.io/managed-by=Helm
    Annotations:         meta.helm.sh/release-name: postgres-operator
                         meta.helm.sh/release-namespace: default
    Image pull secrets:  <none>
    Mountable secrets:   postgres-operator-service-account-token-49c22
    Tokens:              postgres-operator-service-account-token-49c22
    Events:              <none>
    

    You may also check the logs to confirm the Operator is running properly:

    $ kubectl logs -l app=postgres-operator
    

    Use the label app=postgres-operator to search across resources created by the Postgres Operator Helm chart:

    $ kubectl get all -l app=postgres-operator -n postgres-operator
    

    where -n postgres-operator defines the namespace. The output would be similar to:

    NAME                                           READY       STATUS           RESTARTS      AGE
    pod/postgres-operator-69765b8b74-rtms7         1/1         Running          0             3d19h
    NAME                                           TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
    service/postgres-operator-webhook-service      ClusterIP   10.108.211.126   <none>        443/TCP   3d19h
    NAME                                           READY       UP-TO-DATE       AVAILABLE     AGE
    deployment.apps/postgres-operator              1/1         1                1             3d19h
    NAME                                           DESIRED     CURRENT          READY         AGE
    replicaset.apps/postgres-operator-69765b8b74   1           1                1             3d19h
    
  4. If you have existing Postgres instances running from a previous Operator deployment (see step 1), re-apply the instance CRD, using a command similar to:

    $ cd <your-download-location>/postgres-for-kubernetes-v1.2.0/
    
    $ kubectl apply -f operator/crds/postgres-instance.yaml
    

Next steps

After you install the Postgres Operator, you can use it to deploy and manage Postgres instances. To interact with the Postgres Operator, you place a set of instructions into a YAML-formatted configuration file (a Kubernetes manifest) and then use the kubectl utility to send the file instructions to the Operator. The Postgres Operator is then responsible for following the instructions that you provide, and also for maintaining the state of the Postgres instance according to the properties that you defined.

For more details, see: