WEBVTT

00:00.050 --> 00:01.160
Welcome back everybody.

00:01.190 --> 00:06.950
This section is the most exciting because we're going to talk about a very crucial benefit that Kubernetes

00:06.980 --> 00:07.730
provides.

00:07.730 --> 00:10.400
And that is storage orchestration.

00:10.430 --> 00:15.770
If you are deploying your apps in a traditional environment where you've got all of these machines running

00:15.770 --> 00:24.020
all sorts of apps, while your operations team would be the one responsible for manually provisioning

00:24.020 --> 00:31.970
storage inside of each machine, ensuring that that piece of storage is just the right size, and then

00:31.970 --> 00:36.920
configuring each application to bind to that exact piece of storage.

00:36.920 --> 00:42.590
And if you can imagine running that same app on another machine, then we have to repeat that same process.

00:42.590 --> 00:48.530
So scaling up and down is just a really tedious process when you've got to manually provision every

00:48.530 --> 00:53.150
single piece of storage, depending on the machine that your app is running in.

00:53.180 --> 01:01.100
Well, if you take all of these machines, all right, and you have them collaborate under the supervision

01:01.100 --> 01:03.020
of something like Kubernetes.

01:03.050 --> 01:10.580
Then you can fully rely on the Kubernetes control plane to manage the storage for you.

01:10.610 --> 01:15.320
And that's the benefit that we get by deploying our apps in a Kubernetes cluster.

01:15.320 --> 01:18.500
We get automatic storage orchestration.

01:18.710 --> 01:19.790
How does that look?

01:19.820 --> 01:21.830
Give me just a second to get a drink of water.

01:26.090 --> 01:27.620
It looks something like this.

01:27.650 --> 01:29.930
So here we've got two pods.

01:29.930 --> 01:34.910
Each one is running a containerized MongoDB database.

01:35.000 --> 01:43.040
Whenever we save data to one of these databases, it's going to write that data to a local directory.

01:43.280 --> 01:46.430
And you'll remember that pods are ephemeral.

01:46.430 --> 01:49.760
They're very often destroyed and rescheduled.

01:49.760 --> 01:59.540
So if we don't bind this pod to a durable peace of storage, then if that pod ever gets destroyed.

01:59.540 --> 02:05.570
For whatever reason, the data inside of its underlying database would get destroyed as well.

02:05.600 --> 02:13.820
So what can we do in Kubernetes to make sure that stateful applications can actually, um, back up

02:13.820 --> 02:16.220
their data somewhere durable?

02:17.180 --> 02:24.800
Well, what we do is we bind every single container to a persistent volume claim.

02:24.830 --> 02:32.810
A persistent volume claim, which often is referred to as a PVC, is a specialized Kubernetes object

02:32.810 --> 02:40.670
that allows you to declare how much storage your database needs and the storage characteristics.

02:40.700 --> 02:47.660
All you're doing is you're making a claim for storage, and that claim is bound to your container.

02:47.840 --> 02:54.620
When you make a claim for storage behind the scenes, the Kubernetes control plane is going to look

02:54.650 --> 02:56.060
at all of your worker nodes.

02:56.080 --> 03:00.910
Okay, I know we're just developing locally and we've got the one worker node, our laptop.

03:00.910 --> 03:06.880
In this case, let's imagine we've got this Kubernetes cluster on AWS with all of these worker nodes.

03:06.880 --> 03:11.410
When the Kubernetes control plane sees your claim, it's going to look through all of these nodes.

03:11.410 --> 03:18.550
And within one of them, try to find a piece of storage, a piece of physical storage that matches the

03:18.550 --> 03:22.810
storage requirements defined in your persistent volume claim.

03:22.840 --> 03:26.890
When it does, it's going to bind that physical piece of storage.

03:26.890 --> 03:34.210
It's going to bind that persistent volume to your claim, thereby allowing any data that gets saved

03:34.210 --> 03:41.590
to your MongoDB database to be redirected to the persistent volume that lives inside of some node.

03:41.590 --> 03:44.560
We refer to the pod as being stateful.

03:44.560 --> 03:45.130
All right?

03:45.130 --> 03:53.500
It stores data inside of a physical piece of storage within a machine, and we use stateful sets to

03:53.530 --> 04:01.430
manage stateful pods, in contrast to when we used deployments to manage stateless pods.

04:01.430 --> 04:08.150
Stateless pods you'll remember whenever we scheduled them for deployment, they were given some pod

04:08.180 --> 04:14.240
name, the one we specified in our pod template, followed by a randomly generated name.

04:14.270 --> 04:21.500
It doesn't really matter what that name was, mainly because all of these pod replicas, they are completely

04:21.500 --> 04:22.850
interchangeable.

04:22.850 --> 04:27.230
If one pod replica goes down, the other one can easily take its place.

04:27.260 --> 04:34.340
One great submission portal Pod replica is going to do something very identical to another great submission

04:34.340 --> 04:35.600
Portal Pod Replica.

04:35.600 --> 04:40.880
It follows that scaling of pods within a deployment is unordered.

04:40.880 --> 04:47.660
If we had four pods and we decide to scale down, which pod gets removed doesn't really matter.

04:47.690 --> 04:53.530
Now, in a stateful set, every single pod has a unique identity Entity.

04:53.530 --> 05:01.810
And you'll remember that because each pod replica is bound to a PVC when it gets destroyed, we want

05:01.810 --> 05:10.420
it to be rescheduled using the same name as before, so it can reattach to its original PVC and therefore

05:10.420 --> 05:16.990
gain access to all of its original data within the persistent volume that is taking up actual physical

05:16.990 --> 05:18.790
space in the worker node.

05:18.820 --> 05:27.850
Okay, so we need our pods to have unique identities, and it follows that pods within a stateful set.

05:27.880 --> 05:31.300
Each one has its own dedicated storage.

05:32.980 --> 05:34.570
Let's have a closer look.

05:34.570 --> 05:43.420
So this is one MongoDB pod named MongoDB, one that runs an instance of a MongoDB database.

05:43.420 --> 05:50.320
Whenever a data is saved to that MongoDB database, it's going to be saved inside of the local directory

05:50.320 --> 05:57.180
slash data slash db within the containers is file system depending on which database software you're

05:57.180 --> 06:01.710
using, whether that's PostgreSQL or MySQL.

06:01.740 --> 06:04.980
The directory where data is saved will be different.

06:04.980 --> 06:13.410
So if data is being saved in a MySQL database from memory, that gets saved to the directory var lib

06:13.410 --> 06:14.910
slash MySQL.

06:14.910 --> 06:16.890
In this case we're using MongoDB.

06:16.890 --> 06:20.400
So the data gets saved to the directory slash data slash db.

06:20.520 --> 06:23.880
You just got to read the documentation to know this okay.

06:24.570 --> 06:31.380
Now what we want to do is bind this containerized database to a persistent volume claim.

06:31.410 --> 06:39.120
The persistent volume claim is a specialized Kubernetes object that declares how much storage the database

06:39.120 --> 06:43.500
needs, as well as the characteristics of that piece of storage.

06:43.530 --> 06:51.190
Then the Kubernetes control plane is going to try to find a persistent volume that matches the storage

06:51.190 --> 06:53.890
requirements we defined in our PVC.

06:54.280 --> 07:01.090
Once it finds that actual physical piece of storage, what it's going to do is mount that piece of storage

07:01.120 --> 07:07.480
on the local directory where we are saving all of our data, which means that if the pod were to ever

07:07.510 --> 07:13.660
be destroyed, for whatever reason, the data will still live inside of the persistent volume.

07:13.660 --> 07:20.470
And when the pod gets rescheduled using the same name as before, it's going to reattach to the same

07:20.470 --> 07:25.090
PVC and therefore gain access to all of its original data.

07:25.660 --> 07:26.830
That's the gist of it.

07:26.860 --> 07:27.730
Enough theory.

07:27.730 --> 07:28.990
Let's get to work.

07:29.860 --> 07:35.320
You'll notice over here I've already deleted all the deployments inside of my grade submission namespace.

07:35.320 --> 07:38.110
Please feel free to do the same as well.

07:38.620 --> 07:42.760
Okay, once you do, let's go ahead and copy over.

07:42.760 --> 07:44.140
Section six.

07:44.800 --> 07:47.320
Call it section seven.

07:50.670 --> 07:53.370
And inside of section seven I'm going to create a new file.

07:53.370 --> 07:59.970
Call it MongoDB statefulset dot YAML.

08:00.960 --> 08:04.260
All right I'm going to write Statefulset.

08:04.380 --> 08:11.370
And it auto generates a skeleton that we can use to manage all of our stateful pods.

08:11.400 --> 08:11.880
Okay.

08:11.910 --> 08:17.040
Here we define the template upon which each stateful pod will be created.

08:17.040 --> 08:20.460
And here we specify the behavior of our stateful set.

08:20.460 --> 08:23.850
But let's not jump the gun and we'll start with the metadata.

08:23.880 --> 08:30.390
I'm just going to call the stateful set MongoDB with um we're going to deploy it in the namespace.

08:30.390 --> 08:31.620
Great submission.

08:31.920 --> 08:32.520
All right.

08:32.520 --> 08:35.610
Here we specify the behavior of our stateful set.

08:35.640 --> 08:43.740
We're going to have it so that it manages any stateful pod that has the label.

08:46.620 --> 08:47.790
You know what.

08:47.990 --> 08:49.790
Let me start with the pod template.

08:49.790 --> 08:56.210
I'm going to give every single pod, every single stateful pod the following labels.

08:56.240 --> 08:58.850
The cloud native app is still a great submission.

08:58.880 --> 08:59.390
Okay.

08:59.420 --> 09:05.570
And now while the great submission API is the back end and the Great submission portal is the front

09:05.600 --> 09:11.840
end within the great submission experience, our MongoDB database is a database.

09:11.870 --> 09:13.970
Okay, that is the role that it will serve.

09:13.970 --> 09:20.930
It will store all of the great submission data, and every MongoDB pod is going to be given the instance

09:20.930 --> 09:22.340
label MongoDB.

09:22.640 --> 09:29.180
It follows that here where we specify the behavior of the great submission of the MongoDB stateful set.

09:29.210 --> 09:35.150
We can tell it to manage any pod that has the following label.

09:35.150 --> 09:42.080
The service name is the prefix that will be used to name every single pod in the stateful set.

09:42.110 --> 09:45.440
We're just going to have that be MongoDB.

09:45.800 --> 09:53.010
It follows that any pod replica is going to be named using the MongoDB prefix, followed by some number

09:53.010 --> 09:55.680
like 3 or 4.

09:55.710 --> 09:58.320
The numbering goes in ascending order.

09:58.350 --> 10:03.450
Okay, I'm sorry guys, my computer just shut down randomly.

10:03.450 --> 10:07.710
I just had to reopen everything now to pick up where we left off.

10:07.740 --> 10:14.730
Anyways, we've defined a stateful set that's going to be managing two stateful pods.

10:14.730 --> 10:20.790
One of them is going to be called MongoDB zero and the other is going to be called MongoDB one.

10:20.820 --> 10:23.700
Each one having a unique identity.

10:23.730 --> 10:27.300
Now we can go to the pod template.

10:27.330 --> 10:34.650
The pod template provides a skeleton upon which each pod is going to be generated.

10:34.650 --> 10:38.730
So each stateful pod is going to have the following labels.

10:38.760 --> 10:48.950
The instance label is what binds each pod to its corresponding stateful set, and within each pod there's

10:48.950 --> 10:51.770
going to be one MongoDB container.

10:51.770 --> 10:56.390
So here we specify the runtime requirements of each pod.

10:56.420 --> 11:00.080
Each pod is going to be running a container called MongoDB.

11:00.560 --> 11:07.310
And the MongoDB container is going to be created from.

11:09.590 --> 11:12.050
The Mongo image.

11:12.080 --> 11:16.280
Version 4.4.

11:17.270 --> 11:21.260
So this image captures the MongoDB software.

11:21.290 --> 11:23.030
Version 4.4.

11:23.060 --> 11:31.040
What we want to do is pull this image, because from it, we're going to create a running instance of

11:31.040 --> 11:33.680
MongoDB inside of a container.

11:33.710 --> 11:38.750
Now the MongoDB software, by default it serves traffic.

11:38.780 --> 11:41.090
It responds to requests.

11:41.120 --> 11:50.580
Let me just verify on port 27017 follows that we'll need a container port 27017, where our containerized

11:50.580 --> 11:53.670
MongoDB app can respond to traffic.

11:53.700 --> 11:57.630
Okay, we don't need to give our container port a name.

11:57.750 --> 12:00.450
We'll come back to volume mounts later.

12:00.450 --> 12:04.020
And now let's talk about the volume claim templates.

12:04.020 --> 12:13.470
So just as the pod template provides the skeleton upon which every pod is going to be created, the

12:13.470 --> 12:22.800
volume claim templates provides a skeleton upon which each persistent volume claim will be generated.

12:22.800 --> 12:28.710
So we're going to have one persistent volume claim per stateful pod.

12:29.040 --> 12:37.440
Each persistent volume claim is going to start with the name MongoDB Persistent Storage.

12:38.490 --> 12:43.100
So based on this template we're going to end up having two PVCs.

12:43.100 --> 12:51.470
One of them is going to be called MongoDB Persistent Storage, and this PVC is going to bind to the

12:51.470 --> 12:52.520
stateful pod.

12:52.550 --> 12:54.680
MongoDB zero.

12:55.610 --> 13:03.740
And another PVC will be created that binds to the pod MongoDB one.

13:03.830 --> 13:04.790
Okay.

13:04.820 --> 13:13.940
So this template we can use to generate many PVCs, each one binding to a unique pod.

13:13.970 --> 13:15.380
All right.

13:15.770 --> 13:22.640
And each PVC you'll remember it declares what type of storage we want Kubernetes to find.

13:22.640 --> 13:23.540
For us.

13:23.660 --> 13:30.530
We want to declare one gigabyte of storage with an access mode of read, write once, read.

13:30.530 --> 13:35.810
Write once means that only one node can read and write to that piece of storage at a time.

13:35.840 --> 13:40.220
Okay, so each where is my keynote.

13:40.220 --> 13:50.910
So each MongoDB pod is now bound to a PVC, and then Kubernetes is going to do the hard work of finding

13:50.910 --> 13:56.760
a persistent volume that matches the requirements we defined in each PVC.

13:57.120 --> 14:05.460
So here what I can do is say, hey, Kubernetes, the persistent volumes that you find that correspond

14:05.460 --> 14:12.090
to each PVC, I want you to mount them at the corresponding pods.

14:12.090 --> 14:16.110
Local directory slash data slash DB.

14:17.610 --> 14:18.720
All right.

14:18.720 --> 14:21.210
And that's pretty much it.

14:21.810 --> 14:25.320
And so ultimately we end up with the following scenario.

14:25.350 --> 14:33.930
We've got two pods one MongoDB zero one MongoDB one okay.

14:33.960 --> 14:42.140
Each one is bound to its own PVC, which somehow provisions a persistent volume which gets mounted on

14:42.170 --> 14:48.830
that container as its local directory slash data slash debe, such that any data that gets saved here

14:48.830 --> 14:56.840
will automatically be redirected to a durable peace of storage that exists on our machine.

14:57.470 --> 14:58.490
All right.

14:59.990 --> 15:02.990
Let's go ahead and apply the stateful set.

15:02.990 --> 15:10.400
So what I did before is I deleted all the deployments kubectl delete deployments dash all and great

15:10.400 --> 15:11.330
submission.

15:11.420 --> 15:13.610
And I just want to start off on a clean slate.

15:13.610 --> 15:19.340
All right dash dash all no resources found.

15:19.340 --> 15:21.470
You should have no resources found as well.

15:21.470 --> 15:26.120
Let's start clean kubectl apply dash f.

15:26.630 --> 15:33.170
Um I'm just going to start off by applying the stateful set dot YAML.

15:33.980 --> 15:39.190
I'm going to say kubectl get stateful set inside of the namespace.

15:39.190 --> 15:40.480
Create submission.

15:44.020 --> 15:45.340
A stateful set.

15:45.370 --> 15:49.120
Sorry guys, it's so late right now it's 2 a.m..

15:49.270 --> 15:56.980
Anyways, we've got one stateful set that's managing two stateful pods that were created based on the

15:56.980 --> 15:58.330
pod template.

15:58.360 --> 16:04.120
Now each pod is bound to its own persistent volume claim.

16:04.540 --> 16:05.980
Um, I'm going to prove it to you.

16:05.980 --> 16:06.790
Let's do it.

16:06.820 --> 16:09.550
Kubectl get pvc dash n.

16:09.550 --> 16:17.200
Great submission to persistent volume claims were generated on the fly.

16:17.230 --> 16:20.620
Based on our persistent volume claim template.

16:20.620 --> 16:28.360
We have one persistent volume claim that's bound to MongoDB zero and one persistent volume claim that's

16:28.360 --> 16:32.020
bound to the pod MongoDB one.

16:32.170 --> 16:37.700
Each persistent volume claim is going to make a claim for a persistent volume.

16:46.400 --> 16:50.840
So I'm going to go ahead and create a MongoDB service dot YAML.

16:55.340 --> 16:57.080
Service.

16:57.650 --> 16:59.990
I name the service MongoDB.

17:07.100 --> 17:17.210
And this service is going to select any pod that has the following label.

17:17.240 --> 17:21.680
It's going to forward traffic to any pod that has the following label.

17:21.830 --> 17:31.340
The service port is 27017, such that the Great Selection API can make requests to the host MongoDB

17:31.580 --> 17:42.070
port 27017 and after traffic reaches the pod, the target port is used to direct that request to Mongodb's

17:42.070 --> 17:43.060
container port.

17:43.090 --> 17:47.200
That's going to be 27017 as well.

17:47.230 --> 17:47.950
All right.

17:47.980 --> 17:53.410
Let's go ahead and say kubectl apply dash f MongoDB service dot YAML.

17:55.150 --> 17:57.160
Got our service.

17:57.160 --> 17:59.590
We've got a MongoDB pod.

17:59.620 --> 18:06.040
Now we need to instrument the great submission API to make requests to this service.

18:06.190 --> 18:08.050
How do we do that?

18:08.680 --> 18:15.640
Um, well, first and foremost, this version of the Great Submission API was not programmed to make

18:15.640 --> 18:20.830
requests to a stateful MongoDB database.

18:20.860 --> 18:28.420
So what I've got this is the one we've been using all along, but it's not been programmed to interact

18:28.420 --> 18:30.430
with a database like MongoDB.

18:31.420 --> 18:35.660
Uh, stateless V2 is a great submission.

18:35.690 --> 18:41.660
API contains a great submission API app that was programmed to interact with MongoDB.

18:41.780 --> 18:44.780
So we're going to pull this image.

18:47.810 --> 18:47.990
Up.

18:48.020 --> 18:50.660
Ultimately it just adds a hyphen v2.

18:50.690 --> 18:55.940
From this image we're going to create a great submission API, a containerized great submission API

18:55.970 --> 18:58.910
that was designed to interact with a database.

18:58.940 --> 19:01.400
Let me actually show you the code.

19:01.610 --> 19:08.210
So here our application expects two environment variables one MongoDB host one MongoDB port.

19:08.240 --> 19:15.050
These environment variables are necessary in order for our great submission API to establish a connection

19:15.050 --> 19:19.550
with the MongoDB database through the cluster IP service.

19:19.580 --> 19:26.720
Okay, so our container needs to provide its underlying application with these environment variables.

19:26.750 --> 19:27.200
Okay.

19:27.230 --> 19:32.650
And you'll notice very interestingly that I gave the great submission API.

19:32.680 --> 19:43.330
A very simple readiness endpoint that sends back to its readiness probe a status of 200 if it's connected

19:43.330 --> 19:50.380
to the MongoDB database, and a status of 503 if it's not ready to serve requests just yet.

19:50.740 --> 19:58.210
Um, let's go ahead and give our stateless V2 app the environment variables that it needs so we can

19:58.210 --> 19:59.380
do that somewhere here.

19:59.380 --> 20:01.600
Environment variables.

20:01.600 --> 20:04.540
The first environment variable is named.

20:04.990 --> 20:09.430
The first environment variable that it expects is called MongoDB host.

20:10.360 --> 20:17.680
And we need to give it a value that equals the service name.

20:20.980 --> 20:26.620
The second environment variable it expects is the MongoDB port.

20:27.580 --> 20:33.630
And it needs to be given a value that equals the service port, because ultimately the service will

20:33.630 --> 20:42.420
act as a proxy between the Great Submission API and the MongoDB database.

20:43.740 --> 20:44.400
All right.

20:44.400 --> 20:46.140
And that's pretty much it.

20:47.190 --> 20:52.590
Pretty sure we can just deploy everything kubectl apply dash f.

20:55.350 --> 20:59.430
Kubectl get pods dash and great submission.

21:01.560 --> 21:02.790
Let's try this again.

21:05.100 --> 21:05.700
All right.

21:05.730 --> 21:12.630
Notice that the great submission API its containers were created but it still shows zero out of one.

21:12.660 --> 21:13.710
Why is that?

21:13.710 --> 21:19.380
Because the readiness endpoint is sending back 503.

21:19.380 --> 21:20.820
Because it's not ready.

21:20.850 --> 21:25.140
It hasn't connected to MongoDB just yet.

21:25.170 --> 21:25.710
All right.

21:25.710 --> 21:29.830
But once it does connect, it should send back a status of 200.

21:29.890 --> 21:32.560
So if I were to check back again.

21:34.780 --> 21:39.070
Both great submission API pod replicas are ready.

21:39.130 --> 21:40.540
Beautiful.

21:40.600 --> 21:47.290
I'm going to say kubectl logs dash f dash n.

21:47.290 --> 21:48.610
Great submission.

21:50.740 --> 21:52.540
Connected to MongoDB.

21:52.720 --> 21:53.230
All right.

21:53.260 --> 21:53.860
Nice.

21:53.890 --> 22:00.070
Now, one thing I want to note is that notice how the stateful pods have unique identities, unique

22:00.070 --> 22:06.340
names where as the stateless pods have randomly generated names at the end.

22:06.370 --> 22:15.670
That's because the stateless pods are completely interchangeable and the stateful pods are not.

22:15.670 --> 22:21.910
Each one is bound to its own PVC and has access to its own piece of storage.

22:21.940 --> 22:24.700
These ones are stateless.

22:24.700 --> 22:28.650
Whether one gets deleted or replaced by the other doesn't really matter.

22:28.710 --> 22:29.370
All right.

22:29.370 --> 22:37.230
But now, ultimately, to make sure everything works, we're going to start by making a request to the

22:37.230 --> 22:38.730
great submission portal.

22:38.760 --> 22:39.180
All right.

22:39.180 --> 22:43.980
So now from our great submission portal, we're going to be making requests to the Great Submission

22:43.980 --> 22:46.560
API upon submitting great data.

22:46.560 --> 22:52.710
And that is going to persist our data to one of the MongoDB databases.

22:52.740 --> 22:53.520
Okay.

22:53.970 --> 22:58.230
One of these databases will have one piece of storage.

22:58.230 --> 23:00.870
The other database will have another piece of storage.

23:00.870 --> 23:08.040
The cluster IP service is going to round robin our requests between MongoDB zero and MongoDB one.

23:08.070 --> 23:10.950
Each one has their own dedicated storage.

23:10.980 --> 23:12.810
Why will that be a problem?

23:12.810 --> 23:14.550
Let me show you in a bit.

23:14.850 --> 23:24.180
Harry Potter will give him a score of 54 in potions if I submit it, it may or may not show up.

23:24.360 --> 23:25.890
Let me try it again.

23:27.400 --> 23:29.140
um, I don't know.

23:29.140 --> 23:32.350
Ron, 32 potions.

23:32.350 --> 23:34.000
I'm going to submit it.

23:34.030 --> 23:35.320
Try this again.

23:35.320 --> 23:39.040
You might have experienced it already, but just wait for me to experience it.

23:39.070 --> 23:41.650
Neville, 87 and potions.

23:43.000 --> 23:43.810
All right.

23:43.840 --> 23:47.320
Notice how the data is different now.

23:47.320 --> 23:50.890
We've got two databases, all right?

23:50.920 --> 23:52.600
Not just MongoDB zero.

23:52.630 --> 23:55.630
We've got MongoDB zero and MongoDB one.

23:55.840 --> 24:03.910
Whenever the Great Submission API makes a request through the cluster IP service, the cluster IP service

24:03.940 --> 24:10.330
is going to round robin the requests between the two databases, which means they're going to hold different

24:10.330 --> 24:10.990
data.

24:10.990 --> 24:19.300
So whenever that page gets refreshed it might make a request to MongoDB zero or MongoDB one, which

24:19.330 --> 24:21.880
intrinsically have different data sets.

24:21.910 --> 24:26.310
Okay, here I made a request to one of the databases that had Neville.

24:26.340 --> 24:27.870
Now it made a request to the other.

24:27.900 --> 24:30.330
Database that has Harry Potter and run.

24:30.720 --> 24:34.830
And so I only deployed to.

24:34.860 --> 24:40.080
Databases just to show you how the volume claim templates work.

24:40.110 --> 24:43.440
But it only makes sense to have one.

24:43.530 --> 24:53.970
MongoDB stateful pod that's bound to a single persistent volume claim, with one piece of storage mounted

24:53.970 --> 24:57.000
at its container slash data slash DB.

24:57.210 --> 25:01.350
We only want a single MongoDB zero.

25:01.380 --> 25:03.300
That is all.

25:03.810 --> 25:14.970
Okay, so why don't we say kubectl apply dash f MongoDB statefulset reconfigure what we've got.

25:17.070 --> 25:22.140
Kubectl get pods dash n great submission.

25:24.590 --> 25:28.730
So by scaling down, it took off MongoDB one.

25:28.730 --> 25:31.430
Now we're just left with MongoDB zero.

25:31.460 --> 25:34.940
Both of these, they're both ready.

25:34.940 --> 25:41.750
So the readiness endpoint send back a positive response meaning they're both connected to the database.

25:42.500 --> 25:43.520
Beautiful.

25:44.330 --> 25:47.300
Now we should see more consistent results.

25:47.900 --> 25:48.560
All right.

25:48.560 --> 25:52.790
So it left the database that had Harry and Ron.

25:52.910 --> 25:59.450
And it follows that um whatever I submit going forward.

26:02.300 --> 26:04.730
Should remain consistent.

26:04.760 --> 26:05.600
Okay.

26:05.630 --> 26:08.270
I accidentally pressed submit twice.

26:08.420 --> 26:09.590
Sorry about that.

26:09.620 --> 26:10.850
If that confused you.

26:10.880 --> 26:12.050
Let me do it again.

26:12.050 --> 26:17.390
We'll say Snape 98 potions.

26:17.750 --> 26:19.970
I won't press the submit button twice now.

26:20.000 --> 26:21.380
Okay, beautiful.

26:21.380 --> 26:21.400
Uniform.

26:21.400 --> 26:25.720
So now the great submission API, no matter what, is making a request to.

26:25.750 --> 26:30.790
One stateful pod that is bound to one piece of storage.

26:30.820 --> 26:32.140
Okay, everything should work.

26:32.170 --> 26:32.890
Beautifully.

26:32.890 --> 26:39.730
Now, I want to demonstrate to you that all of this data exists in a durable piece of storage within

26:39.730 --> 26:40.390
my node.

26:40.420 --> 26:51.010
I can do that by saying kubectl delete all the pods inside of the great submission namespace.

26:51.010 --> 26:56.080
They're going to get rescheduled because they're being managed by the stateless pods are being managed

26:56.080 --> 26:57.040
by a deployment.

26:57.070 --> 27:01.270
The stateful pod is being managed by a stateful set.

27:05.230 --> 27:14.650
And once MongoDB zero is recreated using the exact same name, it's going to get reattached to that

27:14.650 --> 27:21.470
PVC and gain access to the original data inside of the PV.

27:21.770 --> 27:24.140
So even if this pod gets deleted.

27:24.170 --> 27:27.380
Upon it being rescheduled, we're going to see our data.

27:27.410 --> 27:34.280
Again, the Great Submission API will be able to access that original data from MongoDB zero.

27:34.310 --> 27:36.440
Okay, finally it's done.

27:36.470 --> 27:42.290
I can stop talking and just demonstrate dash and great submission.

27:44.840 --> 27:45.590
All right.

27:45.770 --> 27:49.940
Notice the great submission API is not ready to receive traffic yet.

27:49.970 --> 27:53.990
It hasn't connected to the MongoDB app.

27:55.460 --> 27:55.820
Aunt.

27:55.850 --> 27:56.870
Readiness endpoints.

27:56.900 --> 27:58.160
Just beautiful.

27:58.160 --> 28:03.920
No matter what you do when you containerize your apps, give them liveness and readiness endpoints.

28:03.920 --> 28:06.050
Trust me, you will not regret it.

28:07.190 --> 28:08.390
All right.

28:10.790 --> 28:16.280
If I refresh, all the data is still there.

28:16.310 --> 28:18.560
That's all for stateful pods.

28:18.600 --> 28:19.650
PVCs.

28:19.680 --> 28:20.730
PVS.

28:20.760 --> 28:22.410
I hope you enjoyed this lesson.

28:22.410 --> 28:29.370
We did bring everything together by also incorporating, um, internal pod to pod communication with

28:29.370 --> 28:30.870
cluster IP services.

28:30.870 --> 28:34.470
That's something we covered in the service discovery section as well.

28:34.470 --> 28:41.460
I hope you can just appreciate just how amazing Kubernetes is in provisioning storage.

28:41.790 --> 28:48.390
All we got to do is define our storage requirements without having any idea what the underlying infrastructure

28:48.390 --> 28:48.930
is.

28:48.960 --> 28:56.190
Kubernetes will do all the hard work of provisioning that storage and in essence, binding it to our

28:56.190 --> 28:58.800
application no matter what node it's running on.

28:58.800 --> 29:04.860
I know we're just prototyping in our node is simply our laptop, but this becomes all the more handy

29:04.860 --> 29:11.490
when we're actually running things in an enterprise, in a cluster that's probably running on an actual

29:11.490 --> 29:12.780
cloud provider.

29:12.810 --> 29:15.330
Okay, I hope you enjoyed this lesson.

29:15.330 --> 29:17.010
I'll see you in the next one.
