This page explains how to perform rolling updates for applications in Google Kubernetes Engine (GKE).
Overview
You can perform a rolling update to update the images, configuration, labels, annotations, and resource limits/requests of the workloads in your clusters. Rolling updates incrementally replace your resource's Pods with new ones, which are then scheduled on nodes with available resources. Rolling updates are designed to update your workloads without downtime.
The following objects represent Kubernetes workloads. You can trigger a rolling update on these workloads by updating their Pod template:
- DaemonSets
- Deployments
- StatefulSets
Each of these objects have a
Pod template
represented by the spec: template
field in the object's manifest. The Pod
template field contains a specification for the Pods that the controller creates
to realize the desired state or behavior. You trigger an update rollout by
updating the object's
spec: template
.
The Pod template includes the following fields:
To learn more about the Pod template, refer to the
PodTemplateSpec
documentation.
Scaling a resource or updating fields outside of the Pod template does not trigger a rollout.
Before you begin
Before you start, make sure you have performed the following tasks:
- Enable the Google Kubernetes Engine API. Enable Google Kubernetes Engine API
- If you want to use the Google Cloud CLI for this task,
install and then
initialize the
gcloud CLI. If you previously installed the gcloud CLI, get the latest
version by running
gcloud components update
.
Updating an application
The following section explains how you can update an application using the
Google Cloud console or kubectl
.
kubectl set
You can use kubectl set
to make changes to an object's image
, resources
(compute resource such
as CPU and memory), or selector
fields.
For example, to update a Deployment from nginx
version 1.7.9 to 1.9.1, run
the following command:
kubectl set image deployment nginx nginx=nginx:1.9.1
The kubectl set image
command updates the nginx
image of the Deployment's
Pods one at a time.
As another example, to set the resource requests and limits of the Deployment:
kubectl set resources deployment nginx --limits cpu=200m,memory=512Mi --requests cpu=100m,memory=256Mi
Or, to remove the Deployment's resource requests:
kubectl set resources deployment nginx --limits cpu=0,memory=0 --requests cpu=0,memory=0
kubectl apply
You can use kubectl apply
to update a resource by applying a new or updated configuration.
To apply a new or updated configuration to a resource, run the following command:
kubectl apply -f MANIFEST
Replace MANIFEST
with the name of the manifest file.
If the file doesn't exist, this command creates the resource and applies
the configuration; otherwise, the updated configuration is applied.
Console
To edit the live configuration of an application, perform the following steps:
Go to the Workloads page in the Google Cloud console.
Select the workload that you want to update.
On the Deployment details page, click list Actions > Rolling update.
In the Rolling update dialog, set the image of the workload.
Click Update.
Managing an update rollout
You can use
kubectl rollout
to inspect a rollout as it occurs, to pause and resume a rollout, to rollback an
update, and to view an object's rollout history.
Inspecting a rollout with kubectl rollout status
You can inspect the status of a rollout using the kubectl rollout status
command.
For example, you can inspect the nginx
Deployment's rollout by running the
following command:
kubectl rollout status deployment nginx
The output is similar to the following:
Waiting for rollout to finish: 2 out of 3 newreplicas have been updated...
deployment "nginx" successfully rolled out
After the rollout succeeds, run kubectl get deployment nginx
to verify that
all of its Pods are running. The output is similar to the following:
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
nginx 3 3 3 3 36s
Pausing and resuming a rollout
You can use kubectl rollout pause
to pause a rollout.
For example, to pause the nginx
Deployment's rollout, run the following
command:
kubectl rollout pause deployment nginx
To resume, run the following command:
kubectl rollout resume deployment nginx
Viewing rollout history with kubectl rollout history
You can use kubectl rollout history
to view an object's rollout history.
For example, to view the nginx
Deployment's rollout history, run the following
command:
kubectl rollout history deployment nginx
To see the history of the third revision, run the following command:
kubectl rollout history deployment nginx --revision 3
Rollback an update with kubectl rollout undo
You can rollback an object's rollout using the kubectl rollout undo
command.
For example, to rollback to the previous version of the nginx
Deployment, run
the following command:
kubectl rollout undo deployments nginx
Or, as another example, to rollback to the third revision of the Deployment, run the following command:
kubectl rollout undo deployment nginx --to-revision 3
Considerations for StatefulSets and DaemonSets
StatefulSets since Kubernetes 1.7 and DaemonSets since Kubernetes 1.6 use an
update strategy to configure and disable automated rolling updates for
containers, labels, resource request/limits, and annotations for its Pods. The
update strategy is configured using the spec.updateStrategy
field.
The spec.updateStrategy.type
field accepts either OnDelete
or
RollingUpdate
as values.
OnDelete
is the default behavior when spec.updateStrategy.type
is not
specified. OnDelete
prevents the controller from automatically updating its
Pods. You must manually delete the Pods to cause the controller to create new
Pods that reflect your changes. OnDelete
is useful if you prefer to manually
update Pods.
RollingUpdate
implements automated, rolling updates for the Pods in the
StatefulSet. RollingUpdate
causes the controller to delete and recreate each
of its Pod, and each Pod one at a time. It waits until an updated Pod is
running and ready before to updating its predecessor.
The StatefulSet controller updates all Pods in reverse ordinal order while respecting the StatefulSet guarantees.
Using the RollingUpdate
strategy
You can use the RollingUpdate
strategy to automatically update all Pods in a
StatefulSet or DaemonSet.
For example, to patch the web
StatefulSet to apply the RollingUpdate
strategy, run the following command:
kubectl patch statefulset web -p '{"spec":{"updateStrategy":{"type":"RollingUpdate"}}}'
Next, make a change to the StatefulSet's spec.template
. For example, you can
use kubectl set
to change the container image. In the following example, the
web
StatefulSet is set to have its nginx
container run the nginx-slim:0.7
image:
kubectl set image statefulset web nginx=nginx-slim:0.7
To check that the Pods in the StatefulSet running the nginx
container are
updating, run the following command:
kubectl get pods -l app=nginx -w
The output is similar to the following:
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 7m
web-1 1/1 Running 0 7m
web-2 1/1 Running 0 8m
web-2 1/1 Terminating 0 8m
web-2 1/1 Terminating 0 8m
web-2 0/1 Terminating 0 8m
web-2 0/1 Terminating 0 8m
web-2 0/1 Terminating 0 8m
web-2 0/1 Terminating 0 8m
web-2 0/1 Pending 0 0s
web-2 0/1 Pending 0 0s
web-2 0/1 ContainerCreating 0 0s
web-2 1/1 Running 0 19s
web-1 1/1 Terminating 0 8m
web-1 0/1 Terminating 0 8m
web-1 0/1 Terminating 0 8m
web-1 0/1 Terminating 0 8m
web-1 0/1 Pending 0 0s
web-1 0/1 Pending 0 0s
web-1 0/1 ContainerCreating 0 0s
web-1 1/1 Running 0 6s
web-0 1/1 Terminating 0 7m
web-0 1/1 Terminating 0 7m
web-0 0/1 Terminating 0 7m
web-0 0/1 Terminating 0 7m
web-0 0/1 Terminating 0 7m
web-0 0/1 Terminating 0 7m
web-0 0/1 Pending 0 0s
web-0 0/1 Pending 0 0s
web-0 0/1 ContainerCreating 0 0s
web-0 1/1 Running 0 10s
The Pods in the StatefulSet are updated in reverse ordinal order. The StatefulSet controller terminates each Pod, and waits for it to transition to Running and Ready prior to updating the next Pod.
Partitioning a RollingUpdate
You can specify a partition
parameter a StatefulSet's RollingUpdate
field.
If you specify a partition
, all Pods with an ordinal number that is greater
than or equal to the partition
value are updated. All Pods with an ordinal
number that is less than the partition
value are not updated and, even if
they are deleted, are recreated at the previous version.
If a partition
value is greater than its number of replicas
, updates are not
propagated to its Pods. Partitioning is useful if you want to stage an update,
roll out a canary, or perform a phased roll out.
For example, to partition the web
StatefulSet, run the following command:
kubectl patch statefulset web -p '{"spec":{"updateStrategy":{"type":"RollingUpdate","rollingUpdate":{"partition":3}}}}'
This causes Pods with an ordinal number greater than or equal to 3
to be
updated.
DaemonSet's maxUnavailable
and maxSurge
parameter
DaemonSet's optional maxUnavailable
and maxSurge
parameter are children of
the DaemonSet's rollingUpdate
field.
maxUnavailable
determines the maximum number of DaemonSet Pods that can be
unavailable during updates. The default value, if omitted, is 1
.
maxSurge
is the maximum number of nodes with an existing available DaemonSet
Pod that can have an updated DaemonSet Pod during during an update.
The default value, if omitted, is 0
.
Neither value can be 0
if the other value is 0
. Both the values can be an
absolute number or a percentage.
To learn more, see the DaemonSetSpec.
Updating with the OnDelete
strategy
If you prefer to update a StatefulSet or DaemonSet manually, you can omit the
spec.updateStrategy
field, which instructs the controller to use the OnDelete
strategy.
To update a controller that uses the OnDelete
strategy, you must manually
delete its Pods after making changes to its Pod template.
For example, you can set the web
StatefulSet to use the nginx-slim:0.7
image:
kubectl set image statefulset web nginx=nginx-slim:0.7
Then, to delete the first web
Pod, run the following command:
kubectl delete pod web-0
To watch as the Pod is recreated by the StatefulSet and transitions to Running and Ready, run the following command:
kubectl get pod web-0 -w
The output of this command is similar to the following:
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 54s
web-0 1/1 Terminating 0 1m
web-0 0/1 Terminating 0 1m
web-0 0/1 Terminating 0 1m
web-0 0/1 Terminating 0 1m
web-0 0/1 Pending 0 0s
web-0 0/1 Pending 0 0s
web-0 0/1 ContainerCreating 0 0s
web-0 1/1 Running 0 3s
Updating a Job
When you update a Job's configuration, the new Job and its Pods run with the new configuration. After updating a Job, you must manually delete the old Job and its Pods, if needed.
To delete a Job and all of its Pods, run the following command:
kubectl delete job my-job
To delete a Job but keep its Pods running, specify the --cascade=false
flag:
kubectl delete job my-job --cascade=false
You can also run kubectl describe deployment nginx
, which yields even more
information about the Deployment.