Site iconAxway Blog

API Builder Standalone Multi Container Application Using Kubernetes – Part 2

In this blog post we’ll continue from Part 1. We’ll deploy a two container application to Kubernetes (Minikube). The two containers will be an API Builder app and a MongoDB instance. We will also see how the Kubernetes Horizontal Pod Autoscaler (HPA) works by applying a load to API Builder and seeing how Kubernetes will scale up API Builder by adding more replicas.

Let’s get started.

Deploy MongoDB

We’ll start by deploying a Mongo container to our Kubernetes cluster.

If Minikube is not running, please start it

minikube start

Note: If you haven’t already done so, make sure your prior deployment is removed by following the teardown instructions in Part 1.

Create a file called mongo.yaml with the following contents:

apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: mongo
spec:
  selector:
    matchLabels:
      app: mongo
  replicas: 1
  template:
    metadata:
      labels:
        app: mongo
    spec:
      containers:
      - name: mongo
        image: mongo:latest
        ports:
        - containerPort: 27017
        volumeMounts:
        - name: mongo-persistent-storage
          mountPath: /data/db
      volumes:
      - name: mongo-persistent-storage
        persistentVolumeClaim:
          claimName: mongo-pv-claim
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: local-pv-1
  labels:
    type: local
spec:
  storageClassName: manual
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/mnt/mongodata"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mongo-pv-claim
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi

The mongo.yaml file basically describes a simple Mongo deployment with the addition of a volume to persist data in the host (Minikube).

Deploy to Minikube using the following:

kubectl create -f ./mongo.yaml

The response should be:

deployment.apps/mongo created
persistentvolume/local-pv-1 created
persistentvolumeclaim/mongo-pv-claim created
kubectl get pods

The response should be:

NAME READY STATUS RESTARTS AGE
mongo-57c5c96b97-mw8nw 1/1 Running 0 38s

Note: If the status is not Running (i.e. Pending), please wait before proceeding

kubectl expose deployment mongo --type=NodePort
minikube service mongo --url

The response should be:

http://192.168.99.100:32765

Note that your IP address and Port may be different

Note: I created a database called mydata with collection called dog and inserted one document (record)

Deploy API Builder

Now that Mongo is deployed and populated with a database and collection with data, we can deploy an API Builder app. We’ll use the same API Builder app that we used in Part 1. Remember that this API Builder app can connect to any MongoDB using it’s connection URL, passed in as an environment variable.

Create a file called apib.yaml with the following contents:

apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: apibmongo
spec:
  selector:
    matchLabels:
      app: apibmongo
  replicas: 1
  template:
    metadata:
      labels:
        app: apibmongo
    spec:
      containers:
      - name: apibmongo
        image: lbrenman/apibmongodb:1.0.0
        env:
        - name: MONGO_URL
          value: "mongodb://mongo:27017/mydata"
        ports:
        - containerPort: 8080
        resources:
          requests:
            cpu: "100m"

Note that we are specifying that the API Builder Pod should not consume more than 10% (100m) of the CPU. This is used for testing the Horizontal Pod Autoscaler.

Deploy to Minikube using the following:

kubectl create -f ./apib.yaml

The response should be:

deployment.apps/apibmongo created
kubectl get pods

Note: you may need to wait a bit for API Builder to be able to connect properly to the MongoDB instance since the MongoDB takes some time to start up and be ready to receive incoming requests for data

kubectl logs apibmongo-758fd66664-6c4bx

Note: replace apibmongo-758fd66664-6c4bx above with the name returned from the get pods command

kubectl expose deployment apibmongo --type=NodePort
minikube service apibmongo --url

The response should be:

http://192.168.99.100:32567
curl http://192.168.99.100:30956/api/mongo/dog

You should get the data you populated in MongoDB.

Enable and Test the Kubernetes Horizontal Autoscaler

Now that we have our multi container app running in Kubernetes, let’s take a look at how the Kubernetes Horizontal Pod Autoscaler (HPA) works.

minikube addons enable metrics-server

The response should be:

metrics-server was successfully enabled
kubectl autoscale deployment apibmongo --cpu-percent=10 --min=1 --max=3

The response should be:

horizontalpodautoscaler.autoscaling/apibmongo autoscaled
kubectl get hpa

Response should be:

NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
apibmongo Deployment/apibmongo 0%/10% 1 3 1 2m7s

Note: You can see above that there is one pod (replicas) currently running and that the HPA can scale up to 3 if it sees that the CPU goes above 10%.

In a separate terminal, we’ll simulate a heavy load on API Builder using an infinite HTTP request loop from a worker pod on our cluster to spike the CPU and see how the HPA responds using:

kubectl run -i --tty load-generator --image=busybox --generator=run-pod/v1 /bin/sh

When you get the command prompt (#), enter the following (with the correct API Builder URL and Port from above and your API route):

while true; do wget -q -O- http://192.168.99.100:30378/api/mongo/dog; done

You should see valid API request response in terminal if all is working properly

Back in the first terminal, check the status of the HPA as follows:

kubectl get hpa

Keep trying the ‘get hpa’ command. Eventually, the response should show that Kubernetes has scaled up the API Builder deployment to 3 pods (replicas) as follows:

NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
apibmongo Deployment/apibmongo 668%/10% 1 3 3 4m31s

Note: this can take several minutes, depending on the power of your laptop.

kubectl get hpa

Eventually, the response will be as follows:

NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
apibmongo Deployment/apibmongo 0%/10% 1 3 1 19m

Note that this may take a long time

Use the following commands if you’d like to tear down the application we just deployed:

kubectl delete -f ./
kubectl delete service mongo
kubectl delete service apibmongo
kubectl delete hpa apibmongo
kubectl delete pod load-generator

Note that if you stop minikube, then the host volume (MongoDB database) is deleted

Summary

In this blog post, we used deployment yaml files to stand up a multi container application in Kubernetes using Minikube and the kubectl CLI. We were able to make API requests to API Builder, which retrieved it’s data form a local MongoDB instance (with persistent volume).

Then we enabled the Kubernetes Horizontal Pod Autoscaler and were able to observe how Kubernetes scales up the API Builder pods based on the load of API requests.

Exit mobile version