Skip to content

1 Deploy Applications on Kubernetes

Objective:

  • Review process of creating NameSpaces
  • Review process of changing Context
  • Review process of creating K8s:
    • Services
    • Labels, Selectors
    • Deployments
    • Rolling Updates

1.1 Development Tools

Note

This steps is optional

Step 1 Choose one of the following option to develop the YAML manifests:

Option 1: You can develop in Google Cloud Shell Editor

Option 2: You can also develop locally on your laptop using VCScode. We recommend to use it in conjunction with VSC YAML extension from Redhat

Option 3: Use your preferred text editor on Linux VM (vim, nano).

2.1 Create GKE Cluster

Step 1 Enable the Google Kubernetes Engine API.

gcloud services enable container.googleapis.com

Step 2 From the cloud shell, run the following command to create a cluster with two nodes:

gcloud container clusters create k8s-concepts \
--zone us-central1-c \
--num-nodes 2

Output:

NAME          LOCATION       MASTER_VERSION   MASTER_IP      MACHINE_TYPE  NODE_VERSION     NUM_NODES  STATUS
k8s-concepts  us-central1-c  1.19.9-gke.1400  34.121.222.83  e2-medium     1.19.9-gke.1400  2          RUNNING

Step 3 Authenticate to the cluster.

gcloud container clusters get-credentials k8s-concepts --zone us-central1-c

2.2 Setup KUBECTL AUTOCOMPLETE

Since we going to use a lot of kubectl cli let's setup autocomplete.

source <(kubectl completion bash)
echo "source <(kubectl completion bash)" >> ~/.bashrc

2.3 Create 'dev' namespace and make it default.

Step 1 Create 'dev' namespace that's going to be used to develop and deploy Notestaker application on Kubernetes using kubetl CLI.

kubectl create ns dev

Step 2 Use dev context to create K8s resources inside this namespace.

kubectl config set-context --current --namespace=dev

Step 3 Verify current context:

kubectl config view | grep namespace

Result

dev

2.4 Create Service Object for MySQL

Step 1 Locate directory where kubernetes manifests going to be stored.

cd ~/ycit019/
git pull       # Pull latest assignement3

In case you don't have this folder clone it as following:

cd ~
git clone https://github.com/Cloud-Architects-Program/ycit019
cd ~/ycit019/Assignment3/
ls

Step 2 Go into the local repository you've created:

cd ~/$MY_REPO

Step 3 Copy Assignment 3 deploy folder to your repo:

git pull                              # Pull latest code from you repo
cp -r ~/ycit019/Assignment3/deploy .

Step 4 Commit deploy folder using the following Git commands:

git status 
git add .
git commit -m "adding K8s manifests in deploy folder"

Step 5 Once you've committed code to the local repository, add its contents to Cloud Source Repositories using the git push command:

git push origin master

Step 6 Define a Kubernetes Service object for the backend MySQL database.

cd ~/$MY_REPO/deploy

Follow instructions below to populate gowebapp-mysql-service.yaml

For reference, please see Service docs:

https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service

Additionally, you can use kubectl built-in docs for any type of resources:

kubectl explain service
vim gowebapp-mysql-service.yaml

Note

You can also use VCS or Cloud Code to work with yaml manifest.

apiVersion: v1
kind: Service
metadata:
  name: gowebapp-mysql
  labels:
    run: gowebapp-mysql
spec:
  clusterIP: None
  ports:
  - port: 3306
    targetPort: 3306
  selector:
    run: gowebapp-mysql

Step 3 Create a Service object for MySQL

kubectl apply -f gowebapp-mysql-service.yaml --record

Step 4 Check to make sure it worked

kubectl get service -l "run=gowebapp-mysql"

2.5 Create Deployment object for the backend MySQL database

Step 1 Follow instructions below to populate gowebapp-mysql-deployment.yaml

For reference, please see Deployment doc:

https://kubernetes.io/docs/concepts/workloads/controllers/deployment
vim gowebapp-mysql-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: gowebapp-mysql
  labels:
    run: gowebapp-mysql
    tier: backend
spec:
  replicas: 1
  selector:
    matchLabels:
      run: gowebapp-mysql
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        run: gowebapp-mysql
    spec:
      containers:
      - env:
        - name: MYSQL_ROOT_PASSWORD
          value: rootpasswd
        image: gcr.io/${PROJECT_ID}/gowebapp-mysql:v1
        name: gowebapp-mysql
        ports:
        - containerPort: 3306

Step 2 Create a Deployment object for MySQL

kubectl apply -f gowebapp-mysql-deployment.yaml --record

Step 3 Check to make sure it worked

kubectl get deployment -l "run=gowebapp-mysql"

Step 3 Check mysql pod logs:

List mysql Pods and note the name the pod:

kubectl get pods -l "run=gowebapp-mysql"

Ensure Mysql is up by looking at pod logs:

kubectl logs <Pod_name>

Result

We have created Service and Deployment for backend application.

2.5 Create a K8s Service for the frontend gowebapp.

Step 1 Follow instructions below to populate gowebapp-service.yaml

vim gowebapp-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: gowebapp
  labels:
    run: gowebapp
spec:
  ports:
  - port: 9000
    targetPort: 80
  selector:
    run: gowebapp
  type: LoadBalancer

Step 2 Create a Service object for gowebapp

kubectl apply -f gowebapp-service.yaml --record

Step 3 Check to make sure it worked

kubectl get service -l "run=gowebapp"

2.6 Create a K8s Deployment object for the frontend gowebapp

Step 1 Follow instructions below to populate gowebapp-deployment.yaml

vim gowebapp-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: gowebapp
  labels:
    run: gowebapp
spec:
  replicas: 2
  selector:
    matchLabels:
      run: gowebapp
  template:
    metadata:
      labels:
        run: gowebapp
    spec:
      containers:
      - env:
        - name: MYSQL_ROOT_PASSWORD
          value: rootpasswd
        image: gcr.io/${PROJECT_ID}/gowebapp:v1
        name: gowebapp
        ports:
        - containerPort: 80

Step 2 Create a Deployment object for gowebapp

kubectl apply -f gowebapp-deployment.yaml --record

Step 3 Check to make sure it worked

kubectl get deployment -l "run=gowebapp"

Step 4 Access your application on Public IP via automatically created Loadbalancer created for gowebapp service.

To get the value of Loadbalancer run following command:

kubectl get svc gowebapp -o wide

Expected output:

NAME             TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
gowebapp         Loadbalancer 10.107.15.39  XXXXXX        9000:32634/TCP   30m
gowebapp-mysql   ClusterIP   None           <none>        3306/TCP         1h

Step 5 Access Loadbalancer IP via browser:

Result

Congrats!!! You've deployed you code to Kubernetes

2.7 Fix gowebapp code bugs and build a new image.

Task: As you've noticed gowebapp frontend app has YCIT019 logo in it. Since you may want to use application for you personal needs, let's change YCIT019 logo to you Name.

Step 1 Modify gowebapp frontend so that it has name of you company and link to company web page e.g.

vim ~/$MY_REPO/gowebapp/code/template/partial/footer.tmpl

Step 2 Build a new version of Image

cd ~/$MY_REPO/gowebapp
docker build -t gcr.io/${PROJECT_ID}/gowebapp:v2 .
docker push gcr.io/${PROJECT_ID}/gowebapp:v2 .

2.7 Rolling Upgrade

For gowebapp frontend deployment manifest we've not specified any upgrade strategy type. It means application will use default Upgrade strategy called RollingUpdate.

RollingUpdate strategy - updates Pods in a rolling update fashion.

maxUnavailable - is an optional field that specifies the maximum number of Pods that can be unavailable during the update process. By default, it ensures that at least 25% less than the desired number of Pods are up (25% max unavailable).

Max Surge - is an optional field that specifies the maximum number of Pods that can be created over the desired number of Pods. By default, it ensures that at most 25% more than the desired number of Pods are up (25% max surge).

Step 1 Locate directory with manifest

cd  ~/$MY_REPO/deploy

Step 2 Trigger rolling upgrade using kubectl set command

kubectl set image deployments/gowebapp gowebapp=gcr.io/${PROJECT_ID}/gowebapp:v2

Step 3 Verify rollout history

kubectl rollout history deployment/gowebapp

Step 4 Perform Rollback to v1

kubectl rollout undo deployment/gowebapp --to-revision=1

2.8 Commit K8s manifests to repository and share it with Instructor/Teacher

Step 1 Commit deploy folder using the following Git commands:

git add .
git commit -m "k8s manifests"

Step 2 Push commit to the Cloud Source Repositories:

git push origin master

2.9 Cleaning Up

Step 1 Delete the cluster

gcloud container clusters delete k8s-concepts