PART 1: Deploy modern applications on a production grade, local K8s Cluster, layered with Istio Service Mesh and Observability.
Published: 2024-05-28 21:09:34

---
title: PART 1: Deploy modern applications on a production grade, local K8s Cluster, layered with Istio Service Mesh and Observability.
published: True
description: This is a three part tutorial that showcases how to build modern applications from ground up, using Kubernetes, service mesh, Next.js and FasAPI for Hackathons, MVPs and POCs.
tags: 
# cover_image: https://direct_url_to_image.jpg
# Use a ratio of 100:42 for best results.
# published_at: 2024-05-28 19:44 +0000
---

This first part of the three part series will guide you through, how to setup a Hackathon Starter ready, production grade, local development k8s cluster and a service mesh using Rancher's k3s light weight clusters and Istio service mesh. We will then deploy a sample application, add observability and ramp up traffic to see the service mesh in action. The next two parts of this series which will be released next month, will focus on full stack application development with Next.js and FastAPI, effectively showing intermediate and advanced developers how to scaffold production grade dashboard applications and powerful, scalable Fast REST APIs for all purposes,  and finally deploying them to the infrastructure that we will setup in this part. 

INSTALL DOCKER AND k3d ON LINUX (Debian) & MAC

Install Docker Engine and k3d on MAC
1. `brew update`
2. `brew install --cask docker` (Recommended if you don't have docker desktop installed)
3. `brew install k3d` (Install k3d tool)

On Linux, you will need to uninstall older versions of docker engine on your Linux box if you installed an earlier version. There are two ways to do it.

The first option is to: Uninstall Docker Engine, CLI, containerd, and compose packages
`sudo apt-get purge docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras`

And delete all images, containers and volumes run:
1. `sudo rm -rf /var/lib/docker`
2. `sudo rm -rf /var/lib/containerd`

The second option is to run the command below to install all conflicting packages
`for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done`

Install latest docker engine using the apt repository
Add Docker's official GPG key:
1. `sudo apt-get update`
2. `sudo apt-get install ca-certificates curl`
3. `sudo install -m 0755 -d /etc/apt/keyrings`
4. `sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc`
5. `sudo chmod a+r /etc/apt/keyrings/docker.asc`

Add the repository to Apt sources:
1. `echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null`
2. `sudo apt-get update`

If you use an Ubuntu derivative distro, such as Linux Mint, you may need to use UBUNTU_CODENAME instead of VERSION_CODENAME.

To install the latest version run:
`sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin`

To install a specific version based on your Linux distro version, do this:
List the available versions:
`apt-cache madison docker-ce | awk '{ print $3 }'`
Select and install the desired version
1. `VERSION_STRING=5:26.1.0-1~ubuntu.24.04~noble`
2. `sudo apt-get install docker-ce=$VERSION_STRING docker-ce-cli=$VERSION_STRING containerd.io docker-buildx-plugin docker-compose-plugin`

Create a docker group and add the current user
1. `sudo groupadd -f docker`
2. `sudo usermod -aG docker $USER`

Verify that the Docker Engine installation is successful by running the hello-world image.
`sudo docker run hello-world`

Install K3d, a light weight wrapper to run Rancher's K3s light weight clusters.
Latest Release `curl -s https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | bash`
Specific Release `curl -s https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | TAG=v5.0.0 bash`

Show docker version
`docker version`

Show k3d version
`k3d version`

INSTALL ISTIO (As of the time of writing this doc, the latest was 1.22.0 and it works with Kubernetes 1.30.1)

Install from Istio Download site
1. `curl -L https://istio.io/downloadIstio | sh -`  (Install the Latest Release Version)
2. `curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.22.0 TARGET_ARCH=x86_64 sh -` (Install a specific version OR override processor architecture)

Install from Github Repo
1. `ISTIO_VERSION=1.22.0`
2. `ISTIO_URL=https://github.com/istio/istio/releases/download/$ISTIO_VERSION/istio-$ISTIO_VERSION-linux-amd64.tar.gz` (For Linux processor ARCH, change as needed)
3. `curl -L $ISTIO_URL | tar xz`

Move to the Istio folder and set your PATH env variables for Istio bin directory so you can run istioctl from anywhere
1. `cd istio-1.22.0`
2. `export PATH=$PWD/bin:$PATH` (You should add this line to your shell config file, .zshrc or .bashrc. Replace the $PWD value with the actual value in your shell config)

Show Istio CTL version
`istioctl version`

Inspect profiles:
1. `istioctl profile list` (Will list available profiles)
2. `istioctl profile dump default` (Will dump the default profile config)

Install Istio with the demo profile
`istioctl install --set profile=demo -y`

Deploy Multi-Node K3s Kubernetes Cluster (v1.30.1) with a local registry, disabling treafik for istio instead (3 nodes, including control plane)
The incantation below creates a 3 node Kubernetes cluster (1 control plane and 2 workers) and uses a load balancer port to expose the internal application via the nginx load balancer, also setting up an  internal repository for pushing local images

`k3d cluster create svc-mesh-poc --agents 2 --port 7443:443@loadbalancer --port 3070:80@loadbalancer --api-port 6443 --registry-create svc-mesh-registry --image rancher/k3s:v1.30.1-k3s1 --k3s-arg '--disable=traefik@server:*'`


Probe local k3s docker images and the newly installed cluster
1. `docker ps --format 'table {{.ID}}\t{{.Image}}\t{{.Names}}\t{{.Ports}}'`
2. `kubectl get nodes`
3. `kubectl get ns`
4. `kubectl get pods -A`
5. `kubectl get services -A`

Create a Namespace for Demo Application that will be deployed so we can see Istio in action
`kubectl create namespace istio-demo-app`

To enable the automatic injection of Envoy sidecar proxies on the demo app namespace, run the following: (Otherwise you will need to do this manually when you deploy your applications)
`kubectl label namespace istio-demo-app istio-injection=enabled`

Deploy Istio's demo application using images from the manifests in the Istio installation samples folder which points to their public registries (Please examine the manifest before applying and make sure you are in the istio version folder)
1. `cd istio-1.22.0`
2. `kubectl -n istio-demo-app apply -f samples/bookinfo/platform/kube/bookinfo.yaml`

When installation is complete verify pods and services:
1. `kubectl -n istio-demo-app get services`
2. `kubectl -n istio-demo-app get pods`

Open Outside Traffic to pods so we can browse it locally and on the internal network via the browser:
`kubectl -n istio-demo-app apply -f samples/bookinfo/networking/bookinfo-gateway.yaml`

Analyze Namespace for Errors
`istioctl -n istio-demo-app analyze`

Open in browser
`http://localhost:3070/productpage`

Install Metrics and Tracing Utilities
1. `kubectl apply -f samples/addons`
2. `kubectl rollout status deployment/kiali -n istio-system`

If there are errors trying to install the addons, try running the command again. There may be some timing issues which will be resolved when the command is run again.

Access the Kiali dashboard
`istioctl dashboard kiali`

Ramp up hits on the demo application to see Istio MESH in action on Kiali. Run the command
`for i in $(seq 1 100); 
 do curl -so /dev/null http://localhost:3070/productpage; 
 done`

You many need to clean up all installation in the cluster at some point:
1. `kubectl delete -f samples/addons`
2. `kubectl -n istio-demo-app delete -f samples/bookinfo/networking/bookinfo-gateway.yaml`
3. `kubectl -n istio-demo-app delete -f samples/bookinfo/platform/kube/bookinfo.yaml`
4. `istioctl x uninstall --purge`
5. `kubectl delete namespace istio-system`
6. `kubectl delete namespace istio-demo-app`
7. `kubectl label namespace istio-demo-app istio-injection-`

You my need to delete the k3d/k3s cluster:
`k3d cluster delete svc-mesh-poc`


Yo may want to have more Graphical User Interface to see your cluster in full swing.To do that, deploy Kubernete Dashboard by running the following commands:

Add kubernetes-dashboard repository
`helm repo add kubernetes-dashboard https://kubernetes.github.io/dashboard/`

Deploy a Helm Release named "kubernetes-dashboard" using the kubernetes-dashboard chart
`helm upgrade --install kubernetes-dashboard kubernetes-dashboard/kubernetes-dashboard --create-namespace --namespace kubernetes-dashboard`

Verify that Dashboard is deployed and running.
`kubectl get pod -n kubernetes-dashboard`

Create a ServiceAccount and ClusterRoleBinding to provide admin access to the newly created cluster.
1. `kubectl create serviceaccount -n kubernetes-dashboard admin-user`
2. `kubectl create clusterrolebinding -n kubernetes-dashboard admin-user --clusterrole cluster-admin --serviceaccount=kubernetes-dashboard:admin-user`

To log in to your Dashboard, you need a Bearer Token. Use the following command to store the token in a variable.
`token=$(kubectl -n kubernetes-dashboard create token admin-user)`

Display the token using the echo command and copy it to use for logging into your Dashboard.
`echo $token`

You can access your Dashboard using the kubectl command-line tool and port forwarding by running the following commands and pasting the Bearer token on the text box:
`kubectl -n kubernetes-dashboard port-forward svc/kubernetes-dashboard-kong-proxy 8443:443`

Browse to https://localhost:8443

Clean Up Admin Service Account and Cluster Role Binding for Kubernetes Dashboard user.
1. `kubectl -n kubernetes-dashboard delete serviceaccount admin-user`
2. `kubectl -n kubernetes-dashboard delete clusterrolebinding admin-user`

Now that you have A lightweight multi-node cluster running locally with Istio configured, you can now try out all of these Istio features:
1. Request Routing
2. Fault Injection
3. Traffic Shifting
4. Querying metrics
5. Visualizing metrics
6. Accessing external services
7. Visualizing your mesh.

Stay tuned for more!