Introduction
Declarative YAML is a powerful tool within the Kubernetes ecosystem. It provides a straightforward, readable, and maintainable method for defining and managing resources within a Kubernetes cluster. With declarative YAML, developers can specify their desired state of the system and allow Kubernetes to manage the actual state and reconcile any differences. This approach increases the ease and reliability of deployments, updates, and resource scaling.
Imperative vs Declarative
In the context of programming, the term declarative refers to the practice of defining the desired end state or result, without outlining the specific steps to achieve that result. To illustrate this concept, consider the task of extracting all users over the age of 30 from a list of users.
Imperative Approach
An imperative approach to this task would specify the precise algorithm or steps required:
- Loop through the user list and retrieve each user.
- Check the age of each user.
- If the user is over 30, add them to the results list.
This method details the exact procedures for the task.
Declarative Approach
On the other hand, a declarative approach simply declares the intended outcome:
- Extract users over the age of 30.
In this case, the specific steps or algorithm to achieve the goal are not outlined. The focus is solely on the final result, i.e., users over the age of 30.
Benefits of Declarative Approach
The declarative approach abstracts away the details of the process, focusing on the goal or outcome. This enhances the readability and maintainability of code and increases flexibility. In the context of Infrastructure as Code (IaC), using a declarative format like YAML to define the state of infrastructure improves management and reproducibility.
kubectl run to YAML: Imperative to Declarative
Transitioning from the imperative kubectl run commands to declarative Kubernetes YAML offers a more maintainable and scalable method for managing resources in a Kubernetes cluster.
Imperative
Creating a Pod
Using an imperative approach, a Pod could be created using the following kubectl run
command:
$ kubectl run \
--image gcr.io/google-samples/hello-app:1.0 \
--restart Never \
helloworld
Creating a Service
Similarly, a Service could be created using the kubectl expose
command:
$ kubectl expose pod helloworld \
--type ClusterIP \
--port 8080 \
--name helloworld-clusterip
Creating a Deployment
For creating a Deployment, one could use the kubectl create deployment
command:
$ kubectl create deployment \
--image gcr.io/google-samples/hello-app:1.0 \
helloworld
Declarative
Transitioning to a declarative approach involves generating YAML files that describe the desired state of these resources.
Creating a Pod
The following command can be used to generate a YAML file for a Pod:
$ kubectl run \
--port 8080 \
--image gcr.io/google-samples/hello-app:1.0 \
--restart Never \
--dry-run \
-o yaml \
helloworld > pod.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: helloworld
name: helloworld
spec:
containers:
- image: gcr.io/google-samples/hello-app:1.0
name: helloworld
ports:
- containerPort: 8080
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Never
status: {}
Creating a Service
Similarly, a YAML file for a Service can be created with the following command:
$ kubectl expose pod helloworld \
--type ClusterIP \
--port 8080 \
--name helloworld-clusterip \
--dry-run \
-o yaml > service.yaml
Creating a Deployment
And finally, a Deployment's YAML file can be generated using this command:
$ kubectl create deployment \
--port 8080 \
--image gcr.io/google-samples/hello-app:1.0 \
--dry-run \
-o yaml \
helloworld > deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: helloworld
name: helloworld
spec:
replicas: 1
selector:
matchLabels:
app: helloworld
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: helloworld
spec:
containers:
- image: gcr.io/google-samples/hello-app:1.0
name: hello-app
ports:
- containerPort: 8080
resources: {}
status: {}
Working with YAML in Kubernetes
Once you've transitioned to a declarative approach using YAML in Kubernetes, managing your resources becomes a simpler and more streamlined process. The YAML files are human-readable, making it easier to understand the configurations of each resource. Moreover, they can be stored and version-controlled alongside your application code, ensuring that your infrastructure setup is reproducible and consistent.
Creating Resources Defined in YAML
To create resources defined in a YAML file in Kubernetes, use the kubectl apply -f
command followed by the path to your YAML file. This command instructs Kubernetes to realize the desired state as described in the file.
For example, to create a Pod, Service, and Deployment defined in the YAML files generated in the previous chapter, use the following commands:
$ kubectl apply -f pod.yaml
$ kubectl apply -f service.yaml
$ kubectl apply -f deployment.yaml
Kubernetes will read the configuration from each file, create the respective resource if it does not exist or update it if it does, and ensure that the actual state matches the desired state described in the YAML file.
Deleting Resources Defined in YAML
Deleting resources that were created using a YAML file is equally straightforward. Instead of apply
, use the delete
command. This instructs Kubernetes to remove the resources as defined in the YAML file.
Here are the commands to delete the Pod, Service, and Deployment created earlier:
$ kubectl delete -f pod.yaml
$ kubectl delete -f service.yaml
$ kubectl delete -f deployment.yaml