Now that we have an overview of Kubernetes and why we need it, this article will take you deep into the three core components that are the foundation for building and managing any application on Kubernetes: Nodes , Pods , and Namespaces . Think of them as the most basic building blocks of your Kubernetes house.
1. Nodes: Where the application "resides"
In a Kubernetes cluster, Nodes are the actual working machines where your containerized applications run. A Node can be a physical server or a virtual machine. The Control Plane (which we covered in the previous post) coordinates these Nodes to ensure your application is always stable and has enough resources.
Role of Worker Node:
Worker Nodes are the real “soldiers” responsible for executing tasks assigned by the Control Plane. They run Pods (which we’ll get to in a moment), which are where your application containers reside.
Important components on a Node:
Each Worker Node is equipped with the following components to manage containers and communicate with the Control Plane:
2. Pods: Smallest unit of deployment
In Kubernetes, a Pod is the smallest and most basic unit of deployment. You don't deploy containers directly to Kubernetes, you deploy Pods. A Pod can contain one or more closely related containers that share resources.
Why Pod and not Container directly?
Grouping related containers into a Pod provides several important benefits:
Think of a Pod as a small "apartment". Inside the apartment there can be multiple "rooms" (containers) that share the same "power and water system" (network, storage) and are managed as a single unit.
Structure of a Pod:
A Pod typically consists of:
Pod Life Cycle:
A Pod will go through several states during its lifecycle:
Example of creating a simple Pod using a YAML file:
You can define a Pod using a YAML (or JSON) file. Here is a simple example of a Pod running an Nginx container:
YAML
apiVersion: v1
kind: Pod
metadata:
name: my-nginx-pod
labels: app: my-web
environment: development
spec:
containers:
- name: nginx-container
image: nginx:latest
ports: - containerPort: 80
In this file:
Use kubectl to manage Pods:
After saving the above file as my-nginx-pod.yaml, you can use kubectl to interact with the Pod:
Create Pod:
kubectl apply -f my-nginx-pod.yaml
View information about running Pods:
kubectl get pods
You should see the Pod my-nginx-pod in the list with its status (e.g. Running).
View details about a specific Pod:
kubectl describe pod my-nginx-pod
This command will display a lot of detailed information about the Pod, including containers, state, events, labels, etc.
View logs of a container in a Pod:
kubectl logs my-nginx-pod -c nginx-container
-c nginx-container specifies the container you want to view logs from (if the Pod has multiple containers).
Delete a Pod:
kubectl delete pod my-nginx-pod
Important Note About Pods:
Pods are often considered ephemeral resources. This means that when a Node fails or is re-orchestrated by Kubernetes, the Pods running on that Node may be lost. Therefore, you should not directly create individual Pods for production applications . Instead, you will use Controllers (such as Deployments and StatefulSets) to manage the creation and maintenance of Pods, ensuring the stability and self-healing of the application. We will learn about Controllers in later articles.
3. Namespaces: Virtual space division
When you work with a large Kubernetes cluster, managing all the resources (Pods, Services, Deployments, etc.) in a single space can become very messy and difficult to manage. Namespaces provide a way to divide the resources in a physical cluster into multiple separate virtual clusters.
Think of a physical Kubernetes cluster as a large apartment building. Each Namespace is like a separate apartment within the building. Resources within a Namespace (e.g. Pods, Services) are isolated from resources in other Namespaces (unless you explicitly configure them to allow communication).
Common use cases for Namespaces:
Default Namespaces:
Kubernetes creates some default Namespaces:
How to create and manage Namespaces using kubectl:
Create a new Namespace:
kubectl create namespace my-dev-namespace
See the list of available Namespaces:
kubectl get ns # hoặc kubectl get namespaces
Change the default Namespace for subsequent kubectl commands in the current session:
kubectl config set-context --current --namespace=my-dev-namespace
After this command, all kubectl commands you run will default to operating on the Namespace my-dev-namespace.
Specify Namespace when creating a resource: You can specify a Namespace for a resource in its YAML file by adding a namespace field to the metadata section:
YAML
apiVersion: v1
kind: Pod
metadata:
name: my-pod-in-dev
namespace: my-dev-namespace
labels: app: my-app
spec:
containers:
- name: my-container
image: busybox:latest
command: ['sh', '-c', 'echo Hello from my-dev-namespace && sleep 3600']
4. Labels and Selectors: "Tagging" and "Searching" for Resources
Labels are key-value pairs attached to Kubernetes objects (like Pods, Nodes, Namespaces, Deployments, Services, etc.). They are used to organize and select subsets of objects based on properties that you care about.
Think of Labels as "tags" you stick on objects to categorize them (e.g. "color: red", "size: large", "application: web").
Selectors are expressions that you use to select objects based on their Labels. Kubernetes uses Selectors to link components together. For example, a Deployment uses a Selector to identify the Pods it manages. A Service also uses a Selector to identify the Pods it should route traffic to.
There are two main types of Selectors:
Annotations: Additional Information (Metadata)
Annotations are also key-value pairs attached to Kubernetes objects, similar to Labels. However, Annotations are not used to select objects . Instead, they are designed to store additional information (metadata) that is not directly meaningful to the Kubernetes system. For example, you can store information about the creator of a resource, the software version, or descriptive notes.
Practice:
Create a Namespace:
Bash
kubectl create namespace my-practice-ns
Create a Pod in the Namespace my-practice-ns:
YAML
apiVersion: v1 kind: Pod metadata: name: my-practice-pod namespace: my-practice-ns labels: environment: testing role: worker spec: containers: - name: busybox-container image: busybox:latest command: ['sh', '-c', 'echo Hello from practice && sleep 3600']
Save the above file as my-practice-pod.yaml and run:
Bash
kubectl apply -f my-practice-pod.yaml
Check that the Pod has been created in the Namespace my-practice-ns:
Bash
kubectl get pods -n my-practice-ns
Look for Pods with label environment=testing in Namespace my-practice-ns:
Bash
kubectl get pods -n my-practice-ns -l environment=testing
Search for Pods with role labels that exist in the Namespace my-practice-ns:
Bash
kubectl get pods -n my-practice-ns -l role
Conclude:
Pods, Nodes, and Namespaces are three core concepts that every Kubernetes beginner needs to master. Nodes are the physical or virtual machines where applications run. Pods are the smallest units of deployment, containing one or more related containers. Namespaces provide logical separation of resources in a cluster. Finally, Labels and Selectors are powerful mechanisms for organizing and managing Kubernetes objects. Understanding this “atomic trinity” will lay a solid foundation for your exploration of the vast world of Kubernetes. In future posts, we will explore Controllers and Services, which are more important components for building production-ready applications on Kubernetes.