Kubernetes setup guide
This tutorial shows how to run idlivedoc-server
on a Kubernetes cluster. You will deploy idlivedoc-server
as a load-balanced set of replicas that can scale to the needs of your users.
Objectives¶
- Deploy
idlivedoc-server
to the cluster. - Expose
idlivedoc-server
to the internet. - Deploy a new version of
idlivedoc-server
. - Manage autoscaling for the deployment.
- Clean up all changes.
Before you begin¶
You should have a functioning Kubernetes cluster with a configured kubectl
. To check it, you can runkubectl get nodes
. If everything is OK, you will see something like this:
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
ip-172-20-34-235.us-west-1.compute.internal Ready master 78d v1.16.10
ip-172-20-35-13.us-west-1.compute.internal Ready node 78d v1.16.10
...
Deploying idlivedoc-server
to the cluster¶
To get started, we will define a deployment named idlivedoc-server
by writing a YAML file that Kubernetes can understand. YAML is a human-readable data serialization format that Kubernetes can read and interpret.
Our YAML file will define a Deployment object that launches and manages our application container. You can copy the following file to replicate this demonstration on your own cluster, which we’ll call idlivedoc-server-cluster.yaml.
Let’s take a closer look at this file to describe the specifics of what it defines.
The YAML creates a Kubernetes Deployment object with the name idlivedoc-server
, which also uses the label app: idlivedoc-server
throughout. The spec for the deployment asks for a single replica. This replica is spawned from a Pod template that launches a container based on the idlivedoc-server
container. The spec indicates that the container will listen on port 8080.
Once you’ve saved the file, you can apply it to deploy it to your cluster:
kubectl apply -f idlivedoc-server-deployment.yaml && kubectl get pods
Output:
deployment.apps/idlivedoc-server-deployment created
NAME READY STATUS RESTARTS AGE
idlivedoc-server-deployment-5565574f89-stl8l 1/1 Running 0 14s
Exposing the app idlivedoc-server
to the internet¶
Kubernetes Pods are designed to be ephemeral, spinning up or down based on scaling needs within your cluster. Pods have individually-assigned IP addresses and these IPs can only be reached from inside your cluster. When a Pod crashes due to an error, Kubernetes will automatically redeploy that Pod, assigning a new Pod IP address each time. This process requires us to work with a dynamic set of IP addresses for those Pods.
Kubernetes Services allow us to 1) group those Pods into one static hostname and 2) expose a Pod group outside the cluster to the internet. Pods are grouped using Services into one static IP address, reachable from any Pod inside the cluster. Kubernetes also assigns a DNS hostname to that static IP.
The default Service type in Kubernetes is called ClusterIP, where the Service gets an IP address reachable only from inside the cluster. To expose a Kubernetes Service outside the cluster, you will create a Service of type LoadBalancer. This type of Service spawns an External Load Balancer IP for a set of Pods, reachable via the internet.
We will now expose the idlivedoc-server-deployment
Deployment to the internet using a Service of type LoadBalancer.
Use the kubectl expose
command to generate a Kubernetes Service for the idlivedoc-server-deployment
deployment:
kubectl expose deployment idlivedoc-server-deployment --name=idlivedoc-server-service --type=LoadBalancer --port 8080 --target-port 8080
Here, the --port flag specifies the port number configured on the Load Balancer, and the --target-port flag specifies the port number that the idlivedoc-server
container is listening on.
Run the following command to get the Service details for idlivedoc-server-service:
kubectl get service
Output:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
idlivedoc-server LoadBalancer 100.68.250.228 ab5aab6fe6d3240b785923bd6d64a69f4-291836869.us-west-1.elb.amazonaws.com 8080:31502/TCP 78d
Now that the idlivedoc-server
pods are exposed to the internet via a Kubernetes Service, you can check it using curl:
curl ab5aab6fe6d3240b785923bd6d64a69f4-291836869.us-west-1.elb.amazonaws.com:8080/api_version
{"product":"IDLive-Doc-Server","version":"1.2.0"}
Modifying the version of idlivedoc-server
¶
Now that we have a deployment running on our Kubernetes cluster, we can manage and modify it as circumstances dictate. Kubernetes will take care of a lot of the automated management tasks, but there are still times when we want to influence the behavior of our applications.
To demonstrate this, we will update the idlivedoc-server
version associated with our deployment. Because the application is already running within the cluster, editing the deployment YAML file we created earlier won't make the change we need. We need to modify the spec as stored in the actual cluster.
We can edit existing objects with the kubectl edit
command. The target for the command is the object type and the object name, separated by a forward slash. For our example, we can edit our deployment’s spec by typing:
kubectl edit deploy idlivedoc-server-deployment
The deployment spec will open in the system’s default editor.
Once you save the file, Kubernetes will recognize the difference in the spec and begin to automatically update the Deployment within the cluster.
Scaling the application¶
Now that we’ve demonstrated how to update our applications by modifying the Deployment spec, we can discuss how to scale our containerized workload using Kubernetes’ built-in replication primitives.
We can modify the scale of our deployment with the kubectl
scale command. To complete our request, we need to specify the number of replicas we desire as well as the Kubernetes object we wish to target (in this case, it’s our deploy/mysite object).
To scale our Deployment from one replica up to two, we can type:
kubectl scale deployment idlivedoc-server-deployment --replicas=2
Output:
deployment.apps/idlivedoc-server-deployment scaled
We can check the progress of the scaling operation by asking for the details on our Deployment object:
kubectl get deploy idlivedoc-server-deployment
Output:
NAME READY UP-TO-DATE AVAILABLE AGE
idlivedoc-server-deployment 2/2 2 2 15m
Here, we can see that 2 out of 2 replicas are ready and operational. The output confirms that each of these replicas is serving the most up-to-date version of the spec and that each is capable of serving traffic. The service idlivedoc-server-service
will be ready to serve client requests since at least one pod is in a Ready state. This application now demonstrates High Availability of its services. We will now extend these multiple replicas via autoscaling.
Horizontal Pod Autoscaler¶
The Horizontal Pod Autoscaler automatically scales the number of pods in the deployment set based on the observed CPU utilization. Other metrics can be used with custom support for alternative metrics in the application.
Horizontal Pod Autoscaler, like every API resource, is supported in a standard way by kubectl
.There is a special kubectl autoscale command for easy creation of a Horizontal Pod Autoscaler. For instance, executing the following command will create an autoscaler for deployment idlivedoc-server-deployment
, with target CPU utilization set to 80% and the number of replicas between 2 and 5. The HPA object increased that minimum to 2 and will increase the Pods up to 5 if CPU usage on the Pods reaches 80%:
kubectl autoscale deployment idlivedoc-server-deployment --min=2 --max=5 --cpu-percent=80
Cleaning up Deployment and Service¶
We’ve created a deployment, updated it, and scaled it. Since this is not a real production workload, we should remove it from our cluster once we’re done to clean up after ourselves.
To remove the resources we’ve set up, we only need to delete the Deployment and Service objects. Kubernetes will automatically remove all other child resources associated with it, like the pods and containers that it manages.
Delete the Deployment by typing:
kubectl delete deploy idlivedoc-server-deployment
Output:
deployment.extensions "idlivedoc-server-deployment" deleted
You can double-check that the resources have been removed by getting the list of these resources in the default namespace:
kubectl get deploy idlivedoc-server
kubectl get pods
kubectl get service idlivedoc-server-service
These commands should indicate that the Deployment, Service and all of its associated resources are no longer running.