This repository contains a sample container app (utilizes FastAPI framework), let's call it "demo-app", that connects to a PostgreSQL database. Repository also contains a Helm Chart to release it to Kubernetes Cluster for demo/learning purposes.
To get familiar with some of the Kubernetes objects, please read this.
The following applications are utilized in this project, and thus, are required:
git clone https://github.com/bishalkc/demo-app.git demo-app
git clone [email protected]:bishalkc/demo-app.git demo-app
This project already contains a Dockerfile
and docker-compose
. Using these, you can run the FastAPI app and Postgresql database.
Run the following to build the container image:
docker-compose build
Run the following to provision the container(s) in a detached mode (if you prefer non-detached mode, execute docker-compose up
):
docker-compose up -d
Following command starts a local kubernetes cluster with Kubernetes version 1.25.3
while utilizing docker
as the driver.
minikube start --driver=docker --kubernetes-version=1.25.3
Validate the output of Cluster.
kubectl cluster-info
Retrieve Nodes information:
kubectl get nodes -o wide
Validate all pods in kube-system
namespace are READY:
kubectl -n kube-system get pods
Apply YAML manifest for metrics-server
:
kubectl apply -f metrics-server.yaml
Ensure metrics-server
Pod is in READY state:
kubectl get pods -l k8s-app=metrics-server -n kube-system
If POD is in a state where image PULL has failed, attempt to PULL using the following:
minikube ssh docker pull k8s.gcr.io/metrics-server/metrics-server:v0.6.2
To build and run container (in this case docker images) in minikube's environment, execute the following to configure the appropriate environment variables:
eval $(minikube docker-env)
Build the container image:
docker build -t local/demo-app:v1 .
For the purpose of this tutorial, we will release the helm chart against a specific namespace called `demo'. Let's get started by creating the namespace:
kubectl create ns demo
Pull dependent chart to disk:
helm dependency build helmchart/
Deploy the Kubernetes Objects defined in the Helm Chart using helm to the previously created demo
namespace while naming the Helm Release as demo-app:
helm upgrade -i demo-app helmchart/ --namespace demo
Once deployed, validate that all Pods are demo
namespace are in READY state. NOTE that it may take a few minutes for the Pods to be in READY state as a postgresql image is pulled down and rolled out, and is required for the app to successfully initialize).
kubectl get pods -n demo
Helm chart test hooks are part of the chart, run the following to let helm perform those tests for you:
helm test demo-app -n demo
To tail the app logs, run the following:
kubectl logs -f -l app.kubernetes.io/name=demo-app -n demo
By default, ClusterIP
is used in this helm chart, which technically means that the Service
endpoint is only accessible within the cluster.
In order to access the application endpoints, kubectl port-forward
can be used. It will allow connection/traffic to a local port to be forwarded to the port of the Service
in the cluster for navigation/access purposes.
The command below will setup port forwarding (<HOST_PORT_80>:<SVC_PORT_80>
) on a local host port 80 to be forwarded to the Service
port, which also is running on port 80.
kubectl port-forward svc/demo-app 80:80 -n demo
Please note that kubectl port-forward
process runs interactively (i.e. as a foreground process | use CTRL+C
or CMD+C
keys to end the process), so you may need to open another terminal session for any other activities.
The following command intializes a Pod that makes calls to the Service
Endpoint with the hostname path to retrieve hostname of the Pods traffic is routed to:
kubectl run -n demo -i --tty load-generator --rm --image=busybox --restart=Never -- sh -c "while sleep 0.01; do wget -q -O- http://demo-app.demo.svc.cluster.local/private/hostname && echo; done"
Following command will run a pod based on Apache Bench that will load test the Service Endpoint:
kubectl run -i --tty apache-bench --rm --image=jordi/ab --restart=Never -- -k -c 100 -t 300s http://demo-app.demo.svc.cluster.local/private/hostname
In the mean time, you can monitor the HorizontalPodAutoscaler to view scale-in and scale-out activities:
kubectl get hpa demo-app -n demo -w
Uninstall the helm chart:
helm uninstall demo-app -n demo
Stop minikube cluster:
minikube stop
Delete minikube cluster:
minikube delete
curl -i -H "Content-Type: text/html" -X GET http://localhost/
curl -i -H "Content-Type: application/json" -X GET http://localhost/private/hostname
curl -i -H "Content-Type: application/json" -X GET http://localhost/health/liveness
curl -i -H "Content-Type: application/json" -X GET http://localhost/health/readiness
curl -i -H "Content-Type: application/json" -X GET http://localhost/secrets
curl -i -d '{"text":"HTTP POST method testing"}' -H "Content-Type: application/json" -X POST http://localhost/publisher
This project was developed by Ali Muhammad, modified by [Bishal KC] (https://www.github.com/bishalkc).