avatarJohn David Luther

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

7601

Abstract

monsets-demonstration && <span class="hljs-built_in">ls</span> -al

<span class="hljs-comment"># Check the code files</span> $ tree . ├── daemonsets-demonstration.sh ├── file-cleaner-all-nodes.yaml └── web-app-all-nodes.yaml

<span class="hljs-comment"># daemonsets-demonstration.sh script covers the entire demonstration.</span>

<span class="hljs-comment"># This is how the demonstration Kubernetes cluster looks like</span> kubectl get nodes NAME STATUS ROLES AGE VERSION ip-172-31-0-221.ec2.internal Ready control-plane 30m v1.27.1 ip-172-31-13-253.ec2.internal Ready &lt;none&gt; 27m v1.27.1 ip-172-31-4-118.ec2.internal Ready &lt;none&gt; 27m v1.27.1</pre></div><h2 id="ebba">OBJECTIVE 1 — A File Cleanup Utility DaemonSet Running on All Nodes</h2><p id="0817">Having access to all the code files in the <code>daemonsets-demonstration</code> code folder, let's execute them step by step.</p><p id="be87">The purpose of this DaemonSet demonstration is to show that the daemon running on each node wakes up every 60 seconds and deletes the old files inside the <code>/var/web/data</code> folder written by the web app, also running on each node, in 10-second intervals.</p><p id="3b1c"><b>STEP 1 — Install the web app deployment</b></p><div id="b4d7"><pre><span class="hljs-comment"># Quickly browse the web app deployment manifest</span> <span class="hljs-comment"># We have three replicas, expecting scheduling of a pod on each node.</span> <span class="hljs-comment"># The app creates a whole bunch of files on the hostPath of each node</span> <span class="hljs-built_in">cat</span> web-app-all-nodes.yaml apiVersion: apps/v1 kind: Deployment metadata: name: web-app spec: replicas: 3 selector: matchLabels: app: web-app template: metadata: labels: app: web-app spec: tolerations: - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule volumes: - name: host-vol hostPath: path: /var/web/data <span class="hljs-built_in">type</span>: DirectoryOrCreate containers: - name: web-app-container image: nginx:stable <span class="hljs-built_in">command</span>: [<span class="hljs-string">"/bin/sh"</span>, <span class="hljs-string">"-c"</span>] args: - > count=0; <span class="hljs-keyword">while</span> <span class="hljs-literal">true</span>; <span class="hljs-keyword">do</span> file=<span class="hljs-string">"/data/file-<span class="hljs-variable">count</span>.txt"</span>; <span class="hljs-built_in">echo</span> <span class="hljs-string">"`date` : Written by pod <span class="hljs-variable">POD_NAME</span> running on <span class="hljs-variable">NODE_NAME</span>"</span>\ &gt; <span class="hljs-variable">file</span>; <span class="hljs-built_in">sleep</span> 10; count=<span class="hljs-built_in">expr</span> <span class="hljs-variable">$count</span> + 1 <span class="hljs-keyword">done</span> volumeMounts: - name: host-vol mountPath: /data <span class="hljs-built_in">env</span>: - name: NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name

<span class="hljs-comment"># Deploy the web app</span> kubectl create -f web-app-all-nodes.yaml

<span class="hljs-comment"># Check to make sure pods are running and their respective hosts</span> $ kubectl get pods -o wide NAME READY STATUS NODE ... web-app-75f6bd9b69-fnfkw 1/1 Running ip-172-31-4-118.ec2.internal ... web-app-75f6bd9b69-lk24l 1/1 Running ip-172-31-0-221.ec2.internal ... web-app-75f6bd9b69-wsnfd 1/1 Running ip-172-31-13-253.ec2.internal...

<span class="hljs-comment"># Check the data files written by the deployed app</span> <span class="hljs-comment"># Expect to see a bunch of files sicne a file is written every 10 seconds</span> <span class="hljs-comment"># Use appropriate pod name from kubectl get pods command output above</span> kubectl <span class="hljs-built_in">exec</span> -it web-app-75f6bd9b69-fnfkw -- <span class="hljs-built_in">ls</span> -ltr /data</pre></div><p id="cd65"><b>STEP 2— Deploy the file clean-up utility DaemonSet</b></p><div id="61be"><pre><span class="hljs-comment"># Review the DaemonSet manifest</span> $ <span class="hljs-built_in">cat</span> file-cleaner-all-nodes.yaml apiVersion: apps/v1 kind: DaemonSet metadata: name: file-cleaner spec: selector: matchLabels: app: file-cleaner updateStrategy: <span class="hljs-built_in">type</span>: RollingUpdate rollingUpdate: maxUnavailable: 1 template: metadata: labels: app: file-cleaner spec: tolerations: - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule <span class="hljs-comment">#- key: node-role.kubernetes.io/master</span> <span class="hljs-comment"># operator: Exists</span> <span class="hljs-comment"># effect: NoSchedule</span> containers: - name: file-cleaner-container image: busybox:stable <span class="hljs-built_in">command</span>: [<span class="hljs-string">'sh'</span>, <span class="hljs-string">'-c'</span>, <span class="hljs-string">'while true; do rm ls -t /data/* |\ awk "NR&gt;5"; ls -l /data; sleep 60; done'</span>] volumeMounts: - name: host-vol mountPath: /data volumes: - name: host-vol hostPath: path: /var/web/data <span class="hljs-built_in">type</span>: Directory

<span class="hljs-comment"># Deploy the DaemonSet, responsible to clean up all except the last 5 files</span> kubectl create -f file-cleaner-all-nodes.yaml

<span class="hljs-comment"># Verify the daemonset pods are running, one in each node</span> $ NAME READY STATUS NODE ... file-cleaner-n4pnt 1/1 Running ip-172-31-0-221.ec2.internal ... file-cleaner-p82r6 1/1 Running ip-172-31-13-253.ec2.internal ... file-cleaner-q2k2m 1/1 Running ip-172-31-4-118.ec2.internal ...

<span class="hljs-comment"># Verify the daemon script is doing its job by looking at the pod log</span> <span class="hljs-comment"># Expect to see the last 5 files remaining, written every 60 seconds</span> kubectl logs file-cleaner-q2k2m</pre></div><p id="ca42">Note that since we intended to run the DaemonSet on all nodes, including the control plane, the DaemonSet manifest included the <code>tolerations</code> block above. Without it, the DaemonSet will run on worker nodes only. Refer to the documentation page <a href="https://kubernetes.io/docs/tasks/manage-daemon/pods-some-nodes/"><b><i>Running Pods on Only Some Nodes</i></b></a> to control DaemonSet hosts via node names and node labels.</p><p id="45d0">Let's quickly examine the <code>taints</code> field in the node description so that you can relate it to the <code>tolerations</code> in the DaemonSet manifest.</p><div id="790e"><pre><span class="hljs-comment"># Check for taints in the node description</span> <span class="hljs-comment"># Note: Some nodes may have mult

Options

iple taints</span> $ kubectl describe nodes | grep -i -A1 taint Taints: node-role.kubernetes.io/control-plane:NoSchedule ...

Taints: <none> ...

Taints: <none> ...</pre></div><h2 id="f849">OBJECTIVE 2 — Performing a Rolling Update on a DaemonSet</h2><p id="b2e5">DaemonSet has two update strategy types, <code>OnDelete</code> and <code>RollingUpdate</code>, the latter being the default. See the documentation for more details.</p><p id="db0a">Let's watch it in action.</p><div id="950c"><pre><span class="hljs-comment"># Confirm the current Daemonset update strategy</span> $ kubectl get ds/file-cleaner
-o go-template=<span class="hljs-string">'{{.spec.updateStrategy.type}}{{"\n"}}'</span>

<span class="hljs-comment"># Any updates to the .spec.template section triggers a rolling update </span> <span class="hljs-comment"># (e.g. container image, resources etc.)</span> <span class="hljs-comment"># Updates can take place by </span> <span class="hljs-comment"># 1. Editing the Daemonset object live with edit command or</span> <span class="hljs-comment"># 2. Changing/re-applying the manifest or </span> <span class="hljs-comment"># 3. Imperative command modification</span>

<span class="hljs-comment"># Let's change the image imperatively and see the rolling update process</span> $ kubectl <span class="hljs-built_in">set</span> image ds/file-cleaner file-cleaner-container=busybox:latest

<span class="hljs-comment"># Watch the rolling update rollout status of the latest DaemonSet</span> kubectl rollout status ds/file-cleaner Waiting <span class="hljs-keyword">for</span> daemon <span class="hljs-built_in">set</span> <span class="hljs-string">"file-cleaner"</span> rollout to finish: 0 out of 3 new ... Waiting <span class="hljs-keyword">for</span> daemon <span class="hljs-built_in">set</span> <span class="hljs-string">"file-cleaner"</span> rollout to finish: 2 of 3 updated ... daemon <span class="hljs-built_in">set</span> <span class="hljs-string">"file-cleaner"</span> successfully rolled out</pre></div><h2 id="b4f2">OBJECTIVE 3 — Performing a Rollback on a DaemonSet</h2><p id="08db">Knowing how to rollback is helpful if, for some reason, the update runs into an error or we need to rollback a successful update.</p><p id="d1a0">Here are the steps to perform a rollback.</p><div id="031b"><pre><span class="hljs-comment"># Start by listing all revisions of a DaemonSet update</span> kubectl rollout <span class="hljs-built_in">history</span> ds/file-cleaner daemonset.apps/file-cleaner REVISION CHANGE-CAUSE 1 <none> 2 <none>

<span class="hljs-comment"># Check the details of a specific revision</span> $ kubectl rollout <span class="hljs-built_in">history</span> ds/file-cleaner --revision=1 daemonset.apps/file-cleaner with revision <span class="hljs-comment">#1</span> Pod Template: Labels: app=file-cleaner Containers: file-cleaner-container: Image: busybox:stable Port: <none> Host Port: <none> Command: sh -c <span class="hljs-keyword">while</span> <span class="hljs-literal">true</span>; <span class="hljs-keyword">do</span> <span class="hljs-built_in">rm</span> <span class="hljs-built_in">ls</span> -t /data/* | awk <span class="hljs-string">"NR&gt;5"</span>;
<span class="hljs-built_in">ls</span> -l /data; <span class="hljs-built_in">sleep</span> 60; <span class="hljs-keyword">done</span> Environment: <none> Mounts: /data from host-vol (rw) Volumes: host-vol: Type: HostPath (bare host directory volume) Path: /var/web/data HostPathType: Directory

<span class="hljs-comment"># Roll back to a specific revision</span> <span class="hljs-comment"># Without the optional --to-revision, it reverts to the previous revision</span> $ kubectl rollout undo ds/file-cleaner --to-revision=1 daemonset.apps/file-cleaner rolled back

<span class="hljs-comment"># The rollback increments the revision</span> kubectl rollout <span class="hljs-built_in">history</span> ds/file-cleaner daemonset.apps/file-cleaner REVISION CHANGE-CAUSE 2 &lt;none&gt; 3 &lt;none&gt;</pre></div><h2 id="340c">Final Cleanup</h2><p id="c564">At this point, we're done deploying the necessary components and demonstrating and verifying the DaemonSet functionalities.</p><p id="5b7f">It's time to clean up the resources.</p><div id="23bd"><pre><span class="hljs-comment"># List the resources running</span> kubectl get deploy,ds,pods NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/web-app 3/3 3 3 122m

NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE daemonset.apps/file-cleaner 3 3 3 3 3 <none> 68m

NAME READY STATUS RESTARTS AGE pod/file-cleaner-6bn4t 1/1 Running 0 12m pod/file-cleaner-gpntb 1/1 Running 0 12m pod/file-cleaner-j8tf5 1/1 Running 0 11m pod/web-app-75f6bd9b69-fnfkw 1/1 Running 0 122m pod/web-app-75f6bd9b69-lk24l 1/1 Running 0 122m pod/web-app-75f6bd9b69-wsnfd 1/1 Running 0 122m

<span class="hljs-comment"># Delete both the Deployment and the DaemonSet</span> $ kubectl delete deployment.apps/web-app daemonset.apps/file-cleaner

$ kubectl get deploy,ds,pods No resources found <span class="hljs-keyword">in</span> default namespace.</pre></div><h2 id="56d7">Conclusion</h2><p id="935f">In this post, I performed an end-to-end demonstration of creating a file clean-up utility DaemonSet running on each Kubernetes cluster node, performing a rolling update and rollback on a DaemonSet.</p><p id="8ad3">This task utilized the previously learned <a href="https://readmedium.com/the-aws-way-mastering-kubernetes-one-task-at-a-time-pods-deployments-and-replicasets-233b75629af1">Deployment</a> and <a href="https://readmedium.com/mastering-kubernetes-one-task-at-a-time-persistent-storage-volumes-with-hostpath-ad645714bcc7">Persistent Storage Management </a>skills as part of the <b><i>Mastering Kubernetes One Task at a Time</i></b> series.</p><p id="3abf">Thank you for following and staying in touch. I look forward to seeing you soon with yet another new task in the series.</p><p id="2547" type="7">If you benefited from reading the post, please 👏 a few times before parting, and help others by sharing it; I highly appreciate that!</p><div id="0c42" class="link-block"> <a href="https://jdluther.medium.com/membership"> <div> <div> <h2>Join Medium with my referral link - John David Luther</h2> <div><h3>Learning begets learning. MEDIUM fosters learning. The best gift to yourself is Learning. Turbocharge your career and…</h3></div> <div><p>jdluther.medium.com</p></div> </div> <div> <div style="background-image: url(https://miro.readmedium.com/v2/resize:fit:320/0*cNAtGB2z8l5MM0C4)"></div> </div> </div> </a> </div><p id="1507"><b><i>Please <a href="https://jdluther.medium.com/">follow</a> to stay in touch, track, and be the first to get notified of all future writings on AWS Cloud, Containers, Kubernetes, and Machine Learning. Also, check all my stories on <a href="https://medium.com/the-aws-way/latest">The AWS Way</a> publication.</i></b></p></article></body>

Mastering Kubernetes One Task at a Time — DaemonSet Demonstration

A simple file cleanup utility showing how to write Kubernetes DaemonSets and perform rolling updates and rollbacks.

Table of Contents

  1. Introduction
  2. Kubernetes DaemonSet Resource References
  3. Kubernetes Clusters for Hands-On Practice
  4. Download DaemonSets Demonstration Code from GitHub
  5. OBJECTIVE 1 — A File Cleanup Utility DaemonSet Running on All Nodes
  6. OBJECTIVE 2 — Performing a Rolling Update on a DaemonSet
  7. OBJECTIVE 3 — Performing a Rollback on a DaemonSet
  8. Final Cleanup
  9. Conclusion
Mastering Kubernetes One Task at a Time — DaemonSet Demonstration

Introduction

One of my earlier posts, Mastering Kubernetes One Task at a Time — Pods, Deployments, and ReplicaSets, covered the first of the four Kubernetes built-in Workload Resources groups. Visit the link below for a quick recap.

Subsequently, I also wrote two posts on Kubernetes Volumes, showing how to implement:

  1. Persistent Storage Volumes with 'hostPath'
  2. Ephemeral Storage Volumes with 'emptyDir'

Now, we're ready to apply the knowledge garnered from the reading and practice thus far to implement the next very important Kubernetes workload resource, DaemonSet.

This post demonstrates the following three objectives—

  1. How to write a DaemonSet with an example file clean-up utility that runs on each node of a Kubernetes cluster, including the control plane node.
  2. How to perform a rolling update on a DaemonSet
  3. How to perform a rollback on a DaemonSet

Kubernetes DaemonSet Resource References

For this post, I will refer to the following Kubernetes.io documentation pages.

  1. https://kubernetes.io/docs/concepts/workloads/
  2. https://kubernetes.io/docs/concepts/workloads/controllers/daemonset
  3. https://kubernetes.io/docs/tasks/manage-daemon/rollback-daemon-set/
  4. https://kubernetes.io/docs/tasks/manage-daemon/update-daemon-set/
  5. https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/daemon-set-v1/

Worth highlighting here is the following for a quick understanding.

A DaemonSet ensures that all (or some) Nodes run a copy of a Pod. As nodes are added to the cluster, Pods are added to them. As nodes are removed from the cluster, those Pods are garbage collected. Deleting a DaemonSet will clean up the Pods it created.

Some typical uses of a DaemonSet are:

. running a cluster storage daemon on every node

. running a logs collection daemon on every node

. running a node monitoring daemon on every node

Kubernetes Clusters for Hands-On Practice

This DaemonSet demonstration works on any Kubernetes cluster, including the following two clusters that you're free to spin up anytime in a matter of minutes to practice all your Kubernetes hands-on exercises.

I am demonstrating on the second one below, the Kubeadm-based cluster.

Download DaemonSets Demonstration Code from GitHub

Let's download the code repo and walk through the THREE OBJECTIVES step by step while executing the code along the way.

# Clone the jdluther-kubernetes-io-tasks github repo 
$ REPO=jdluther-kubernetes-io-tasks && \
    git clone https://github.com/jdluther2020/$REPO.git && \
    cd $REPO

$ cd daemonsets-demonstration && ls -al

# Check the code files
$ tree
.
├── daemonsets-demonstration.sh
├── file-cleaner-all-nodes.yaml
└── web-app-all-nodes.yaml

# daemonsets-demonstration.sh script covers the entire demonstration.

# This is how the demonstration Kubernetes cluster looks like
$ kubectl get nodes
NAME                            STATUS   ROLES           AGE   VERSION
ip-172-31-0-221.ec2.internal    Ready    control-plane   30m   v1.27.1
ip-172-31-13-253.ec2.internal   Ready    <none>          27m   v1.27.1
ip-172-31-4-118.ec2.internal    Ready    <none>          27m   v1.27.1

OBJECTIVE 1 — A File Cleanup Utility DaemonSet Running on All Nodes

Having access to all the code files in the daemonsets-demonstration code folder, let's execute them step by step.

The purpose of this DaemonSet demonstration is to show that the daemon running on each node wakes up every 60 seconds and deletes the old files inside the /var/web/data folder written by the web app, also running on each node, in 10-second intervals.

STEP 1 — Install the web app deployment

# Quickly browse the web app deployment manifest
# We have three replicas, expecting scheduling of a pod on each node.
# The app creates a whole bunch of files on the hostPath of each node
$ cat web-app-all-nodes.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web-app
  template:
    metadata:
      labels:
        app: web-app
    spec:
      tolerations:
      - key: node-role.kubernetes.io/control-plane
        operator: Exists
        effect: NoSchedule
      - key: node-role.kubernetes.io/master
        operator: Exists
        effect: NoSchedule
      volumes:
      - name: host-vol
        hostPath:
          path: /var/web/data
          type: DirectoryOrCreate
      containers:
      - name: web-app-container
        image: nginx:stable
        command: ["/bin/sh", "-c"]
        args:
        - >
          count=0;
          while true;
          do
            file="/data/file-$count.txt";
            echo "`date` : Written by pod $POD_NAME running on $NODE_NAME"\
                 > $file;
            sleep 10;
            count=`expr $count + 1`
          done
        volumeMounts:
        - name: host-vol
          mountPath: /data
        env:
        - name: NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name

# Deploy the web app
kubectl create -f web-app-all-nodes.yaml

# Check to make sure pods are running and their respective hosts
$ kubectl get pods -o wide
NAME                       READY STATUS    NODE                         ...
web-app-75f6bd9b69-fnfkw   1/1   Running   ip-172-31-4-118.ec2.internal ...
web-app-75f6bd9b69-lk24l   1/1   Running   ip-172-31-0-221.ec2.internal ...
web-app-75f6bd9b69-wsnfd   1/1   Running   ip-172-31-13-253.ec2.internal...

# Check the data files written by the deployed app
# Expect to see a bunch of files sicne a file is written every 10 seconds
# Use appropriate pod name from kubectl get pods command output above
kubectl exec -it web-app-75f6bd9b69-fnfkw -- ls -ltr /data

STEP 2— Deploy the file clean-up utility DaemonSet

# Review the DaemonSet manifest
$ cat file-cleaner-all-nodes.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: file-cleaner
spec:
  selector:
    matchLabels:
      app: file-cleaner
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
  template:
    metadata:
      labels:
        app: file-cleaner
    spec:
      tolerations:
      - key: node-role.kubernetes.io/control-plane
        operator: Exists
        effect: NoSchedule
      #- key: node-role.kubernetes.io/master
      #  operator: Exists
      #  effect: NoSchedule
      containers:
      - name: file-cleaner-container
        image: busybox:stable
        command: ['sh', '-c', 'while true; do rm `ls -t /data/* |\
            awk "NR>5"`; ls -l /data; sleep 60; done']
        volumeMounts:
        - name: host-vol
          mountPath: /data
      volumes:
      - name: host-vol
        hostPath:
          path: /var/web/data
          type: Directory

# Deploy the DaemonSet, responsible to clean up all except the last 5 files
kubectl create -f file-cleaner-all-nodes.yaml

# Verify the daemonset pods are running, one in each node
$ NAME              READY   STATUS    NODE                          ...
file-cleaner-n4pnt  1/1     Running   ip-172-31-0-221.ec2.internal  ...
file-cleaner-p82r6  1/1     Running   ip-172-31-13-253.ec2.internal ...
file-cleaner-q2k2m  1/1     Running   ip-172-31-4-118.ec2.internal  ...

# Verify the daemon script is doing its job by looking at the pod log
# Expect to see the last 5 files remaining, written every 60 seconds
kubectl logs file-cleaner-q2k2m

Note that since we intended to run the DaemonSet on all nodes, including the control plane, the DaemonSet manifest included the tolerations block above. Without it, the DaemonSet will run on worker nodes only. Refer to the documentation page Running Pods on Only Some Nodes to control DaemonSet hosts via node names and node labels.

Let's quickly examine the taints field in the node description so that you can relate it to the tolerations in the DaemonSet manifest.

# Check for taints in the node description
# Note: Some nodes may have multiple taints
$ kubectl describe nodes | grep -i -A1 taint
Taints:             node-role.kubernetes.io/control-plane:NoSchedule
...
--
Taints:             <none>
...
--
Taints:             <none>
...

OBJECTIVE 2 — Performing a Rolling Update on a DaemonSet

DaemonSet has two update strategy types, OnDelete and RollingUpdate, the latter being the default. See the documentation for more details.

Let's watch it in action.

# Confirm the current Daemonset update strategy
$ kubectl get ds/file-cleaner \
  -o go-template='{{.spec.updateStrategy.type}}{{"\n"}}'

# Any updates to the .spec.template section triggers a rolling update 
# (e.g. container image, resources etc.)
# Updates can take place by 
# 1. Editing the Daemonset object live with edit command or
# 2. Changing/re-applying the manifest or 
# 3. Imperative command modification

# Let's change the image imperatively and see the rolling update process
$ kubectl set image ds/file-cleaner file-cleaner-container=busybox:latest

# Watch the rolling update rollout status of the latest DaemonSet
$ kubectl rollout status ds/file-cleaner
Waiting for daemon set "file-cleaner" rollout to finish: 0 out of 3 new ...
Waiting for daemon set "file-cleaner" rollout to finish: 2 of 3 updated ...
daemon set "file-cleaner" successfully rolled out

OBJECTIVE 3 — Performing a Rollback on a DaemonSet

Knowing how to rollback is helpful if, for some reason, the update runs into an error or we need to rollback a successful update.

Here are the steps to perform a rollback.

# Start by listing all revisions of a DaemonSet update
$ kubectl rollout history ds/file-cleaner
daemonset.apps/file-cleaner
REVISION  CHANGE-CAUSE
1         <none>
2         <none>

# Check the details of a specific revision
$ kubectl rollout history  ds/file-cleaner --revision=1
daemonset.apps/file-cleaner with revision #1
Pod Template:
  Labels: app=file-cleaner
  Containers:
   file-cleaner-container:
    Image: busybox:stable
    Port: <none>
    Host Port: <none>
    Command:
      sh
      -c
      while true; do rm `ls -t /data/* | awk "NR>5"`;\
        ls -l /data; sleep 60; done
    Environment: <none>
    Mounts:
      /data from host-vol (rw)
  Volumes:
   host-vol:
    Type: HostPath (bare host directory volume)
    Path: /var/web/data
    HostPathType: Directory

# Roll back to a specific revision
# Without the optional --to-revision, it reverts to the previous revision
$ kubectl rollout undo ds/file-cleaner --to-revision=1
daemonset.apps/file-cleaner rolled back

# The rollback increments the revision
$ kubectl rollout history ds/file-cleaner
daemonset.apps/file-cleaner
REVISION  CHANGE-CAUSE
2         <none>
3         <none>

Final Cleanup

At this point, we're done deploying the necessary components and demonstrating and verifying the DaemonSet functionalities.

It's time to clean up the resources.

# List the resources running
$ kubectl get deploy,ds,pods
NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/web-app   3/3     3            3           122m

NAME                          DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
daemonset.apps/file-cleaner   3         3         3       3            3           <none>          68m

NAME                           READY   STATUS    RESTARTS   AGE
pod/file-cleaner-6bn4t         1/1     Running   0          12m
pod/file-cleaner-gpntb         1/1     Running   0          12m
pod/file-cleaner-j8tf5         1/1     Running   0          11m
pod/web-app-75f6bd9b69-fnfkw   1/1     Running   0          122m
pod/web-app-75f6bd9b69-lk24l   1/1     Running   0          122m
pod/web-app-75f6bd9b69-wsnfd   1/1     Running   0          122m

# Delete both the Deployment and the DaemonSet
$ kubectl delete deployment.apps/web-app daemonset.apps/file-cleaner

$ kubectl get deploy,ds,pods
No resources found in default namespace.

Conclusion

In this post, I performed an end-to-end demonstration of creating a file clean-up utility DaemonSet running on each Kubernetes cluster node, performing a rolling update and rollback on a DaemonSet.

This task utilized the previously learned Deployment and Persistent Storage Management skills as part of the Mastering Kubernetes One Task at a Time series.

Thank you for following and staying in touch. I look forward to seeing you soon with yet another new task in the series.

If you benefited from reading the post, please 👏 a few times before parting, and help others by sharing it; I highly appreciate that!

Please follow to stay in touch, track, and be the first to get notified of all future writings on AWS Cloud, Containers, Kubernetes, and Machine Learning. Also, check all my stories on The AWS Way publication.

AWS
Kubernetes
Terraform
DevOps
Infrastructure As Code
Recommended from ReadMedium
avatarAdnan Turgay Aydin
Kubernetes Helm Basics

Helm Basics

12 min read