Welcome back! In our previous lesson, we explored the fundamental building blocks of Kubernetes: Pods, Deployments, Services, and ConfigMaps. We established that you tell Kubernetes your desired state using declarative YAML files, and the cluster works to make it a reality.
Today, we transition from theory to practice. Our goal is to take a containerized application and deploy it to a live (though local) Kubernetes cluster. You will write the necessary Deployment and Service manifests and use the kubectl command-line tool to bring your application to life. By the end of this 60-minute lesson, you will have deployed your first microservice on Kubernetes.
1. Setting Up Your Local Kubernetes Lab
To experiment with Kubernetes without incurring cloud costs, we'll run a cluster on your local machine. Several tools enable this, but we'll focus on Minikube, which creates a single-node Kubernetes cluster inside a Docker container or virtual machine. This provides a fully functional Kubernetes environment for development and testing.
You'll also use kubectl (pronounced "koob-control" or "koob-cuttle"), the primary command-line tool for interacting with any Kubernetes cluster, local or in the cloud.
Let's get your local lab set up.
Kubernetes Crash Course for Absolute Beginners [NEW]
The video "Kubernetes Crash Course for Absolute Beginners" by TechWorld with Nana has a clear guide for this setup.
Please watch the section on setting up Minikube and kubectl. Follow the instructions to install Minikube using Docker as the driver, start your cluster with minikube start, and verify the installation with kubectl get nodes.
Once you have successfully run kubectl get nodes and see a single node with a Ready status, your local cluster is up and running.
2. Defining the Application Deployment
With your cluster ready, the next step is to define what you want to deploy. In the last lesson, we learned that a Deployment is the Kubernetes object responsible for managing your application's Pods.
For this lesson, we will deploy a simple, pre-built FastAPI application. The container image for this application is publicly hosted on Docker Hub, so you don't need to build it yourself. The image is public.ecr.aws/l6j4t5e6/fastapi-k8s-demo:latest.
Let's create the YAML manifest for our Deployment. Create a new file named deployment.yaml and add the following content:
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: fastapi-app
spec:
replicas: 2
selector:
matchLabels:
app: fastapi
template:
metadata:
labels:
app: fastapi
spec:
containers:
- name: api
image: public.ecr.aws/l6j4t5e6/fastapi-k8s-demo:latest
ports:
- containerPort: 8000
Let's break this down:
kind: Deployment: We are defining a Deployment object.replicas: 2: We are telling Kubernetes we want two instances (Pods) of our application running for availability.selector.matchLabels: This tells the Deployment which Pods to manage. It will look for Pods with the labelapp: fastapi.template: This is the blueprint for the Pods the Deployment will create.metadata.labels: We apply the labelapp: fastapito the Pods so the Deployment's selector can find them.spec.containers: Here we define the container(s) to run inside the Pod.image: The public Docker image for our FastAPI application.containerPort: 8000: The port our FastAPI application is listening on inside the container.

3. Exposing the Application with a Service
Our Deployment ensures the Pods are running, but they are not yet accessible from outside the cluster. For that, we need a Service. The Service will provide a stable network endpoint and route traffic to our fastapi-app Pods.
Create a second file named service.yaml:
# service.yaml
apiVersion: v1
kind: Service
metadata:
name: fastapi-service
spec:
type: NodePort
selector:
app: fastapi
ports:
- protocol: TCP
port: 80
targetPort: 8000
Key parts of this manifest:
kind: Service: We are defining a Service object.type: NodePort: This specific type of Service exposes the application on a static port on each cluster Node. This is a simple way to get external traffic into our cluster for development purposes.selector.app: fastapi: This is the crucial link. The Service will find all Pods with the labelapp: fastapiand distribute traffic among them. This matches the labels we defined in ourdeployment.yaml.ports:port: 80: The port the Service itself will listen on inside the cluster.targetPort: 8000: The port on the Pods to which the traffic should be forwarded. This must match thecontainerPortfrom our Deployment.
4. Deploying and Verifying Your Microservice
Now for the exciting part. We have our cluster running and our declarative manifests written. It's time to apply them and watch Kubernetes bring our application to life.
For a detailed walkthrough of the deployment process, we'll turn back to the "Kubernetes Crash Course" video. While the video deploys a more complex application (Node.js with a database), the kubectl commands and verification steps are identical.
Kubernetes Crash Course for Absolute Beginners [NEW]
This comprehensive segment demonstrates the end-to-end process of deploying an application to Kubernetes.
Watch the demonstration from "Let's Deploy an App!". You don't need to follow the video's specific YAML files (we've created our own simplified ones). Instead, focus on the process and the kubectl commands used to: Apply configuration files (kubectl apply -f <filename>). Check the status of created components (kubectl get pods, kubectl get deployment, kubectl get service). Check application logs (kubectl logs <pod-name>). Access an application exposed via a NodePort service.
Follow these steps in your own terminal, using the deployment.yaml and service.yaml files you created:
-
Apply the manifests:
Navigate to the directory containing your two YAML files and run:kubectl apply -f deployment.yaml kubectl apply -f service.yamlYou should see messages confirming that a deployment and a service were created.
-
Verify the Deployment and Pods:
Check the status of your deployment:kubectl get deployment fastapi-appNow, watch your Pods being created. The
-wflag will "watch" for changes.kubectl get pods -wWait until you see two
fastapi-appPods with a status ofRunning. -
Inspect the Service:
Check that your service was created and see whichNodePortwas assigned.kubectl get service fastapi-serviceThe output will look something like this. Note the port number next to
80:in thePORT(S)column (e.g.,30100). This is the externally accessible port.NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE fastapi-service NodePort 10.108.144.20 <none> 80:30100/TCP 2m15s -
Access Your Application:
To access theNodePort, you need the IP address of your Minikube cluster.minikube ipCombine this IP address with the
NodePortfrom the previous step. For example, if your IP is192.168.49.2and your NodePort is30100, open your web browser or usecurlto access:http://192.168.49.2:30100.You should see the message:
{"message":"Hello, from your FastAPI microservice!"}.
Congratulations! You have successfully deployed a containerized microservice to a Kubernetes cluster.
Conclusion
In this lesson, you bridged the gap from theory to practice by deploying a real application. You saw how the concepts from the previous lesson translate directly into YAML manifests and how a few simple kubectl commands are all it takes to orchestrate your application.
Key Takeaways:
- Minikube provides a simple, effective way to run a local Kubernetes cluster for development.
- A
Deploymentmanifest describes the desired state for your application Pods, including the container image and number of replicas. - A
Servicemanifest creates a stable network endpoint for your Pods. Usingtype: NodePortmakes the service accessible from outside the local cluster. - The
kubectl apply -f <filename>command is used to apply your declarative configuration to the cluster. - Commands like
kubectl get podsandkubectl get svcare essential for verifying the status of your deployment.
Preview of the Next Lesson
Our application is running, but what happens when we need to update it with a new feature or a bug fix? A key benefit of Kubernetes is its ability to perform updates without any downtime. In the next lesson, we will learn how to configure and execute rolling deployments for zero-downtime updates, a critical practice for any production system.