This comprehensive guide introduces Kubernetes, an open-source system for automating the deployment, scaling, and management of containerized applications. The resource begins by explaining fundamental concepts like pods, deployments, and services, detailing how they work together within a Kubernetes cluster. It proceeds with practical demonstrations, including building custom Docker images, pushing them to Docker Hub, and deploying them within Kubernetes. The guide further illustrates how to establish communication between different deployments and concludes by showcasing how to alter the container runtime within a Kubernetes environment.
Kubernetes: Container Orchestration and Management Essentials
Kubernetes is an open-source container orchestration system that has become the de facto standard for deploying containerized applications into production environments. It simplifies the process of taking containerized applications and deploying them to production.
What Kubernetes Manages: Kubernetes automates various aspects of application deployment and management across different servers, whether they are physical (bare metal) or virtual. Key responsibilities include:
- Automatic Deployment: Deploying containerized applications across multiple servers without manual intervention.
- Load Distribution: Distributing the application load across these multiple servers, which helps in efficient resource utilization and prevents under or over-utilization.
- Auto-scaling: Automatically scaling deployed applications up or down by increasing or decreasing the number of containers based on demand.
- Monitoring and Health Checks: Continuously monitoring the health of containers and automatically replacing any failed containers without requiring manual intervention.
- Container Runtime Management: It uses a specific container runtime to deploy applications, supporting options like Docker, CRI-O, and containerD, meaning Kubernetes can operate even without Docker installed.
Core Components and Terminology:
- Pods: In Kubernetes, the smallest deployable unit is a “pod”. A pod can contain one or multiple containers, shared volumes, and shared network resources, including a shared IP address. While a single container per pod is the most common scenario, multiple containers can exist in the same pod if they are tightly coupled and depend heavily on each other within the same namespace. Each pod must be located on a single server and cannot spread its containers across different servers in a Kubernetes cluster. Pods can be created, removed, or moved between nodes automatically by Kubernetes.
- Nodes: A Kubernetes cluster consists of “nodes,” which are servers (either bare metal or virtual). Nodes typically house pods and can be located in different data centers, though they are usually kept close for efficiency. Kubernetes automatically deploys pods onto different nodes.
- Kubernetes Cluster: This is a collection of nodes managed together. Within a cluster, there is one master node (also referred to as the “control plane”) and one or more worker nodes.
- Master Node: The master node manages the worker nodes, distributing load and overseeing the cluster’s operations. It runs system-level pods responsible for the Kubernetes cluster’s general work, rather than client applications.
- Worker Nodes: These nodes are where your client application pods are deployed and run.
Services Running on Nodes:
- On Each Node (Master and Worker):
- kubelet: This service communicates with the API Server on the master node.
- kube-proxy: Responsible for network communication within each node and between nodes.
- Container Runtime: Runs the actual containers inside each node. Supported runtimes include Docker, CRI-O, and containerD.
- On Master Node Only:
- API Server: The main point of communication within the Kubernetes cluster. It allows external tools like kubectl to manage the cluster remotely via a REST API over HTTPS.
- Scheduler: Responsible for planning and distributing the workload (pods) across different nodes in the cluster.
- Cube controller manager: A central component that controls what happens on each node in the cluster.
- Cloud controller manager: Handles interaction with cloud service providers where the Kubernetes cluster might be running, especially for services like load balancers.
- etcd: Stores all logs related to the entire Kubernetes cluster’s operation as key-value pairs.
- DNS service: Responsible for name resolution within the cluster, allowing deployments to connect to each other by name.
Managing Kubernetes:
- kubectl: This is a separate command-line tool used to connect to and manage a Kubernetes cluster remotely. It communicates with the API Server on the master node.
- Approaches to Configuration:Imperative Approach: Involves using kubectl commands directly to create and manage deployments and services.
- Declarative Approach: The preferred method, where YAML configuration files are created to describe all the details for deployments and services, and then applied using the kubectl apply command.
Deployment and Scaling:
- Deployments: Deployments are responsible for creating, scaling, and managing multiple identical pods. They ensure that a desired quantity of pods is running and can be used to modify configurations or update application versions.
- Replica Sets: A deployment implicitly creates and manages “replica sets,” which are sets of replicas (pods) of your application. Replica sets handle the actual creation and management of pods to match the desired state defined by the deployment.
- Scaling: Deployments can be easily scaled up or down by modifying the desired number of replicas. Kubernetes automatically creates or terminates pods to match the new replica count.
- Rolling Updates: Kubernetes supports rolling updates as a deployment strategy, allowing for smooth, interruption-free rollouts of new application versions. New pods with the updated image are created while old ones are gradually terminated, ensuring continuous service availability.
Networking and Services:
- Pod IP Addresses: Pods receive internal IP addresses, which are dynamic and not directly accessible from outside the Kubernetes cluster.
- Services: To enable stable access to deployments, Kubernetes uses “services.” Services provide a stable IP address and load balancing across the pods within a deployment.
- ClusterIP: This service type creates a virtual IP address that is only accessible from inside the Kubernetes cluster. It’s used for inter-deployment communication (e.g., a frontend connecting to a backend database).
- NodePort: This service type exposes a deployment on a static port on each node’s IP address. This allows access to the deployment from outside the cluster via the node’s IP and the specified NodePort.
- LoadBalancer: Typically used in cloud environments, this service type provisions an external IP address from the cloud provider, which acts as a single entry point for the entire Kubernetes cluster for a specific deployment. It provides load balancing and is accessible from the outside world.
- Inter-Deployment Communication: Deployments can connect to each other using the name of their respective services, facilitated by Kubernetes’ internal DNS service, which resolves service names to their ClusterIP addresses.
Local Cluster for Learning: For local testing and learning, tools like MiniKube can be used to create a single-node Kubernetes cluster on a personal computer. This single node acts as both the master and worker node. MiniKube can run with various virtual machine or container managers such as VirtualBox, VMware, Docker, or Hyper-V.
Kubernetes Rolling Update Strategy
Kubernetes primarily supports a deployment strategy known as Rolling Update.
Rolling Update Strategy: This strategy is designed to ensure a smooth and uninterrupted rollout of new application versions into a production environment. When a new version of an application is released, Kubernetes automatically handles the update process by:
- Gradual Replacement: New pods with the updated application image are created incrementally, while the older version pods are still running.
- Continuous Availability: This method ensures that the service remains continuously available during the update, as old pods are only terminated gradually after new pods are successfully brought online and are ready to serve traffic.
- Automated Process: Kubernetes manages this process automatically, replacing old replicas with new ones one by one until all previous replicas are terminated and the new version is fully deployed.
The status of a rolling update can be monitored using the K rollout status command. The process typically shows messages indicating how many new replicas have been updated and how many old replicas are pending termination, ultimately confirming successful rollout once all updates are complete. This strategy also allows for rolling back to a previous version of the application if needed.
Kubernetes Container Runtimes: Choices and Changes
Container runtimes are essential components in a Kubernetes cluster, responsible for running the actual containers that host applications. Kubernetes is designed to be flexible and is not tied to a single container runtime, supporting various options.
Supported Container Runtimes: Kubernetes supports several container runtimes, including:
- Docker: While commonly associated with containers, Docker is just one of the supported runtimes.
- CRI-O: An open-source container runtime purpose-built for Kubernetes.
- containerD: Another industry-standard container runtime.
A specific container runtime, such as Docker or CRI-O, must be running on each server (node) included in the Kubernetes cluster. The key takeaway is that Kubernetes can be utilized entirely without Docker installed, as it supports other runtimes like CRI-O and containerD.
Container Runtimes in a Kubernetes Node: In a Kubernetes cluster, services like kubelet, kube-proxy, and the container runtime itself are present on every node (both master and worker nodes). The container runtime’s specific job is to run the actual containers inside each node.
For instance, when a pod is created, the container runtime (e.g., Docker) within the Kubernetes node is requested to pull the necessary image (e.g., Nginx) from a repository like Docker Hub and create the corresponding container based on that image. All containers inside a pod also share network resources and a shared IP address, which is managed by the container runtime.
When Docker is the container runtime, each pod typically involves the creation of a “pause container” in addition to the application container. This pause container is responsible for holding the namespace of the specific pod, allowing all other containers within that pod to share that namespace.
Changing Container Runtime (Demonstrated with MiniKube): The source describes a practical demonstration of changing the container runtime from Docker to CRI-O within a local MiniKube Kubernetes cluster. This process involves:
- Stopping and Deleting the Current Cluster: The existing MiniKube setup needs to be stopped (mini cube stop) and then deleted (mini cube delete) to remove all traces of the previous configuration.
- Starting a New Cluster with the Desired Runtime: A new MiniKube cluster is then started, explicitly specifying the desired container runtime using the –container-runtime option (e.g., mini cube start –driver virtualbox –container-runtime cri-o). While Docker is a common driver for MiniKube, it’s noted that changing the container runtime to CRI-O or containerD might not work if Docker is used as the MiniKube driver itself, suggesting alternatives like VirtualBox.
- Verifying the Change: After the new cluster starts, the container runtime can be verified.
- If Docker was the previous runtime, docker ps would list running containers.
- If the runtime is changed to CRI-O, docker ps will indicate that it cannot connect to Docker, confirming Docker is not running in the node. Instead, sudo CRI CTL ps should be used to list the containers managed by CRI-O. This command will show system containers (like kube-proxy, core-dns) as well as application containers within the nodes, confirming that CRI-O is now managing them.
This demonstrates Kubernetes’ flexibility, allowing users to choose or change the underlying container runtime without necessarily altering the application deployment process.
Kubernetes Services: Concepts, Types, and Connectivity
Kubernetes Services are a fundamental networking concept that enable reliable and accessible communication with and between your applications deployed within a cluster. They abstract away the dynamic nature of Pod IPs, providing a stable network identity for a set of Pods.
Purpose of Services Services allow you to:
- Connect to Deployments: They provide a single, stable IP address or hostname to connect to one or more pods belonging to a deployment, even as pods are created, deleted, or moved.
- Load Balance Traffic: Services automatically distribute incoming requests across the multiple pods they manage, ensuring efficient resource utilization and high availability.
- Enable Inter-Application Communication: Different applications (deployments) within the Kubernetes cluster can communicate with each other using stable service names, abstracting away the underlying pod IPs.
- Expose Applications Externally: Services can be configured to make applications accessible from outside the Kubernetes cluster.
Types of Services Kubernetes offers different service types, each designed for specific access patterns:
- ClusterIP (Default Type):
- Purpose: This is the default service type, primarily used for internal communication within the Kubernetes cluster.
- Access: A ClusterIP service creates a virtual IP address that is only reachable from within the cluster. It’s ideal for backend services like databases that should not be exposed to the outside world.
- Traffic Flow: Kubernetes distributes the load across the pods assigned to the service using this single Cluster IP. For example, if you have a database deployment, a ClusterIP service allows other deployments in the cluster to connect to it using this stable IP, without exposing it externally.
- Dynamic Nature: The IP address of a pod is dynamic and should not be relied upon for connection. The ClusterIP provides a stable address.
- Configuration Example: An internal container port (e.g., Nginx’s default port 80) can be exposed to an internal service port (e.g., 8080) for other applications within the cluster to use.
- NodePort:
- Purpose: This service type exposes a deployment at a static port on each node’s IP address.
- Access: It makes the service accessible from outside the cluster using the IP address of any node in the cluster and a specific, randomly generated port (typically in a high range like 30000-32767), or a pre-defined port if explicitly set.
- Traffic Flow: External requests arriving at the node’s IP and the NodePort are routed to the cluster IP and then load-balanced across the underlying pods.
- Use Case: Suitable for demonstrating external access in local development environments like MiniKube.
- LoadBalancer:
- Purpose: This service type integrates with cloud providers to automatically provision an external load balancer.
- Access: When deployed in a cloud environment (e.g., Amazon, Google Cloud), the cloud provider assigns an external IP address to the service, making it publicly accessible. In a local MiniKube setup, the external IP might remain “pending,” but it behaves similarly to a NodePort service, allowing connection via the node’s IP and a generated port.
- Traffic Flow: The cloud-managed load balancer directs external traffic to the service’s ClusterIP, which then distributes it among the pods.
- Managed by Cloud Controller Manager: The assignment of LoadBalancer IP addresses is usually managed by the cloud controller manager service running on the master node.
Connecting Deployments and Service Resolution Services are linked to deployments using selectors and labels. When a service is created, it specifies labels that match the labels defined in the pod template of a deployment. This allows the service to identify and manage the correct set of pods.
Crucially, Kubernetes includes an internal DNS service responsible for name resolution within the cluster. This DNS service allows deployments to connect to each other by using the service name as a static hostname, rather than relying on dynamic Cluster IPs. For instance, a web application in one deployment can connect to an Nginx service in another deployment simply by using “Nginx” as the hostname. The DNS service resolves “Nginx” to the Cluster IP of the Nginx service, and Kubernetes then balances the traffic to the appropriate Nginx pods. This ensures that even if the Cluster IP changes (which is rare but possible), the service name remains constant, providing reliable inter-application communication.
MiniKube for Local Kubernetes Development
For local Kubernetes development, the primary tool discussed in the sources is MiniKube. It provides a free and convenient way to set up a small Kubernetes cluster directly on your computer, serving as a personal playground for learning and testing applications.
MiniKube: Your Local Kubernetes Cluster
- Single-Node Cluster MiniKube creates a single-node Kubernetes cluster where this one node acts as both the master node and a worker node. This simplifies the setup for development and testing purposes.
- Prerequisites To run MiniKube successfully, you need a virtual machine manager or a container manager installed on your computer. Supported options include VirtualBox, VMware, Docker, Hyper-V, or Parallels.
- For Windows users, Hyper-V is recommended as it’s often available out of the box.
- For macOS users, VirtualBox (free and open source), Parallels, or VMware Fusion are suggested.
- While MiniKube can run as a container inside Docker, it’s generally not recommended for local development because it has limitations, such as difficulties in changing the container runtime (e.g., to CRI-O or containerD). The VirtualBox driver is often used for demonstrations.
- Starting a Cluster You can start a MiniKube cluster with a simple command: minikube start. You can also specify the driver to use, for example, minikube start –driver virtualbox. By default, MiniKube often uses Docker as its container runtime inside the node unless specified otherwise.
- Verifying Cluster Status After starting, you can check the cluster’s status using minikube status, which should indicate that the host, kubelet, API server, and kube config are all running. You can also get the node’s IP address with minikube IP.
Interacting with Your Local Cluster Once your MiniKube cluster is running, you’ll primarily use the kubectl (or k alias) command-line tool to interact with it and deploy applications.
- kubectl (or k) This tool allows you to manage the Kubernetes cluster, including creating, scaling, and deleting deployments and services. It connects to the API server service on the master node via REST API over HTTPS. You can create an alias for kubectl (e.g., alias k=’kubectl’) for shorter commands, though this alias is usually temporary for the current terminal session.
- Accessing the Node You can SSH into the MiniKube node (which is a virtual machine) using ssh docker@<minikube-ip> (default username is ‘docker’, default password is ‘tcuser’) to inspect its internal state, such as checking running Docker containers (if Docker is the runtime) or CRI-O containers.
- Deploying Applications You can create deployments and services using kubectl commands (imperative approach) or, more commonly, by defining YAML configuration files (declarative approach) and applying them using kubectl apply -f <filename.yaml>.
- Accessing ServicesFor services of type NodePort, you can access your application from your local machine using the MiniKube node’s IP address and the automatically generated NodePort (typically in the 30000-32767 range).
- The minikube service <service-name> command can automatically open your service’s URL in a web browser. You can also get just the URL with minikube service <service-name> –url.
- Kubernetes Dashboard MiniKube provides an easy way to launch the Kubernetes Dashboard with minikube dashboard. This web-based UI allows you to observe the status of your deployments, services, pods, and nodes visually.
Other Essential Tools for Local Development
- Visual Studio Code: A recommended code editor for writing Kubernetes YAML configuration files. It can be enhanced with extensions like the Kubernetes extension for faster YAML file creation and the Docker extension for managing Docker images.
- Docker Desktop: While MiniKube itself doesn’t strictly require Docker to run the cluster (as it can use other VM drivers and container runtimes), you will need Docker installed and running on your local machine if you plan to build custom Docker images for your applications and push them to a registry like Docker Hub.

By Amjad Izhar
Contact: amjad.izhar@gmail.com
https://amjadizhar.blog
Affiliate Disclosure: This blog may contain affiliate links, which means I may earn a small commission if you click on the link and make a purchase. This comes at no additional cost to you. I only recommend products or services that I believe will add value to my readers. Your support helps keep this blog running and allows me to continue providing you with quality content. Thank you for your support!

Leave a comment