How to Build Python Flask RestAPI with Postgres and Dockerize It on Google Kubernetes using HELM - Part 2

How to Build Python Flask RestAPI with Postgres and Dockerize It on Google Kubernetes using HELM - Part 2

ยท

5 min read

Deploy Containerized RestAPI to Google Kubernetes using HELM

My previous post described How to Build Python Flask RestAPI with Postgres and Dockerize It on Google Kubernetes using HELM - Part 1

Here I deploy the docker to Google Kubernetes using HELM for learning Kubernetes and HELM tech.

Notes: Google Cloud service is fee-based, and you can sign up for a free account to try it out if you are a new user. After the trial ends, if you don't want to continue using it, please stop the related service to avoid being charged.

Google Cloud

Service Account

Create Service Account

Log in to Google Cloud, and click the "Service Accounts"

image.png

And create service account

image.png

Input the service account name : dataflow

And click done

image.png

Then click on the account that was created.

And find the menu "KEYS", so I can add a new key.

After clicking on "Create new key", the key will be automatically downloaded

image.png

The key file is crafty-sound-368922-c79c42843b1f.json

image.png

IAM

Then add Permissions for my project in the IAM

image.png

Add role "Kubernetes Engine Admin" and "Storage Admin" image.png

Enable Container Registry

image.png

Enable Kubernetes Engine

image.png

Install Google Cloud SDK

Download and install Google Cloud SDK

./google-cloud-sdk/install.sh

image.png

./google-cloud-sdk/bin/gcloud init

image.png

And follow the step, open the browser, and log in with my Google account ( this account is also my Google Cloud account )

And then pick cloud project to use:

image.png

I pick my project [1] crafty-sound-368922

Push Docker Image to Container Registry

Configure docker with the project

gcloud auth configure-docker --project crafty-sound-368922

image.png

Activate service account

gcloud auth activate-service-account dataflow@crafty-sound-368922.iam.gserviceaccount.com --key-file="/Users/jasonsong/Downloads/crafty-sound-368922-c79c42843b1f.json"

image.png

Docker tag for pushing

docker tag pythonrestapi gcr.io/crafty-sound-368922/restapi:v1
docker images

image.png

Push docker

docker push gcr.io/crafty-sound-368922/restapi:v1

image.png

Check the image in the Container Registry

image.png

Create Helm Chart

Download and install helm

tar -zxvf helm-v3.10.2-darwin-amd64.tar.gz 

chmod +x darwin-amd64/helm 

sudo mv darwin-amd64/helm /usr/local/bin/helm

Creates the sample structure, this is a Helm chart for Kubernetes

helm create python-api-chart

image.png

Keep the project files like this:

image.png

deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: rest-api
  name: {{.Values.application.name}}
spec:
  replicas: {{.Values.replicaCount}}
  selector:
    matchLabels:
      app: rest-api
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: rest-api
    spec:
      containers:
      - image: {{.Values.image.repository}}
        name: api
        imagePullPolicy: {{.Values.image.pullPolicy}}
        resources: {}
        ports:
          - containerPort: 8080 
status: {}

service.yaml

apiVersion: v1
kind: Service
metadata:
  name: {{.Values.application.name}}
  labels:
    run: {{.Values.application.name}}
spec:
  ports:
  - port: 8080
    protocol: TCP
  selector:
    app: {{.Values.application.name}}
  type: LoadBalancer

Chart.yaml

apiVersion: v2
name: python-api-chart
description: A Helm chart for Kubernetes

# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application

# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.1.0

# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
appVersion: 1.16.0

And my values.yaml

# This is a YAML-formatted file.
# Declare variables to be passed into your templates.

replicaCount: 10

image:
  repository: gcr.io/crafty-sound-368922/restapi:v1
  pullPolicy: Always

application:
  name: rest-api

Package to a file python-api-chart-0.1.0.tgz

helm package python-api-chart

image.png

Create Kubernetes cluster

Click Kubernetes engine from the menu of Google Cloud, and click the create button

image.png

Select the second one, and click configure

image.png

Create a cluster, my first cluster

image.png

Cluster basics like this, and I change zone to "europe-central2-a" which is close to me, click create button

image.png

Deploy to Kubernetes cluster using Helm

Successful creation of Kubernetes Engine cluster "api-cluster", and there are 3 nodes in this cluster, then click connect

image.png

Copy this code from the popup window

image.png

Command-line access

gcloud container clusters get-credentials api-cluster --zone europe-central2-a --project crafty-sound-368922

image.png

Intall the Helm Chart on the Kubernetes cluster

helm install api-release1 python-api-chart-0.1.0.tgz

image.png

Successful deployment like this

image.png

Download and install kubectl

curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/darwin/amd64/kubectl"

chmod +x kubectl 

sudo mv kubectl /usr/local/bin/kubectl

Check the pods and service installed with kubectl command

kubectl get deploy

kubectl get po

kubectl get svc

image.png

Testing the RestAPI

And now, I can know the cluster public IP address, so I can access the IP from my browser

http://34.116.219.2:8080/api/tasks

image.png

Next, I will use curl to add, update and delete a record vis Rest request.

Get all records

curl http://34.116.219.2:8080/api/tasks

image.png

Add a task record

curl -X POST -H "Content-Type: application/json" \
    -d '{"name": "task4","description": "This is task 4"}' \
    http://34.116.219.2:8080/api/task

image.png

Update the task record

curl -X PUT  -H "Content-Type: application/json" \
    -d '{"name": "task4 U","description": "This is task 4 updated"}' \
    http://34.116.219.2:8080/api/task/4

image.png

Delete the task record

curl -X DELETE http://34.116.219.2:8080/api/task/4

image.png

Conclusion

I strongly feel that the integration of various technologies is the trend of development, not only to provide more innovative and efficient solutions, but also to better solve various needs in real business. I find the most interesting process is to learn about these technologies and get them up and running through hands-on practice, and I really enjoy it! ๐Ÿ˜Š

Read More

๐Ÿ”— Thanks to Bhargav Bachina for introducing How To Deploy Python APIs on GCP GKE using HELM

ย