To deploy an application on Kubernetes, developers must first create a container image. The image must then be organized into a format that Kubernetes can interpret, which is achieved by writing configuration files. These files, typically in YAML format, define the application's containers, parameters, and settings. Kubernetes emphasizes this declarative approach over direct command-line container execution. The primary command to create resources from a configuration file is:
kubectl create -f config-file.yaml
Example: Deploying an Nginx Application
A Kubernetes configuration file corresponds to an API object. The following YAML defines a Deployment, which manages a set of Pod replicas.
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-server-deployment
spec:
selector:
matchLabels:
component: web-server
replicas: 2
template:
metadata:
labels:
component: web-server
spec:
containers:
- name: web-server
image: nginx:1.7.9
ports:
- containerPort: 80
The kind field specifies the API object type. A Deployment is a controller that manages the lifecycle of multiple identical Pods, ensuring the specified number of replicas are running and handling updates.
The spec.replicas field defines the desired number of Pod instances. The Pod template (spec.template) describes the Pod's structure. In this example, each Pod runs a single container using the nginx:1.7.9 image, exposing port 80.
This pattern of one API object (Deployment) managing another (Pod) is the controller pattern. The metadata section contains identifying information, primarily labels. The controller uses the label selector (spec.selector.matchLabels) to identify the Pods it manages—in this case, all Pods with the label component: web-server. The annotations field is used for internal Kubernetes metadata.
API object definitions generally consist of a standard metadata section and a unique spec section that describes the object's intended state.
To create the Deployment, execute:
kubectl create -f web-server-deployment.yaml
Verify the Pods are running using kubectl get with a label filter:
kubectl get pods -l component=web-server
The -l parameter filters objects by label key-value pairs. The output should show two Pods in the Running state.
For detailed information about a specific Pod, use kubectl describe:
kubectl describe pod <pod-name>
The output includes the Pod's IP address, container status, and a crucial Events section. This log records significant actions like scheduling, image pulling, and container startup, which is essential for debugging.
Updating the Application
To update the application, such as changing the container image version, modify the YAML file. Change the image field in the container specification:
...
spec:
containers:
- name: web-server
image: nginx:1.8
ports:
- containerPort: 80
Apply the changes to the cluster. While kubectl replace can be used, kubectl apply is recommended for creating and updating objects declaratively:
kubectl apply -f web-server-deployment.yaml
Kubernetes detects the change in the YAML file and performs the necessary operations. This approach facilitates collaboration around version-controlled configuration files.
Adding a Volume to the Pod
Volumes are defined at the Pod level. To add a volume, modify the Pod template within the Deployment. The following example adds an emptyDir volume and mounts it into the container.
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-server-deployment
spec:
selector:
matchLabels:
component: web-server
replicas: 2
template:
metadata:
labels:
component: web-server
spec:
containers:
- name: web-server
image: nginx:1.8
ports:
- containerPort: 80
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: html-volume
volumes:
- name: html-volume
emptyDir: {}
An emptyDir volume is a temporary directory created on the host node and bound to the Pod's lifecycle. The volumeMounts field specifies the mount point inside the container.
Kubernetes also supports hostPath volumes for explicit host directory mapping:
...
volumes:
- name: html-volume
hostPath:
path: /var/data
Apply the updated configuration:
kubectl apply -f web-server-deployment.yaml
Kubernetes will perform a rolling update, replacing old Pods with new ones. Monitor the process:
kubectl get pods
Use kubectl describe to confirm the volume is attached. To interact with the volume inside a running Pod, use kubectl exec:
kubectl exec -it <pod-name> -- /bin/bash
ls /usr/share/nginx/html
exit
Deleting the Deployment
To remove all resources defined in the configuration file:
kubectl delete -f web-server-deployment.yaml