In a Kubernetes Cluster, a ReplicaSet guarantees that a certain number of Pods are created. A ReplicaSet ensures that a specified number of pod replicas are running at any one time. If there are more than that, it will kill some of them off. If there are fewer, it will start up new ones. However, because changing the ReplicaSet has no effect on current Pods, it is not feasible to simply modify the image version, using replica sets.
A deployment is a higher abstraction that controls the rollout of a new version by managing one or more ReplicaSets. A deployment object creates and maintains a replica set. When the image version in the Deployment is modified, a new ReplicaSet for that version is created, with zero replicas at first. After then, it will be scaled up to one replica, and after that, the previous ReplicaSet will be scaled down. You can configure this behavior.
When you create a deployment, you tell Kubernetes how many replicas of your application you want to run, and the deployment controller does its best to maintain that state. The deployment controller is responsible for creating and deleting replicas, and for automatically rolling out (and rolling back) new versions of your application. The popular misconception is that deployments only roll out changes to your application; in fact, they can also be used to scale your application up or down. Let's say you have a web app with a ReplicaSet of 10 pods, and you want to deploy a new version of the app. With a deployment, you can specify that the new version should be rolled out gradually, one replica at a time. The old version will continue to serve requests until all 10 replicas have been upgraded to the new version. This is called a "rolling update."
If you are not in the middle of a rollout, a deployment will create one replica set with the replication factor managed by the deployment object.
Let's see a replicasets in action,
When you create a deployment object, Kubernetes automatically creates
replicasets,If you run the following command,
kubectl get replicasets
You will see the following output:
NAME DESIRED CURRENT READY AGE nginx-85658cc69f 2 2 2 22m
You can increase or decrease the number of replicas using a deployment object without changing the name of this
kubectl scale deployment nginx --replicas=3 kubectl get replicasets
NAME DESIRED CURRENT READY AGE nginx-85658cc69f 3 3 3 23m
But if you update the image Kubernetes will create a new replicaset with a different name and update the older
replicaset to 0 as soon as the deployment is complete. for example, run the following 2 commands at the same time.
kubectl set image deployment/nginx nginx=nginx:1.16.1 kubectl get replicasets
NAME DESIRED CURRENT READY AGE nginx-59d4f6646f 1 1 0 2s nginx-85658cc69f 3 3 3 26m
Here the new replicaset
nginx-59d4f6646f is just created. Run the command again, the older replicaset
nginx-85658cc69f "DESIRED" value is set to 0.
kubectl get replicasets
NAME DESIRED CURRENT READY AGE nginx-59d4f6646f 3 3 3 82s nginx-85658cc69f 0 0 0 28m
So for every image update deployment controller create new replicasets to handle the update process. You can verify this as follows,
kubectl set image deployment/nginx nginx=nginx:1.16.1 kubectl set image deployment/nginx nginx=nginx:1.16.2 kubectl set image deployment/nginx nginx=nginx:1.16.3 kubectl set image deployment/nginx nginx=nginx:1.16.4 kubectl set image deployment/nginx nginx=nginx:latest kubectl get replicasets
NAME DESIRED CURRENT READY AGE nginx-56c7d798cd 0 0 0 58s nginx-59d4f6646f 0 0 0 67s nginx-68984b745f 2 2 2 55s nginx-6d6f557bdd 0 0 0 62s nginx-7c75f8bf8c 0 0 0 60s nginx-85658cc69f 0 0 0 93s