# Deployments

DeploymentsA Deployment manages a set of Pods to run an application workload, usually one that doesn't maintain state.A Deployment provides declarative updates for Pods and ReplicaSets.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: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.Use CaseThe following are typical use cases for Deployments:Create a Deployment to rollout a ReplicaSet. The ReplicaSet creates Pods in the background. Check the status of the rollout to see if it succeeds or not.Declare the new state of the Pods by updating the PodTemplateSpec of the Deployment. A new ReplicaSet is created, and the Deployment gradually scales it up while scaling down the old ReplicaSet, ensuring Pods are replaced at a controlled rate. Each new ReplicaSet updates the revision of the Deployment.Rollback to an earlier Deployment revision if the current state of the Deployment is not stable. Each rollback updates the revision of the Deployment.Scale up the Deployment to facilitate more load.Pause the rollout of a Deployment to apply multiple fixes to its PodTemplateSpec and then resume it to start a new rollout.Use the status of the Deployment as an indicator that a rollout has stuck.Clean up older ReplicaSets that you don't need anymore.Creating a DeploymentThe following is an example of a Deployment. It creates a ReplicaSet to bring up three nginx Pods:controllers/nginx-deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment labels: app: nginx spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80 In this example:A Deployment named nginx-deployment is created, indicated by the .metadata.name field. This name will become the basis for the ReplicaSets and Pods which are created later. See Writing a Deployment Spec for more details.The Deployment creates a ReplicaSet that creates three replicated Pods, indicated by the .spec.replicas field.The .spec.selector field defines how the created ReplicaSet finds which Pods to manage. In this case, you 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:The .spec.selector.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.The .spec.template field contains the following sub-fields:The Pods are labeled app: nginxusing the .metadata.labels field.The Pod template's specification, or .spec field, indicates that the Pods run one container, nginx, which runs the nginx Docker Hub image at version 1.14.2.Create one container and name it nginx using the .spec.containers[0].name field.Before you begin, make sure your Kubernetes cluster is up and running. Follow the steps given below to create the above Deployment:Create the Deployment by running the following command:kubectl apply -f https://k8s.io/examples/controllers/nginx-deployment.yaml 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:NAME READY UP-TO-DATE AVAILABLE AGE nginx-deployment 0/3 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 namespace.READY displays how many replicas of the application are available to your users. It follows the pattern ready/desired.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 number of desired replicas is 3 according to .spec.replicas field.To see the Deployment rollout status, run kubectl rollout status deployment/nginx-deployment.The output is similar to:Waiting for rollout to finish: 2 out of 3 new replicas have been updated... deployment "nginx-deployment" successfully rolled out Run the kubectl get deployments again a few seconds later. The output is similar to this:NAME READY 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.To see the ReplicaSet (rs) created by the Deployment, run kubectl get rs. The output is similar to this:NAME DESIRED CURRENT READY AGE nginx-deployment-75675f5897 3 3 3 18s ReplicaSet output shows the following fields:NAME lists the names of the ReplicaSets in the namespace.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.READY 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 that the name of the ReplicaSet is always formatted as [DEPLOYMENT-NAME]-[HASH]. This name will become the basis for the Pods which are created.The HASH string is the same as the pod-template-hash label on the ReplicaSet.To see the labels automatically generated for each Pod, run kubectl get pods --show-labels. The output is similar to:NAME READY STATUS RESTARTS AGE LABELS nginx-deployment-75675f5897-7ci7o 1/1 Running 0 18s app=nginx,pod-template-hash=75675f5897 nginx-deployment-75675f5897-kzszj 1/1 Running 0 18s app=nginx,pod-template-hash=75675f5897 nginx-deployment-75675f5897-qqcnn 1/1 Running 0 18s app=nginx,pod-template-hash=75675f5897 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, app: nginx).Do not overlap labels or selectors with other controllers (including other Deployments and StatefulSets). Kubernetes doesn't stop you from overlapping, and if multiple controllers have overlapping selectors those controllers might conflict and behave unexpectedly.Pod-template-hash labelCaution:Do not change this label.The pod-template-hash label is added by the Deployment controller to every ReplicaSet that a Deployment creates or adopts.This label ensures that child ReplicaSets of a Deployment do not overlap. It is generated by hashing the PodTemplate of the ReplicaSet and using the resulting hash as the label value that is added to the ReplicaSet selector, Pod template labels, and in any existing Pods that the ReplicaSet might have.Updating a DeploymentNote: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.Follow the steps given below to update your Deployment:Let's update the nginx Pods to use the nginx:1.16.1 image instead of the nginx:1.14.2 image.kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.16.1 or use the following command:kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1 where deployment/nginx-deployment indicates the Deployment, nginx indicates the Container the update will take place and nginx:1.16.1 indicates the new image and its tag.The output is similar to:deployment.apps/nginx-deployment image updated Alternatively, you can edit the Deployment and change .spec.template.spec.containers[0].image from nginx:1.14.2 to nginx:1.16.1:kubectl edit deployment/nginx-deployment The output is similar to:deployment.apps/nginx-deployment edited To see the rollout status, run:kubectl rollout status deployment/nginx-deployment The output is similar to this:Waiting for rollout to finish: 2 out of 3 new replicas have been updated... ordeployment "nginx-deployment" successfully rolled out Get more details on your updated Deployment:After the rollout succeeds, you can view the Deployment by running kubectl get deployments. The output is similar to this:NAME READY UP-TO-DATE AVAILABLE AGE nginx-deployment 3/3 3 3 36s 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.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:kubectl get pods The output is similar to this:NAME READY STATUS RESTARTS AGE nginx-deployment-1564180365-khku8 1/1 Running 0 14s nginx-deployment-1564180365-nacti 1/1 Running 0 14s nginx-deployment-1564180365-z9gth 1/1 Running 0 14s