[MUSIC]
Hello, and welcome to this lecture on Kubernetes Pods.
Before we head into understanding Pods,
we would like to assume that the following have been set up already.
At this point, we assume that the application is already developed
and built into Docker images
and it is available on a Docker repository
like Docker Hub so Kubernetes can pull it down.
We also assume that the Kubernetes Cluster has already been set up and is working.
This could be a single node setup or a multi-node setup, it doesn't matter.
All the services need to be in a running state.
As we discussed before,
with Kubernetes, our ultimate aim is to deploy our application
in the form of containers on a set of machines
that are configured as worker nodes in a cluster.
However, Kubernetes does not deploy containers directly on the worker nodes.
The containers are encapsulated into a Kubernetes object known as Pods.
A Pod is a single instance of an application.
A Pod is the smallest object that you can create in Kubernetes.
Here we see the simplest of simplest cases
where you have a single node Kubernetes cluster
with a single instance of your application
running in a single Docker container encapsulated in a Pod.
What if the number of users accessing your application increase
and you need to scale your application?
You need to add additional instances of your web application to share the load.
Now, where would you spin up additional instances?
Do we bring up a new container instance within the same Pod?
No, we create new Pod altogether
with a new instance of the same application.
As you can see, we now have two instances of our web application
running on two separate Pods on the same Kubernetes system or node.
What if the user base further increases
and your current node has no sufficient capacity?
Well, then you can always deploy additional Pods on a new node in the cluster.
You will have a new node added to the cluster
to expand the cluster's physical capacity.
What I'm trying to illustrate in this slide
is that Pods usually have a one-to-one relationship
with containers running your application.
To scale up, you create new Pods, and to scale down, you delete existing Pods.
You do not add additional containers to an existing Pod to scale your application.
Also, if you're wondering how we implement all of this,
and how we achieve load balancing between the containers, et cetera,
we will get into all of that in a later lecture.
For now, we're only trying to understand the basic concepts.
We just said that Pods usually have
a one-to-one relationship with the containers,
but are we restricted to having a single container in a single Pod?
No.
A single Pod can have multiple containers
except for the fact that they're usually not multiple containers of the same kind.
As we discussed in the previous slide,
if our intention was to scale our application,
then we would need to create additional Pods.
Sometimes you might have a scenario where you have a helper container
that might be doing some kind of supporting task for our web application,
such as processing a user-entered data,
processing a file uploaded by the user, et cetera,
and you want these helper containers
to live alongside your application container.
In that case, you can have both of these containers part of the same Pod,
so that when a new application container is created,
the helper is also created
and when it dies, the helper also dies since they are part of the same Pod.
The two containers can also communicate with each other directly
by referring to each other as localhost since they share the same network space.
Plus they can easily share the same storage space as well.
If you still have doubts in this topic,
I would understand if you did
because I did the first time I learned these concepts.
We could take another shot
at understanding Pods from a different angle.
Let's, for a moment, keep Kubernetes out of our discussion
and talk about simple Docker containers.
Let's assume we were developing a process or a script
to deploy our application on a Docker host.
Then we would first simply deploy our application
using a simple docker run python-app command,
and the application runs fine and our users are able to access it.
When the load increases,
we deploy more instances of our application
by running the docker run commands many more times.
This works fine, and we're all happy.
Now sometime in the future, our application is further developed,
undergoes architectural changes, and grows and gets complex.
We now have a new helper container that helps our web application
by processing or fetching data from elsewhere.
These helper containers maintain a one-to-one relationship
with our application container,
and thus needs to communicate with the application containers directly
and access data from those containers.
For this, we need to maintain a map
of what app and helper containers are connected to each other.
We will need to establish network connectivity
between these containers ourselves using links and custom networks.
We would need to create shareable volumes and share it among the containers.
We would need to maintain a map of that as well.
Most importantly, we will need to monitor the state of the application container
and when it dies, manually kill the helper container as well
as it's no longer required.
When a new container is deployed,
we would need to deploy the new helper container as well.
With Pods, Kubernetes does all of this for us automatically.
We just need to define what containers a Pod consists of
and the containers in a Pod, by default, will have access to the same storage,
the same network namespace, and same fate.
As in they will be created together and destroyed together.
Even if our application didn't happen to be so complex,
and we could live with a single container,
Kubernetes still requires you to create Pods,
but this is good in the long run
as your application is now equipped for architectural changes
and scale in the future.
However, also note that multi Pod containers are a rare use case,
and we're going to stick to single containers per Pod in this course.
Let us now look at how to deploy Pods.
Earlier, we learned about the kubectl run command.
What this command really does is it deploys a Docker container by creating a Pod.
It first creates a Pod automatically
and deploys an instance of the nginx Docker image,
but where does it get the application image from?
For that, you need to specify the image name using the image parameter.
The application image, in this case, the nginx image
is downloaded from the Docker Hub repository.
Docker Hub, as we discussed is a public repository
where latest Docker images of various applications are stored.
You could configure Kubernetes to pull the image from the public Docker Hub
or a private repository within the organization.
Now that we have a Pod created, how do we see the list of Pods available?
The kubectl get pods command helps us see the list of Pods in our cluster.
In this case, we see the Pod is in a container creating state
and soon changes to a running state when it is actually running.
Also, remember that we haven't really talked about the concepts
on how a user can access the nginx web server.
In the current state,
we haven't made the web server accessible to external users.
You can access it internally from the node,
but for now, we will just see how to deploy a Pod
and later, in a later lecture,
once we learn about networking and services,
we will get to know how to make the service accessible to end-users.
Well, that's it for this lecture,
head over to our demo and I will see you in the next one.