This section is going to discuss service discovery.
But before we start this section off, please delete all the pods that we've deployed so far.
So kubectl delete pods, dash, dash all to delete all the pods in the current context.
That's going to delete the API pod, the portal pod.
So once you've done that then feel free to unpause the video so we can start this lesson.
Port forwarding isn't a very reliable way to access our application.
We need something more stable, something more durable.
And that's going to be the main theme of this lesson a Kubernetes primitive that provides us with stable
endpoints to access our pods.
Now you'll notice I just created a folder called section two.
Okay.
What I want you to do is copy the pod definitions we have so far into the section two folder.
We're done with this one.
We've deleted.
We've deleted the pods um associated with its definitions.
And then these new pod definitions.
Delete the health checkers.
We don't need them.
I just wanted to demonstrate to you the sidecar pattern, where you have one app that simply can't exist
without the creation of another app.
In this case, put them in the same pod where they are created and destroyed together, where they share
the same network namespace.
But in this case, we don't need health checkers, because Kubernetes automatically provides the liveness
and readiness probes that you can leverage out of the box.
I'll show you how to leverage these probes in another section.
But anyway, we're not going to create containers that we don't need so that they can consume valuable
memory and CPU.
Okay, we'll delete those.
We don't want to demo the sidecar pattern anymore.
And let's start this lesson.
Every pod in Kubernetes is given a virtual IP address.
If we think of an IP address as, um, a sequence of characters that identifies the location where our
app is running, then technically we can connect to our app by specifying the IP address, the location
where it's running, followed by the port where it's serving requests.
Okay, this all makes sense until you realize that pods in Kubernetes are ephemeral.
They're not durable.
Pods are constantly created and destroyed.
That's how Kubernetes performs scaling, self-healing, and so on and so forth.
And whenever these pods are created and destroyed, they're given new IP addresses.
So pod IP addresses are not a very reliable way of accessing our applications.
So here we have a pod that is initially confined within the Kubernetes setup that's running on our local
machine.
Remember because we're prototyping, our Kubernetes cluster is just composed of one node, one machine,
your laptop, your desktop, whatever it may be.
And in order to be able to access this, um, great submission portal.
Externally, through our browser, we specify a node port service.
Remember the node being our machine, our local machine.
What the node port service is going to do is it's going to open a static port on your node on your computer.
That static port typically ranges between 30,000 and and 32,000.
And so then we can say localhost 32,000.
And that kind of gives us an entry into our Kubernetes setup.
So our request has made it inside of Kubernetes.
Now we want to direct that request to the great submission portal pod.
And that is done using a label selector.
So the great submission portal has these labels that identify it and categorize it into distinct groups.
And we can query this labeled pod using a label selector.
So at this point we've forwarded that traffic to the appropriate pod.
And then once that traffic has been forwarded, the target port that we specify in the node port service
ensures that that request ends up going to the pod port where our application is serving requests,
which ultimately sends back a response.
And we've essentially accessed our app.
So that's one scenario.
Now you'll notice here that the pod IP addresses are changing.
This implies a scenario where the old pod was destroyed for whatever reason.
Maybe it failed and was restarted.
And then a new pod was created with a different IP address.
Well, in this case, we're not connecting to the pod using its IP address.
Not directly at least.
The label selector is querying the pod based on whatever labels it has and forwarding traffic to it.
Now, behind the scenes, what happens is a kube proxy is going to find the pod with the matching labels.
And it knows what that party's IP address is and forwards it that request accordingly.
But we don't need to worry about what's happening behind the scenes.
All we need to know is that the node port service uses label selectors to forward external traffic to
the appropriate pod.
Now let's imagine a scenario where we're actually ready to deploy a real Kubernetes cluster on AWS with
many, many worker nodes.
If we deploy a node port service, what it's going to do is open up a static port on every single machine,
on every single worker node, even the ones that aren't running our app.
This is very, very bad, mainly for security reasons.
It's very clunky.
It makes things very hard to scale.
I'll go over the disadvantages later once we talk about ingress and load balancing.
But ultimately node port is never something that you'd ever, ever use in production.
We use it for prototyping when we have only one node that makes up our Kubernetes cluster, in this
case our local machine.
So in real life, you'd never actually use node port to expose your pods for external traffic.
Okay.
And I added a screaming cat just to emphasize this.
All right.
So a node port service is used to access applications externally.
We mainly use it in prototyping.
Let's go ahead and look at an example right now.
So um here I'm going to create a new file called grade submission.
Portal service dot YAML I'm going to say service.
And thanks to our Kubernetes extension we get the auto generated YAML.
Uh my app is great submission portal.
So I've given the service a name.
And here is the label selector.
The label selector is what we use to query the pod in order to know where to forward traffic.
So we're going to forward traffic to any pod that has the label app Kubernetes.io slash name or no app
dot Kubernetes.io slash instance.
Great submission portal.
So through the selector we've created a link between the great Submission portal service that's going
to receive external traffic to the Great Submission Portal pod, which will respond to requests.
All right.
Now here we specify the service port the target port and the node port.
All right.
Because ultimately this service remember is going to be of type node port.
So under spec I'm going to say type node port.
Uh so the target port is going to be 5001 the node port.
I'm going to say 32,000.
Usually the node port is limited between values of 30,000 to 32,000.
So make sure to specify a value in that range.
The service port allows for internal access will make it the same value as the target port.
Let's just go ahead and say kubectl apply or no.
We'll have to go inside of section two.
Um we'll go inside or we'll just say kubectl apply dash f.
Great submission portal pod dot YAML kubectl apply dash f.
Great submission service, great submission portal service dot YAML.
And now a port has been exposed.
A static port hasn't been exposed on our node such that if we say localhost 32,000, that request is
going to be forwarded to the pod that has this label grade submission portal.
And then once the pod receives that request, the target port ensures that it goes to the pod port 5001,
where that request will get processed and a response will be sent back.
Let's go ahead and try it out.
Localhost 32,000.
Wonderful.
Now when we submit grade data.
Nothing happens because we need to instrument our grade submission portal to connect to the grade submission
API pod, which we've not deployed yet.
And that connection is going to be made through a cluster IP service.
The conduit is going to be a cluster IP service.
The conduit for internal pod to pod Communication.
Now a cluster IP service is given.
As the name implies, a cluster IP address that can be used to communicate with it.
Now, you don't actually have to know the IP address, because the name of your cluster IP service will
automatically resolve to it.
So the Great Submission portal can interact with the cluster IP service by making a request to the service
name, followed by the service port, a logical port that allows us to interact with the service itself.
And then once that request from our great Submission portal has been sent to the cluster IP service,
it's going to forward that request to whatever pod whose label matches the label selector.
Okay.
And once that request has been forwarded to the right pod, in this case, the great submission API
pod that target port ensures that that request gets sent to the port where requests are being processed
by the actual grade submission API app.
So in this case, in a cluster IP service, we just define the service port and the target port.
So let's go ahead and orchestrate this I'm going to create a grade.
What am I doing within section two I'll create a new file a grade submission API service dot YAML.
Um I'm going to say service auto generate the skeleton app name grade submission API.
Under spec, we specify how we want the service to behave, such that it's going to select any app that
has the following label.
It's going to query apps that have this label and forward any traffic.
Get that gets sent to it's service port 3000 to a target port of 3000 as well.
Okay.
And that's pretty much it.
I'm going to go ahead and say kubectl apply dash f.
Great submission API service dot YAML.
Uh great submission API dot YAML or pod dot YAML.
Beautiful.
So now we've got let me go ahead and say kubectl get pods.
We've got two pods each one running one container kubectl get services.
We've got two services.
You can ignore this one.
It's created by default one great submission API cluster IP service and one great submission portal
node port service.
So this service has been set up to forward all traffic to any pod that matches this label.
And then once that traffic gets there, it's going to ensure that the target port within this pod is
able to receive the traffic and send back a response.
Okay, but how do we make sure that the Great Submission Portal actually sends a request to the Great
Submission API service?
How can we get it to make this request?
Well, let me show you some code.
This application was programmed.
This is something your developer would need to do.
This application was programmed to receive an environment variable, a variable from the environment
that it's running in, in order to fill this URL with the correct host.
Okay.
So this application, this portal has been packaged up into an image.
And subsequently a container was created from this image.
And the container must give the underlying app that's running in it the environment variable that it
needs in order to make requests at the correct URL.
In this case, the URL needs to be grade submission.
API needs to refer to the service name followed by the service port, which was already hard coded into
the app.
Okay, how do we ensure that the container gives its underlying application an environment variable?
Very simple.
Here we say env such that the container is going to give its underlying app one environment variable.
The underlying app has been programmed to expect the environment variable.
Grade service host okay.
And we're going to set the grade service host to have a value of grade submission API.
So once this environment variable penetrates our app, it it will resolve to sending requests to the
following URL, and it should therefore be able to connect to the cluster IP service at its service
port, which will in turn forward that traffic to the correct pod by virtue of having the correct label
selector matching that pods label.
And the target port that we define over here is going to make sure that the request goes to the container
port where our great submission API is listening for traffic.
And that's all guys I'm going to go ahead and say kubectl apply um, dash f everything inside of section
two.
So we can just say dot to say current directory.
Oh.
Let me go ahead and delete the pod.
Great submission portal.
Okay.
Then I'll say kubectl apply dash f create submission portal pod dot YAML.
So now the pod was recreated such that the container is giving its underlying app the environment variable
that it needs to connect to the service.
I think we should be good guys.
Let's go ahead and test it out.
So I accessed the first app using a Nodeport service.
Everything is working fine so far.
Now, um, as I submit GRE data to the front end, we expect the front end to make that request to this
cluster IP service, forwarding it to the Great Submission API.
Will that work?
Harry will give him a 64 in potions.
Fingers crossed.
Submit.
Beautiful.
Ignore the ugly UI.
The app doesn't run well on Safari, but it is what it is.
And that's pretty much it.
Guys.
Hope you enjoyed this lesson.
I hope it's clear why we want the service port and the target port to match, because from the application's
perspective, it doesn't know that it's making requests to a cluster IP service.
This looks like it's making requests directly to the Great Submission API at its normal port.
And that's simply because we named the service Great Submission API.
And we made sure that the service port that we specify matched the container port itself.
So that's pretty much the difference between a cluster IP service and a node port service one is used
for external access, one is used for internal pod to pod communication.
That's all.
See you in the next section.