Udacity | SUSE: Orchestration - Kubernetes Manifests
Tags: kubernetes, devops, devjournal, docker
Published: 2021-06-22 14:43:32

> *This is the ninth article in the series,* ***Udacity: SUSE Cloud Native Foundations***. *This is an extension of the previous section on Kubernetes. Most of the deployments discussed so far is through the* ***imperative approach***. *We'll take on a different view in this section.*

---

## 📌 The Declarative Way

There are two ways we can follow in deploying Kubernetes clusters. The first one is what we've been doing so far, the imperative approach.

The **imperative approach** allows managing resources using kubectl commands directly on the live cluster.  This technique is best suited for development stages only, as it presents a low entry-level bar to interact with the cluster.

The **declarative approach** uses manifests that is stored locally to create and manage Kubertenest objects. This approach is recommended for production releases, as we can version control the state of the deployed resources.

However, there is a much higher learning curve in doing the declarative approach as solid understanding of YAML template is needed.

---

## 📑 YAML Manifest structure

The Kubernetes manifest contains the full configuration for the Kubernetes object and is in *YAML* format, which is a data-serialization standard.

There are 4 sections in a YAML manifest file

- **apiversion** - API version used to create a Kubernetes object
- **kind** - object type to be created or configured
- **metadata** - stores data that makes the object identifiable
- **spec** - defines the desired configuration state of the resource

To get the YAML manifest of any resource within the cluster, use the <code>kubectl get</code> command, associated with the <code>-o yaml</code> flag, which requests the output in YAML format. 

--------

## 📗 Deployment YAML manifest

In addition to the required sections of a YAML manifest, a Deployment resource covers the configuration of *ReplicaSet, RollingOut strategy,* and *containers*. See below for an example,

```yaml
## Set the API endpoint used to create the Deployment resource.
apiVersion: apps/v1

## Define the type of the resource.
kind: Deployment

## Set the parameters that make the object identifiable, such as its name, namespace, and labels.
metadata:
  annotations:
  labels:
    app: go-helloworld
  name: go-helloworld
  namespace: default

## Define the desired configuration for the Deployment resource.
spec:
  ## Set the number of replicas.
  ## This will create a ReplicaSet that will manage 3 pods of the Go hello-world application.
  replicas: 3
  ## Identify the pods managed by this Deployment using the following selectors.
  ## In this case, all pods with the label `go-helloworld`.
  selector:
    matchLabels:
      app: go-helloworld
  ## Set the RollingOut strategy for the Deployment.
  ## For example, roll out only 25% of the new pods at a time.
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  ## Set the configuration for the pods.
  template:
    ## Define the identifiable metadata for the pods.
    ## For example, all pods should have the label `go-helloworld`
    metadata:
      labels:
        app: go-helloworld
    ## Define the desired state of the pod configuration.
    spec:
      containers:
        ## Set the image to be executed inside the container and image pull policy
        ## In this case, run the `go-helloworld` application in version v2.0.0 and
        ## only pull the image if it's not available on the current host.
      - image: pixelpotato/go-helloworld:v2.0.0
        imagePullPolicy: IfNotPresent
        name: go-helloworld
        ## Expose the port the container is listening on.
        ## For example, exposing the application port 6112 via TCP.
        ports:
        - containerPort: 6112
          protocol: TCP
        ## Define the rules for the liveness probes.
        ## For example, verify the application on the main route `/`,
        ## on application port 6112. If the application is not responsive, then the pod will be restarted automatically. 
        livenessProbe:
           httpGet:
             path: /
             port: 6112
        ## Define the rules for the readiness probes.
        ## For example, verify the application on the main route `/`,
        ## on application port 6112. If the application is responsive, then traffic will be sent to this pod.
        readinessProbe:
           httpGet:
             path: /
             port: 6112
        ## Set the resource requests and limits for an application.
        resources:
        ## The resource requests guarantees that the desired amount 
        ## CPU and memory is allocated for a pod. In this example, 
        ## the pod will be allocated with 64 Mebibytes and 250 miliCPUs.
          requests:
            memory: "64Mi"
            cpu: "250m"
        ## The resource limits ensure that the application is not consuming 
        ## more than the specified CPU and memory values. In this example, 
        ## the pod will not surpass 128 Mebibytes and 500 miliCPUs.
          limits:
            memory: "128Mi"
            cpu: "500m"
```

---

## 📒 Service YAML manifest

In addition to the required sections of a YAML manifest, a Service resource covers the configuration of service type and ports the service should configure. 

```yaml
## Set the API endpoint used to create the Service resource.
apiVersion: v1

## Define the type of the resource.
kind: Service

## Set the parameters that make the object identifiable, such as its name, namespace, and labels.
metadata:
  labels:
    app: go-helloworld
  name: go-helloworld
  namespace: default

## Define the desired configuration for the Service resource.
spec:
  ## Define the ports that the service should serve on. 
  ## For example, the service is exposed on port 8111, and
  ## directs the traffic to the pods on port 6112, using TCP.
  ports:
  - port: 8111
    protocol: TCP
    targetPort: 6112
  ## Identify the pods managed by this Service using the following selectors.
  ## In this case, all pods with the label `go-helloworld`.
  selector:
    app: go-helloworld
  ## Define the Service type, here set to ClusterIP.
  type: ClusterIP
```

-----

## 🔰 Useful commands

To create a resource defined in the YAML manifests with the name manifest.yaml

```yaml
kubectl apply -f manifest.yaml
```

To delete a resource using a YAML manifest,

```yaml
kubectl delete -f manifest.yaml
```

You can check out all the available parameters in the Kubernetes documentation. In addition to this, you can also build a YAML template using the kubectl commands. 

This is possible by using the <code>--dry-run=client</code> and <code>-o yaml</code> flags which instructs that the command should be evaluated on the client-side only and output the result in YAML format.

The below command gets the YAML template for a resource.
```yaml
kubectl create RESOURCE [REQUIRED FLAGS] --dry-run=client -o yaml
```

As an example,you can get the template for a Deployment resource by using the <code>create</code> command, pass the required parameters, and associated with the <code>--dry-run</code> and <code>-o yaml</code> flags. This outputs the base template, which can be used further for more advanced configuration.

Invoke the command below to get the base YAML templated for a demo Deployment running an NGINX application

```YAML
kubectl create deploy demo --image=nginx --dry-run=client -o yaml
```
---

Up next, lab time!

---

> *If you enjoy this write-up and would like to learn more, make sure to hit the* **Follow** *just below and bookmark the series. I'll also be glad to connect with you on [Twitter](https://twitter.com/eden_noel08). <br>
See you there!* 😃
____________________________________________

{% user jeden %}