With the Deployment manifest ready, we can run kubectl apply to update the desired state of our cluster:
$ kubectl apply -f manifests/elasticsearch/deployment.yaml
deployment.apps "elasticsearch" created
This will trigger a set of events:
- kubectl sends the Deployment manifest to the Kubernetes API server (kube-apiserver). kube-apiserver will assign it a unique ID, and adds it on to etcd.
- The API server will also create the corresponding ReplicaSet and Pod Objects and add it to etcd.
- The scheduler watches etcd and notices that there are Pods that have not been assigned to a node. Then, the scheduler will make a decision about where to deploy the Pods specified by the Deployment.
- Once a decision is made, it will inform etcd of its decision; etcd records the decision.
- The kubelet service running on each node will notice this change on etcd, and pull down a PodSpec – the Pod's manifest file. It will then run and manage a new Pod according to the PodSpec.
During the entire process, the scheduler and kubelets keep etcd up to date at all times via the Kubernetes API.
If we query for the state of the Deployment in the first few seconds after we run kubectl apply, we will see that etcd has updated its records with our desired state, but the Pods and containers will not be available yet:
$ kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
elasticsearch 3 3 3 0 2s
We can then run kubectl rollout status to be notified, in real-time, when each Pod is ready:
$ kubectl rollout status deployment/elasticsearch
Waiting for rollout to finish: 0 of 3 updated replicas are available...
Waiting for rollout to finish: 1 of 3 updated replicas are available...
Waiting for rollout to finish: 2 of 3 updated replicas are available...
deployment "elasticsearch" successfully rolled out
Then, we can check the deployment again, and we can see that all three replica Pods are available:
$ kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
elasticsearch 3 3 3 3 2m
We have now successfully switched our approach from an imperative one (using kubectl run), to a declarative one (using manifest files and kubectl apply).