WEBVTT

00:00.140 --> 00:00.650
Hey everybody.

00:00.650 --> 00:01.610
Welcome back.

00:01.610 --> 00:07.310
In the last video, we deployed a containerized grade submission portal application.

00:07.310 --> 00:11.780
And in this video we're going to do the same for the grade submission API.

00:11.780 --> 00:17.570
So ultimately we're going to have a grade submission API pod that runs a containerized grade submission

00:17.600 --> 00:18.800
API app.

00:18.800 --> 00:24.410
The app was programmed to serve requests on port 3000.

00:24.410 --> 00:31.550
So we're going to set up a container port 3000, which will which the pod will automatically expose

00:31.550 --> 00:36.830
for internal traffic within the Kubernetes cluster and within the pod.

00:36.860 --> 00:44.090
We're also going to specify the resource requirements for this containerized app to run properly.

00:44.090 --> 00:50.810
Uh, the minimum amount of resources that this container app that this containerized app needs in order

00:50.810 --> 00:51.650
to function.

00:51.680 --> 00:52.280
Okay.

00:52.310 --> 00:57.500
So without too much preamble, let's just dive right into it, because we did something very similar

00:57.500 --> 01:04.300
to that in the previous video within the section one folder, create a new file called Great Submission

01:04.570 --> 01:08.890
API pod dot YAML.

01:09.010 --> 01:14.860
Once again we go ahead and say pod and using the Kubernetes extension, we can auto generate the skeleton

01:14.860 --> 01:15.820
for a pod.

01:15.850 --> 01:18.040
I'm going to zoom in for you okay.

01:18.400 --> 01:23.320
Remember that when we're creating a pod, first we define the pod metadata.

01:23.560 --> 01:31.060
So starting with the name, there's usually a 1 to 1 relationship between the pod and the containerized

01:31.090 --> 01:32.500
app that it's running.

01:32.500 --> 01:36.130
So we'll call the name simply Great Submission API.

01:37.660 --> 01:38.290
All right.

01:38.290 --> 01:48.310
And remember we use labels to identify and categorize our pod into distinct groups which helps for querying

01:48.310 --> 01:49.060
later on.

01:49.060 --> 01:58.800
So it's important that first we specify the name of the cloud native app that this microservice, if

01:58.800 --> 02:00.120
you will, belongs to.

02:00.150 --> 02:07.380
Remember, we stick with the labeling convention app dot kubernetes.io followed by the application name

02:07.380 --> 02:10.620
that this great submission API belongs to.

02:10.620 --> 02:14.250
So that would be the great submission app.

02:16.050 --> 02:16.920
All right.

02:16.920 --> 02:18.900
And now we get more granular.

02:18.900 --> 02:27.240
So I'm going to say once again app.kubernetes.io using this labeling convention slash components.

02:27.450 --> 02:34.650
So we get even more granular now because now we specify uh the component within the application architecture

02:34.650 --> 02:36.750
that this API belongs to.

02:36.780 --> 02:41.040
So remember the um, the great submission portal was the front end.

02:41.040 --> 02:45.330
It provides the user interface that the client will interact with.

02:45.360 --> 02:51.810
The great Submission API will be managing whatever data the client submits in the back end.

02:51.840 --> 02:55.620
So accordingly this will be the back end.

02:56.900 --> 02:57.470
All right.

02:57.470 --> 03:05.870
And finally, the last label I'm going to use to identify the specific instance, the specific microservice.

03:05.870 --> 03:08.660
So that would be the great submission API.

03:08.690 --> 03:09.470
Okay.

03:12.770 --> 03:17.690
So this is one way that we can use to define the metadata for a pod.

03:17.720 --> 03:18.590
Okay.

03:18.620 --> 03:24.680
Now we specify the runtime requirements of our pod, the containerized app that it's going to be running.

03:24.680 --> 03:28.340
The container will be the great submission API.

03:28.370 --> 03:28.940
Okay.

03:28.970 --> 03:35.780
And the image from which this container will be created I recently uploaded to my Docker Hub.

03:35.810 --> 03:38.390
Let me just pull it up for you right now.

03:39.770 --> 03:42.200
Uh, for some reason it's not pulling up.

03:42.230 --> 03:43.310
Well, there it is.

03:45.020 --> 03:47.570
So if you go to Docker Hub, right.

03:47.600 --> 03:49.970
My name is slim 087.

03:49.970 --> 03:58.150
And you can find this repo right over here, are slim 087 Kubernetes Course Grade Submission API.

03:58.210 --> 04:02.800
If you're too lazy to go to Docker Hub, you can just write this down.

04:04.900 --> 04:11.320
And what that's going to do is pull the image that captures the grade submission API code and all the

04:11.320 --> 04:16.180
dependencies that that code needs in order to run after the image has been pulled.

04:16.180 --> 04:22.630
The container brings that image to life by by actually running the application by creating a running

04:22.630 --> 04:23.500
process.

04:23.530 --> 04:28.540
And now let's assume that we're deploying this pod within a Kubernetes cluster with many, many nodes,

04:28.540 --> 04:30.310
not just the one node.

04:30.340 --> 04:31.600
Our laptop.

04:31.600 --> 04:33.850
We'll assume we're doing things on AWS.

04:33.850 --> 04:42.220
The resources that we request for the containerized app will ultimately determine which node this pod

04:42.220 --> 04:49.240
gets scheduled on, the one that can most comfortably, in this case, provision 128 maybe, maybe bytes

04:49.240 --> 04:49.990
of memory.

04:49.990 --> 04:56.820
And we'll just say the same number for the CPU 128 Millicores of CPU.

04:56.850 --> 04:57.420
Okay.

04:57.420 --> 05:05.190
And now remember that because memory is incompressible, we want to specify a limit so that we don't

05:05.220 --> 05:09.870
exceed the amount of memory that was initially allocated to it.

05:09.900 --> 05:10.740
Okay.

05:11.340 --> 05:21.330
So um, this is the minimum guaranteed amount of memory that our container will be given upon it being

05:21.330 --> 05:22.500
scheduled on the node.

05:22.500 --> 05:29.310
And this limits the amount of memory that can be consumed by this containerized app to be the exact

05:29.310 --> 05:31.170
amount that it was initially allocated.

05:31.200 --> 05:37.950
Okay, and remember that because CPU is a compressible resource, we don't want to place a limit on

05:37.980 --> 05:38.280
that.

05:38.280 --> 05:43.560
If there is extra CPU, we want this containerized app to be able to use it if it needs to.

05:43.650 --> 05:50.250
Okay, now these numbers should be suitable for this really simple, great submission API app that I

05:50.280 --> 05:52.760
coded up myself and packaged up into an image.

05:52.760 --> 05:59.330
But ultimately the numbers that you choose will depend on load testing that you and your team end up

05:59.330 --> 06:03.560
doing on this app and monitoring its performance metrics.

06:03.590 --> 06:10.880
Now this app, this great submission API, it was when I coded it, it was programmed to serve requests

06:10.880 --> 06:12.260
on port 3000.

06:12.260 --> 06:16.130
So we want to create a matching container port 3000.

06:16.160 --> 06:16.760
All right.

06:16.760 --> 06:19.190
So container port 3000.

06:19.340 --> 06:23.840
If you're curious to see the application itself just give me one second.

06:25.880 --> 06:30.590
So this here is the app that was packaged up into an image.

06:30.590 --> 06:34.100
And it was configured to listen on port 3000.

06:34.100 --> 06:38.390
So we create a container port 3000 where it can serve these requests.

06:38.390 --> 06:45.830
And the pod will automatically, uh, expose this container port for internal traffic within the Kubernetes

06:45.830 --> 06:51.460
cluster, which we're ultimately going to port forward to a static port on our machine later on.

06:51.940 --> 06:53.140
All right.

06:53.770 --> 06:56.650
And that's pretty much it.

06:56.650 --> 06:58.480
But I don't want to beat around the bush.

06:58.480 --> 07:01.960
Let's go ahead and deploy.

07:01.990 --> 07:03.370
What's it called?

07:03.490 --> 07:04.990
The health checker as well.

07:04.990 --> 07:06.430
So similar to before.

07:06.430 --> 07:14.230
We have the pattern where the pod, which is named after the main containerized microservice that it's

07:14.230 --> 07:14.860
running.

07:14.860 --> 07:20.560
And we're also going to have another container running within this pod, which is a health checker that

07:20.560 --> 07:25.900
basically cannot exist without this microservice being there with it.

07:25.930 --> 07:26.380
All right.

07:26.380 --> 07:33.760
So we're going to deploy a great submission API health checker that continuously monitors the health

07:33.760 --> 07:36.550
endpoint of the great submission API.

07:36.550 --> 07:42.700
And we need to deploy it in the same pod because containers that are in the same pod, they share the

07:42.700 --> 07:44.530
same network namespace.

07:44.530 --> 07:50.490
So it can easily connect to the Great Submission API using localhost.

07:50.550 --> 07:52.770
That's how the application was programmed.

07:52.770 --> 07:57.660
So we're going to make sure that it's in the same pod.

07:58.710 --> 08:05.790
See it's making requests to localhost 3000 at the great submission APIs health endpoint.

08:06.060 --> 08:08.460
So we want to make sure it's in the same pod.

08:08.460 --> 08:14.400
And another reason why it's in the same pod is because this health checker cannot exist without the

08:14.400 --> 08:15.480
great submission API.

08:15.510 --> 08:21.240
So when we create the pod, when we delete the pod, we want to make sure that the health checker is

08:21.240 --> 08:24.600
deleted and created with the Great Submission API.

08:24.630 --> 08:25.500
Okay.

08:26.970 --> 08:30.270
Um, it is a sidecar app.

08:30.300 --> 08:36.690
It simply enhances the functionality of the main app that is running within this pod.

08:36.690 --> 08:38.790
So we can go ahead and just copy this.

08:38.790 --> 08:44.550
So containers allows us to specify an array of containers that can run within the pod.

08:44.580 --> 08:49.660
The next one I'm going to run is the grade submission API health checker.

08:51.130 --> 08:51.730
All right.

08:51.730 --> 08:59.500
And this code, which you don't need, I've already built a Docker image out of it and uploaded it to

08:59.530 --> 09:03.490
my local to my Docker Hub registry.

09:03.520 --> 09:07.810
Okay so great submission Kubernetes course.

09:07.840 --> 09:09.730
Great submission API health checker.

09:09.760 --> 09:14.950
Go to my Docker Hub repo by going to Docker Hub.

09:14.950 --> 09:19.450
Click writing my username and then finding this specific repo.

09:19.480 --> 09:25.990
You can copy the following great submission API health checker.

09:31.390 --> 09:35.890
So from this image we're going to create a great submission API health checker container.

09:35.890 --> 09:38.260
This is not a web application.

09:38.260 --> 09:46.020
All it's going to be doing is making requests to the Great Submission API itself, which is a web app,

09:46.020 --> 09:49.620
and we can go ahead and finalize this right now.

09:50.460 --> 09:54.270
I'll go ahead and say kubectl apply dash f.

09:54.270 --> 09:56.790
Great submission portal pod.

09:57.930 --> 09:58.650
Uh, no.

09:58.650 --> 09:59.310
Great submission.

09:59.340 --> 10:00.720
API pod.

10:01.080 --> 10:04.860
We're going to deploy a pod that's running to containers.

10:04.860 --> 10:09.810
I don't have Docker running at the moment, so let me just snap my fingers and it will in a sec.

10:10.200 --> 10:11.010
Okay cool.

10:11.010 --> 10:12.420
Let's try this again.

10:18.600 --> 10:23.340
It's going to take a while because I just started up my Docker engine.

10:25.470 --> 10:26.190
Beautiful.

10:26.220 --> 10:32.070
Let's say kubectl we're going to get all the pods in the default namespace.

10:32.100 --> 10:37.170
I'll talk about namespaces later, but let's get all the pods that we've deployed so far.

10:38.160 --> 10:40.920
Um, the great submission portal.

10:42.620 --> 10:43.370
Weird.

10:43.400 --> 10:44.630
Let me try it again.

10:46.670 --> 10:53.030
Okay, so there was an error in the great submission API pulling one of the images.

10:54.770 --> 11:03.920
Um, our slim 087 kubectl describe will describe the pod grid submission API.

11:03.950 --> 11:05.090
See what's happening.

11:05.960 --> 11:07.760
Failed to pull image.

11:07.760 --> 11:09.530
Kubernetes course grid submission API.

11:09.560 --> 11:11.390
Latest not found.

11:12.770 --> 11:14.870
Okay, let me go to my repositories.

11:15.200 --> 11:19.490
See, I'm glad I got this bug because I was able to debug in front of you.

11:19.520 --> 11:25.640
Because sometimes people get errors in Kubernetes and they're too scared to troubleshoot because they

11:25.640 --> 11:27.230
think it's something really, really serious.

11:27.230 --> 11:33.020
But if you just describe the pod, you'll find out that it's not that serious.

11:33.020 --> 11:37.340
So there was a problem pulling this image if I go to tags.

11:38.030 --> 11:39.650
Ah okay.

11:39.710 --> 11:45.250
So we need to pull our slim 087 Kubernetes core is great submission API stateless.

11:45.250 --> 11:47.860
That is the tag that we should be using.

11:47.860 --> 11:54.340
If you don't specify an image tag, it's going to default to pulling latest.

11:54.370 --> 11:57.730
A latest tag doesn't exist in this repo.

11:57.730 --> 12:00.730
So we're going to say stateless okay.

12:00.790 --> 12:05.500
Let me try this again I'm going to delete the pod great submission API.

12:09.220 --> 12:10.360
Give it some time.

12:24.670 --> 12:26.560
Normally it doesn't take this long.

12:27.940 --> 12:29.200
That is what it is.

12:36.250 --> 12:36.700
Okay.

12:36.700 --> 12:38.020
You can delete now.

12:39.420 --> 12:40.050
There you go.

12:40.080 --> 12:40.500
All right.

12:40.530 --> 12:48.660
Now we'll say kubectl apply dash f grade submission API pod.

12:51.000 --> 12:51.540
All right.

12:51.570 --> 12:53.250
I'm going to give it a second.

12:55.590 --> 12:56.700
Should be good now.

12:56.730 --> 12:59.010
Kubectl get pods.

13:02.370 --> 13:03.120
All right.

13:03.120 --> 13:05.550
So we've got two pods.

13:05.550 --> 13:12.840
Both of them have two containers each that are running the grade submission API has the great submission

13:12.870 --> 13:19.770
API containerized service running and its corresponding health checker that is constantly making requests

13:19.770 --> 13:22.410
to its port 3000.

13:22.440 --> 13:25.740
As this diagram depicts.

13:25.860 --> 13:26.430
All right.

13:26.490 --> 13:28.950
Now, what I'll do is I'll clear the output.

13:29.070 --> 13:30.990
Create another terminal.

13:31.200 --> 13:39.590
This terminal, what it's going to do is, um, stream the logs in real time for the pod grade submission

13:39.620 --> 13:40.670
API.

13:41.090 --> 13:45.740
Within the grade submission API health checker.

13:46.070 --> 13:53.840
Okay, so we're streaming the logs for this containerized sidecar application.

13:53.870 --> 14:03.620
And as you can see, the great submission API sidecar is continuously making localhost requests to our

14:03.620 --> 14:10.220
great submission API at its health endpoint, essentially monitoring our great submission API app.

14:10.220 --> 14:13.580
And every time it's getting a status of healthy.

14:13.580 --> 14:22.280
So because the sidecar is telling me that the great submission API microservice is healthy, um, I'm

14:22.280 --> 14:30.080
not going to bother port forwarding the pod port 3000 to a static port on my local machine, because

14:30.080 --> 14:33.290
I don't need to troubleshoot the great submission API.

14:33.530 --> 14:39.550
Uh, the sidecar is already monitoring it and it's telling me that everything is healthy.

14:39.580 --> 14:46.750
So the last thing we want to do is right now we have two pods, one with a great submission portal microservice,

14:46.780 --> 14:49.870
one with a great submission API microservice.

14:49.870 --> 14:59.830
And when you have two separate pods, they're automatically separated at the network level because of

14:59.830 --> 15:01.390
the network namespace.

15:01.390 --> 15:08.950
The network namespace is a logical construct in Kubernetes that essentially isolates Kubernetes resources

15:08.950 --> 15:09.910
at the network level.

15:09.910 --> 15:17.230
And some way, somehow we want the great submission portal when it receives submitted data from the

15:17.230 --> 15:23.710
client to forward that data to the Great Submission API, which is going to manage the submitted great

15:23.740 --> 15:25.300
data in the back end.

15:25.330 --> 15:25.570
Okay.

15:25.600 --> 15:28.270
It's going to manage its storage somehow.

15:28.270 --> 15:32.200
We need to get these two containers to talk to each other, and that's going to be the focus of the

15:32.200 --> 15:33.250
next section.

15:33.280 --> 15:34.420
I'll see you there.
