Kubernetes - Overview
Kubernetes - Overview
Kubernetes - Overview
Kubernetes in an open source container management tool hosted by Cloud Native
Computing Foundation (CNCF). This is also known as the enhanced version of Borg which
was developed at Google to manage both long running processes and batch jobs, which
was earlier handled by separate systems.
Features of Kubernetes
Following are some of the important features of Kubernetes.
Containerized infrastructure
Application-centric management
Auto-scalable infrastructure
Loosely coupled infrastructure, where each component can act as a separate unit
One of the key components of Kubernetes is, it can run application on clusters of physical
and virtual machine infrastructure. It also has the capability to run applications on cloud.
It helps in moving from host-centric infrastructure to container-centric
infrastructure.
Kubernetes - Architecture
In this chapter, we will discuss the basic architecture of Kubernetes.
The key components of master and node are defined in the following section.
Explore our latest online courses and learn new skills at your own pace. Enroll and
become a certified expert to boost your career.
etcd
It stores the configuration information which can be used by each of the nodes in the
cluster. It is a high availability key value store that can be distributed among multiple
nodes. It is accessible only by Kubernetes API server as it may have some sensitive
information. It is a distributed key value Store which is accessible to all.
API Server
Kubernetes is an API server which provides all the operation on cluster using the API. API
server implements an interface, which means different tools and libraries can readily
communicate with it. Kubeconfig is a package along with the server side tools that can be
used for communication. It exposes Kubernetes API.
Controller Manager
This component is responsible for most of the collectors that regulates the state of cluster
and performs a task. In general, it can be considered as a daemon which runs in
nonterminating loop and is responsible for collecting and sending information to API
server. It works toward getting the shared state of cluster and then make changes to bring
the current status of the server to the desired state. The key controllers are replication
controller, endpoint controller, namespace controller, and service account controller. The
controller manager runs different kind of controllers to handle nodes, endpoints, etc.
Page 3 of 65
Scheduler
This is one of the key components of Kubernetes master. It is a service in master
responsible for distributing the workload. It is responsible for tracking utilization of
working load on cluster nodes and then placing the workload on which resources are
available and accept the workload. In other words, this is the mechanism responsible for
allocating pods to available nodes. The scheduler is responsible for workload utilization and
allocating pod to new node.
Docker
The first requirement of each node is Docker which helps in running the encapsulated
application containers in a relatively isolated but lightweight operating environment.
Kubelet Service
This is a small service in each node responsible for relaying information to and from
control plane service. It interacts with etcd store to read configuration details and wright
values. This communicates with the master component to receive commands and work.
The kubelet process then assumes responsibility for maintaining the state of work and the
node server. It manages network rules, port forwarding, etc.
Kubernetes - Setup
It is important to set up the Virtual Datacenter (vDC) before setting up Kubernetes. This
can be considered as a set of machines where they can communicate with each other via
the network. For hands-on approach, you can set up vDC on PROFITBRICKS if you do
not have a physical or cloud infrastructure set up.
Once the IaaS setup on any cloud is complete, you need to configure the Master and the
Node.
Note − The setup is shown for Ubuntu machines. The same can be set up on other Linux
machines as well.
Prerequisites
Page 5 of 65
Installing Docker − Docker is required on all the instances of Kubernetes. Following are
the steps to install the Docker.
Step 2 − Update the package information. Make sure that the apt package is working.
Once all the above tasks are complete, you can start with the actual installation of the
Docker engine. However, before this you need to verify that the kernel version you are
using is correct.
$ curl -L https://github.com/coreos/etcd/releases/download/v2.0.0/etcd
-v2.0.0-linux-amd64.tar.gz -o etcd-v2.0.0-linux-amd64.tar.gz ->1
$ tar xzvf etcd-v2.0.0-linux-amd64.tar.gz ------>2
$ cd etcd-v2.0.0-linux-amd64 ------------>3
$ mkdir /opt/bin ------------->4
$ cp etcd* /opt/bin ----------->5
Now we are ready to build Kubernetes. We need to install Kubernetes on all the machines
on the cluster.
The above command will create a _output dir in the root of the kubernetes folder. Next,
we can extract the directory into any of the directory of our choice /opt/bin, etc.
Next, comes the networking part wherein we need to actually start with the setup of
Kubernetes master and node. In order to do this, we will make an entry in the host file
which can be done on the node machine.
Page 7 of 65
First, we will start copying all the configuration files to their correct location.
The above command will copy all the configuration files to the required location. Now we
will come back to the same directory where we have built the Kubernetes folder.
$ cp kubernetes/cluster/ubuntu/init_conf/kube-apiserver.conf /etc/init/
$ cp kubernetes/cluster/ubuntu/init_conf/kube-controller-manager.conf /etc/init/
$ cp kubernetes/cluster/ubuntu/init_conf/kube-kube-scheduler.conf /etc/init/
$ cp kubernetes/cluster/ubuntu/initd_scripts/kube-apiserver /etc/init.d/
$ cp kubernetes/cluster/ubuntu/initd_scripts/kube-controller-manager /etc/init.d/
$ cp kubernetes/cluster/ubuntu/initd_scripts/kube-kube-scheduler /etc/init.d/
$ cp kubernetes/cluster/ubuntu/default_scripts/kubelet /etc/default/
Page 8 of 65
$ cp kubernetes/cluster/ubuntu/default_scripts/kube-proxy /etc/default/
$ cp kubernetes/cluster/ubuntu/default_scripts/kubelet /etc/default/
The next step is to update the copied configuration file under /etc. dir.
Configure kube-apiserver
For this on the master, we need to edit the /etc/default/kube-apiserver file which we
copied earlier.
Once all the above tasks are complete, we are good to go ahead by bring up the
Kubernetes Master. In order to do this, we will restart the Docker.
Page 9 of 65
Use the same method of copying the files that we did for kubernetes master. As it will only
run the kubelet and the kube-proxy, we will configure them.
$ cp kubernetes/cluster/ubuntu/init_conf/kubelet.conf /etc/init/
$ cp kubernetes/cluster/ubuntu/init_conf/kube-proxy.conf /etc/init/
$ cp kubernetes/cluster/ubuntu/initd_scripts/kubelet /etc/init.d/
$ cp kubernetes/cluster/ubuntu/initd_scripts/kube-proxy /etc/init.d/
$ cp kubernetes/cluster/ubuntu/default_scripts/kubelet /etc/default/
$ cp kubernetes/cluster/ubuntu/default_scripts/kube-proxy /etc/default/
Now we are done with the configuration. You can check by running the following
commands.
Kubernetes - Images
Kubernetes (Docker) images are the key building blocks of Containerized Infrastructure. As
of now, we are only supporting Kubernetes to support Docker images. Each container in a
pod has its Docker image running inside it.
When we are configuring a pod, the image property in the configuration file has the same
syntax as the Docker command does. The configuration file has a field to define the image
name, which we are planning to pull from the registry.
Following is the common configuration structure which will pull image from Docker registry
and deploy in to Kubernetes container.
apiVersion: v1
kind: pod
metadata:
name: Tesing_for_Image_pull -----------> 1
spec:
containers:
- name: neo4j-server ------------------------> 2
image: <Name of the Docker image>----------> 3
imagePullPolicy: Always ------------->4
command: ["echo", "SUCCESS"] ------------------->
name: neo4j-server − This is the name given to the container that we are trying
to create. Like we have given neo4j-server.
image: <Name of the Docker image> − This is the name of the image which
we are trying to pull from the Docker or internal registry of images. We need to
define a complete registry path along with the image name that we are trying to
pull.
imagePullPolicy − Always - This image pull policy defines that whenever we run
this file to create the container, it will pull the same name again.
command: [“echo”, “SUCCESS”] − With this, when we create the container and
if everything goes fine, it will display a message when we will access the container.
In order to pull the image and create a container, we will run the following command.
The above command will produce an output of success or we will get an output as failure.
Kubernetes - Jobs
The main function of a job is to create one or more pod and tracks about the success of
pods. They ensure that the specified number of pods are completed successfully. When a
specified number of successful run of pods is completed, then the job is considered
complete.
Creating a Job
Use the following command to create a job −
apiVersion: v1
kind: Job ------------------------> 1
metadata:
name: py
Page 12 of 65
spec:
template:
metadata
name: py -------> 2
spec:
containers:
- name: py ------------------------> 3
image: python----------> 4
command: ["python", "SUCCESS"]
restartPocliy: Never --------> 5
kind: Job → We have defined the kind as Job which will tell kubectl that the yaml
file being used is to create a job type pod.
Name:py → This is the name of the template that we are using and the spec
defines the template.
Image: python → the image which we are going to pull to create the container
which will run inside the pod.
We will create the job using the following command with yaml which is saved with the
name py.yaml.
The above command will create a job. If you want to check the status of a job, use the
following command.
The above command will create a job. If you want to check the status of a job, use the
following command.
Scheduled Job
Page 13 of 65
Scheduled job in Kubernetes uses Cronetes, which takes Kubernetes job and launches
them in Kubernetes cluster.
Note − The feature of a scheduled job is supported by version 1.4 and the betch/v2alpha
1 API is turned on by passing the –runtime-config=batch/v2alpha1 while bringing up
the API server.
We will use the same yaml which we used to create the job and make it a scheduled job.
apiVersion: v1
kind: Job
metadata:
name: py
spec:
schedule: h/30 * * * * ? -------------------> 1
template:
metadata
name: py
spec:
containers:
- name: py
image: python
args:
/bin/sh -------> 2
-c
ps –eaf ------------> 3
restartPocliy: OnFailure
ps –eaf → Will run ps -eaf command on the machine and list all the running
process inside a container.
This scheduled job concept is useful when we are trying to build and run a set of tasks at a
specified point of time and then complete the process.
Page 14 of 65
Selectors
Labels do not provide uniqueness. In general, we can say many objects can carry the
same labels. Labels selector are core grouping primitive in Kubernetes. They are used by
the users to select a set of objects.
Equality-based selectors
Set-based selectors
Equality-based Selectors
They allow filtering by key and value. Matching objects should satisfy all the specified
labels.
Set-based Selectors
Set-based selectors allow filtering of keys according to a set of values.
apiVersion: v1
kind: Service
metadata:
name: sp-neo4j-standalone
spec:
ports:
- port: 7474
name: neo4j
type: NodePort
selector:
app: salesplatform ---------> 1
component: neo4j -----------> 2
Page 15 of 65
In the above code, we are using the label selector as app: salesplatform and component
as component: neo4j.
Once we run the file using the kubectl command, it will create a service with the name
sp-neo4j-standalone which will communicate on port 7474. The ype is NodePort with
the new label selector as app: salesplatform and component: neo4j.
Kubernetes - Namespace
Namespace provides an additional qualification to a resource name. This is helpful when
multiple teams are using the same cluster and there is a potential of name collision. It can
be as a virtual wall between multiple clusters.
Functionality of Namespace
Following are some of the important functionalities of a Namespace in Kubernetes −
Namespaces are virtual clusters that can sit on top of the same physical cluster.
They provide logical separation between the teams and their environments.
Create a Namespace
The following command is used to create a namespace.
apiVersion: v1
kind: Namespce
metadata
name: elk
This will get a particular namespace whose name is specified in the command.
apiVersion: v1
kind: Service
metadata:
name: elasticsearch
namespace: elk
labels:
component: elasticsearch
spec:
type: LoadBalancer
selector:
component: elasticsearch
ports:
- name: http
port: 9200
protocol: TCP
- name: transport
port: 9300
protocol: TCP
In the above code, we are using the same namespace under service metadata with the
name of elk.
Kubernetes - Node
A node is a working machine in Kubernetes cluster which is also known as a minion. They
are working units which can be physical, VM, or a cloud instance.
Each node has all the required configuration required to run a pod on it such as the proxy
service and kubelet service along with the Docker, which is used to run the Docker
containers on the pod created on the node.
Page 17 of 65
They are not created by Kubernetes but they are created externally either by the cloud
service provider or the Kubernetes cluster manager on physical or VM machines.
The key component of Kubernetes to handle multiple nodes is the controller manager,
which runs multiple kind of controllers to manage nodes. To manage nodes, Kubernetes
creates an object of kind node which will validate that the object which is created is a valid
node.
apiVersion: v1
kind: node
metadata:
name: < ip address of the node>
labels:
name: <lable name>
{
Kind: node
apiVersion: v1
"metadata":
{
"name": "10.01.1.10",
"labels"
{
"name": "cluster 1 node"
}
}
}
Node Controller
They are the collection of services which run in the Kubernetes master and continuously
monitor the node in the cluster on the basis of metadata.name. If all the required services
are running, then the node is validated and a newly created pod will be assigned to that
node by the controller. If it is not valid, then the master will not assign any pod to it and
will wait until it becomes valid.
–register-node = true
However, if the cluster administrator wants to manage it manually then it could be done by
turning the flat of −
–register-node = false
Kubernetes - Service
A service can be defined as a logical set of pods. It can be defined as an abstraction on the
top of the pod which provides a single IP address and DNS name by which pods can be
accessed. With Service, it is very easy to manage load balancing configuration. It helps
pods to scale very easily.
apiVersion: v1
kind: Service
metadata:
name: Tutorial_point_service
spec:
ports:
- port: 8080
targetPort: 31999
The above configuration will create a service with the name Tutorial_point_service.
apiVersion: v1
kind: Service
metadata:
name: Tutorial_point_service
spec:
selector:
application: "My Application" -------------------> (Selector)
ports:
Page 19 of 65
- port: 8080
targetPort: 31999
apiVersion: v1
kind: Endpoints
metadata:
name: Tutorial_point_service
subnets:
address:
"ip": "192.168.168.40" -------------------> (Selector)
ports:
- port: 8080
In the above code, we have created an endpoint which will route the traffic to the endpoint
defined as “192.168.168.40:8080”.
apiVersion: v1
kind: Service
metadata:
name: Tutorial_point_service
spec:
selector:
application: “My Application” -------------------> (Selector)
ClusterIP: 10.3.0.12
ports:
-name: http
protocol: TCP
port: 80
targetPort: 31999
-name:https
Protocol: TCP
Port: 443
targetPort: 31998
Types of Services
Page 20 of 65
ClusterIP − This helps in restricting the service within the cluster. It exposes the service
within the defined Kubernetes cluster.
spec:
type: NodePort
ports:
- port: 8080
nodePort: 31999
name: NodeportService
NodePort − It will expose the service on a static port on the deployed node. A ClusterIP
service, to which NodePort service will route, is automatically created. The service can be
accessed from outside the cluster using the NodeIP:nodePort.
spec:
ports:
- port: 8080
nodePort: 31999
name: NodeportService
clusterIP: 10.20.30.40
Load Balancer − It uses cloud providers’ load balancer. NodePort and ClusterIP
services are created automatically to which the external load balancer will route.
A full service yaml file with service type as Node Port. Try to create one yourself.
apiVersion: v1
kind: Service
metadata:
name: appname
labels:
k8s-app: appname
spec:
type: NodePort
ports:
- port: 8080
nodePort: 31999
name: omninginx
selector:
k8s-app: appname
Page 21 of 65
component: nginx
env: env_name
Kubernetes - Pod
A pod is a collection of containers and its storage inside a node of a Kubernetes cluster. It
is possible to create a pod with multiple containers inside it. For example, keeping a
database container and data container in the same pod.
Types of Pod
There are two types of Pods −
Example − We will create a pod with a tomcat image which is available on the Docker
hub.
This can also be done by creating the yaml file and then running the kubectl create
command.
apiVersion: v1
kind: Pod
metadata:
name: Tomcat
spec:
containers:
- name: Tomcat
image: tomcat: 8.0
ports:
Page 22 of 65
containerPort: 7500
imagePullPolicy: Always
Once the above yaml file is created, we will save the file with the name of tomcat.yml
and run the create command to run the document.
It will create a pod with the name of tomcat. We can use the describe command along with
kubectl to describe the pod.
apiVersion: v1
kind: Pod
metadata:
name: Tomcat
spec:
containers:
- name: Tomcat
image: tomcat: 8.0
ports:
containerPort: 7500
imagePullPolicy: Always
-name: Database
Image: mongoDB
Ports:
containerPort: 7501
imagePullPolicy: Always
In the above code, we have created one pod with two containers inside it, one for tomcat
and the other for MongoDB.
It is a best practice to use the replication controller to manage the pod life cycle rather
than creating a pod again and again.
apiVersion: v1
kind: ReplicationController --------------------------> 1
metadata:
name: Tomcat-ReplicationController --------------------------> 2
spec:
replicas: 3 ------------------------> 3
template:
metadata:
name: Tomcat-ReplicationController
labels:
app: App
component: neo4j
spec:
containers:
- name: Tomcat- -----------------------> 4
image: tomcat: 8.0
ports:
- containerPort: 7474 ------------------------> 5
Setup Details
name: Tomcat → In the spec section, we have defined the name as tomcat which
will tell the replication controller that the container present inside the pods is
tomcat.
containerPort: 7474 → It helps in making sure that all the nodes in the cluster
where the pod is running the container inside the pod will be exposed on the same
port 7474.
Page 24 of 65
Here, the Kubernetes service is working as a load balancer for three tomcat replicas.
component: neo4j
spec:
containers:
- name: Tomcat
image: tomcat: 8.0
ports:
- containerPort: 7474
Setup Details
tier: Backend → We have defined the label tier as backend which creates a
matching selector.
Run the above file using kubectl and create the backend replica set with the provided
definition in the yaml file.
Kubernetes - Deployments
Deployments are upgraded and higher version of replication controller. They manage the
deployment of replica sets which is also an upgraded version of the replication controller.
Page 26 of 65
They have the capability to update the replica set and are also capable of rolling back to
the previous version.
They provide many updated features of matchLabels and selectors. We have got a new
controller in the Kubernetes master called the deployment controller which makes it
happen. It has the capability to change the deployment midway.
Rollback − We can roll back the deployment or the deployment in progress. The user can
create or update the deployment by using DeploymentSpec.PodTemplateSpec =
oldRC.PodTemplateSpec.
Deployment Strategies
Deployment strategies help in defining how the new RC should replace the existing RC.
Recreate − This feature will kill all the existing RC and then bring up the new ones. This
results in quick deployment however it will result in downtime when the old pods are down
and the new pods have not come up.
Rolling Update − This feature gradually brings down the old RC and brings up the new
one. This results in slow deployment, however there is no deployment. At all times, few
old pods and few new pods are available in this process.
- name: Tomcatimage:
tomcat: 8.0
ports:
- containerPort: 7474
In the above code, the only thing which is different from the replica set is we have defined
the kind as deployment.
Create Deployment
Kubernetes - Volumes
In Kubernetes, a volume can be thought of as a directory which is accessible to the
containers in a pod. We have different types of volumes in Kubernetes and the type
defines how the volume is created and its content.
Page 28 of 65
The concept of volume was present with the Docker, however the only issue was that the
volume was very much limited to a particular pod. As soon as the life of a pod ended, the
volume was also lost.
On the other hand, the volumes that are created through Kubernetes is not limited to any
container. It supports any or all the containers deployed inside the pod of Kubernetes. A
key advantage of Kubernetes volume is, it supports different kind of storage wherein the
pod can use multiple of them at the same time.
hostPath − This type of volume mounts a file or directory from the host node’s
filesystem into your pod.
nfs − An nfs volume allows an existing NFS (Network File System) to be mounted
into your pod. The data in an nfs volume is not erased when the Pod is removed
from the node. The volume is only unmounted.
iscsi − An iscsi volume allows an existing iSCSI (SCSI over IP) volume to be
mounted into your pod.
rbd − RBD stands for Rados Block Device. An rbd volume allows a Rados Block
Device volume to be mounted into your pod. Data remains preserved after the Pod
is removed from the node.
Persistent Volume Claim (PVC) − The storage requested by Kubernetes for its pods is
known as PVC. The user does not need to know the underlying provisioning. The claims
must be created in the same namespace where the pod is created.
ReadWriteOnce → This tells the access rights of the volume that we are creating.
path: "/tmp/data01" → This definition tells the machine that we are trying to
create volume under this path on the underlying infrastructure.
Creating PV
Checking PV
$ kubectl get pv
NAME CAPACITY ACCESSMODES STATUS CLAIM REASON AGE
pv0001 10Gi RWO Available 14s
Describing PV
storage: 3Gi → This will tell kubernetes about the amount of space we are trying
to claim.
Creating PVC
Describe PVC
kind: Pod
apiVersion: v1
metadata:
name: mypod
labels:
name: frontendhttp
spec:
containers:
- name: myfrontend
image: nginx
ports:
Page 32 of 65
- containerPort: 80
name: "http-server"
volumeMounts: ----------------------------> 1
- mountPath: "/usr/share/tomcat/html"
name: mypd
volumes: -----------------------> 2
- name: mypd
persistentVolumeClaim: ------------------------->3
claimName: myclaim-1
volumeMounts: → This is the path in the container on which the mounting will
take place.
Volume: → This definition defines the volume definition that we are going to claim.
persistentVolumeClaim: → Under this, we define the volume name which we are
going to use in the defined pod.
Kubernetes - Secrets
Secrets can be defined as Kubernetes objects used to store sensitive data such as user
name and passwords with encryption.
apiVersion: v1
kind: Secret
metadata:
name: tomcat-pass
type: Opaque
data:
password: <User Password>
username: <User Name>
Using Secrets
Once we have created the secrets, it can be consumed in a pod or the replication controller
as −
Environment Variable
Volume
As Environment Variable
In order to use the secret as environment variable, we will use env under the spec section
of pod yaml file.
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: mysecret
key: tomcat-pass
As Volume
spec:
volumes:
- name: "secretstest"
Page 34 of 65
secret:
secretName: tomcat-pass
containers:
- image: tomcat:7.0
name: awebserver
volumeMounts:
- mountPath: "/tmp/mysec"
name: "secretstest"
apiVersion: v1
kind: ReplicationController
metadata:
name: appname
spec:
replicas: replica_count
template:
metadata:
name: appname
spec:
nodeSelector:
resource-group:
containers:
- name: appname
image:
imagePullPolicy: Always
ports:
- containerPort: 3000
env: -----------------------------> 1
- name: ENV
valueFrom:
configMapKeyRef:
name: appname
key: tomcat-secrets
In the above code, under the env definition, we are using secrets as environment variable
in the replication controller.
apiVersion: v1
kind: pod
metadata:
name: appname
spec:
metadata:
name: appname
spec:
volumes:
- name: "secretstest"
secret:
secretName: tomcat-pass
containers:
- image: tomcat: 8.0
name: awebserver
volumeMounts:
- mountPath: "/tmp/mysec"
name: "secretstest"
First, we need to configure Namespace Isolation Policy. Basically, this kind of networking
policies are required on the load balancers.
kind: Namespace
apiVersion: v1
metadata:
annotations:
net.beta.kubernetes.io/network-policy: |
{
"ingress":
{
"isolation": "DefaultDeny"
}
}
Page 36 of 65
kind: NetworkPolicy
apiVersion: extensions/v1beta1
metadata:
name: allow-frontend
namespace: myns
spec:
podSelector:
matchLabels:
role: backend
ingress:
- from:
- podSelector:
matchLabels:
role: frontend
ports:
- protocol: TCP
port: 6379
Kubernetes - API
Kubernetes API serves as a foundation for declarative configuration schema for the
system. Kubectl command-line tool can be used to create, update, delete, and get API
object. Kubernetes API acts a communicator among different components of Kubernetes.
The API which is getting added should be useful to more than 50% of the users. There is
no other way to implement the functionality in Kubernetes. Exceptional circumstances are
discussed in the community meeting of Kubernetes, and then API is added.
Page 37 of 65
API Changes
In order to increase the capability of Kubernetes, changes are continuously introduced to
the system. It is done by Kubernetes team to add the functionality to Kubernetes without
removing or impacting the existing functionality of the system.
The api.Pod is validated, and any errors are returned to the user
Now that we have the Pod object stored, a user can GET that object in any supported API
version. For example −
The JSON is read from etcd and unmarshalled into a v6.Pod structure
The implication of this process is that API changes must be done carefully and backward
compatibly.
API Versioning
To make it easier to support multiple structures, Kubernetes supports multiple API versions
each at different API path such as /api/v1 or /apsi/extensions/v1beta1
Alpha Level
This version may be buggy; the enabled version may have bugs
Recommended to be used in short term testing only as the support may not be
present all the time.
Beta Level
The code is fully tested and the enabled version is supposed to be stable.
The support of the feature will not be dropped; there may be some small changes.
Stable Level
Stable versions of features will appear in the released software for many
subsequent versions.
Kubernetes - Kubectl
Kubectl is the command line utility to interact with Kubernetes API. It is an interface which
is used to communicate and manage pods in Kubernetes cluster.
One needs to set up kubectl to local in order to interact with Kubernetes cluster.
Setting Kubectl
Download the executable to the local workstation using the curl command.
On Linux
$ curl -O https://storage.googleapis.com/kubernetesrelease/
release/v1.5.2/bin/linux/amd64/kubectl
On OS X workstation
Page 39 of 65
$ curl -O https://storage.googleapis.com/kubernetesrelease/
release/v1.5.2/bin/darwin/amd64/kubectl
After download is complete, move the binaries in the path of the system.
$ chmod +x kubectl
$ mv kubectl /usr/local/bin/kubectl
Configuring Kubectl
Following are the steps to perform the configuration operation.
Replace ${MASTER_HOST} with the master node address or name used in the
previous steps.
Replace ${CA_CERT} with the absolute path to the ca.pem created in the
previous steps.
Kubectl commands are used to interact and manage Kubernetes objects and the cluster.
In this chapter, we will discuss a few commands used in Kubernetes via kubectl.
For example,
$ kubectl api-version;
kubectl autoscale − This is used to auto scale pods which are defined such as
Deployment, replica set, Replication Controller.
$ kubectl cluster-info
In the same way, we can create multiple things as listed using the create command along
with kubectl.
deployment
namespace
quota
secret docker-registry
secret
secret generic
secret tls
serviceaccount
service clusterip
service loadbalancer
service nodeport
kubectl delete − Deletes resources by file name, stdin, resource and names.
kubectl drain − This is used to drain a node for maintenance purpose. It prepares the
node for maintenance. This will mark the node as unavailable so that it should not be
assigned with a new container which will be created.
kubectl edit − It is used to end the resources on the server. This allows to directly edit a
resource which one can receive via the command line tool.
kubectl expose − This is used to expose the Kubernetes objects such as pod, replication
controller, and service as a new Kubernetes service. This has the capability to expose it via
a running container or from a yaml file.
kubectl get − This command is capable of fetching data on the cluster about the
Kubernetes resources.
For example,
kubectl logs − They are used to get the logs of the container in a pod. Printing the logs
can be defining the container name in the pod. If the POD has only one container there is
no need to define its name.
kubectl port-forward − They are used to forward one or more local port to pods.
Apart from the above, we can perform multiple tasks using the rollout such as −
rollout history
rollout pause
rollout resume
rollout status
rollout undo
kubectl run − Run command has the capability to run an image on the Kubernetes
cluster.
Page 46 of 65
$ kubectl run NAME --image = image [--env = "key = value"] [--port = port] [--
replicas = replicas] [--dry-run = bool] [--overrides = inline-json] [--command] --
[COMMAND] [args...]
$ kubectl run tomcat --image = tomcat:7.0
$ kubectl run tomcat –-image = tomcat:7.0 –port = 5000
kubectl scale − It will scale the size of Kubernetes Deployments, ReplicaSet, Replication
Controller, or job.
kubectl set resources − It is used to set the content of the resource. It updates
resource/limits on object with pod template.
$ kubectl set resources (-f FILENAME | TYPE NAME) ([--limits = LIMITS & --
requests = REQUESTS]
$ kubectl set resources deployment tomcat -c = tomcat --
limits = cpu = 200m,memory = 512Mi
kubectl top node − It displays CPU/Memory/Storage usage. The top command allows
you to see the resource consumption for nodes.
By downloading
By Downloading
The existing image can be downloaded from Docker hub and can be stored on the local
Docker registry.
The above screenshot shows a set of images which are stored in our local Docker registry.
If we want to build a container from the image which consists of an application to test, we
can do it using the Docker run command.
FROM ubuntu:14.04
MAINTAINER vipinkumarmishra@virtusapolaris.com
ENV REFRESHED_AT 2017-01-15
Page 48 of 65
Once the above file is created, save it with the name of Dockerfile and cd to the file path.
Then, run the following command.
Once the image is built, we can test if the image is working fine and can be converted to a
container.
In this setup, we can have a load balancer setting on top of one application diverting traffic
to a set of pods and later they communicate to backend pods. The communication
between pods happen via the service object built in Kubernetes.
apiVersion: v1
kind: Service
metadata:
name: oppv-dev-nginx
labels:
k8s-app: omni-ppv-api
spec:
type: NodePort
ports:
- port: 8080
nodePort: 31999
name: omninginx
selector:
k8s-app: appname
component: nginx
env: dev
apiVersion: v1
kind: ReplicationController
metadata:
name: appname
spec:
replicas: replica_count
template:
metadata:
name: appname
labels:
k8s-app: appname
component: nginx
env: env_name
spec:
nodeSelector:
resource-group: oppv
containers:
- name: appname
image: IMAGE_TEMPLATE
imagePullPolicy: Always
ports:
- containerPort: 8080
Page 51 of 65
resources:
requests:
memory: "request_mem"
cpu: "request_cpu"
limits:
memory: "limit_mem"
cpu: "limit_cpu"
env:
- name: BACKEND_HOST
value: oppv-env_name-node:3000
apiVersion: v1
kind: Service
metadata:
name: appname
labels:
k8s-app: appname
spec:
type: NodePort
ports:
- name: http
port: 3000
protocol: TCP
targetPort: 3000
selector:
k8s-app: appname
component: nodejs
env: dev
apiVersion: v1
kind: ReplicationController
metadata:
name: Frontend
spec:
replicas: 3
template:
Page 52 of 65
metadata:
name: frontend
labels:
k8s-app: Frontend
component: nodejs
env: Dev
spec:
nodeSelector:
resource-group: oppv
containers:
- name: appname
image: IMAGE_TEMPLATE
imagePullPolicy: Always
ports:
- containerPort: 3000
resources:
requests:
memory: "request_mem"
cpu: "limit_cpu"
limits:
memory: "limit_mem"
cpu: "limit_cpu"
env:
- name: ENV
valueFrom:
configMapKeyRef:
name: appname
key: config-env
apiVersion: v1
kind: Service
metadata:
name: backend
labels:
k8s-app: backend
spec:
type: NodePort
ports:
- name: http
Page 53 of 65
port: 9010
protocol: TCP
targetPort: 9000
selector:
k8s-app: appname
component: play
env: dev
apiVersion: v1
kind: ReplicationController
metadata:
name: backend
spec:
replicas: 3
template:
metadata:
name: backend
labels:
k8s-app: beckend
component: play
env: dev
spec:
nodeSelector:
resource-group: oppv
containers:
- name: appname
image: IMAGE_TEMPLATE
imagePullPolicy: Always
ports:
- containerPort: 9000
command: [ "./docker-entrypoint.sh" ]
resources:
requests:
memory: "request_mem"
cpu: "request_cpu"
limits:
memory: "limit_mem"
cpu: "limit_cpu"
volumeMounts:
Page 54 of 65
- name: config-volume
mountPath: /app/vipin/play/conf
volumes:
- name: config-volume
configMap:
name: appname
Kubernetes - Autoscaling
Autoscaling is one of the key features in Kubernetes cluster. It is a feature in which the
cluster is capable of increasing the number of nodes as the demand for service response
increases and decrease the number of nodes as the requirement decreases. This feature of
auto scaling is currently supported in Google Cloud Engine (GCE) and Google Container
Engine (GKE) and will start with AWS pretty soon.
In order to set up scalable infrastructure in GCE, we need to first have an active GCE
project with features of Google cloud monitoring, google cloud logging, and stackdriver
enabled.
First, we will set up the cluster with few nodes running in it. Once done, we need to set up
the following environment variable.
Environment Variable
export NUM_NODES = 2
export KUBE_AUTOSCALER_MIN_NODES = 2
export KUBE_AUTOSCALER_MAX_NODES = 5
export KUBE_ENABLE_CLUSTER_AUTOSCALER = true
Once done, we will start the cluster by running kube-up.sh. This will create a cluster
together with cluster auto-scalar add on.
./cluster/kube-up.sh
On creation of the cluster, we can check our cluster using the following kubectl command.
Now, we can deploy an application on the cluster and then enable the horizontal pod
autoscaler. This can be done using the following command.
The above command shows that we will maintain at least one and maximum 10 replica of
the POD as the load on the application increases.
We can check the status of autoscaler by running the $kubclt get hpa command. We will
increase the load on the pods using the following command.
We can check the number of pods running using the following command.
Docker (1.3+)
go (1.5+)
nodejs (4.2.2+)
npm (1.3+)
java (7+)
gulp (3.9+)
Kubernetes (1.1.2+)
Installing Python
$ sudo apt-get install python
$ sudo apt-get install python3
Installing GCC
$ sudo apt-get install gcc-4.8 g++-4.8
Installing make
$ sudo apt-get install make
Installing Java
$ sudo apt-get install openjdk-7-jdk
Installing Node.js
Page 57 of 65
$ wget https://nodejs.org/dist/v4.2.2/node-v4.2.2.tar.gz
$ tar -xzf node-v4.2.2.tar.gz
$ cd node-v4.2.2
$ ./configure
$ make
$ sudo make install
Installing gulp
$ npm install -g gulp
$ npm install gulp
Verifying Versions
Java Version
$ java –version
java version "1.7.0_91"
OpenJDK Runtime Environment (IcedTea 2.6.3) (7u91-2.6.3-1~deb8u1+rpi1)
OpenJDK Zero VM (build 24.91-b01, mixed mode)
$ node –v
V4.2.2
$ npn -v
2.14.7
$ gulp -v
[09:51:28] CLI version 3.9.0
Installing GO
Building GO
$ ./all.bash
$ vi /root/.bashrc
In the .bashrc
export GOROOT = $HOME/go
export PATH = $PATH:$GOROOT/bin
$ go version
go version go1.4.3 linux/arm
Kubernetes - Monitoring
Monitoring is one of the key component for managing large clusters. For this, we have a
number of tools.
It is a monitoring and alerting system. It was built at SoundCloud and was open sourced in
2012. It handles the multi-dimensional data very well.
Prometheus node explore − Gets the host level matrices and exposes them to
Prometheus.
InfuxDB − Time series database specifically used to store data from rancher.
Create an SPM App of type “Docker” to obtain the SPM App Token. SPM App will
hold your Kubernetes performance metrics and event.
Create a Logsene App to obtain the Logsene App Token. Logsene App will hold your
Kubernetes logs.
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
name: sematext-agent
spec:
template:
metadata:
labels:
app: sematext-agent
spec:
selector: {}
dnsPolicy: "ClusterFirst"
restartPolicy: "Always"
containers:
- name: sematext-agent
image: sematext/sematext-agent-docker:latest
imagePullPolicy: "Always"
env:
- name: SPM_TOKEN
value: "REPLACE THIS WITH YOUR SPM TOKEN"
- name: LOGSENE_TOKEN
Page 62 of 65
Kubernetes Log
Kubernetes containers’ logs are not much different from Docker container logs. However,
Kubernetes users need to view logs for the deployed pods. Hence, it is very useful to have
Kubernetes-specific information available for log search, such as −
Kubernetes namespace
Kubernetes UID
The following code shows how to set up ELK cluster on Kubernetes and create service for
ElasticSearch −
apiVersion: v1
kind: Service
metadata:
name: elasticsearch
namespace: elk
labels:
component: elasticsearch
spec:
type: LoadBalancer
selector:
component: elasticsearch
ports:
- name: http
port: 9200
protocol: TCP
- name: transport
port: 9300
protocol: TCP
apiVersion: v1
kind: ReplicationController
metadata:
name: es
namespace: elk
labels:
component: elasticsearch
spec:
replicas: 1
template:
metadata:
labels:
component: elasticsearch
spec:
serviceAccount: elasticsearch
containers:
- name: es
Page 64 of 65
securityContext:
capabilities:
add:
- IPC_LOCK
image: quay.io/pires/docker-elasticsearch-kubernetes:1.7.1-4
env:
- name: KUBERNETES_CA_CERTIFICATE_FILE
value: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
- name: NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: "CLUSTER_NAME"
value: "myesdb"
- name: "DISCOVERY_SERVICE"
value: "elasticsearch"
- name: NODE_MASTER
value: "true"
- name: NODE_DATA
value: "true"
- name: HTTP_ENABLE
value: "true"
ports:
- containerPort: 9200
name: http
protocol: TCP
- containerPort: 9300
volumeMounts:
- mountPath: /data
name: storage
volumes:
- name: storage
emptyDir: {}
Kibana URL
For Kibana, we provide the Elasticsearch URL as an environment variable.
- name: KIBANA_ES_URL
value: "http://elasticsearch.elk.svc.cluster.local:9200"
Page 65 of 65
- name: KUBERNETES_TRUST_CERT
value: "true"
Kibana UI will be reachable at container port 5601 and corresponding host/Node Port
combination. When you begin, there won’t be any data in Kibana (which is expected as
you have not pushed any data).