2022-06-27

Declarative YAML in Kubernetes

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:

  1. Loop through the user list and retrieve each user.
  2. Check the age of each user.
  3. 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:

  1. 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:

bash
$ 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:

bash
$ 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:

bash
$ 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:

bash
$ kubectl run \
    --port 8080 \
    --image gcr.io/google-samples/hello-app:1.0 \
    --restart Never \
    --dry-run \
    -o yaml \
    helloworld > pod.yaml
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:

bash
$ 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:

bash
$ kubectl create deployment \
    --port 8080 \
    --image gcr.io/google-samples/hello-app:1.0 \
    --dry-run \
    -o yaml \
    helloworld > deployment.yaml
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:

bash
$ 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:

bash
$ kubectl delete -f pod.yaml
$ kubectl delete -f service.yaml
$ kubectl delete -f deployment.yaml

Ryusei Kakujo

researchgatelinkedingithub

Focusing on data science for mobility

Bench Press 100kg!