github twitter linkedin email rss
How to create PostgreSQL container on Google Container Engine
Jan 25, 2017
3 minutes read

Introduction

Google Container Engine is getting popular because a combination of Docker and Kubernetes makes applications more scalable and maintainable. However, you might consider choosing database whatever you want, even if Google has Cloud SQL.

I will introduce how to create a container for PostgreSQL on Kubernetes cluster. The way is also capable for other database containers like MongoDB. I wrote this article based on Eric Oestrich’s blog because I still needed to change some operations because of GCE’s update.

Create a new instance

Before you start, you need to create an instance on Google Compute Engine to format the disk to store data for postgres. To create the minimum instance, you can run a command on the console below:

gcloud compute instances create pg-disk-formatter --image ubuntu-1604-lts  --custom-cpu 1 --custom-memory 1

Create a new disk

Let’s create a new disk to store postgres data. Please make sure the zone for the disk is same as an instance you created in the previous step.

gcloud compute disks create pg-data-disk --size 50GB`

Next, let’s attach the disk to the machine through a command below.

gcloud compute instances attach-disk pg-disk-formatter --disk pg-data-disk

SSH into the machine and make sure it’s mounted on /dev/disk/by-id/

gcloud compute ssh pg-disk-formatter
$ ls /dev/disk/by-id/
...
google-pg-data-disk-part1 scsi-0Google_PersistentDisk_pg-data-disk
...

Format the new disk

Our next step is formatting the disk. To do that we need to download a script which is made by google. Run commands below on the machine you SSHed in the previous step. It might fail to mount on your machine, but it’s fine as long as the formatting succeeded.

wget https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/saltbase/salt/helpers/safe_format_and_mount
chmod 755 safe_format_and_mount
./safe_format_and_mount -m "mkfs.ext4 -F" /dev/disk/by-id/google-pg-data-disk /media/pg-data

Create files for Kubernetes

This part is nothing different with

postgres-persistence.yml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pg-data-disk
  labels:
    name: pg-data-disk
spec:
  capacity:
    storage: 50Gi
  accessModes:
    - ReadWriteOnce
  gcePersistentDisk:
    pdName: "pg-data-disk"
    fsType: "ext4"`

postgres-claim.yml

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: pg-data-claim
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 50Gi

postgres-pod.yml

apiVersion: v1
kind: Pod
metadata:
  name: postgres
    labels:
      name: postgres
spec:
  containers:
    - name: postgres
      image: postgres
      env:
        - name: DB_PASS
          value: password
        - name: PGDATA
          value: /var/lib/postgresql/data/pgdata
      ports:
        - containerPort: 5432
      volumeMounts:
        - mountPath: /var/lib/postgresql/data
          name: pg-data
  volumes:
    - name: pg-data
      persistentVolumeClaim:
        claimName: pg-data-claim

postgres-service.yml

apiVersion: v1
kind: Service
metadata:
  name: postgres
  labels:
    name: postgres
spec:
  ports:
    - port: 5432
  selector:
    name: postgres

Then now, you can create these services on Kubernetes through running commands as follows:

kubectl create -f postgres-persistence.yml
kubectl create -f postgres-claim.yml
kubectl create -f postgres-pod.yml
kubectl create -f postgres-service.yml

Create your app and connect to the postgres container

Inside of Kubernetes clusters, you can resolve names to access other services by the service name. In our case, you can just use postgres to access to it from your application.

yourapp-service.yml

apiVersion: v1
kind: Service
metadata:
  name: yourapp
  labels:
    run: yourapp
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: yourapp
spec:
  replicas: 1
  template:
    metadata:
      labels:
        run: yourapp
    spec:
      containers:
      - name: yourapp-server
        image: yourapp-server:latest
        imagePullPolicy: Always
        ports:
        - protocol: TCP
          containerPort: 5900
        env:
        - name: HOST
          value: postgres:5432
        - name: PASSWORD
          value: password

Then, run kubectl create -f yourapp-service.yml.


Back to posts


comments powered by Disqus