With this tutorial, you can try out Tanzu Postgres in a Minikube Kubernetes development environment running on your MacOS or Linux laptop.
In this tutorial, you will deploy the Postgres operator, create a Postgres instance, and build and deploy the Spring Music web app to a Minikube Kubernetes cluster. Minikube is a one-node Kubernetes cluster that runs in a virtual machine on your workstation.
The Postgres operator is a controller for Postgres instance resources. You install the Postgres operator using the Helm package manager. The operator is responsible for managing Postgres instances.
A Postgres instance is a container with a VMware Postgres installation. The Postgres operator provisions two persistent volumes for a Postgres instance, one for database data, and another for backups. The Postgres operator creates a user database named testdb, where the Spring Music app creates its data table.
The Spring Music app is a sample web application built with Spring Framework and Spring Boot. It is configured to use the Postgres instance named my-postgres for its database service.
This following figure illustrates the resources deployed to the Minikube Kubernetes node in this example.
The Postgres operator and the Spring Music app are deployments managing replica sets (one-replica each) for the Postgres operator image, Postgres instances, and Spring Music services.
The Postgres instance and Spring Music services provide access to the database and web app on their Cluster IP (internal) addresses. The External IPs are greyed out in this illustration because Minikube does not automatically set up routes for External IPs. On a production Kubernetes cluster, an External IP would be allocated to allow access from outside the cluster.
To run this tutorial you must have installed Docker, Minikube, kubectl
, and Helm 3 on your system. These links will take you to installation instructions.
kubectl
, Minikube, and, if needed, a hypervisor such as VirtualBox. On MacOS systems you can use the built-in Hyperkit hypervisor by installing the Minikube Hyperkit driver.Download Tanzu Postgres from VMware Tanzu Network. The name of the download file is in the format postgres-for-kubernetes-v<version>.tar.gz
, where <version>
is the Tanzu Postgres version number.
Extract the download file.
$ tar xfz postgres-for-kubernetes-v<version>.tar.gz
The contents of the download file are extracted into the directory postgres-for-kubernetes-v<version>
.
Change into the postgres-for-kubernetes-v<version>
directory.
$ cd postgres-for-kubernetes-v*
Start Minikube.
$ minikube start --cpus 4 --memory 4G
😄 minikube v1.5.2 on Darwin 10.15.3
✨ Automatically selected the 'hyperkit' driver (alternates: [virtualbox])
🔥 Creating hyperkit VM (CPUs=4, Memory=4000MB, Disk=20000MB) ...
🐳 Preparing Kubernetes v1.16.2 on Docker '18.09.9' ...
🚜 Pulling images ...
🚀 Launching Kubernetes ...
⌛ Waiting for: apiserver
🏄 Done! kubectl is now configured to use "minikube"
Minikube automatically selects a hypervisor. If you want to specify a different hypervisor add --vm-driver=<driver>
to the minikube start
command, for example --vm-driver=virtualbox
.
Set the Docker environment to use Minikube.
$ eval $(minikube docker-env)
Install Cert Manager. The Postgres operator requires Cert Manager.
$ kubectl apply --validate=false \
-f https://github.com/jetstack/cert-manager/releases/download/v0.15.0/cert-manager.yaml
Tanzu Postgres provides two images: the Postgres operator and the Postgres instance. You must load both into your Docker registry so that Helm can deploy them to the cluster.
$ docker load -i ./images/postgres-operator
c8be1b8f4d60: Loading layer [==================================================>] 65.58MB/65.58MB
977183d4e999: Loading layer [==================================================>] 991.2kB/991.2kB
6597da2e2e52: Loading layer [==================================================>] 15.87kB/15.87kB
16542a8fc3be: Loading layer [==================================================>] 3.072kB/3.072kB
b5ad6316ad03: Loading layer [==================================================>] 406kB/406kB
59717e88b76f: Loading layer [==================================================>] 40.88MB/40.88MB
Loaded image: postgres-operator:v0.3.0
$ docker load -i ./images/postgres-instance
f18c8721f59c: Loading layer [==================================================>] 31.87MB/31.87MB
012e544fc273: Loading layer [==================================================>] 5.632kB/5.632kB
a5988d6bd81b: Loading layer [==================================================>] 2.048kB/2.048kB
f25939fc235a: Loading layer [==================================================>] 332MB/332MB
9859d37be96a: Loading layer [==================================================>] 60.42kB/60.42kB
Loaded image: postgres-instance:v0.3.0
This task creates a Postgres operator release in the Kubernetes cluster. The Postgres operator is the controller for Postgres instances in the cluster.
Install the Postgres operator into the cluster using helm
.
$ helm install postgres-operator operator/
$ helm install postgres-operator operator/
NAME: postgres-operator
LAST DEPLOYED: Mon May 4 11:07:04 2020
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
Verify that the Postgres operator pod has been created and its status is "Running".
$ watch kubectl get all
Every 2.0s: kubectl get all MBP-Pivotal: Thu May 7 16:49:50 2020
NAME READY STATUS RESTARTS AGE
pod/postgres-operator-5475ff58b4-hxlw8 1/1 Running 0 49s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 6m41s
service/postgres-operator-webhook-service ClusterIP 10.102.190.99 <none> 443/TCP 49s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/postgres-operator 1/1 1 1 49s
NAME DESIRED CURRENT READY AGE
replicaset.apps/postgres-operator-5475ff58b4 1 1 1 49s
Press Ctrl-C to break out of watch
.
A Postgres instance is defined in a Kubernetes configuration file. The Tanzu Postgres distribution includes a sample configuration file named pg-instance-example.yaml
that defines a Postgres instance named my-postgres
.
Create the my-postgres
instance.
$ kubectl create -f pg-instance-example.yaml
postgres.sql.tanzu.vmware.com/my-postgres created
Check the status of the instance to verify that it was created and its status is Running
.
$ kubectl get postgres/my-postgres
NAME STATUS AGE
my-postgres Running 99s
Use the kubectl exec
command to start the psql
utility on the Postgres pod and check that you can connect to Postgres.
kubectl exec -it my-postgres-0 -- bash -c psql
psql (11.7 (VMware Postgres 11.7.1))
Type "help" for help.
postgres=# \c
You are now connected to database "postgres" as user "postgres".
Enter \q
to exit the psql
utility.
The Spring Music app is a simple web application that manages a table named album
in the testdb
database.
Change to the sample-app
directory and build the app.
$ cd sample-app
$ docker build . -t spring-music:latest -f Dockerfile
... build output is omitted
Create the Spring Music deployment using the spring-music.yaml
Kubernetes configuration file.
$ kubectl create -f spring-music.yaml
deployment.apps/spring-music created
service/spring-music-service created
List the deployments, pods, and services in the Kubernetes cluster.
$ kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
postgres-operator 1/1 1 1 16m
spring-music 0/1 1 0 14s
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
my-postgres-0 1/1 Running 0 15m
postgres-operator-6677b8f95c-rqfcj 1/1 Running 0 17m
spring-music-56f78fd987-s9nkk 1/1 Running 0 69s
$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 11m
my-postgres LoadBalancer 10.99.172.182 <pending> 5432:31861/TCP 4m2s
postgres-operator-webhook-service ClusterIP 10.102.190.99 <none> 443/TCP 5m44s
spring-music-service LoadBalancer 10.101.179.41 <pending> 80:30253/TCP 50s
Verify that the Spring Music app has created the album table in the testdb database in your Postgres instance.
$ kubectl exec -it my-postgres-0 -- psql -d testdb
testdb=# SELECT COUNT(*) FROM album;
count
-------
29
(1 row)
testdb=# \q
Access the Spring Music app in your browser at the internal ip of the spring-music-service
service. You can use the following commands to find the URL for the app.
$ host=$(minikube ip)
$ port=$(kubectl get service spring-music-service -o jsonpath='{.spec.ports[0].nodePort}')
$ echo "Connect to the Spring Music app at http://$host:$port"
Note: In a full Kubernetes cluster, you would use the LoadBalancer's external IP and port, but Minikube does not set up LoadBalancer routes automatically.
Using the Spring Music app, you can sort, change the view, and add or delete albums. Changes you make in the browser UI are saved in the albums table in your my-postgres-0
Postgres instance.
Run minikube delete
to destroy your Minikube environment.
$ minikube delete
🔥 Removing /home/<user>/.minikube/machines/minikube ...
💀 Removed all traces of the "minikube" cluster.