Understand Kubernetes Object–Service

Background

This is the fourth part of the series on building highly scalable multi-container apps using AKS. Previous posts in this series:

This post we will focus on creating another basic resource in Kubernetes named Service.

We will be performing following actions during this post

  • Understand the basics of Service object in Kubernetes
  • Build Kubernetes service manifest file
  • Create a service using Kubernetes CLI kubectl
  • Get details about Service using kubectl
  • Get Details about service using Kubernetes dashboard
  • Delete service using Kubectl

Understand the basics of Service object in Kubernetes

If you recall from the last post, we successfully deployed the web application container using the Deployment controller. If we want to access the web user interface, how do we do that? This is where Kubernetes Service comes into the picture.

Service provides a stable endpoint for various components to talk to one another. It is an abstraction which defines the policy by which to access the pods. Assume that there are 2 replicas of a pod running on two different nodes. There is new version of the container to be deployed. The Kubernetes master decides to schedule the workload for the new version on completely different nodes. It would be extremely difficult for dependent services to keep updating the endpoint addresses every time there is a new deployment. This is where Service discovery mechanism and load balancing within Kubernetes comes into the picture. It provides stable endpoint for all the services which need to be exposed internally within the cluster or even outside the cluster.

Build Kubernetes service manifest file

We can use the kubectl command to create a service with all the parameters from the command line. Personally I prefer to use manifest file. Lets look at the example of the Service file manifest.

service-definition

Like earlier manifest files we had used for Namespace and Deployment, we start with the API version and the kind attributes. The metadata attribute defines the name of the service as webfront. We also specify the namespace as abc2018sg.

The specification of the service is defined using Spec. The type defines how the service will be exposed to other components within the Kubernetes cluster or to the outside world. Available options are ClusterIP / NodePort / LoadBalancer / ExterName. In our example we are using LoadBalancer. This will expose the service using Azure load balancer. LoadBalancer service type automatically creates the NodePort and ClusterIP to which the external load balancer will route the requests.

The default service type is ClusterIP. It exposes the service on clusters internal IP. The disadvantage of this is the service will not be accessible from outside the Kubernetes cluster.

If we use NodePort the same port will be exposed on all the nodes of the cluster. We can access the service from any node on the cluster by using the specified port number.

ExternalName maps the service to the contents of the externalName. This is useful we wish to connect to a service outside of the Kubernetes cluster using a stable name. The example that comes to mind is that of connecting to a SQL Azure database instance.

Next we define the ports which need to be exposed using the service. Here we are exposing port 80.

The last part is the most important one. This links the service to the underlying pod using the selector. Be very careful to match the key value pairs. Usually spelling errors are the most common mistake while trying to match the labels if you are typing everything by hand.

Create service using Kubernetes CLI kubectl

Save the contents of the file shown above with name web-service.yml. We use Kubectl to create the service object as

kubectl create –-filename web-service.yml

Get details about Service using kubectl

We can query the Kubernetes API server to get the list of services. We can use any one of the following commands

kubectl get services –namespace abc201sg
kubectl get services -n abc201sg

Once we have the name which is webfront, we can query the service details

kubectl get  service webfront –namespace abc2018sg
kubectl get  service webfront -n abc2018sg

The output of the above commands is shown below

kubectl output

We can see that in case of LoadBalancer service type the Cluster-IP and the External-IP both are created. It also exposes port 80 and a higher order port with 31960. We can now access the service using the external IP and Port combination http://104.4.129.205:80

The Public IP address provisioning can take few minutes depending on the cloud provider.

web UI

Note that since I am using Azure subscription,I keep the cluster running only for short period of time. When the cluster is recreated the public IP address will be different.

Get Details about service using Kubernetes dashboard

The process is similar to what we had in the previous one to access details of the pod and deployment. We filter the namespace and then the services section

service initializing

Delete service using Kubectl

Deleting the service is similar to deleting other objects.

kubectl delete service webfront –namespace abc2018sg
kubectl delete service webfront -n abc2018sg

You can use the dashboard or the kubectl command to query the service details and ensure that it has been deleted successfully. I will skip the part related to deleting the service from UI using the Kubernetes dashboard. You can try it out yourself which is same what we did in the last post for deleting the deployment.

Conclusion

In this post we saw how to access pods using Service. Service gives the stable endpoint that other dependent components can rely on even if the node on which the pods are running are impacted. Services is one of the topic which would need more than one post to cover all the major aspects related to things like networking, load balancing, scaling etc. We will cover them in more details as and when the need arises. In the future posts we will see other service types like NodePort and ClusterIP.

As always the complete source code for this post and the related posts is available on Github.

Until next time code with passion and strive for excellence.

spacer

Understand Kubernetes Objects – Pod and Deployment

Background

This is the third part of the series on building highly scalable multi-container apps using AKS. Previous posts in this series:

This post we will focus on creating another basic resource in Kubernetes named Pod.

We will be performing the following actions during this post

  • Get familiar with Pod and Deployment
  • Create a Pod using Kubernetes manifest file via Controller (Deployment)
  • Find details about the Pod and Deployment using Kubernetes CLI kubectl
  • Find Pod and deployment details using Kubernetes dashboard
  • Delete the Deployment using Kubernetes CLI kubectl
  • Delete Deployment using Kubernetes dashboard

Pod

A pod is the smallest unit of deployment in Kubernetes. Usually a pod consists of a single container and its related resources like storage/networking and the specification of how to run the container. This is illustrated in the diagram below.

Pods

Each Pod has its own IP and the container as shown in Pod1. Pod 2 is an example where a Pod has Volume attached to it. We will cover Volume later in the series. Pod 3 is an example where multiple containers are scheduled to run as part of the same pod. Finally Pod 4 is an example where we have multiple containers and multiple volumes within the same pod.

We can create pod using the kubectl create pod command. It is generally recommended to use a higher level API to create pod instead of directly creating them ourselves. We will use Controller API with the Deployment to create pod.

Deployment

Deployment is one of the higher level API provided Kubernetes. It interacts with basic objects like Namespaces and Pods. Deployment consists of the template to deploy a containerized application. We can create deployments similar to the way we created namespace in the earlier post using kubectl. Lets look at the deployment file for ASP.Net Core web application.

web-deployment

Here is the brief description of important attributes in the manifest file.

metadata: creates a deployment named techtalksweb in the abc2018sg namespace created in the previous post.

Deployment specification (spec): We have specified the replica as 1.

Selector : is used to select the template based on the matching label. The label is key value pair. We can also specify multiple labels to identify the deployment.

Be careful with the key value pairs used for different labels. For a newbie it is quite common to make spelling mistakes in the label names. At times I had to spend lot of time debugging different Kubernetes resources when things did not work out correctly due to mismatch in the labels

template:spec : Describes the pod details. Deployment can deploy a single container or multiple containers. This is represented using the containers collection on line 21. In this case we have only one container. Later we would be able to see use of multiple containers used within single deployment when we talk about init-containers.

The name and image on lines 22 and 23 are self explanatory. For each container we specify the properties like image name in the container registry. I am using DockerHub as the public container registry. The repository is named nileshgule and the image name is techtalksweb. As we did not specify the specific version, latest image will be pulled and deployed to the Kubernetes cluster.

env : specifies the environment variables we wish to override in the container. We also specify the port which needs to be exposed. We have also defined the policies for pulling images and restarts.

In the deployment template we can specify multiple constraints like the memory and CPU requirements. If the container exceeds the limits, Kubernetes master will kill the container and start a new instance. We specify how the termination process should be handled. In this case we are specifying that the graceful time for termination is 30 seconds using terminationGracePeriodSeconds attribute. This will be applied when the container is killed and it needs time to gracefully perform operations like closing database connections etc.

Save the contents of the file to disk with file named web-deployment.yml. We can create the deployment using kubectl by running the command

kubectl create –-filename web-deployment.yml

Find details about the Pod and Deployment using Kubernetes CLI kubectl

Lets query the Kubernetes cluster to know details about the newly created deployment object. We can start with getting all the deployments

kubectl get deployments

deployments status

Initially there are no results. We get a message No resources found. But if you look at the earlier command output, it  says deployment “techtalksweb’ created. What happened there? The kubectl is referring to default namespace. The object that we created is linked with the abc2018sg namespace. We need to add the namespace filter to the command as follows

kubectl get deployments –-namespace abc2018sg

Now we get the correct result with the name of the deployment as techtalksweb. We can get details of the individual deployment using the command

kubectl describe deployment techtalksweb –-namespace=abc2018sg

kubectl describe deployment

We can cross verify from the screen shot above that all the details specified in the deployment manifest are matching with the output. We can also find the additional details which are set to default values. Some of the examples of default properties being applied are StrategyType, MinReadySeconds, Volumes.

These details are related to the deployment. How about individual pod? We can query the Kubernetes cluster to get all pods. Note that most of the commands from here on will require us to specify the namespace to filter the details. We can first get a list of all the pods running within a namespace using the command

kubectl get pods –namespace abc2018sg
get pods

Once we know the name of the pod, we can drill down to a specific pod. Remember the command we had used in the previous post to describe the details for a namespace? Off course it is the describe command

kubectl describe pod –namespace abc2018sg techtalksweb-594576578c-kh475
describe pod

Here we can see details related to the pod which are derived from the template we defined in the manifest file as well as the default values provided by Kubernetes itself.

Details of Pods and Deployments using Kubernetes dashboard

We can retrieve the same information that is available using CLI commands instead using the Kubernetes dashboard. Browse to the Kubernetes dashboard by running the following command

az aks browse --resource-group=ABC2018ResourceGroup --name=ABC2018AKSCluster

Filter the namespace on the left navigation pane. We can then list all the pods using the Pods link as shown below

pod details

Similar to the pods, we can also get details about the deployments using Deployments link.

deployment details

We get the same details that were available in the CLI output in a graphical form.

Delete deployment using Kubernetes CLI Kubectl

Deleting any resources in Kubernetes is done using the delete command and passing the type of the resource. Here is the example of how we would delete the Techtalksweb deployment

kubectl delete deployment techtalksweb –namespace abc2018sg

Another option to delete the deployment is by giving the manifest file reference as follows

kubectl delete –filename techtalksweb-deployment.yml 

Note that we need not specify the namespace name when uisng the manifest fielname as it is already part of the declarative markup. The approach of using filename instead of individual resource name is extremely useful if you are creating multiple objects using the same manifest file and would like to delete them all in one go. Personally I prefer to define one single Kubernetes object in one manifest file. You might come across one big yaml file containing all the object definition.

Delete Pod and Deployment using Kubernetes dashboard

Deleting Pod or deployment using dashboard is done using the context menu associated with the resource. Here is an example of deleting the pod

delete pod

Conclusion

In this post we saw how to interact with Deployments using the Kubernetes CLI as well as the dashboard. The deployment controller internally creates the pod which is one of the basic object in Kubernetes. A pod has an IP, volume and container encapsulated together. Deployment defines the template for creating and managing a running instance of a pod. Later in this series we will see how to define resource constraints for the containers as well as how to manage dependencies or pre-requisites between containers using the concept of init-containers. The complete source code for the examples used during this multipart series is available on Github.

Until next time, code with passion and strive for excellence.

spacer

Understand Kubernetes Objects – Namespace

Background

This is the second part of the series on building highly scalable multi-container apps using AKS. In the earlier post  we provisioned a managed Kubernetes cluster using Azure Kubernetes Service (AKS). I will reuse the code which was prepared for my talk during the Global Azure Bootcamp event in Singapore on 21st April 2018. This post we will focus on creating one of the most basic resource in Kubernetes. Lets get started with some basic understanding of the Kubernetes objects.

We will be performing the following actions during this post

  • Create a namespace using kubectl
  • Create a namespace using Kubernetes manifest file
  • Delete the namespace using kubectl
  • Find details about the namespace using kubectl

Kubernetes Objects

Kubernetes or K8s as it is commonly called has support for different types of objects. It provides different ways to create basic objects like Namespace, Pod, Volume, Service, etc. There are higher level API’s which make use of the basic objects. These include things like Deployment, ReplicaSet, StatefulSet, DemonSet etc. To start with, we will look at the most basic objects and in the later part of the series revisit other objects as and when the need arises.

Lets start with the simplest of all basic objects Namespaces.

Namespaces

Namespaces is simple concept which is quite powerful in nature. It allows us to define logical cluster within a physical Kubernetes cluster. Imagine that a Kubernetes cluster is shared by two or more teams. They have the need to isolate each others services within Kubernetes environment. Namespace can be used for this purpose. Another example of using namespace could be to make logical separation of the same Kubernetes cluster for different environments like Dev, QA etc.

Create namespace using kubectl

Lets see how we can create namespace using Kubernetes CLI, kubectl. Fire up the terminal of your choice and execute the following command

kubectl create namespace abc2018sg

Successful completion of the command would create a namespace named abc2018sg. I found this as the simplest way to create a namespace. This is good if we want to do it once. In todays modern day systems which are built using Continuous Integration (CI) and deployed using Continuous Deployment (CD) techniques, we use approaches like Infrastructure as Code. In such cases we can make use of Kubernetes manifest file to declaratively describe the object we wish to create using a yaml or json file.

Create namespace using Kubernetes manifest

Here is an example of the same namespace described using a yaml file. The file is named 00_ABCNamespace.yml. It uses the declarative approach to describe the kind of object we wish to create.

Kubernetes supports multiple versions of the API. It is very important to specify which version if the API we intend to use while creating a resource. In our case we are using the stable version v1. The name of the object is specified using the metadata property. Such files which describe the different attributes of Kubernetes resources are called as manifest file. It can be used to create any Kubernetes resource using the command line. Similar to the process of using a script file with the SQL command line tool like sqlcmd, we can pass the file to the kubectl with the command

kubectl create –-filename 00_ABCNamespace.yml 

from the directory where the file is located on the disk. The result of this command is exactly the same as the previous one.

kubectl is a smart tool. We can use recursive nature to create multiple resources by just specifying the top level folder. All the yaml files will be executed as part of the create or delete or any other action performed using the kubectl command. We will see example of this later in the series.

Delete namespace using kubectl

Deleting a namespace using kubectl is as simple as creating a namespace. Run the following command in the terminal

kubectl delete namespace abc2018sg

Find details about namespace using kubectl & dashboard

kubectl provides a helpful command named describe which can be used to get details about different objects. We can use it to describe the namespace as follows

kubectl describe namespace abc2018sg

We get the output as shown below.

describe namespace

We can also get the details about a namespace using the Kubernetes dashboard by selecting the abc2018sg namespace from the list of namespaces.

Kubernetes Namespace list

We can see multiple namespaces in the screenshot above for the Kubernetes cluster. By default Kubernetes creates 3 namespaces named default, kube-public and kube-system. Kube-public and kube-system are used internally by Kubernetes cluster. If we do not specify any namespace while creating a resource, it will be created under the default namespace.

Conclusion

In this post we saw basic Kubernetes object namespace. As the series progresses, we will discover more objects based on their relevance. Lets conclude this post with a feeling of getting started with Kubernetes using both the Kubernetes CLI as well as the manifest files. There is a wonderful cheatsheet available for Kubernetes. I personally found this quite handy when getting started with Kubernetes. In the next post we will look at another building blocks in Kubernetes the Pod and Deployment. We will be able to put the namespace that we created today to good use in the future parts of this series. Most of the resources we will create, will be part of the namespace abc2018sg.

Until next time code with passion and strive for excellence.

spacer