Perform a Rolling Update on a DaemonSet

This page shows how to perform a rolling update on a DaemonSet.

Before you begin

  • The DaemonSet rolling update feature is only supported in Kubernetes version 1.6 or later.

DaemonSet Update Strategy

DaemonSet has two update strategy types:

  • OnDelete: With OnDelete update strategy, after you update a DaemonSet template, new DaemonSet pods will only be created when you manually delete old DaemonSet pods. This is the same behavior of DaemonSet in Kubernetes version 1.5 or before.
  • RollingUpdate: This is the default update strategy.
    With RollingUpdate update strategy, after you update a DaemonSet template, old DaemonSet pods will be killed, and new DaemonSet pods will be created automatically, in a controlled fashion. At most one pod of the DaemonSet will be running on each node during the whole update process.

Performing a Rolling Update

To enable the rolling update feature of a DaemonSet, you must set its .spec.updateStrategy.type to RollingUpdate.

You may want to set .spec.updateStrategy.rollingUpdate.maxUnavailable (default to 1) and .spec.minReadySeconds (default to 0) as well.

Creating a DaemonSet with RollingUpdate update strategy

This YAML file specifies a DaemonSet with an update strategy as ‘RollingUpdate’

controllers/fluentd-daemonset.yaml Perform a Rolling Update on a DaemonSet - 图1

  1. apiVersion: apps/v1
  2. kind: DaemonSet
  3. metadata:
  4. name: fluentd-elasticsearch
  5. namespace: kube-system
  6. labels:
  7. k8s-app: fluentd-logging
  8. spec:
  9. selector:
  10. matchLabels:
  11. name: fluentd-elasticsearch
  12. updateStrategy:
  13. type: RollingUpdate
  14. rollingUpdate:
  15. maxUnavailable: 1
  16. template:
  17. metadata:
  18. labels:
  19. name: fluentd-elasticsearch
  20. spec:
  21. tolerations:
  22. # this toleration is to have the daemonset runnable on master nodes
  23. # remove it if your masters can't run pods
  24. - key: node-role.kubernetes.io/master
  25. effect: NoSchedule
  26. containers:
  27. - name: fluentd-elasticsearch
  28. image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
  29. volumeMounts:
  30. - name: varlog
  31. mountPath: /var/log
  32. - name: varlibdockercontainers
  33. mountPath: /var/lib/docker/containers
  34. readOnly: true
  35. terminationGracePeriodSeconds: 30
  36. volumes:
  37. - name: varlog
  38. hostPath:
  39. path: /var/log
  40. - name: varlibdockercontainers
  41. hostPath:
  42. path: /var/lib/docker/containers

After verifying the update strategy of the DaemonSet manifest, create the DaemonSet:

  1. kubectl create -f https://k8s.io/examples/controllers/fluentd-daemonset.yaml

Alternatively, use kubectl apply to create the same DaemonSet if you plan to update the DaemonSet with kubectl apply.

  1. kubectl apply -f https://k8s.io/examples/controllers/fluentd-daemonset.yaml

Checking DaemonSet RollingUpdate update strategy

Check the update strategy of your DaemonSet, and make sure it’s set to RollingUpdate:

  1. kubectl get ds/fluentd-elasticsearch -o go-template='{{.spec.updateStrategy.type}}{{"\n"}}' -n kube-system

If you haven’t created the DaemonSet in the system, check your DaemonSet manifest with the following command instead:

  1. kubectl apply -f https://k8s.io/examples/controllers/fluentd-daemonset.yaml --dry-run=client -o go-template='{{.spec.updateStrategy.type}}{{"\n"}}'

The output from both commands should be:

  1. RollingUpdate

If the output isn’t RollingUpdate, go back and modify the DaemonSet object or manifest accordingly.

Updating a DaemonSet template

Any updates to a RollingUpdate DaemonSet .spec.template will trigger a rolling update. Let’s update the DaemonSet by applying a new YAML file. This can be done with several different kubectl commands.

controllers/fluentd-daemonset-update.yaml Perform a Rolling Update on a DaemonSet - 图2

  1. apiVersion: apps/v1
  2. kind: DaemonSet
  3. metadata:
  4. name: fluentd-elasticsearch
  5. namespace: kube-system
  6. labels:
  7. k8s-app: fluentd-logging
  8. spec:
  9. selector:
  10. matchLabels:
  11. name: fluentd-elasticsearch
  12. updateStrategy:
  13. type: RollingUpdate
  14. rollingUpdate:
  15. maxUnavailable: 1
  16. template:
  17. metadata:
  18. labels:
  19. name: fluentd-elasticsearch
  20. spec:
  21. tolerations:
  22. # this toleration is to have the daemonset runnable on master nodes
  23. # remove it if your masters can't run pods
  24. - key: node-role.kubernetes.io/master
  25. effect: NoSchedule
  26. containers:
  27. - name: fluentd-elasticsearch
  28. image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
  29. resources:
  30. limits:
  31. memory: 200Mi
  32. requests:
  33. cpu: 100m
  34. memory: 200Mi
  35. volumeMounts:
  36. - name: varlog
  37. mountPath: /var/log
  38. - name: varlibdockercontainers
  39. mountPath: /var/lib/docker/containers
  40. readOnly: true
  41. terminationGracePeriodSeconds: 30
  42. volumes:
  43. - name: varlog
  44. hostPath:
  45. path: /var/log
  46. - name: varlibdockercontainers
  47. hostPath:
  48. path: /var/lib/docker/containers

Declarative commands

If you update DaemonSets using configuration files, use kubectl apply:

  1. kubectl apply -f https://k8s.io/examples/controllers/fluentd-daemonset-update.yaml

Imperative commands

If you update DaemonSets using imperative commands, use kubectl edit :

  1. kubectl edit ds/fluentd-elasticsearch -n kube-system
Updating only the container image

If you just need to update the container image in the DaemonSet template, i.e. .spec.template.spec.containers[*].image, use kubectl set image:

  1. kubectl set image ds/fluentd-elasticsearch fluentd-elasticsearch=quay.io/fluentd_elasticsearch/fluentd:v2.6.0 -n kube-system

Watching the rolling update status

Finally, watch the rollout status of the latest DaemonSet rolling update:

  1. kubectl rollout status ds/fluentd-elasticsearch -n kube-system

When the rollout is complete, the output is similar to this:

  1. daemonset "fluentd-elasticsearch" successfully rolled out

Troubleshooting

DaemonSet rolling update is stuck

Sometimes, a DaemonSet rolling update may be stuck. Here are some possible causes:

Some nodes run out of resources

The rollout is stuck because new DaemonSet pods can’t be scheduled on at least one node. This is possible when the node is running out of resources.

When this happens, find the nodes that don’t have the DaemonSet pods scheduled on by comparing the output of kubectl get nodes and the output of:

  1. kubectl get pods -l name=fluentd-elasticsearch -o wide -n kube-system

Once you’ve found those nodes, delete some non-DaemonSet pods from the node to make room for new DaemonSet pods.

Note: This will cause service disruption when deleted pods are not controlled by any controllers or pods are not replicated. This does not respect PodDisruptionBudget either.

Broken rollout

If the recent DaemonSet template update is broken, for example, the container is crash looping, or the container image doesn’t exist (often due to a typo), DaemonSet rollout won’t progress.

To fix this, just update the DaemonSet template again. New rollout won’t be blocked by previous unhealthy rollouts.

Clock skew

If .spec.minReadySeconds is specified in the DaemonSet, clock skew between master and nodes will make DaemonSet unable to detect the right rollout progress.

Clean up

Delete DaemonSet from a namespace :

  1. kubectl delete ds fluentd-elasticsearch -n kube-system

What’s next