Caution
All material provides only an introduction to containerization & K8s. It is not intended for production use and does not cover all best practices. Please dig especially into security topics before deploying anything to production.
This workshop is intended for developers who want to learn how to deploy applications to Kubernetes.
Tip
Check if your local environment is setup correctly by running the following command:
git clone [email protected]:l3montree-dev/kubernetes-developer-workshop.git
cd kubernetes-developer-workshop
./check_env.shIf the script notifies you of any missing dependencies, please install them before proceeding.
Table of Contents
- Prerequisites
- Color-Application Architecture Overview
- Section 1 Containerize the Application
- Section 2 Kubernetes Deployment
- Part 2.1 Installing and Starting Minikube
- Part 2.2 Create the "workshop" Namespace in Minikube
- Part 2.3 PostgreSQL Installation Using Helm
- Part 2.4 Creating Kubernetes Deployment Files
- Part 2.5 Deploy the Entire Application
- Section 3: Helm Charts
flowchart TD
A[React Frontend] -->|Fetches Color| B[Spring-Boot Color-API]
B -->|Returns| A
B-->|Logs Request| C[PostgreSQL]
-
Explore the example Spring Boot application in the color-api directory. It provides an endpoint that returns a random hex color.
-
Review the Dockerfile.
-
Build the container image with the following command:
docker build -t spring-boot-demo:latest color-api
-
Inspect the image, which is essentially a tar archive:
docker save spring-boot-demo:latest -o spring-boot-demo.tar
-
Run the
inspect_layers.shscript:- It extracts the tar archive into the extracted_image folder.
- It extracts each layer tar archive in the extracted_image/blobs folder into the layers folder.
- It merges the layers into a single file system in the merged_layers folder, resolving conflicts by replacing files as needed.
-
Examine the merged_layers folder to see the file system of the container image.
- Modify the Dockerfile as instructed in the comments to create a multi-stage build. Rebuild and inspect the image again.
- Explore the example Next.js application in the nextjs-frontend directory. It fetches the randomly generated color from the color-api and displays it.
- Build and run the container:
docker build -t nextjs-frontend:latest nextjs-frontend docker run -p 3000:3000 nextjs-frontend:latest
- Open http://localhost:3000 in your browser.
- Review the docker-compose.yaml file.
- Note that it adds PostgreSQL to the deployment and configures the
COLOR_API_URLenvironment variable. - Build and start the containers using the following command. Use the image references from GitHub to avoid building the images yourself:
docker compose up
- Open http://localhost:3000 in your browser. It should now return a color from the color-api.
Follow the instructions at Minikube Start.
brew install minikube && minikube startEnable the storage provisioner and ingress controller:
minikube addons enable storage-provisioner
minikube addons enable ingressSet the kubectl alias to the Minikube cluster:
alias kubectl="minikube kubectl --"Create the namespace:
kubectl create namespace workshopAlternatively, install kubectl by following the official documentation.
Add the Bitnami repository:
helm repo add bitnami https://charts.bitnami.com/bitnamiInstall PostgreSQL:
helm install -n workshop postgresql bitnami/postgresql
# or
helm install postgresql -n workshop oci://registry-1.docker.io/bitnamicharts/postgresqlInspect the running deployment to ensure it started successfully:
kubectl get pods -n workshop
NAME READY STATUS RESTARTS AGE
postgresql-0 1/1 Running 1 (2m5s ago) 15m-
Deploy the COLOR-API
The Next.js frontend deployment files are already provided as an example in the kube/nextjs-frontend directory.
kubectl apply -n workshop -f kube/nextjs-frontend
Create the
color-apideployment files and apply them to the cluster:kubectl apply -n workshop -f kube/color-api
Hints:
- You need a deployment and a service.
- Use the image
ghcr.io/l3montree-dev/kubernetes-developer-workshop/color-api:latest. - The application runs on port 8080.
- Required environment variables:
DB_URL: jdbc:postgresql://postgresql:5432/postgresDB_USER: postgresDB_PASS: ? (check the secret created by the PostgreSQL Helm chart)
-
Configure the connection between the frontend and the color-api using the
COLOR_API_URLenvironment variable.
Kubernetes is idempotent, so you can apply the entire configuration:
kubectl apply -n workshop -R -f kubeCheck the running pods:
kubectl get pods -n workshop
NAME READY STATUS RESTARTS AGE
color-api-5c8bc7f9d6-2t7df 1/1 Running 0 23m
color-api-5c8bc7f9d6-72qnw 1/1 Running 0 23m
frontend-68bcf87ffd-n7wtp 1/1 Running 0 39m
postgresql-0 1/1 Running 1 (49m ago) 63mUse Minikube to view the frontend:
minikube tunnelThe frontend should be available at http://127.0.0.1.
Create a new Helm chart:
helm create color-applicationRemove everything except Chart.yaml and values.yaml:
rm -rf color-application/templates/* color-application/chartsClear the values.yaml file:
echo "" > color-application/values.yamlCopy the contents of the kube folder into the templates folder of the Helm chart:
cp -r kube/* color-application/templates/Modify the color-application/nextjs-frontend/ingress.yaml file to use the path prefix /helm.
Install the Helm chart:
helm upgrade --install -n workshop-helm --create-namespace color-application color-applicationCheck the running pods in the workshop-helm namespace:
kubectl get pods -n workshop-helm
NAME READY STATUS RESTARTS AGE
color-api-564cf76456-nchc7 0/1 CreateContainerConfigError 0 9m56s
color-api-564cf76456-w2dkr 0/1 CreateContainerConfigError 0 9m56s
frontend-68bcf87ffd-6pkz9 1/1 Running 0 9m56sThe color-api pods are not starting because the database is missing. Add the PostgreSQL dependency to Chart.yaml:
dependencies:
- name: postgresql
version: 16.4.9
repository: https://charts.bitnami.com/bitnamiInstall the Helm chart again:
helm upgrade --install -n workshop-helm --create-namespace color-application color-applicationIf it fails, install the dependencies first:
helm dependency update color-applicationApply the Helm chart again:
helm upgrade --install -n workshop-helm --create-namespace color-application color-applicationCheck the running pods:
kubectl get pods -n workshop-helm
NAME READY STATUS RESTARTS AGE
color-api-564cf76456-khh2s 0/1 CreateContainerConfigError 0 52s
color-api-564cf76456-w2dkr 0/1 CreateContainerConfigError 0 16m
color-application-postgresql-0 1/1 Running 0 108s
frontend-68bcf87ffd-6pkz9 1/1 Running 0 16mThe color-api pods are still not starting. Configure the environment variables correctly:
env:
- name: DB_PASS
valueFrom:
secretKeyRef:
name: color-application-postgresql
key: postgres-passwordCheck if the DB_URL is correctly configured. Find the service name with:
kubectl get services -n workshop-helmApply the Helm chart again:
helm upgrade --install -n workshop-helm --create-namespace color-application color-applicationCheck the running pods and visit the frontend.
Set the number of replicas in values.yaml:
# values.yaml
replicaCount: 2Use the replicaCount value in the color-application/color-api/deployment.yaml:
spec:
replicas: {{ .Values.replicaCount }}Apply the Helm chart again:
helm upgrade --install -n workshop-helm --create-namespace color-application color-applicationCheck the running pods:
kubectl get pods -n workshop-helm
NAME READY STATUS RESTARTS AGE
color-api-86f8b7bb7d-29mt7 1/1 Running 0 8m48s
color-api-86f8b7bb7d-2lzql 1/1 Running 0 8m46s
color-api-86f8b7bb7d-rl78x 1/1 Running 0 15s
color-application-postgresql-0 1/1 Running 0 10m
frontend-68bcf87ffd-vvv5v 1/1 Running 0 10mVisit the frontend. You should see three different colors after reloading a few times.
Package the Helm chart:
helm package color-applicationThe packaged Helm chart is in the color-application-0.1.0.tgz file. Install the packaged Helm chart:
helm install -n workshop-helm-packaged --create-namespace color-application color-application-0.1.0.tgz --set replicaCount=1The installation fails due to a conflicting path in the ingress. Maybe this can be made configurable as well?
Build and push the Docker images:
docker buildx build --push --platform linux/arm64/v8,linux/amd64 -t ghcr.io/l3montree-dev/kubernetes-developer-workshop/nextjs-frontend:latest nextjs-frontenddocker buildx build --push --platform linux/arm64/v8,linux/amd64 -t ghcr.io/l3montree-dev/kubernetes-developer-workshop/color-api:latest color-api
