In the previous post, we had a look at the concept of Worker nodes. Now let's look at how we do deployments of applications to Worker nodes.
Kubernetes has a couple of basic objects that host your applications and services. These are, in order, Pods, ReplicaSets and Deployments.
Kubernetes uses YAML files to create these entities, so let's see how this works. A Kubernetes YAML file always contains the following required default statements.
Lets create the following file, awesome-app-pod.yaml.
apiVersion: v1 kind: Pod /* This is the object type being created */ metadata: name: my-awesome-app labels: app: awesome-app spec: containers: // this is a list/array - name: awesome-app-container // the dash means list item image: awesome-app
You would create the above object as a Pod in you Kubernetes cluster by issuing the following command;
kubectl create -f awesome-app-pod.yaml
The '-f' tells kubectl to read from the file specified.
If you're not familiar with YAML, please note that indentation really, really matters and also that YAML doesn't like tabs, so be sure to user spaces!
When you have indented statements - like those under metadata - you're in actuality creating a key-value dictionary/object with hierarchies and nesting defined by the level of indentation. So app: is a child of labels:, which in turn is a child of metadata:.
To view your newly created pod, run;
kubectl get pods
Or, to see more details for a specific pod in particular
kubectl describe pod my-awesome-app
And there you go, you have just deployed your application to your cluster.
So what do you do when your fancy new pods gets deployed, serves users for a good while and then unexpectedly crashes? Do you need to constantly keep an eye on your pods and delete ones that have crashed and create new ones to replace them?
What about sudden surges in requests from users? If your application gets shared on HackerNews and you suddenly have to serve 50x the requests, could you rely on that one, lonesome pod to just keep on chugging along and hold its own?
ReplicationSets and Replication Controllers to the rescue!
ReplicationSets and/or Replication Controllers are processes that ensure that a certain number of identical pods are always running on your cluster, allowing for more redundancy and fallover protection. If a pod fails, the ReplicationSet or Replication Controller will remove it and replace it with a new one.
They will also makes sure that you have a specified minimum amount of replicated pods running at all times, in order to make sure your application can meet your traffic needs.
ReplicationSets/Controllers can operate over multiple nodes in your cluster too, so you won't be limited to the resource availability of a single node either.
Replication Controller VS ReplicaSet
So what's the difference between ReplicaSets and Controllers?
Well, they do more or less the same thing, ReplicationSets are just the new and improved implementation of the older Replication Controller. Both will do just fine, but ReplicationSets are the way forward and offer you a little bit more control, so we'll be focussing on them for this post.
Let's set up a ReplicationSet with YAML, create the file awesome-app-replicaset.yml
apiVersion: apps/v1 // <-- Note the addition of 'apps/'. This is required. kind: ReplicaSet metadata: // <-- metadata for replicaset name: awesome-app-replicaset labels: app: awesome-app type: web-app spec:// <-- spec for replicaset template: metadata // <-- metadata for pods to be replicated name: awesome-app-pod labels: app: awesome-app type: web-app spec: // <-- spec for pods to be replicated containers: - name: awesome-app-container image: awesome-app-image replicas: 3 selector: // <-- can be used to include existing pods matchLabels: type: web-app
Then create the ReplicationSet with the following command;
kubectl create -f awesome-app-replicaset.yml
and then view them with
kubectl get replicaset
You can also view the pods created by the ReplicaSet by running
kubectl get pods
You'll see that the pods are named based on the name property in your ReplicaSet metadata.
So now how do we scale up the replicated pods? By updating the replicas property in the YAML file and then replacing the deployed ReplicaSet with;
kubectl replace -f awesome-app-replicaset.yml
Another way is to directly update the running ReplicaSet process with
kubectl scale --replicas=8 replicaset awesome-app-replicaset
or alternatively, to edit any other properties of the running ReplicaSet, run;
kubectl edit replicaset awesome-app-replicaset
Note that using the kubectl scale command doesn't update the YAML file itself, only the running process.
There are of course ways to automatically scale replicas up or down based on traffic load, but we'll get to automation a little bit later.
A Deployment is a Kubernetes entity/object one level higher than a ReplicaSet, ie Deployments contain ReplicaSets, which in turn contain Pods.
Deployments control the updating of its underlying entities.
Deployments can do the following;
- Create instances of running applications as ReplicaSets.
- Upgrade outdated containers with new ones via rolling updates, where running instances are updated one after the other, in order to not disrupt containers currently interacting with users.
- Roll back failed updates.
- Updating the environment properties like scaling settings, deployment version or resource allocations.
Deployments are also defined using YAML files. Let's have a look at deployment.yaml.
You'll see it looks exactly like a ReplicaSet YAML file, except the kind property changed to Deployment, and other references for replicaset changed to deployment.
apiVersion: apps/v1 // <-- Note the addition of 'apps/'. This is required. kind: Deployment metadata: // <-- metadata for deployment name: awesome-app-deployment labels: app: awesome-app type: web-app spec:// <-- spec for deployment template: metadata // <-- metadata for pods to be deployed name: awesome-app-pod labels: app: awesome-app type: web-app spec: // <-- spec for pods to be deployed containers: - name: awesome-app-container image: awesome-app-image replicas: 3 selector: // <-- can be used to include existing pods matchLabels: type: web-app
Create it with;
kubectl create -f deployment.yaml
View your deployment with;
kubectl get deployments
You can also view you deployment in more detail with;
kubectl describe deployment awesome-app-deployment
Pro tip! To save time you can use kubectl to generate the YAML file boilerplate by running;
kubectl create deployment --image=awesome-app-image awesome-app-deployment --dry-run -o yaml
This will log out a good starting template for you to copy and paste, and get up to speed faster.
We had a look at the basic objects used to deploy services in a Kubernetes cluster. These include Pods, ReplicaSets and Deployments. We also had a look at some of the commands kubectl uses to create, view and edit these objects.
Here's a handy little command to view everything that is currently running on your cluster
kubectl get all