Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 73

Deploy Microservices to Local Kubernetes

Recommended resources

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 label app: fastapi.
  • template: This is the blueprint for the Pods the Deployment will create.
    • metadata.labels: We apply the label app: fastapi to 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.
Kubernetes Deployment YAML and Demo
This diagram shows how a Deployment manifest (left) creates a ReplicaSet, which in turn manages the desired number of Pods (right). Our YAML file follows this exact structure.

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 label app: fastapi and distribute traffic among them. This matches the labels we defined in our deployment.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 the containerPort from 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:

  1. Apply the manifests:
    Navigate to the directory containing your two YAML files and run:

    kubectl apply -f deployment.yaml
    kubectl apply -f service.yaml
    

    You should see messages confirming that a deployment and a service were created.

  2. Verify the Deployment and Pods:
    Check the status of your deployment:

    kubectl get deployment fastapi-app
    

    Now, watch your Pods being created. The -w flag will "watch" for changes.

    kubectl get pods -w
    

    Wait until you see two fastapi-app Pods with a status of Running.

  3. Inspect the Service:
    Check that your service was created and see which NodePort was assigned.

    kubectl get service fastapi-service
    

    The output will look something like this. Note the port number next to 80: in the PORT(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
    
  4. Access Your Application:
    To access the NodePort, you need the IP address of your Minikube cluster.

    minikube ip
    

    Combine this IP address with the NodePort from the previous step. For example, if your IP is 192.168.49.2 and your NodePort is 30100, open your web browser or use curl to 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 Deployment manifest describes the desired state for your application Pods, including the container image and number of replicas.
  • A Service manifest creates a stable network endpoint for your Pods. Using type: NodePort makes 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 pods and kubectl get svc are 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.