Update and organize the content on Deployments (#14861)
* Update and organize the content on Deployments fix formatting issues Format a note Formats the content Format content Fix formatting issues Format content Format content Update and organize the content on Deployments * Update the content as per the comments * Update as per the comments * Update as per the comments
This commit is contained in:
committed by
Kubernetes Prow Robot
parent
b692fddd32
commit
0f4543b94b
@@ -17,10 +17,10 @@ weight: 30
|
||||
A _Deployment_ controller provides declarative updates for [Pods](/docs/concepts/workloads/pods/pod/) and
|
||||
[ReplicaSets](/docs/concepts/workloads/controllers/replicaset/).
|
||||
|
||||
You describe a _desired state_ in a Deployment object, and the Deployment controller changes the actual state to the desired state at a controlled rate. You can define Deployments to create new ReplicaSets, or to remove existing Deployments and adopt all their resources with new Deployments.
|
||||
You describe a _desired state_ in a Deployment, and the Deployment controller changes the actual state to the desired state at a controlled rate. You can define Deployments to create new ReplicaSets, or to remove existing Deployments and adopt all their resources with new Deployments.
|
||||
|
||||
{{< note >}}
|
||||
You should not manage ReplicaSets owned by a Deployment. All the use cases should be covered by manipulating the Deployment object. Consider opening an issue in the main Kubernetes repository if your use case is not covered below.
|
||||
Do not manage ReplicaSets owned by a Deployment. Consider opening an issue in the main Kubernetes repository if your use case is not covered below.
|
||||
{{< /note >}}
|
||||
|
||||
{{% /capture %}}
|
||||
@@ -54,11 +54,11 @@ In this example:
|
||||
In this case, you simply select a label that is defined in the Pod template (`app: nginx`).
|
||||
However, more sophisticated selection rules are possible,
|
||||
as long as the Pod template itself satisfies the rule.
|
||||
|
||||
{{< note >}}
|
||||
`matchLabels` is a map of {key,value} pairs. A single {key,value} in the `matchLabels` map
|
||||
is equivalent to an element of `matchExpressions`, whose key field is "key", the operator is "In",
|
||||
and the values array contains only "value". The requirements are ANDed.
|
||||
The `matchLabels` field is a map of {key,value} pairs. A single {key,value} in the `matchLabels` map
|
||||
is equivalent to an element of `matchExpressions`, whose key field is "key" the operator is "In",
|
||||
and the values array contains only "value".
|
||||
All of the requirements, from both `matchLabels` and `matchExpressions`, must be satisfied in order to match.
|
||||
{{< /note >}}
|
||||
|
||||
* The `template` field contains the following sub-fields:
|
||||
@@ -67,81 +67,67 @@ In this example:
|
||||
the Pods run one container, `nginx`, which runs the `nginx`
|
||||
[Docker Hub](https://hub.docker.com/) image at version 1.7.9.
|
||||
* Create one container and name it `nginx` using the `name` field.
|
||||
* Open port `80` so that the container can send and accept traffic.
|
||||
|
||||
To create this Deployment, run the following command:
|
||||
Follow the steps given below to create the above Deployment:
|
||||
|
||||
Before you begin, make sure your Kubernetes cluster is up and running.
|
||||
|
||||
1. Create the Deployment by running the following command:
|
||||
|
||||
{{< note >}}
|
||||
You may specify the `--record` flag to write the command executed in the resource annotation `kubernetes.io/change-cause`. It is useful for future introspection.
|
||||
For example, to see the commands executed in each Deployment revision.
|
||||
{{< /note >}}
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/controllers/nginx-deployment.yaml
|
||||
```
|
||||
|
||||
{{< note >}}
|
||||
You may specify the `--record` flag to write the command executed in the resource annotation `kubernetes.io/change-cause`. It is useful for future introspection, for example to see the commands executed in each Deployment revision.
|
||||
{{< /note >}}
|
||||
|
||||
Next, run `kubectl get deployments`. The output is similar to the following:
|
||||
|
||||
2. Run `kubectl get deployments` to check if the Deployment was created. If the Deployment is still being created, the output is similar to the following:
|
||||
```shell
|
||||
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
|
||||
nginx-deployment 3 0 0 0 1s
|
||||
```
|
||||
|
||||
When you inspect the Deployments in your cluster, the following fields are displayed:
|
||||
|
||||
* `NAME` lists the names of the Deployments in the cluster.
|
||||
* `DESIRED` displays the desired number of _replicas_ of the application, which
|
||||
you define when you create the Deployment. This is the _desired state_.
|
||||
* `DESIRED` displays the desired number of _replicas_ of the application, which you define when you create the Deployment. This is the _desired state_.
|
||||
* `CURRENT` displays how many replicas are currently running.
|
||||
* `UP-TO-DATE` displays the number of replicas that have been updated to achieve
|
||||
the desired state.
|
||||
* `AVAILABLE` displays how many replicas of the application are available to
|
||||
your users.
|
||||
* `UP-TO-DATE` displays the number of replicas that have been updated to achieve the desired state.
|
||||
* `AVAILABLE` displays how many replicas of the application are available to your users.
|
||||
* `AGE` displays the amount of time that the application has been running.
|
||||
|
||||
Notice how the values in each field correspond to the values in the Deployment specification:
|
||||
|
||||
* The number of desired replicas is 3 according to `.spec.replicas` field.
|
||||
* The number of current replicas is 0 according to the `.status.replicas` field.
|
||||
* The number of up-to-date replicas is 0 according to the `.status.updatedReplicas` field.
|
||||
* The number of available replicas is 0 according to the `.status.availableReplicas` field.
|
||||
|
||||
To see the Deployment rollout status, run `kubectl rollout status deployment.v1.apps/nginx-deployment`. This command returns the following output:
|
||||
Notice how the number of desired replicas is 3 according to `.spec.replicas` field.
|
||||
|
||||
3. To see the Deployment rollout status, run `kubectl rollout status deployment.v1.apps/nginx-deployment`. The output is similar to this:
|
||||
```shell
|
||||
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
|
||||
deployment.apps/nginx-deployment successfully rolled out
|
||||
```
|
||||
|
||||
Run the `kubectl get deployments` again a few seconds later:
|
||||
|
||||
4. Run the `kubectl get deployments` again a few seconds later. The output is similar to this:
|
||||
```shell
|
||||
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
|
||||
nginx-deployment 3 3 3 3 18s
|
||||
```
|
||||
Notice that the Deployment has created all three replicas, and all replicas are up-to-date (they contain the latest Pod template) and available.
|
||||
|
||||
Notice that the Deployment has created all three replicas, and all replicas are up-to-date (they contain the
|
||||
latest Pod template) and available (the Pod status is Ready for at least the value of the Deployment's `.spec.minReadySeconds` field).
|
||||
|
||||
To see the ReplicaSet (`rs`) created by the deployment, run `kubectl get rs`:
|
||||
|
||||
5. To see the ReplicaSet (`rs`) created by the Deployment, run `kubectl get rs`. The output is similar to this:
|
||||
```shell
|
||||
NAME DESIRED CURRENT READY AGE
|
||||
nginx-deployment-75675f5897 3 3 3 18s
|
||||
```
|
||||
|
||||
Notice that the name of the ReplicaSet is always formatted as `[DEPLOYMENT-NAME]-[RANDOM-STRING]`. The random string is
|
||||
randomly generated and uses the pod-template-hash as a seed.
|
||||
|
||||
To see the labels automatically generated for each pod, run `kubectl get pods --show-labels`. The following output is returned:
|
||||
|
||||
6. To see the labels automatically generated for each Pod, run `kubectl get pods --show-labels`. The following output is returned:
|
||||
```shell
|
||||
NAME READY STATUS RESTARTS AGE LABELS
|
||||
nginx-deployment-75675f5897-7ci7o 1/1 Running 0 18s app=nginx,pod-template-hash=3123191453
|
||||
nginx-deployment-75675f5897-kzszj 1/1 Running 0 18s app=nginx,pod-template-hash=3123191453
|
||||
nginx-deployment-75675f5897-qqcnn 1/1 Running 0 18s app=nginx,pod-template-hash=3123191453
|
||||
```
|
||||
|
||||
The created ReplicaSet ensures that there are three `nginx` Pods running at all times.
|
||||
The created ReplicaSet ensures that there are three `nginx` Pods.
|
||||
|
||||
{{< note >}}
|
||||
You must specify an appropriate selector and Pod template labels in a Deployment (in this case,
|
||||
@@ -162,18 +148,20 @@ and in any existing Pods that the ReplicaSet might have.
|
||||
## Updating a Deployment
|
||||
|
||||
{{< note >}}
|
||||
A Deployment's rollout is triggered if and only if the Deployment's pod template (that is, `.spec.template`)
|
||||
A Deployment's rollout is triggered if and only if the Deployment's Pod template (that is, `.spec.template`)
|
||||
is changed, for example if the labels or container images of the template are updated. Other updates, such as scaling the Deployment, do not trigger a rollout.
|
||||
{{< /note >}}
|
||||
|
||||
Suppose that you now want to update the nginx Pods to use the `nginx:1.9.1` image
|
||||
instead of the `nginx:1.7.9` image.
|
||||
Follow the steps given below to update your Deployment:
|
||||
|
||||
1. Let's update the nginx Pods to use the `nginx:1.9.1` image instead of the `nginx:1.7.9` image.
|
||||
|
||||
```shell
|
||||
kubectl --record deployment.apps/nginx-deployment set image deployment.v1.apps/nginx-deployment nginx=nginx:1.9.1
|
||||
```
|
||||
The output is similar to this:
|
||||
```
|
||||
image updated
|
||||
deployment.apps/nginx-deployment image updated
|
||||
```
|
||||
|
||||
Alternatively, you can `edit` the Deployment and change `.spec.template.spec.containers[0].image` from `nginx:1.7.9` to `nginx:1.9.1`:
|
||||
@@ -181,51 +169,57 @@ Alternatively, you can `edit` the Deployment and change `.spec.template.spec.con
|
||||
```shell
|
||||
kubectl edit deployment.v1.apps/nginx-deployment
|
||||
```
|
||||
|
||||
The output is similar to this:
|
||||
```
|
||||
deployment.apps/nginx-deployment edited
|
||||
```
|
||||
|
||||
To see the rollout status, run:
|
||||
2. To see the rollout status, run:
|
||||
|
||||
```shell
|
||||
kubectl rollout status deployment.v1.apps/nginx-deployment
|
||||
```
|
||||
|
||||
The output is similar to this:
|
||||
```
|
||||
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
|
||||
```
|
||||
or
|
||||
```
|
||||
deployment.apps/nginx-deployment successfully rolled out
|
||||
```
|
||||
|
||||
After the rollout succeeds, you may want to `get` the Deployment:
|
||||
Get more details on your updated Deployment:
|
||||
|
||||
```shell
|
||||
kubectl get deployments
|
||||
```
|
||||
* After the rollout succeeds, you can view the Deployment by running `kubectl get deployments`.
|
||||
The output is similar to this:
|
||||
```
|
||||
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
|
||||
nginx-deployment 3 3 3 3 36s
|
||||
```
|
||||
|
||||
The number of up-to-date replicas indicates that the Deployment has updated the replicas to the latest configuration.
|
||||
The current replicas indicates the total replicas this Deployment manages, and the available replicas indicates the
|
||||
number of current replicas that are available.
|
||||
|
||||
You can run `kubectl get rs` to see that the Deployment updated the Pods by creating a new ReplicaSet and scaling it
|
||||
* Run `kubectl get rs` to see that the Deployment updated the Pods by creating a new ReplicaSet and scaling it
|
||||
up to 3 replicas, as well as scaling down the old ReplicaSet to 0 replicas.
|
||||
|
||||
```shell
|
||||
kubectl get rs
|
||||
```
|
||||
|
||||
The output is similar to this:
|
||||
```
|
||||
NAME DESIRED CURRENT READY AGE
|
||||
nginx-deployment-1564180365 3 3 3 6s
|
||||
nginx-deployment-2035384211 0 0 0 36s
|
||||
```
|
||||
|
||||
Running `get pods` should now show only the new Pods:
|
||||
* Running `get pods` should now show only the new Pods:
|
||||
|
||||
```shell
|
||||
kubectl get pods
|
||||
```
|
||||
|
||||
The output is similar to this:
|
||||
```
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
nginx-deployment-1564180365-khku8 1/1 Running 0 14s
|
||||
@@ -233,22 +227,24 @@ nginx-deployment-1564180365-nacti 1/1 Running 0 14s
|
||||
nginx-deployment-1564180365-z9gth 1/1 Running 0 14s
|
||||
```
|
||||
|
||||
Next time you want to update these Pods, you only need to update the Deployment's pod template again.
|
||||
Next time you want to update these Pods, you only need to update the Deployment's Pod template again.
|
||||
|
||||
Deployment can ensure that only a certain number of Pods may be down while they are being updated. By
|
||||
default, it ensures that at least 25% less than the desired number of Pods are up (25% max unavailable).
|
||||
Deployment ensures that only a certain number of Pods are down while they are being updated. By default,
|
||||
it ensures that at least 25% of the desired number of Pods are up (25% max unavailable).
|
||||
|
||||
Deployment can also ensure that only a certain number of Pods may be created above the desired number of
|
||||
Pods. By default, it ensures that at most 25% more than the desired number of Pods are up (25% max surge).
|
||||
Deployment also ensures that only a certain number of Pods are created above the desired number of Pods.
|
||||
By default, it ensures that at most 25% of the desired number of Pods are up (25% max surge).
|
||||
|
||||
For example, if you look at the above Deployment closely, you will see that it first created a new Pod,
|
||||
then deleted some old Pods and created new ones. It does not kill old Pods until a sufficient number of
|
||||
then deleted some old Pods, and created new ones. It does not kill old Pods until a sufficient number of
|
||||
new Pods have come up, and does not create new Pods until a sufficient number of old Pods have been killed.
|
||||
It makes sure that number of available Pods is at least 2 and the number of total Pods is at most 4.
|
||||
It makes sure that at least 2 Pods are available and that at max 4 Pods in total are available.
|
||||
|
||||
* Get details of your Deployment:
|
||||
```shell
|
||||
kubectl describe deployments
|
||||
```
|
||||
The output is similar to this:
|
||||
```
|
||||
Name: nginx-deployment
|
||||
Namespace: default
|
||||
@@ -287,7 +283,6 @@ Events:
|
||||
Normal ScalingReplicaSet 19s deployment-controller Scaled up replica set nginx-deployment-1564180365 to 3
|
||||
Normal ScalingReplicaSet 14s deployment-controller Scaled down replica set nginx-deployment-2035384211 to 0
|
||||
```
|
||||
|
||||
Here you see that when you first created the Deployment, it created a ReplicaSet (nginx-deployment-2035384211)
|
||||
and scaled it up to 3 replicas directly. When you updated the Deployment, it created a new ReplicaSet
|
||||
(nginx-deployment-1564180365) and scaled it up to 1 and then scaled down the old ReplicaSet to 2, so that at
|
||||
@@ -297,20 +292,20 @@ in the new ReplicaSet, and the old ReplicaSet is scaled down to 0.
|
||||
|
||||
### Rollover (aka multiple updates in-flight)
|
||||
|
||||
Each time a new deployment object is observed by the Deployment controller, a ReplicaSet is created to bring up
|
||||
the desired Pods if there is no existing ReplicaSet doing so. Existing ReplicaSet controlling Pods whose labels
|
||||
Each time a new Deployment is observed by the Deployment controller, a ReplicaSet is created to bring up
|
||||
the desired Pods. If the Deployment is updated, the existing ReplicaSet that controls Pods whose labels
|
||||
match `.spec.selector` but whose template does not match `.spec.template` are scaled down. Eventually, the new
|
||||
ReplicaSet will be scaled to `.spec.replicas` and all old ReplicaSets will be scaled to 0.
|
||||
ReplicaSet is scaled to `.spec.replicas` and all old ReplicaSets is scaled to 0.
|
||||
|
||||
If you update a Deployment while an existing rollout is in progress, the Deployment will create a new ReplicaSet
|
||||
as per the update and start scaling that up, and will roll over the ReplicaSet that it was scaling up previously
|
||||
-- it will add it to its list of old ReplicaSets and will start scaling it down.
|
||||
If you update a Deployment while an existing rollout is in progress, the Deployment creates a new ReplicaSet
|
||||
as per the update and start scaling that up, and rolls over the ReplicaSet that it was scaling up previously
|
||||
-- it will add it to its list of old ReplicaSets and start scaling it down.
|
||||
|
||||
For example, suppose you create a Deployment to create 5 replicas of `nginx:1.7.9`,
|
||||
but then updates the Deployment to create 5 replicas of `nginx:1.9.1`, when only 3
|
||||
replicas of `nginx:1.7.9` had been created. In that case, Deployment will immediately start
|
||||
killing the 3 `nginx:1.7.9` Pods that it had created, and will start creating
|
||||
`nginx:1.9.1` Pods. It will not wait for 5 replicas of `nginx:1.7.9` to be created
|
||||
but then update the Deployment to create 5 replicas of `nginx:1.9.1`, when only 3
|
||||
replicas of `nginx:1.7.9` had been created. In that case, the Deployment immediately starts
|
||||
killing the 3 `nginx:1.7.9` Pods that it had created, and starts creating
|
||||
`nginx:1.9.1` Pods. It does not wait for the 5 replicas of `nginx:1.7.9` to be created
|
||||
before changing course.
|
||||
|
||||
### Label selector updates
|
||||
@@ -323,56 +318,62 @@ all of the implications.
|
||||
In API version `apps/v1`, a Deployment's label selector is immutable after it gets created.
|
||||
{{< /note >}}
|
||||
|
||||
* Selector additions require the pod template labels in the Deployment spec to be updated with the new label too,
|
||||
* Selector additions require the Pod template labels in the Deployment spec to be updated with the new label too,
|
||||
otherwise a validation error is returned. This change is a non-overlapping one, meaning that the new selector does
|
||||
not select ReplicaSets and Pods created with the old selector, resulting in orphaning all old ReplicaSets and
|
||||
creating a new ReplicaSet.
|
||||
* Selector updates -- that is, changing the existing value in a selector key -- result in the same behavior as additions.
|
||||
* Selector removals -- that is, removing an existing key from the Deployment selector -- do not require any changes in the
|
||||
pod template labels. No existing ReplicaSet is orphaned, and a new ReplicaSet is not created, but note that the
|
||||
* Selector updates changes the existing value in a selector key -- result in the same behavior as additions.
|
||||
* Selector removals removes an existing key from the Deployment selector -- do not require any changes in the
|
||||
Pod template labels. Existing ReplicaSets are not orphaned, and a new ReplicaSet is not created, but note that the
|
||||
removed label still exists in any existing Pods and ReplicaSets.
|
||||
|
||||
## Rolling Back a Deployment
|
||||
|
||||
Sometimes you may want to rollback a Deployment; for example, when the Deployment is not stable, such as crash looping.
|
||||
Sometimes, you may want to rollback a Deployment; for example, when the Deployment is not stable, such as crash looping.
|
||||
By default, all of the Deployment's rollout history is kept in the system so that you can rollback anytime you want
|
||||
(you can change that by modifying revision history limit).
|
||||
|
||||
{{< note >}}
|
||||
A Deployment's revision is created when a Deployment's rollout is triggered. This means that the
|
||||
new revision is created if and only if the Deployment's pod template (`.spec.template`) is changed,
|
||||
new revision is created if and only if the Deployment's Pod template (`.spec.template`) is changed,
|
||||
for example if you update the labels or container images of the template. Other updates, such as scaling the Deployment,
|
||||
do not create a Deployment revision, so that you can facilitate simultaneous manual- or auto-scaling.
|
||||
This means that when you roll back to an earlier revision, only the Deployment's pod template part is
|
||||
This means that when you roll back to an earlier revision, only the Deployment's Pod template part is
|
||||
rolled back.
|
||||
{{< /note >}}
|
||||
|
||||
Suppose that you made a typo while updating the Deployment, by putting the image name as `nginx:1.91` instead of `nginx:1.9.1`:
|
||||
* Suppose that you made a typo while updating the Deployment, by putting the image name as `nginx:1.91` instead of `nginx:1.9.1`:
|
||||
|
||||
```shell
|
||||
kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.91 --record=true
|
||||
```
|
||||
|
||||
The output is similar to this:
|
||||
```
|
||||
deployment.apps/nginx-deployment image updated
|
||||
```
|
||||
|
||||
The rollout will be stuck.
|
||||
* The rollout gets stuck. You can verify it by checking the rollout status:
|
||||
|
||||
```shell
|
||||
kubectl rollout status deployment.v1.apps/nginx-deployment
|
||||
```
|
||||
|
||||
The output is similar to this:
|
||||
```
|
||||
Waiting for rollout to finish: 1 out of 3 new replicas have been updated...
|
||||
```
|
||||
|
||||
Press Ctrl-C to stop the above rollout status watch. For more information on stuck rollouts,
|
||||
* Press Ctrl-C to stop the above rollout status watch. For more information on stuck rollouts,
|
||||
[read more here](#deployment-status).
|
||||
|
||||
You will see that the number of old replicas (nginx-deployment-1564180365 and nginx-deployment-2035384211) is 2, and new replicas (nginx-deployment-3066724191) is 1.
|
||||
* You see that the number of old replicas (`nginx-deployment-1564180365` and `nginx-deployment-2035384211`) is 2, and new replicas (nginx-deployment-3066724191) is 1.
|
||||
|
||||
```shell
|
||||
kubectl get rs
|
||||
```
|
||||
|
||||
The output is similar to this:
|
||||
```
|
||||
NAME DESIRED CURRENT READY AGE
|
||||
nginx-deployment-1564180365 3 3 3 25s
|
||||
@@ -380,11 +381,13 @@ nginx-deployment-2035384211 0 0 0 36s
|
||||
nginx-deployment-3066724191 1 1 0 6s
|
||||
```
|
||||
|
||||
Looking at the Pods created, you will see that 1 Pod created by new ReplicaSet is stuck in an image pull loop.
|
||||
* Looking at the Pods created, you see that 1 Pod created by new ReplicaSet is stuck in an image pull loop.
|
||||
|
||||
```shell
|
||||
kubectl get pods
|
||||
```
|
||||
|
||||
The output is similar to this:
|
||||
```
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
nginx-deployment-1564180365-70iae 1/1 Running 0 25s
|
||||
@@ -394,14 +397,17 @@ nginx-deployment-3066724191-08mng 0/1 ImagePullBackOff 0 6s
|
||||
```
|
||||
|
||||
{{< note >}}
|
||||
The Deployment controller will stop the bad rollout automatically, and will stop scaling up the new
|
||||
The Deployment controller stops the bad rollout automatically, and stops scaling up the new
|
||||
ReplicaSet. This depends on the rollingUpdate parameters (`maxUnavailable` specifically) that you have specified.
|
||||
Kubernetes by default sets the value to 25%.
|
||||
{{< /note >}}
|
||||
|
||||
* Get the description of the Deployment:
|
||||
```shell
|
||||
kubectl describe deployment
|
||||
```
|
||||
|
||||
The output is similar to this:
|
||||
```
|
||||
Name: nginx-deployment
|
||||
Namespace: default
|
||||
@@ -446,11 +452,13 @@ To fix this, you need to rollback to a previous revision of Deployment that is s
|
||||
|
||||
### Checking Rollout History of a Deployment
|
||||
|
||||
First, check the revisions of this deployment:
|
||||
Follow the steps given below to check the rollout history:
|
||||
|
||||
1. First, check the revisions of this Deployment:
|
||||
```shell
|
||||
kubectl rollout history deployment.v1.apps/nginx-deployment
|
||||
```
|
||||
The output is similar to this:
|
||||
```
|
||||
deployments "nginx-deployment"
|
||||
REVISION CHANGE-CAUSE
|
||||
@@ -458,17 +466,19 @@ REVISION CHANGE-CAUSE
|
||||
2 kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.9.1 --record=true
|
||||
3 kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.91 --record=true
|
||||
```
|
||||
`CHANGE-CAUSE` is copied from the Deployment annotation `kubernetes.io/change-cause` to its revisions upon creation. You could specify the`CHANGE-CAUSE` message by:
|
||||
|
||||
`CHANGE-CAUSE` is copied from the Deployment annotation `kubernetes.io/change-cause` to its revisions upon creation. You can specify the`CHANGE-CAUSE` message by:
|
||||
|
||||
* Annotating the Deployment with `kubectl annotate deployment.v1.apps/nginx-deployment kubernetes.io/change-cause="image updated to 1.9.1"`
|
||||
* Append the `--record` flag to save the `kubectl` command that is making changes to the resource.
|
||||
* Manually editing the manifest of the resource.
|
||||
|
||||
To further see the details of each revision, run:
|
||||
|
||||
2. To see the details of each revision, run:
|
||||
```shell
|
||||
kubectl rollout history deployment.v1.apps/nginx-deployment --revision=2
|
||||
```
|
||||
|
||||
The output is similar to this:
|
||||
```
|
||||
deployments "nginx-deployment" revision 2
|
||||
Labels: app=nginx
|
||||
@@ -486,21 +496,24 @@ deployments "nginx-deployment" revision 2
|
||||
```
|
||||
|
||||
### Rolling Back to a Previous Revision
|
||||
Follow the steps given below to rollback the Deployment from the current version to the previous version, which is version 2.
|
||||
|
||||
Now you've decided to undo the current rollout and rollback to the previous revision:
|
||||
|
||||
1. Now you've decided to undo the current rollout and rollback to the previous revision:
|
||||
```shell
|
||||
kubectl rollout undo deployment.v1.apps/nginx-deployment
|
||||
```
|
||||
|
||||
The output is similar to this:
|
||||
```
|
||||
deployment.apps/nginx-deployment
|
||||
```
|
||||
|
||||
Alternatively, you can rollback to a specific revision by specifying it with `--to-revision`:
|
||||
|
||||
```shell
|
||||
kubectl rollout undo deployment.v1.apps/nginx-deployment --to-revision=2
|
||||
```
|
||||
|
||||
The output is similar to this:
|
||||
```
|
||||
deployment.apps/nginx-deployment
|
||||
```
|
||||
@@ -510,17 +523,21 @@ For more details about rollout related commands, read [`kubectl rollout`](/docs/
|
||||
The Deployment is now rolled back to a previous stable revision. As you can see, a `DeploymentRollback` event
|
||||
for rolling back to revision 2 is generated from Deployment controller.
|
||||
|
||||
2. Check if the rollback was successful and the Deployment is running as expected, run:
|
||||
```shell
|
||||
kubectl get deployment nginx-deployment
|
||||
```
|
||||
|
||||
The output is similar to this:
|
||||
```
|
||||
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
|
||||
nginx-deployment 3 3 3 3 30m
|
||||
```
|
||||
|
||||
3. Get the description of the Deployment:
|
||||
```shell
|
||||
kubectl describe deployment nginx-deployment
|
||||
```
|
||||
The output is similar to this:
|
||||
```
|
||||
Name: nginx-deployment
|
||||
Namespace: default
|
||||
@@ -572,17 +589,19 @@ You can scale a Deployment by using the following command:
|
||||
```shell
|
||||
kubectl scale deployment.v1.apps/nginx-deployment --replicas=10
|
||||
```
|
||||
The output is similar to this:
|
||||
```
|
||||
deployment.apps/nginx-deployment scaled
|
||||
```
|
||||
|
||||
Assuming [horizontal pod autoscaling](/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/) is enabled
|
||||
Assuming [horizontal Pod autoscaling](/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/) is enabled
|
||||
in your cluster, you can setup an autoscaler for your Deployment and choose the minimum and maximum number of
|
||||
Pods you want to run based on the CPU utilization of your existing Pods.
|
||||
|
||||
```shell
|
||||
kubectl autoscale deployment.v1.apps/nginx-deployment --min=10 --max=15 --cpu-percent=80
|
||||
```
|
||||
The output is similar to this:
|
||||
```
|
||||
deployment.apps/nginx-deployment scaled
|
||||
```
|
||||
@@ -591,62 +610,70 @@ deployment.apps/nginx-deployment scaled
|
||||
|
||||
RollingUpdate Deployments support running multiple versions of an application at the same time. When you
|
||||
or an autoscaler scales a RollingUpdate Deployment that is in the middle of a rollout (either in progress
|
||||
or paused), then the Deployment controller will balance the additional replicas in the existing active
|
||||
or paused), the Deployment controller balances the additional replicas in the existing active
|
||||
ReplicaSets (ReplicaSets with Pods) in order to mitigate risk. This is called *proportional scaling*.
|
||||
|
||||
For example, you are running a Deployment with 10 replicas, [maxSurge](#max-surge)=3, and [maxUnavailable](#max-unavailable)=2.
|
||||
|
||||
* Ensure that the 10 replicas in your Deployment are running.
|
||||
```shell
|
||||
kubectl get deploy
|
||||
```
|
||||
The output is similar to this:
|
||||
|
||||
```
|
||||
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
|
||||
nginx-deployment 10 10 10 10 50s
|
||||
```
|
||||
|
||||
You update to a new image which happens to be unresolvable from inside the cluster.
|
||||
|
||||
* You update to a new image which happens to be unresolvable from inside the cluster.
|
||||
```shell
|
||||
kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:sometag
|
||||
```
|
||||
|
||||
The output is similar to this:
|
||||
```
|
||||
deployment.apps/nginx-deployment image updated
|
||||
```
|
||||
|
||||
The image update starts a new rollout with ReplicaSet nginx-deployment-1989198191, but it's blocked due to the
|
||||
`maxUnavailable` requirement that you mentioned above.
|
||||
|
||||
* The image update starts a new rollout with ReplicaSet nginx-deployment-1989198191, but it's blocked due to the
|
||||
`maxUnavailable` requirement that you mentioned above. Check out the rollout status:
|
||||
```shell
|
||||
kubectl get rs
|
||||
```
|
||||
The output is similar to this:
|
||||
```
|
||||
NAME DESIRED CURRENT READY AGE
|
||||
nginx-deployment-1989198191 5 5 0 9s
|
||||
nginx-deployment-618515232 8 8 8 1m
|
||||
```
|
||||
|
||||
Then a new scaling request for the Deployment comes along. The autoscaler increments the Deployment replicas
|
||||
* Then a new scaling request for the Deployment comes along. The autoscaler increments the Deployment replicas
|
||||
to 15. The Deployment controller needs to decide where to add these new 5 replicas. If you weren't using
|
||||
proportional scaling, all 5 of them would be added in the new ReplicaSet. With proportional scaling, you
|
||||
spread the additional replicas across all ReplicaSets. Bigger proportions go to the ReplicaSets with the
|
||||
most replicas and lower proportions go to ReplicaSets with less replicas. Any leftovers are added to the
|
||||
ReplicaSet with the most replicas. ReplicaSets with zero replicas are not scaled up.
|
||||
|
||||
In our example above, 3 replicas will be added to the old ReplicaSet and 2 replicas will be added to the
|
||||
In our example above, 3 replicas are added to the old ReplicaSet and 2 replicas are added to the
|
||||
new ReplicaSet. The rollout process should eventually move all replicas to the new ReplicaSet, assuming
|
||||
the new replicas become healthy.
|
||||
the new replicas become healthy. To confirm this, run:
|
||||
|
||||
```shell
|
||||
kubectl get deploy
|
||||
```
|
||||
|
||||
The output is similar to this:
|
||||
```
|
||||
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
|
||||
nginx-deployment 15 18 7 8 7m
|
||||
```
|
||||
|
||||
The rollout status confirms how the replicas were added to each ReplicaSet.
|
||||
```shell
|
||||
kubectl get rs
|
||||
```
|
||||
|
||||
The output is similar to this:
|
||||
```
|
||||
NAME DESIRED CURRENT READY AGE
|
||||
nginx-deployment-1989198191 7 7 0 7m
|
||||
@@ -655,68 +682,77 @@ nginx-deployment-618515232 11 11 11 7m
|
||||
|
||||
## Pausing and Resuming a Deployment
|
||||
|
||||
You can pause a Deployment before triggering one or more updates and then resume it. This will allow you to
|
||||
You can pause a Deployment before triggering one or more updates and then resume it. This allows you to
|
||||
apply multiple fixes in between pausing and resuming without triggering unnecessary rollouts.
|
||||
|
||||
For example, with a Deployment that was just created:
|
||||
|
||||
* For example, with a Deployment that was just created:
|
||||
Get the Deployment details:
|
||||
```shell
|
||||
kubectl get deploy
|
||||
```
|
||||
The output is similar to this:
|
||||
```
|
||||
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
|
||||
nginx 3 3 3 3 1m
|
||||
```
|
||||
Get the rollout status:
|
||||
```shell
|
||||
kubectl get rs
|
||||
```
|
||||
The output is similar to this:
|
||||
```
|
||||
NAME DESIRED CURRENT READY AGE
|
||||
nginx-2142116321 3 3 3 1m
|
||||
```
|
||||
|
||||
Pause by running the following command:
|
||||
|
||||
* Pause by running the following command:
|
||||
```shell
|
||||
kubectl rollout pause deployment.v1.apps/nginx-deployment
|
||||
```
|
||||
|
||||
The output is similar to this:
|
||||
```
|
||||
deployment.apps/nginx-deployment paused
|
||||
```
|
||||
|
||||
Then update the image of the Deployment:
|
||||
|
||||
* Then update the image of the Deployment:
|
||||
```shell
|
||||
kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.9.1
|
||||
```
|
||||
|
||||
The output is similar to this:
|
||||
```
|
||||
deployment.apps/nginx-deployment image updated
|
||||
```
|
||||
|
||||
Notice that no new rollout started:
|
||||
|
||||
* Notice that no new rollout started:
|
||||
```shell
|
||||
kubectl rollout history deployment.v1.apps/nginx-deployment
|
||||
```
|
||||
|
||||
The output is similar to this:
|
||||
```
|
||||
deployments "nginx"
|
||||
REVISION CHANGE-CAUSE
|
||||
1 <none>
|
||||
```
|
||||
|
||||
* Get the rollout status to ensure that the Deployment is updates successfully:
|
||||
```shell
|
||||
kubectl get rs
|
||||
```
|
||||
|
||||
The output is similar to this:
|
||||
```
|
||||
NAME DESIRED CURRENT READY AGE
|
||||
nginx-2142116321 3 3 3 2m
|
||||
```
|
||||
|
||||
You can make as many updates as you wish, for example, update the resources that will be used:
|
||||
|
||||
* You can make as many updates as you wish, for example, update the resources that will be used:
|
||||
```shell
|
||||
kubectl set resources deployment.v1.apps/nginx-deployment -c=nginx --limits=cpu=200m,memory=512Mi
|
||||
```
|
||||
|
||||
The output is similar to this:
|
||||
```
|
||||
deployment.apps/nginx-deployment resource requirements updated
|
||||
```
|
||||
@@ -724,20 +760,21 @@ deployment.apps/nginx-deployment resource requirements updated
|
||||
The initial state of the Deployment prior to pausing it will continue its function, but new updates to
|
||||
the Deployment will not have any effect as long as the Deployment is paused.
|
||||
|
||||
Eventually, resume the Deployment and observe a new ReplicaSet coming up with all the new updates:
|
||||
|
||||
* Eventually, resume the Deployment and observe a new ReplicaSet coming up with all the new updates:
|
||||
```shell
|
||||
kubectl rollout resume deployment.v1.apps/nginx-deployment
|
||||
```
|
||||
|
||||
The output is similar to this:
|
||||
```
|
||||
deployment.apps/nginx-deployment resumed
|
||||
```
|
||||
|
||||
* Watch the status of the rollout until it's done.
|
||||
```shell
|
||||
kubectl get rs -w
|
||||
```
|
||||
|
||||
The output is similar to this:
|
||||
```
|
||||
NAME DESIRED CURRENT READY AGE
|
||||
nginx-2142116321 2 2 2 2m
|
||||
@@ -754,17 +791,18 @@ nginx-2142116321 0 1 1 2m
|
||||
nginx-2142116321 0 1 1 2m
|
||||
nginx-2142116321 0 0 0 2m
|
||||
nginx-3926361531 3 3 3 20s
|
||||
|
||||
```
|
||||
* Get the status of the latest rollout:
|
||||
```shell
|
||||
kubectl get rs
|
||||
```
|
||||
|
||||
The output is similar to this:
|
||||
```
|
||||
NAME DESIRED CURRENT READY AGE
|
||||
nginx-2142116321 0 0 0 2m
|
||||
nginx-3926361531 3 3 3 28s
|
||||
```
|
||||
|
||||
{{< note >}}
|
||||
You cannot rollback a paused Deployment until you resume it.
|
||||
{{< /note >}}
|
||||
@@ -800,6 +838,7 @@ successfully, `kubectl rollout status` returns a zero exit code.
|
||||
```shell
|
||||
kubectl rollout status deployment.v1.apps/nginx-deployment
|
||||
```
|
||||
The output is similar to this:
|
||||
```
|
||||
Waiting for rollout to finish: 2 of 3 updated replicas are available...
|
||||
deployment.apps/nginx-deployment successfully rolled out
|
||||
@@ -830,6 +869,7 @@ lack of progress for a Deployment after 10 minutes:
|
||||
```shell
|
||||
kubectl patch deployment.v1.apps/nginx-deployment -p '{"spec":{"progressDeadlineSeconds":600}}'
|
||||
```
|
||||
The output is similar to this:
|
||||
```
|
||||
deployment.apps/nginx-deployment patched
|
||||
```
|
||||
@@ -843,7 +883,7 @@ attributes to the Deployment's `.status.conditions`:
|
||||
See the [Kubernetes API conventions](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties) for more information on status conditions.
|
||||
|
||||
{{< note >}}
|
||||
Kubernetes will take no action on a stalled Deployment other than to report a status condition with
|
||||
Kubernetes takes no action on a stalled Deployment other than to report a status condition with
|
||||
`Reason=ProgressDeadlineExceeded`. Higher level orchestrators can take advantage of it and act accordingly, for
|
||||
example, rollback the Deployment to its previous version.
|
||||
{{< /note >}}
|
||||
@@ -861,6 +901,7 @@ insufficient quota. If you describe the Deployment you will notice the following
|
||||
```shell
|
||||
kubectl describe deployment nginx-deployment
|
||||
```
|
||||
The output is similar to this:
|
||||
```
|
||||
<...>
|
||||
Conditions:
|
||||
@@ -872,7 +913,7 @@ Conditions:
|
||||
<...>
|
||||
```
|
||||
|
||||
If you run `kubectl get deployment nginx-deployment -o yaml`, the Deployment status might look like this:
|
||||
If you run `kubectl get deployment nginx-deployment -o yaml`, the Deployment status is similar to this:
|
||||
|
||||
```
|
||||
status:
|
||||
@@ -939,6 +980,7 @@ returns a non-zero exit code if the Deployment has exceeded the progression dead
|
||||
```shell
|
||||
kubectl rollout status deployment.v1.apps/nginx-deployment
|
||||
```
|
||||
The output is similar to this:
|
||||
```
|
||||
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
|
||||
error: deployment "nginx" exceeded its progress deadline
|
||||
@@ -949,7 +991,7 @@ $ echo $?
|
||||
### Operating on a failed deployment
|
||||
|
||||
All actions that apply to a complete Deployment also apply to a failed Deployment. You can scale it up/down, roll back
|
||||
to a previous revision, or even pause it if you need to apply multiple tweaks in the Deployment pod template.
|
||||
to a previous revision, or even pause it if you need to apply multiple tweaks in the Deployment Pod template.
|
||||
|
||||
## Clean up Policy
|
||||
|
||||
@@ -962,9 +1004,7 @@ Explicitly setting this field to 0, will result in cleaning up all the history o
|
||||
thus that Deployment will not be able to roll back.
|
||||
{{< /note >}}
|
||||
|
||||
## Use Cases
|
||||
|
||||
### Canary Deployment
|
||||
## Canary Deployment
|
||||
|
||||
If you want to roll out releases to a subset of users or servers using the Deployment, you
|
||||
can create multiple Deployments, one for each release, following the canary pattern described in
|
||||
@@ -982,10 +1022,10 @@ A Deployment also needs a [`.spec` section](https://git.k8s.io/community/contrib
|
||||
|
||||
The `.spec.template` and `.spec.selector` are the only required field of the `.spec`.
|
||||
|
||||
The `.spec.template` is a [pod template](/docs/concepts/workloads/pods/pod-overview/#pod-templates). It has exactly the same schema as a [Pod](/docs/concepts/workloads/pods/pod/), except it is nested and does not have an
|
||||
The `.spec.template` is a [Pod template](/docs/concepts/workloads/pods/pod-overview/#pod-templates). It has exactly the same schema as a [Pod](/docs/concepts/workloads/pods/pod/), except it is nested and does not have an
|
||||
`apiVersion` or `kind`.
|
||||
|
||||
In addition to required fields for a Pod, a pod template in a Deployment must specify appropriate
|
||||
In addition to required fields for a Pod, a Pod template in a Deployment must specify appropriate
|
||||
labels and an appropriate restart policy. For labels, make sure not to overlap with other controllers. See [selector](#selector)).
|
||||
|
||||
Only a [`.spec.template.spec.restartPolicy`](/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy) equal to `Always` is
|
||||
@@ -998,7 +1038,7 @@ allowed, which is the default if not specified.
|
||||
### Selector
|
||||
|
||||
`.spec.selector` is an required field that specifies a [label selector](/docs/concepts/overview/working-with-objects/labels/)
|
||||
for the Pods targeted by this deployment.
|
||||
for the Pods targeted by this Deployment.
|
||||
|
||||
`.spec.selector` must match `.spec.template.metadata.labels`, or it will be rejected by the API.
|
||||
|
||||
@@ -1009,9 +1049,9 @@ from `.spec.template` or if the total number of such Pods exceeds `.spec.replica
|
||||
Pods with `.spec.template` if the number of Pods is less than the desired number.
|
||||
|
||||
{{< note >}}
|
||||
You should not create other pods whose labels match this selector, either directly, by creating
|
||||
You should not create other Pods whose labels match this selector, either directly, by creating
|
||||
another Deployment, or by creating another controller such as a ReplicaSet or a ReplicationController. If you
|
||||
do so, the first Deployment thinks that it created these other pods. Kubernetes does not stop you from doing this.
|
||||
do so, the first Deployment thinks that it created these other Pods. Kubernetes does not stop you from doing this.
|
||||
{{< /note >}}
|
||||
|
||||
If you have multiple controllers that have overlapping selectors, the controllers will fight with each
|
||||
@@ -1062,8 +1102,8 @@ total number of Pods running at any time during the update is at most 130% of de
|
||||
`.spec.progressDeadlineSeconds` is an optional field that specifies the number of seconds you want
|
||||
to wait for your Deployment to progress before the system reports back that the Deployment has
|
||||
[failed progressing](#failed-deployment) - surfaced as a condition with `Type=Progressing`, `Status=False`.
|
||||
and `Reason=ProgressDeadlineExceeded` in the status of the resource. The deployment controller will keep
|
||||
retrying the Deployment. In the future, once automatic rollback will be implemented, the deployment
|
||||
and `Reason=ProgressDeadlineExceeded` in the status of the resource. The Deployment controller will keep
|
||||
retrying the Deployment. In the future, once automatic rollback will be implemented, the Deployment
|
||||
controller will roll back a Deployment as soon as it observes such a condition.
|
||||
|
||||
If specified, this field needs to be greater than `.spec.minReadySeconds`.
|
||||
|
||||
Reference in New Issue
Block a user