Kubernetes

Table of contents
- π From Container to Production: The Need for Orchestration
- ποΈ Kubernetes Architecture: The Building Blocks of a Cluster
- π³ Docker vs Containerd + CLI Tools (ctr, nerdctl, crictl)
- βοΈ Setting Up Kubernetes: A Beginnerβs Guide
- Pods
- βΈοΈ Kubernetes Controllers
- π Replication Controller
- β What is a Replica? Why Use a Replication Controller?
- β Role of the Replication Controller
- π€ Can It Be Used for Just One Pod?
- π Scaling & Load Balancing
- π ReplicaSet vs Replication Controller
- Replication Controller
- Letβs Now look into ReplicaSet
- Labels and Selectors
- Scale Replica Set
- Kubernetes Deployments
- π Kubernetes Networking Basics
- π‘ Kubernetes Services Explained
- π§© Kubernetes Services β ClusterIP
- βοΈ Kubernetes Service β LoadBalancer
- β Kubernetes Service Types β Recap
π From Container to Production: The Need for Orchestration
So, you've containerized your application using Dockerβawesome! π
But now comes the real challenge:
How do you run that application in production?
Letβs say your app depends on other services like a database, messaging queue, or authentication backend. What if thousands of users show up? Youβll need to scale your app up. What if demand drops? Youβll want to scale down and save resources.
This is where container orchestration comes into play.
π§ What is Container Orchestration?
Container orchestration is the automated management of containerized applicationsβhandling deployment, scaling, networking, and health monitoring.
With orchestration tools, you can:
π§© Manage multi-container apps seamlessly
π Connect containers across services
π Automatically scale with traffic spikes
β οΈ Recover from hardware or service failures
π Use declarative YAML configs to define system behavior
βοΈ The Tools of the Trade
There are several container orchestration platforms available:
Tool | Description | Ease of Use | Features |
Docker Swarm | Native orchestration tool from Docker | β Easy | β Limited |
Apache Mesos | Powerful but complex | β Hard | β Advanced |
Kubernetes | The gold standard in orchestration | β οΈ Moderate | π Feature-rich |
π Why Kubernetes Stands Out
Kubernetes (aka K8s), originally developed by Google, is now the most widely adopted container orchestration platform in the worldβand for good reason:
π§ Highly customizable deployments
βοΈ Runs on all major clouds (AWS, GCP, Azure)
π Massive open-source community
π¦ Supports complex microservice architectures
Kubernetes isn't just a toolβit's an entire ecosystem for managing modern apps.
π― Key Benefits of Kubernetes
Feature | Benefit |
π Self-Healing | Automatically replaces failed containers |
βοΈ Load Balancing | Distributes traffic across running containers |
π¦ Auto-Scaling | Dynamically adjusts resources based on demand |
π§± Service Abstraction | Exposes apps via internal or external services |
π Declarative Configs | Infrastructure as Code using YAML |
π‘ Rolling Updates | Deploy new versions with zero downtime |
Kubernetes allows you to run hundreds or thousands of containers reliably across clustersβwithout breaking a sweat. πͺ
ποΈ Kubernetes Architecture: The Building Blocks of a Cluster
Before diving into setting up a Kubernetes cluster, itβs crucial to understand its core components and how they work together. This foundational knowledge helps make sense of the key terms and processes you'll encounter throughout your Kubernetes journey.
π§± What is a Node?
A Node is a physical or virtual machine on which Kubernetes is installed. It acts as a worker machineβthis is where your containers actually run.
π§ Fun fact: Nodes were once referred to as Minions.
But hereβs the catch:
What happens if the node running your application fails?
π Your application goes down.
To avoid this, Kubernetes clusters are designed with multiple nodesβso if one fails, another steps in. This ensures high availability and load distribution.
π₯ What is a Cluster?
A Cluster is a group of nodes working together as a unified system. This allows:
Resilience: If one node fails, others continue serving the application.
Load Sharing: Requests are distributed across nodes to prevent overload.
π Enter the Master Node (Control Plane)
A cluster of worker nodes must be managed and coordinated. Thatβs the job of the Master Node, also known as the Control Plane.
The Master node is responsible for:
Monitoring the health of nodes
Managing deployments
Rescheduling containers if a node goes down
βοΈ Core Components of Kubernetes
When you install Kubernetes, you're actually installing a collection of components. Here's what powers the cluster:
π API Server
Acts as the front door to the cluster.
All communicationβwhether from users, tools, or CLIsβgoes through the API Server.
kubectl cluster-info # View cluster info via the API server
π¦ etcd (Key-Value Store)
A distributed, reliable key-value store used to persist the cluster state.
Stores all configuration data
Ensures consistency across nodes and masters
Helps in managing logs and consensus in distributed environments
π§ Scheduler
The Scheduler decides where new containers should run by:
Analyzing resource availability
Assigning workloads to the best-fit node
𧬠Controllers
Controllers are the brain behind orchestration.
They:
Detect changes or failures
Take corrective action (e.g., restart containers, rebalance workloads)
Think of them as automated managers ensuring desired state is always maintained.
π³ Container Runtime
The software responsible for running containers. Common runtimes include:
Runtime | Description |
Docker | Most widely used (used in this course) |
containerd | Lightweight Docker alternative |
CRI-O | Kubernetes-native runtime |
Rocket | Now deprecated, but once popular |
π°οΈ Kubelet
An agent that runs on every worker node.
Communicates with the Master
Ensures containers are running as expected
Executes commands sent from the Control Plane
π§ Master vs Worker Node β Whatβs the Difference?
Component | Master Node | Worker Node |
kube-apiserver | β | β |
controller-manager | β | β |
scheduler | β | β |
etcd (optional) | β | β |
kubelet | β | β |
container runtime (e.g. Docker) | β | β |
π§° Meet kubectl: Your Command Line Superpower
kubectl
(pronounced "kube control") is the primary CLI tool for interacting with a Kubernetes cluster.
Some essential commands:
kubectl run hello-minikube # Deploy an app to the cluster
kubectl cluster-info # View cluster information
kubectl get nodes # List all nodes in the cluster
With kubectl
, you can manage deployments, inspect logs, scale services, and moreβall from your terminal.
π³ Docker vs Containerd + CLI Tools (ctr
, nerdctl
, crictl
)
π₯ The Rise of Docker
In the early days of containerization, Docker became the dominant container tool due to its simplicity and complete developer experience. It bundled everything:
CLI tools
Image building capabilities
Volume and networking support
Security features
The container runtime itself (powered by Containerd and runc)
Kubernetes was initially designed to orchestrate Docker containers.
π The Kubernetes Evolution
As Kubernetes gained popularity, there was demand to support other container runtimes beyond Dockerβsuch as rkt (Rocket).
This led Kubernetes to introduce the Container Runtime Interface (CRI)βa standard interface that allows Kubernetes to work with any OCI-compliant runtime.
π¦ What is OCI?
OCI stands for Open Container Initiative, which defines:
ποΈ Image Spec β how container images should be built
βοΈ Runtime Spec β how runtimes should behave
π§© Enter CRI and Docker Shim
Since Docker was developed before CRI existed, it did not natively support CRI.
To continue supporting Docker, Kubernetes introduced the "Docker Shim", a workaround that allowed Docker to work with Kubernetes via a compatibility layer.
However, this was only a temporary solutionβand Kubernetes eventually deprecated Docker support in favor of CRI-compatible runtimes like Containerd and CRI-O.
π§ Docker vs Containerd
Feature | Docker | Containerd |
Purpose | Complete container platform | Lightweight container runtime |
Includes | CLI, image builder, networking, volumes, runtime | Only the container runtime layer |
CRI-Compatible | β (via shim only) | β |
Works with Kubernetes | Yes (deprecated) | β (native) |
CLI Tools | docker | ctr , nerdctl |
π οΈ CLI Tools Explained
1. βοΈ ctr
β Containerd's Native CLI
Comes built-in with Containerd
Low-level CLI primarily for debugging
Not user-friendly or suitable for production use
ctr images pull docker.io/library/redis:alpine
ctr run docker.io/library/redis:alpine redis
2. π nerdctl
β Docker-like CLI for Containerd
Developed by the Containerd community
User-friendly, supports Docker-like syntax
Enables advanced features not available in Docker:
Encrypted container images
Lazy pulling
P2P image distribution
Image signing and verification
Kubernetes namespaces
nerdctl run --name redis redis:alpine
nerdctl run --name webserver -p 80:80 -d nginx
3. π crictl
β CRI Debug Tool
CLI tool developed by the Kubernetes community
Interacts with CRI-compatible runtimes (e.g., Containerd, CRI-O)
Used for inspecting, debugging, and monitoring
Not used for creating or managing containers directly
crictl pull busybox
crictl images
crictl ps -a
crictl exec -i -t <container_ID> ls
crictl logs <container_ID>
crictl pods
π Summary Table
Tool | Purpose | Developed By | Works With |
ctr | Low-level CLI for Containerd | Containerd community | Only Containerd |
nerdctl | Docker-like CLI for Containerd | Containerd community | Only Containerd |
crictl | Debug/Inspect CRI runtimes | Kubernetes community | Any CRI-compatible runtime |
βοΈ Setting Up Kubernetes: A Beginnerβs Guide
There are multiple ways to set up a Kubernetes clusterβranging from local development setups to full-scale production environments in the cloud.
π Kubernetes Setup Options
Environment | Tools/Services | Use Case |
π₯οΈ Local Machine | Minikube, MicroK8s, Kind | Development & learning |
π’ Production | kubeadm | Manual setup for real-world deployments |
βοΈ Cloud | GKE (Google), EKS (AWS), IBM Cloud, etc. | Managed clusters in the cloud |
π Getting Started with Minikube
For beginners, the easiest way to spin up a Kubernetes cluster on your laptop is with Minikube.
π§ What is Minikube?
Minikube is a lightweight tool that creates a single-node Kubernetes cluster on your local machine.
π Itβs designed for:
Learning Kubernetes
Testing clusters
Local app development
βοΈ How Does Minikube Work?
Minikube bundles all of Kubernetesβ core components into a pre-packaged image, providing a ready-to-go cluster in minutes.
Components it includes:
Master Node Services:
kube-apiserver
etcd
key-value storecontroller-manager
scheduler
Worker Node Services:
kubelet
(agent)container runtime
(like Docker or Containerd)
π‘ Instead of manually setting up each of these components across different machines, Minikube provides a pre-configured ISO image that includes everything.
π₯οΈ Minikube Installation Requirements
To get Minikube up and running, youβll need:
Requirement | Description |
π₯οΈ Hypervisor | A virtualization platform like Oracle VirtualBox or VMware |
π§ kubectl | Kubernetes CLI tool to interact with the cluster |
π¦ Minikube | The Minikube executable to install and run the local cluster |
Once installed, you can run commands like:
minikube start # Start a local Kubernetes cluster
kubectl get nodes # View node(s) in the cluster
kubectl get pods --all-namespaces
Pods
π¦ What is a Pod in Kubernetes?
A Pod is the smallest thing you can run in Kubernetes.
It usually contains one containerβyour app.
π§ Simple Setup: One Cluster β One Node β One Pod
You start with:
π§© Cluster (Kubernetes)
π₯οΈ Node (Machine where apps run)
π¦ Pod (Your app wrapped in a container)
π§Ύ Command to create a Pod:
kubectl run myapp --image=nginx
This command:
Creates a Pod named
myapp
Runs the Nginx web server inside it
π Check the Pod:
kubectl get pods
π Scale Up: Add More Pods
As traffic grows, we want to run multiple copies of the app (Pods).
We do this by creating a Deployment that manages scaling.
π§Ύ Create a Deployment with one replica:
kubectl create deployment myapp --image=nginx
π§Ύ Scale to 3 Pods (replicas):
kubectl scale deployment myapp --replicas=3
π Check running Pods:
kubectl get pods
You should see 3 pods like:
myapp-xxxxxxx-abcde
myapp-xxxxxxx-fghij
myapp-xxxxxxx-klmno
π Scale Down: Reduce to 1 Pod
When traffic is low, reduce the number of Pods to save resources.
π§Ύ Scale down to 1 Pod:
kubectl scale deployment myapp --replicas=1
π Check again:
kubectl get pods
Now only one Pod should be running.
Pods With YAML - Creating Pods using a YAML based configuration file
Kubernetes uses YAML files as inputs for the creation of objects such as pods, replicas, deployments, services. All of this follows a similar structure. A Kubernetes defination file always contains four top-level fields, the apiVersion, kind, metadata, and spec. These are the top level or root level properties.
apiVersion: This is the version of the kubernetes API we are using to create the object. Depending on what we are trying to create, we must use the right API version. For now, since we are working on pods, we will set the API version as v1. Few other possible values for this field are apps/v1, beta, extensions/v1, etc.
kind: Kind refers to the type of object we are trying to create. Which in this case happened to be a Pod. Some other possible values here could be ReplicaSet, Deployment, or Service.
metadata: Metadata is the data about the object, like its name, labels, etc. Under the metadata what we put a dictionary. Name and Label are the child of metadata. Under the metadata, the name is a string value, like name: myapp-pod
. And the Label is further a dictionary (Label is a dictionary within the metadata dictionary).
Note: Under metadata we can only specify name or label or anything else that Kubernetes expects to be under metadata. But under Labels, we can add any kind of key-value pairs.
spec (Specification section): Depending on the object we are going to create, this is where we would provide additional information to Kubernetes pertaining to that object. Spec is a dictionary, so we added a property under it called containers. Containers is a list or an array. The reason this property is a list because the pods can have multiple containers within them. (Although we are adding a single item in the list).
Once the file is created, run the command kubectl create -f <file-name>
and Kubernetes creates a pod.
kubectl get pods
use to see list of pod available.
kubectl describe pod <pod-name>
to see detailed information about pod when it was created.
Example: pod.yaml
After creating yaml file, Need to create the pod object, and for that we can use, create
or, apply
command. Both work as same.
kubectl create -f pod.yaml
or, kubectl apply -f pod.yaml
βΈοΈ Kubernetes Controllers
Controllers are the brain behind Kubernetes.
They are background processes that monitor Kubernetes objects and respond accordingly to maintain the desired state.
π Replication Controller
One important controller is the Replication Controller.
β What is a Replica? Why Use a Replication Controller?
Letβs go back to our first scenario where we had a single Pod running our application.
πΉ What if the application crashes and the Pod fails?
πΉ Users will no longer be able to access the application.
To prevent downtime, we need to have more than one instance (or Pod) running at the same time.
That way, if one fails, others keep the application alive.
β Role of the Replication Controller
Helps run multiple instances of a single Pod.
Ensures high availability of your application.
Monitors and maintains the desired number of Pods at all times.
Even if one Pod fails, it automatically replaces it with a new one.
π€ Can It Be Used for Just One Pod?
Yes!
Even if you want to run just one Pod, the Replication Controller is useful because:
It ensures the Pod is recreated if it fails.
You donβt have to manually restart it.
π Scaling & Load Balancing
The Replication Controller helps:
Create multiple Pods to handle more users.
Balance load across different Pods and nodes in the cluster.
Automatically deploy more Pods when demand increases.
Distribute Pods across multiple nodes if needed.
π ReplicaSet vs Replication Controller
πΉ Both serve the same purpose: maintaining a desired number of Pods.
πΉ But Replication Controller is the older technology.
ReplicaSet is the newer and recommended controller.
There are minor differences in how they work internally.
Going forward, we will stick to ReplicaSets in all demos and implementations.
Replication Controller
Any Kubernetes definition file, we have four sections, apiVersion, kind, metadata, and spec. The API version is specific to what we are creating. In this case, Replication Controller is supported in Kubernetes API version v1. The kind is ReplicationController, So far it is very similar to how we created a Pod in the previous section. Spec (Specification) is the most crucial part. For any Kubernetes definition file, the spec section defines whatβs inside the object we are creating. In this case, we know the Replication Controller creates multiple instances of a Pod. But what Pod? We create a template under spec to provide a Pod template to be used by the Replication Controller to create replicas. For that we can use all of our previous definition file written for Pod creation except apiVersion, and kind.
We have nested two definition files together. The Replication Controller being the parent and the Pod defination being the child. But still we didnβt mentioned how many replicas we need in the Replication Controller. For that we need to add another property to the spec called replicas and input the number of replicas under it.
Now, Creating Replication Controller,
kubectl create -f rc-definition.yml
To view list of created replication controller,
kubectl get replicationcontroller
To see the pods created by the replication controller,
kubectl get pods
Letβs Now look into ReplicaSet
It is very similar to the Replication Controller, But Look into the apiVersion, We need to set it apps/v1
, Otherwise there will be an error in ReplicaSet. One more thing is ReplicaSet requires a selector definition. The selector section helps the replica set identify what pods fall under it.
But why we need to specify what pods fall under it, if we providing the contents of the pod definition file itself in the template?
β Itβs because ReplicaSet can also manage Pods that were not created as part of the ReplicaSet creation. For example, there are pods created before the creation of the ReplicaSet that match labels specified in the selector. The ReplicaSet also take those pods into consideration when creating the replicas.
The selector is one of the major differences between ReplicationController and ReplicaSet. Selector is not a required field in case of ReplicationController, but it is still available. When we skip this, as we did in the previous example, it assumes it to be the same as the labels provided in the Pod definition file.
In case of ReplicaSet, User input is required for the property, and it has to be written in the form of matchLabels. The match labels selector simply matches the labels specified under it to the labels on the Pod. (Also there are other options in selector for ReplicaSet which are not available in ReplicaController).
Similar command to creating and viewing Pods
kubectl create -f replicaset-difination.yml
kubectl get replicaset
kubectl get pods
kubectl delete replicaset myapp-replicaset
, to delete the ReplicaSet as well as all Underlying PODskubectl describe replicaset myapp-replicaset
, to get more information about replicaset
Labels and Selectors
Why do we label our Pods and objects in Kubernetes ?
Let us look at a simple scenario, Say we deployed three instances of our front end web application as three Pods. We would like to create a ReplicationController of ReplicaSet to ensure that we have three active Pods at any time. And that is one of the use cases of ReplicaSets, we can monitor existing Pods if we have them already created as it. In case they are not created, the ReplicaSet will create them for us. The ReplicaSet is to monitor the Pods and if any of them were to fail, deploy new ones. The ReplicaSet is infact a process that monitor the Pods.
Now how does the ReplicaSet know what Pods to monitor?
There colud be hundreds of other Pods in the Cluster running different applications. This is where labeling our Pods during creation comes in handy.
We could now provide these labels as a filter for ReplicaSet. Under the Selector section we use the matchLabels filter and provide the same label that we have used while creating the Pods. This way ReplicaSet know which Pod need to monitor. The same concept of labels and selectors is used in many other places throughout the Kubernetes.
In the ReplicaSet specification section, we learned that there are three sections, template, replicas, and selector. We need three replicas and we have updated our selector based on the previous discussed section.
Suppose we have the same scenario where we have three existing Pods that were created already. And we need to create a ReplicaSet to monitor the Pods to ensure there are a minimum of three running at all times.
When a replication controller is created, it is not going to deploy a new instance of pod as three of them with matching labels are already created. In that case do we really need to provide a template section in the ReplicaSet specification since we are not expecting the ReplicaSet to create a new pod on deployment?
β Yes we do, Because in case on of the pods were to fail in the future, the ReplicaSet need to create a new one to maintain the desired number of pods. And for the ReplicaSet to create a new pod, the template definition section is required.
Scale Replica Set
Letβs now look how we can scale ReplicaSet. Say we started with three replica, and in the future we decided to scale to six.
Option 1:
We can update the number of replicas in the ReplicaSet definition file, and then run the following command
kubectl replace -f replicaset-definition.yml
or,
kubectl edit replicaset myapp-replicaset
It will opens up the running configuration of the replicaset in a text editor.
Option 2:
kubectl scale --replicas=6 -f replicaset-definition.yml
, This will scale to 6 but not update in the definition file.
Option 3:
kubectl scale --replicas=6 replicaset myapp-replicaset
, this is TYPE/NAME format, wherereplicaset = TYPE
andmyapp-replicaset = NAME
. For TYPE, we can users
in place ofreplicaset
.
Kubernetes Deployments
Deploying an Application in a Production Environment using Kubernetes
When deploying a web server in a production environment, we often need multiple instances of the application running simultaneously β not just one β for reasons like load balancing, high availability, and fault tolerance.
Additionally, when new versions of the application become available on a Docker registry, weβd like to upgrade these Docker instances seamlessly. However, upgrading all instances at once can disrupt users who are currently accessing the application. To prevent this, we prefer to upgrade them gradually, one after the other. This controlled upgrade mechanism is known as a Rolling Update.
Rolling Updates
With rolling updates, new versions of the application are deployed incrementally, replacing the old versions one pod at a time. This ensures minimal downtime and provides the opportunity to monitor the system for any issues during the rollout.
Rollbacks
Sometimes, a newly rolled-out update may result in unexpected errors. In such cases, we need the ability to roll back to the previous stable version quickly. Kubernetes makes this easy using its rollback feature.
Pausing and Resuming Deployments
There may be scenarios where we want to apply multiple changes to our environmentβsuch as:
Upgrading the web server version
Scaling the number of instances
Modifying resource allocations (CPU, memory, etc.)
Rather than applying each change immediately, Kubernetes allows us to pause the deployment, make all necessary changes, and then resume it so that all changes are rolled out together. This prevents intermediate states and ensures a clean deployment transition.
Kubernetes Deployment: High-Level Overview
So far, weβve discussed Pods, which are the smallest deployable units in Kubernetes and encapsulate containers.
To run multiple pods, we use:
ReplicaSets: Ensure a specified number of pod replicas are running at all times.
ReplicationControllers: An older version of ReplicaSets.
But for higher-level management, Kubernetes provides the Deployment object.
Why Use Deployments?
Kubernetes Deployments offer powerful capabilities:
Manage ReplicaSets automatically
Enable rolling updates
Support rollbacks
Allow pausing and resuming deployments
Creating a Deployment
To create a deployment:
Prepare a deployment definition YAML file.
The structure is similar to a ReplicaSet file, except:- The
kind
is set to"Deployment"
instead of"ReplicaSet"
.
- The
Use the
kubectl create
command to apply the file:kubectl create -f deployment-definition.yaml
To verify the deployment:
kubectl get deployments
The deployment automatically creates a ReplicaSet, which can be viewed using:
kubectl get replicaset
The ReplicaSet then creates the pods, which can be listed with:
kubectl get pods
To view all the related resources at once:
kubectl get all
-β One line command to create a Deployment
kubectl create deployment <dep-name> --image=<image-name> --replicas=3
Kubernetes Deployments: Update and Rollback
π Understanding Rollouts and Versioning
When we first create a Deployment, Kubernetes triggers a rollout, which in turn creates a Deployment revision.
The first deployment is considered Revision 1.
When the application is upgraded (e.g., a new container version is deployed), a new rollout is triggered, and a new revision is created β e.g., Revision 2.
This versioning system helps track changes made to the deployment and allows us to roll back to any previous version if necessary.
Useful Commands:
π’ Check rollout status
kubectl rollout status deployment/myapp-deployment
π View rollout history
kubectl rollout history deployment/myapp-deployment
π οΈ Deployment Strategies
Assume we have 5 replicas of our web application running.
1. Recreate Strategy
All old pods are terminated first.
Then, new pods with the updated version are created.
This causes downtime β the app is unavailable during the transition.
β οΈ Not the default strategy.
2. Rolling Update Strategy (β Default)
One pod at a time is terminated and replaced with a new one.
Ensures zero downtime during the update process.
Provides a seamless user experience.
π§ Updating a Deployment
You can update deployments in several ways:
1. Edit the Deployment YAML
For changes such as:
Container image version
Labels
Number of replicas
Resource limits
kubectl apply -f deployment-definition.yaml
- This command triggers a new rollout, creating a new ReplicaSet behind the scenes.
2. Update Image via CLI
To update the image directly using kubectl
:
kubectl set image deployment/myapp-deployment nginx-container=nginx:1.9.1
β οΈ Note: This updates the deployment in Kubernetes, but does not update your local YAML file. Keep this in mind for version control.
π Viewing Deployment Details
Use the following command to inspect the details of a deployment:
kubectl describe deployment myapp-deployment
This provides:
Rollout history
Strategy used
ReplicaSets managed
Events and status
βοΈ How Updates Work Internally
When you create a deployment (e.g., with 5 replicas), Kubernetes:
Creates a ReplicaSet
Which in turn creates 5 pods
When you update the deployment:
Kubernetes creates a new ReplicaSet
Begins deploying updated pods there
Simultaneously, starts terminating old pods from the previous ReplicaSet (rolling update)
You can observe these changes using:
kubectl get replicasets
βͺ Rolling Back a Deployment
If a newly deployed update is found to be faulty, you can undo the deployment and revert to the previous version:
kubectl rollout undo deployment/myapp-deployment
Kubernetes will:
Terminate the pods in the new ReplicaSet
Spin up pods from the previous ReplicaSet
This ensures that your application returns to its last known good state quickly and efficiently.
kubectl create -f deployment.yaml --record
To record the cause of change.
kubectl edit deployment myapp-deployment --record
To edit in a running deployment.
kubectl describe deployment myapp-deployment
To see the details of deployment.
π Kubernetes Networking Basics
π§© Single Node Cluster
Letβs begin by understanding networking in a single-node Kubernetes cluster.
Suppose your node (e.g., a VM or minikube instance) has an IP address:
192.168.1.2
.If you're using Minikube, this IP refers to the VM inside your hypervisor, not your actual laptop IP (which might be something like
192.168.1.10
).Inside this node, you create a Pod, which hosts a container.
β Important Distinction:
In Docker, containers are assigned individual IPs.
In Kubernetes, IPs are assigned to Pods, not directly to containers.
For example:
Your pod may get an IP like
10.244.0.2
β this is from an internal virtual network Kubernetes creates (e.g.,10.244.0.0/16
).Every Pod gets a unique internal IP, and Pods can communicate with one another via these IPs within the same node.
However:
Pod IPs are ephemeral (i.e., they may change when Pods are recreated).
Therefore, relying directly on Pod IPs for communication is not recommended.
π Kubernetes Cluster Networking Goals
Kubernetes networking has core principles:
All Pods can communicate with each other without NAT (Network Address Translation).
All nodes can communicate with all Pods and vice versa without NAT.
π§ Multi-Node Networking Challenges
Letβs scale up to a multi-node cluster (e.g., two nodes):
Node 1 IP:
192.168.1.2
Node 2 IP:
192.168.1.3
Initially, if both nodes assign Pods IPs from the same internal network range (e.g., 10.244.0.0
), there will be:
IP conflicts
Broken communication across nodes
This is because:
Kubernetes does not set up inter-node networking by default.
It's the responsibility of the cluster administrator to install a Container Network Interface (CNI) plugin that fulfills Kubernetesβ networking requirements.
π οΈ Network Plugins (CNI Solutions)
To solve networking issues in a Kubernetes cluster, we use network plugins like:
Plugin | Description |
Calico | Powerful and widely used, supports network policy |
Flannel | Simple and easy to configure |
Weave Net | Common in learning environments like Play-with-K8s |
Cilium | Advanced security and observability with eBPF |
VMware NSX-T | Suitable for VMware environments |
Cisco ACI, Big Cloud Fabric | Enterprise networking solutions |
β In many hands-on labs and demo setups (like Mumshad Mannambeth's course), Calico is used.
πΊοΈ How Cluster Networking Works with Calico
Once a plugin like Calico is installed:
Each node is assigned a unique Pod network range, e.g.:
Node 1 β
10.244.1.0/24
Node 2 β
10.244.2.0/24
Pods within each node are assigned unique IPs from these subnets:
10.244.1.2
on Node 110.244.2.2
on Node 2
Calico handles:
IP address assignment
Routing traffic between nodes
Enabling Pod-to-Pod communication across the cluster
The result:
A virtual network spanning all Pods and nodes
No NAT is required
Direct communication is possible using Pod IPs
π‘ Kubernetes Services Explained
π What is a Kubernetes Service?
Kubernetes Services enable communication between various components of an application β both internally (within the cluster) and externally (from outside the cluster).
In a microservices architecture, we may have:
A frontend pod group (serving web pages),
A backend pod group (handling business logic),
And a database or external system connection.
β‘οΈ Services help connect these components:
Frontend to backend
Backend to database
External users to frontend
Thus, Services enable loose coupling between microservices.
π Accessing Pods Externally
Letβs take a typical scenario:
A web application runs inside a Pod.
The Pod has an internal IP like
10.244.0.2
(not accessible from your laptop on, say,192.168.1.10
).The Kubernetes node hosting the Pod has an IP
192.168.1.2
.
Now, how do you, as an external user, access the web page?
You canβt directly access 10.244.0.2
because itβs inside the clusterβs virtual network. You could SSH into the node and curl
http://10.244.0.2
, but thatβs not ideal.
β Solution: Kubernetes Service
A Service acts as a bridge, mapping requests from outside to the internal Pod.
π§± Kubernetes Service Types
Type | Description |
NodePort | Exposes the Pod via a port on the node, accessible from outside the cluster |
ClusterIP | Internal-only service to connect Pods within the cluster |
LoadBalancer | Provisions an external load balancer (cloud providers only) |
π NodePort Service (External Access)
βοΈ How it works:
The web server inside the Pod listens on port 80 β this is the
targetPort
.The Service listens on an internal
port
(also usually 80).The Node listens on a NodePort (e.g.,
30008
), which is open to external users.
External Request --> Node IP:NodePort --> Service Port --> Pod TargetPort
--> 192.168.1.2:30008 --> 80 --> 80
π― Valid NodePort range: 30000β32767
π NodePort Service YAML Example
apiVersion: v1
kind: Service
metadata:
name: myapp-service
spec:
type: NodePort
selector:
app: myapp
ports:
- port: 80 # Port on the Service
targetPort: 80 # Port inside the Pod
nodePort: 30008 # Exposed Port on the Node
π Note:
If
targetPort
is omitted, it's assumed to be the same asport
.If
nodePort
is omitted, Kubernetes will assign a random port within range.
π Linking Service to Pods
Services use labels and selectors to identify which Pods to route traffic to.
Example:
selector: app: myapp
All Pods with this label (
app: myapp
) become endpoints of the service.
π Service Load Balancing
If you have multiple Pods running the same application (for scalability and high availability), and they share the same labels, the Service:
Automatically selects all of them
Distributes traffic randomly among them
Acts as a built-in load balancer
No extra config is needed from you!
π Multi-Node Cluster
Imagine you have:
Three nodes (
192.168.1.2
,192.168.1.3
,192.168.1.4
)Pods with the same label (
app: myapp
) distributed across them
When you create a NodePort service:
Kubernetes automatically exposes the same NodePort (e.g., 30008) on all nodes
You can now access your app via any node in the cluster:
curl http://192.168.1.2:30008 curl http://192.168.1.3:30008 curl http://192.168.1.4:30008
β Summary:
Works with one Pod, multiple Pods, or Pods across multiple nodes
No additional config required
Highly resilient and scalable
π Service Commands
Purpose | Command |
Create a service | kubectl apply -f service-definition.yaml or, kubectl create -f <File.yaml> |
View all services | kubectl get services or, kubectl get svc |
Get detailed info | kubectl describe service myapp-service |
Test access | curl http://<NodeIP>:<NodePort> |
Tells you the node IP = 192.168.49.2 | kubectl get nodes -o wide |
Returns http://192.168.49.2:30008 | minikube service myapp-service --url |
π§© Kubernetes Services β ClusterIP
π What is ClusterIP?
ClusterIP
is the default type of Kubernetes service.
It enables internal communication between components within the cluster (Pod-to-Pod communication). Itβs not accessible externally from outside the cluster.
π¦ Use Case Example:
Frontend Pods need to call Backend Pods.
Backend Pods need to connect to a Redis or MySQL service.
All these are handled internally via ClusterIP services.
π§ Problem:
Pod IPs are dynamic β they change when Pods restart. So we canβt rely on direct Pod IPs for internal communication.
β Solution: Use a ClusterIP Service
It groups all relevant Pods under a common internal IP and DNS name.
Any Pod inside the cluster can use that service name or ClusterIP to access those Pods.
π§± ClusterIP Service YAML Example
apiVersion: v1
kind: Service
metadata:
name: backend-service
spec:
type: ClusterIP
selector:
app: myapp
tier: backend
ports:
- port: 80 # Port exposed by the service (used internally)
targetPort: 80 # Port exposed inside each backend Pod
π Selector connects the Service to Pods with matching labels:
app: myapp
tier: backend
π Access from other Pods:
curl http://backend-service:80
or just:
curl http://backend-service
π Built-in Load Balancing:
ClusterIP also distributes traffic randomly across all Pods that match the selector β just like NodePort β enabling internal load balancing.
π§ͺ Commands:
Purpose | Command |
Create ClusterIP | kubectl apply -f clusterip-service.yaml |
View Services | kubectl get services |
Describe Service | kubectl describe service backend-service |
βοΈ Kubernetes Service β LoadBalancer
π What is LoadBalancer?
LoadBalancer exposes your service externally to the internet.
It works only in supported cloud providers (e.g., GCP, AWS, Azure).
Automatically provisions a cloud-based load balancer with an external IP.
π¦ Use Case:
You want users to access your app publicly at a domain like:
http://myapp.com
π§ How It Works:
LoadBalancer β NodePort β Service Port β Pod TargetPort
External IP (cloud LB) β NodePort (internal) β Pod
π LoadBalancer YAML Example:
apiVersion: v1
kind: Service
metadata:
name: frontend-service
spec:
type: LoadBalancer
selector:
app: myapp
tier: frontend
ports:
- port: 80 # Port exposed via the LoadBalancer
targetPort: 80 # Port inside the Pod
π Output of kubectl get svc
:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
frontend-service LoadBalancer 10.96.105.30 35.232.101.22 80:30082/TCP 3m
π‘ DNS Setup:
Point your domain (myapp.com
) to the EXTERNAL-IP using a DNS provider.
π If you're on local setup and want LoadBalancer-like behavior:
- Use MetalLB or minikube tunnel to simulate a LoadBalancer.
π§ͺ Commands:
Purpose | Command |
Create LoadBalancer svc | kubectl apply -f loadbalancer-service.yaml |
View Services | kubectl get services |
Test external access | curl http://<EXTERNAL-IP> |
β Kubernetes Service Types β Recap
Type | Scope | Access | Cloud Required | Use Case |
ClusterIP | Internal only | Within cluster (Pods) | β No | Frontend β Backend, DB access |
NodePort | External | NodeIP:Port (fixed range) | β No | External dev/test environment |
LoadBalancer | External | Public IP from Cloud LB | β Yes | Production public access |
Subscribe to my newsletter
Read articles from Arindam Baidya directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
