Kubernetes — Orchestration Guide [A Lovely Symphony 2]
This is a part two of our Kubernetes guide, do check out our part1 if you haven’t seen it to make it easier to understand this writeup.
When concluding part 1 of our Kubernetes series, we created a yaml config
file called ourapp-pod.yaml
in the root folder of our codebase which I promised we would continue from.
Open up ourapp-pod.yaml
file and type in the following:
apiVersion: v1
kind: Pod
metadata:
name: ourapp
labels:
component: web
spec:
containers:
- name: ourapp-container
image: covenant/dockerize-nodejs-image
ports:
- containerPort: 5000
Create a new file in that same root folder of your project, let’s call it ourapp-node.yaml
and type in the following:
apiVersion: v1
kind: Service
metadata:
name: ourapp-node
spec:
type: NodePort
ports:
- port: 5050
targetPort: 5000
nodePort: 30001
selector:
component: web
Don’t worry, we would go into details of what exactly are those files and what their contents mean 😎.
Objects in Kubernetes
Kubernetes uses config files to describe objects declaratively, a Pod for example as we would soon see is a type of object in Kubernetes.
Objects are basically “items” we create in our Kubernetes environment to make our applications work in an expected way. These items are used to serve various purposes from setting up networks to monitoring and running containers.
API-Versions which are represented by the apiVersion: v1
attribute, which you saw earlier, in both config files are used by Kubernetes internally to scope the types of objects that we can create in a given config file.
A different API-Version would contain a completely different set of objects that we would be allowed to create.
The kind
attribute in our config files represents the “type of object” we are creating.
apiVersion: v1
kind: Pod
#from ourapp-pod.yaml file
-------------------------------------------------apiVersion: v1
kind: Service
#from ourapp-node.yaml file
A config file that has a kind
attribute of Pod is used to define the config settings and specification which Kubernetes will use to run a container.
A config file with kind: Service
is used by Kubernetes to setup networking within a kubernetes cluster.
Don’t worry if it sounds a bit confusing, you will understand much better as we go on 😊😊.
Pods
A pod is the smallest unit of deployment in Kubernetes. It is what will serve as a “carrier” or “enclosure” of a container.
A pod is used to run a grouping of one or more containers that are very closely related and have a tightly coupled relationship.
A pod is used as an enclosure for one or more containers that must absolutely be executed with each other.
Here’s a diagram representing our current project that would help you understand the structure and relationship between a Node, Pod and Container:
Here’s another diagram depicting a Pod for a hypothetical project that contains a MongoDB container and a service in NodeJS that listens to whenever a new record is inserted helps recompute indexes:
Let’s go back to our first config file now ourapp.yaml
that had these contents having kind: Pod
.
apiVersion: v1
kind: Pod
metadata:
name: ourapp
labels:
component: web
spec:
containers:
- name: ourapp-container
image: covenant/dockerize-nodejs-image
ports:
- containerPort: 5000
It should be a bit clear now what this config file means. We are instructing Kubernetes to do the following:
apiVersion: v1
:- uses the v1 scope so that we can have access toobject types
like Pod which are under the v1 scope.kind: Pod
:- describes the type of object we want Kubernetes to create in using this config file. In our case, we want Kubernetes to create a Pod for us.metadata
:- this is used to describe our pods through naming and also having customlabels
that better describe what our pod is about. A particular label which we used calledcomponent
is also used to associate our Pod with our service as we would soon see.spec
:- this is used to describe the contents of our object and their definitions.containers
:- since we are creating a pod which is essentially a grouping of one or more containers that are tightly coupled together, we enumerate our containers under thecontainers
attribute.containers | -name
:- we use the name attribute to give an identity to the container we are creating in this pod. It is this name attribute that would help us in identifying individual containers in a pod which could be very useful in instances where we want to view the log of a particular container.containers | image
:- we use the image attribute to point Kubernetes to our image which has been pushed to our Docker Hub repository.containers | ports
:- we use this attribute to enumerate the various port structures associated with our individual containers.containers | ports | containerPort
:- the containerPort attribute is used to specify the particular port which we want exposed to the outside world from our individual container. In this case we want “port 5000” exposed because it is the port which our nodejs app starts on.
Services
A service is a Kubernetes object that is used to setup networking in a Kubernetes cluster.
We have four major types of Services which are
- Load Balancer.
- Ingress.
- NodePort.
- ClusterIp.
A NodePort type of service is used for exposing a Pod to the outside world and is only used mostly in development environments. This is what is being used in our current ourapp-node.yaml
file to make the container in our pod accessible from our browser as we will soon see
We will discuss what the other 3 sub-types are in more detail later.
Let’s get into our ourapp-node.yaml
file which is the config file describing a service and understand what it does.
apiVersion: v1
kind: Service
metadata:
name: ourapp-node
spec:
type: NodePort
ports:
- port: 5050
targetPort: 5000
nodePort: 30001
selector:
component: web
We’ve talked about apiVersion, kind and metadata
attributes earlier on, we’ve also discussed what a spec type of NodePort
means.
Let’s discuss on the remaining two which are selector
and ports
.
Selector
Selector as the name suggests is a key-value pair which is used to identify the Kubernetes objects to which the Service should be applied. You would remember that in our Pod config file i.e ourapp.yaml, we had a label property:
apiVersion: v1
kind: Pod
metadata:
name: ourapp-container
labels:
component: web
spec:
containers:
- name: ourapp
image: covenant/dockerize-nodejs-image
ports:
- containerPort: 5000
Our selector simply searches for every Kubernetes objects(in our case it was a Pod) that have a key value label metadata
matching it’s description. Since “component: web”
in our label matches our selector description of “component: web”
, Kubernetes immediately knows to apply our NodePort service
to our Pod.
Ports
The ports attribute defines the port mappings for our service.
- - port: This defines the port number through which another pod in the same Kubernetes cluster could use to access our
target
pod. - targetPort: This is the port number of the target container in our Pod that we want to open up traffic to. You would notice that the value here (5000) matches what we defined as our
container port
in ourapp.yaml file. - nodePort: This is the port number that we are going to use in our browser i.e in the outside world to access our container when it is running.
Sticky Notes
- Kubernetes works with a concept of “objects” which are used to serve various purposes from setting up networks to monitoring and running containers.
- A Pod is a type of Kubernetes Object.
- A pod is the smallest unit of deployment in Kubernetes and serves as enclosure for one or more containers that are tightly related to each other.
- We define a Pod in a kubernetes config file by using a
kind
attribute of “Pod” - A Service is also a type of Kubernetes Object which is majorly used to setup networking.
- Kubernetes uses the concept of labels and selectors to apply services to other Kubernetes objects such as Pods.
- A NodePort service should only be used in development for the most part.
Conclusion
We’ve learnt alot in this section about Pods and NodePort services, we will still learn a whole lot about this brilliant tool as we continue.
Hire Me
Have any interesting project?, super awesome. Shoot me an email at covenantchukwudi@gmail.com