Kubernetes objects: Pods, YAML and namespaces
What a Kubernetes object is, how a YAML manifest describes one, and the first two objects you will create, the Pod and the namespace.
The last post set up a local cluster with Minikube or
Kind and introduced kubectl. This one covers the building blocks you will create on that
cluster: YAML manifests, Pods and namespaces. Everything else in Kubernetes is built on them.
Kubernetes objects
Kubernetes manages objects. An object is a record of intent: it tells Kubernetes what you want the cluster's state to look like. Once you create one, the control plane keeps working to make the cluster's actual state match the desired state you described.
You usually write objects as YAML files. YAML stands for YAML Ain't Markup Language.
YAML manifests
YAML is easy for people to read and good at representing nested data. It lets you describe your resources declaratively: instead of telling Kubernetes how to do something, you tell it what you want.
Almost every Kubernetes manifest has four top-level fields:
apiVersionis the Kubernetes API version the object uses, such asv1orapps/v1. It tells Kubernetes which set of rules applies to the object.kindis the type of resource you are creating, such asPod,Deployment,ServiceorNamespace.metadataholds the data that identifies the object, such as itsname,namespaceandlabels.specdescribes the desired state of the object. Its contents change a lot depending on thekind.
YAML uses spaces for indentation, never tabs, and the indentation defines the structure. Keep it consistent: a single misplaced space is enough to make a manifest fail.
Pods
If containers are the bricks of your application, Pods are the smallest houses built from them. A Pod is the smallest deployable unit in Kubernetes, and it wraps:
- one or more containers
- shared storage, in the form of volumes
- a unique IP address
- options that control how the containers run
Pods are designed to be temporary. When a Pod dies, Kubernetes does not try to heal it. A new Pod replaces it instead, created by a higher-level object such as a Deployment.
Containers in the same Pod share a network namespace, so they can reach each other on
localhost using different ports. They can also share storage volumes.
Most Pods hold a single application container. Some hold more than one, usually for the sidecar pattern, where a helper container such as a log shipper or a data synchronizer runs alongside the main application container.
Create your first Pod
This Pod runs an Nginx web server. Save it as nginx-pod.yaml:
# nginx-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: my-nginx-pod
labels:
app: nginx
environment: development
spec:
containers:
- name: nginx-container
image: nginx:latest
ports:
- containerPort: 80Here is what each part does:
apiVersion: v1is the standard API version for Pods.kind: Podtells Kubernetes to create a Pod.metadata.namegives the Pod a unique name,my-nginx-pod.metadata.labelsholds key-value pairs, hereapp: nginxandenvironment: development, that organize and identify resources. Labels are how you select and manage groups of objects.specdescribes the desired state of the Pod.spec.containerslists the containers to run inside the Pod. This one has a single container namednginx-container, which pulls and runs thenginx:latestimage and exposes port 80.
Deploy it to your cluster:
kubectl apply -f nginx-pod.yamlThe output should be pod/my-nginx-pod created.
Check that the Pod is running:
kubectl get podsmy-nginx-pod should show a STATUS of Running. For more detail about the Pod:
kubectl describe pod my-nginx-podDelete the Pod using the same file:
kubectl delete -f nginx-pod.yamlOr by name:
kubectl delete pod my-nginx-podYou can create Pods directly like this, but in real work you will almost always use a higher-level object such as a Deployment to manage them. Deployments add self-healing, scaling and rolling updates, which any application you depend on needs.
Namespaces
As a cluster grows, it ends up running many applications for different teams and environments, such as development, staging and production. Namespaces keep them apart. You can think of a namespace as a virtual cluster inside your physical cluster.
Namespaces separate resources logically. You can have a Pod named my-app in the development
namespace and another Pod named my-app in the production namespace, and they do not conflict.
They also keep a cluster organized when several teams or projects share it.
And they are where you control access and resource use. Resource quotas, which limit CPU and memory use, and role-based access control (RBAC) policies both apply at the namespace level, so different teams or users can get different permissions.
Built-in namespaces
Every cluster comes with a few namespaces already defined:
defaultis where resources go when you don't specify a namespace. It is fine for learning and small experiments, but for serious work, create your own namespaces.kube-systemis reserved for objects the Kubernetes control plane creates itself, such as core services like the API server and the scheduler. You generally should not touch anything in it.kube-publicholds resources that every user can read.kube-node-leaseholds the Lease objects that nodes use as heartbeats.
Working with namespaces
List the namespaces:
kubectl get namespaces
# or
kubectl get nsYou can create a namespace imperatively, with a command:
kubectl create namespace my-dev-namespaceOr declaratively, from a YAML file such as my-dev-namespace.yaml:
# my-dev-namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: my-dev-namespaceThen apply it:
kubectl apply -f my-dev-namespace.yamlTo create a resource in a specific namespace, pass -n or --namespace:
kubectl apply -f nginx-pod.yaml -n my-dev-namespaceTo list the resources in a specific namespace:
kubectl get pods -n my-dev-namespaceTo delete a namespace:
kubectl delete namespace my-dev-namespaceDeleting a namespace deletes every resource inside it, so be very careful with this command.
The next post moves beyond individual Pods to Deployments and ReplicaSets, which manage and scale your applications for you: Deployments, ReplicaSets, Jobs and CronJobs.