WEBVTT

00:00.020 --> 00:00.890
Welcome back, everybody.

00:00.890 --> 00:06.860
In this section, we reach the final stage of our MongoDB deployment, metamorphosis, because we're

00:06.860 --> 00:10.220
going to deploy it through an operator okay.

00:10.220 --> 00:17.960
So the first phase if we recap, was we manually created all of the configuration files and created

00:17.960 --> 00:20.330
a very minimalistic deployment.

00:20.450 --> 00:25.340
This deployment was actually very effective and suited our purposes just fine.

00:25.880 --> 00:32.450
But then upon expanding our Kubernetes toolbox, we learned about the helm package manager, and we

00:32.450 --> 00:37.730
learned that there are many repositories online with many, many helm charts that allow us to deploy

00:37.730 --> 00:41.690
whatever softwares we want with minimal configuration.

00:41.690 --> 00:47.390
So these helm charts already contain all of the configuration files that we really don't need to touch.

00:47.390 --> 00:54.710
All we got to do is update a values.yaml file in order to steer the deployment towards whatever it is

00:54.710 --> 00:56.210
that we want to accomplish.

00:56.240 --> 01:04.590
Now, the final phase of our metamorphosis will be to use helm to simply deploy an operator.

01:04.590 --> 01:13.740
An operator extends the Kubernetes API and consists of many custom controllers that watch for custom

01:13.740 --> 01:21.120
resource definitions and based on whatever you define inside of these custom resources, whatever desired

01:21.120 --> 01:27.030
state you define in there, your operator, through its custom controllers, will create your desired

01:27.030 --> 01:34.170
deployment and will always be monitoring your deployment to always ensure that it's at that desired

01:34.170 --> 01:34.710
state.

01:34.800 --> 01:43.530
So the gist of an operator is that it consists of custom controllers that watch out for custom resources,

01:43.530 --> 01:51.060
and based on whatever custom resources that we define, it's going to create actual Kubernetes resources

01:51.060 --> 01:57.300
to configure our deployment and consistently monitor them to ensure that they're always at that desired

01:57.300 --> 01:58.020
state.

01:58.050 --> 02:01.300
Now controllers aren't a foreign concept.

02:01.300 --> 02:05.620
We've actually been dealing with them all throughout this course, but we've only been dealing with

02:05.620 --> 02:09.130
the core controllers that are native to Kubernetes.

02:09.130 --> 02:13.900
So, um, a very prominent example is the deployment controller.

02:13.900 --> 02:19.990
So whenever you set up a deployment object with a desired state of, let's say three pod replicas and

02:19.990 --> 02:26.860
whatever pod template you want all of your pods to have, your deployment controller is what's watching

02:26.860 --> 02:34.450
for your deployment object, creates a replica set based on whatever your desired state is, and continuously

02:34.450 --> 02:35.650
monitors your replica.

02:35.650 --> 02:38.860
Set objects to ensure that they're always at that state.

02:38.860 --> 02:41.260
And that's how we get things like rolling updates.

02:41.260 --> 02:48.910
So if I update my deployment to use another version, the deployment controller is watching this resource

02:48.910 --> 02:52.240
and continuously updating the target resource.

02:52.270 --> 02:53.110
Okay.

02:54.160 --> 03:01.140
Uh, the replica set controllers, whenever the replica set objects change, it will create new paths

03:01.140 --> 03:03.090
and monitor the pod state.

03:03.090 --> 03:05.280
So I hope you can see the pattern.

03:05.280 --> 03:12.510
The HPA controller consistently watches out for HPA objects and continuously monitor Pod metrics.

03:12.510 --> 03:15.870
To know when to create and terminate new pods.

03:15.930 --> 03:23.130
Your PV controller consistently watches out for your PVC object, and based on whatever desired state

03:23.130 --> 03:29.550
you define, it's going to bind a persistent volume based on the requirements here, and continuously

03:29.550 --> 03:34.620
monitor the PV status to ensure that it's in adherence to whatever we define here.

03:36.390 --> 03:39.780
So a Kubernetes controller follows this basic pattern.

03:39.780 --> 03:46.380
It watches out for a desired state, creates whatever resources it needs to create, and continuously

03:46.380 --> 03:53.670
monitors them to take it from whatever its current state is to the desired state that is defined in

03:53.670 --> 03:54.480
the resource.

03:54.480 --> 04:00.280
So if I create, let's say, another deployment object with a new desired state.

04:00.280 --> 04:05.740
The deployment controller, which is consistently watching out for our deployment objects, will look

04:05.770 --> 04:12.010
at the current state of whatever the replica set objects are and update them to a desired state.

04:12.040 --> 04:16.930
So that's why we have the controller manager running in the master node, which coordinates all of these

04:16.930 --> 04:17.980
core controllers.

04:18.010 --> 04:18.580
Okay.

04:18.580 --> 04:26.350
And these benefits that we get from Kubernetes, they all come by virtue of having all of these core

04:26.350 --> 04:34.540
controllers running in a loop, consistently watching out for whatever resources we deploy, and updating

04:34.570 --> 04:38.710
target resources accordingly, ensuring that they get to a desired state.

04:38.740 --> 04:43.750
But one benefit that we've yet to leverage, which we will in this section, is extensibility.

04:43.750 --> 04:49.270
Because operators, what they do is they extend the Kubernetes API.

04:49.270 --> 04:55.150
It provides a set of custom controllers that watch out for custom resources.

04:55.150 --> 05:03.440
So let's note the distinction before we had your standard core controllers like like deployment controllers

05:03.440 --> 05:07.220
which watched out for standard resources like deployments.

05:07.220 --> 05:12.740
But operators, they extend the API in a way where now we have these custom controllers looking out

05:12.740 --> 05:14.930
for custom resources.

05:14.930 --> 05:20.390
And based on these custom resources that we can now define, it will create whatever deployment that

05:20.390 --> 05:21.560
we want.

05:21.770 --> 05:22.760
Okay.

05:22.880 --> 05:26.210
So this simply reiterates the definition.

05:26.210 --> 05:32.300
Uh, it the gist is it's a set of custom controllers that watch for custom resources and will create

05:32.300 --> 05:38.450
Kubernetes resources consistently monitor these resources to always ensure that they are at whatever

05:38.450 --> 05:41.300
desired state that we define in our CRD.

05:41.870 --> 05:46.790
So this is a schematic that depicts, um, how an operator works.

05:46.820 --> 05:51.890
Note how similar it is to the schematic for a Kubernetes controller.

05:51.920 --> 05:52.610
Okay.

05:52.610 --> 05:59.670
So you've got the operator which provides custom controllers, will watch for custom resources that

05:59.670 --> 06:02.760
we create using custom resource definitions.

06:02.760 --> 06:09.180
The operator will look at the desired state that we defined in our custom resource, and accordingly,

06:09.180 --> 06:15.060
it will create Kubernetes resources that can adhere to our desired application state.

06:15.060 --> 06:22.320
So if we look at the MongoDB operator specifically, uh, it extends the Kubernetes API in a way where

06:22.320 --> 06:29.700
we can define a custom resource called MongoDB community and the MongoDB community custom resource.

06:29.700 --> 06:34.800
We can define things like how we want authentication to the MongoDB database to occur.

06:34.800 --> 06:38.550
We can specify how many MongoDB replicas that we want.

06:38.580 --> 06:45.210
The operator will watch for our desired state and create all the Kubernetes resources that it needs

06:45.210 --> 06:49.800
to create in order to ensure that we're at that desired application state.

06:49.800 --> 06:56.680
Continuously monitor these resources in the event that if a failure ever happens, it can continuously

06:56.680 --> 07:03.970
reconcile these errors and always ensure that we're adhering to whatever we defined in the custom resource.

07:03.970 --> 07:06.190
So that's enough about that.

07:06.610 --> 07:09.370
Uh, this is from the earlier lecture.

07:09.430 --> 07:11.380
Um, where is the code?

07:11.410 --> 07:18.370
What I want to do to start off this lesson is I want to uninstall the helm chart from section 12.

07:18.400 --> 07:20.650
Helm uninstall.

07:20.980 --> 07:25.990
Well, let's actually start by listing all of the helm releases.

07:28.300 --> 07:28.960
All right.

07:28.960 --> 07:31.300
The one we want to uninstall is the following.

07:31.330 --> 07:37.570
Helm uninstall the MongoDB helm release from the namespace MongoDB.

07:40.000 --> 07:44.740
We also want to start off on a clean slate and just stay on the safe side.

07:44.740 --> 07:54.510
Maybe delete any PVCs PVCs services you can say service or SVC doesn't matter.

07:55.110 --> 08:01.950
Um, statefulsets or pods that may persist in that namespace.

08:03.720 --> 08:04.470
And good.

08:04.470 --> 08:08.340
I wasn't expecting anything, but you can never be too safe.

08:08.460 --> 08:13.170
Uh, the helm release upon it being uninstalled will just remove everything that came with it.

08:13.260 --> 08:16.980
And now what I want to do is say helm search repo.

08:18.510 --> 08:22.770
And I want to remove the Bitnami repository.

08:23.040 --> 08:33.480
So what I can do is simply say helm repo remove bitnami.

08:35.880 --> 08:36.720
That's gone.

08:36.720 --> 08:38.910
So if I say helm search.

08:39.750 --> 08:43.560
So if I say helm search repo again no repositories configured.

08:43.590 --> 08:44.070
All right.

08:44.070 --> 08:45.780
We're off to a clean slate.

08:45.810 --> 08:47.190
Funds about to start.

08:47.190 --> 08:53.020
But one more thing before we, um, get too excited.

08:53.020 --> 08:55.810
Let's copy the following.

08:57.070 --> 08:58.660
We'll say section 13.

08:58.690 --> 09:00.790
Final section of this course.

09:05.620 --> 09:08.740
Let's get started okay.

09:08.740 --> 09:17.470
So we can start by adding the repository that has all the related helm charts.

09:17.500 --> 09:20.770
Now we can define an alias for that repository.

09:20.800 --> 09:22.300
We can call it MongoDB.

09:22.330 --> 09:25.330
We can call it my MongoDB repo.

09:25.360 --> 09:29.740
Whatever your heart desires I think MongoDB is a good enough name.

09:29.770 --> 09:31.780
Helm repo add MongoDB.

09:32.440 --> 09:40.270
Um, the repository from where we're going to grab all of these helm charts is they're all hosted at

09:40.270 --> 09:42.100
the following end point.

09:42.130 --> 09:45.850
Let me make sure I wrote this right https MongoDB Github.io.

09:45.880 --> 09:47.920
Yep, that's the right one.

09:48.790 --> 09:54.050
And after you've added this repository to your local helm configuration.

09:54.860 --> 09:55.610
Um, you know what?

09:55.640 --> 10:02.360
Just for reference, just want to reiterate that it's good practice to always update your helm repositories.

10:02.360 --> 10:05.480
I didn't need to in this case because I just added this repository.

10:05.480 --> 10:06.710
But whatever.

10:06.740 --> 10:16.010
We'll search, uh, the repositories and we just have the one MongoDB has all of these different helm

10:16.010 --> 10:17.420
charts.

10:17.930 --> 10:22.460
Um, here is the latest chart version for each one.

10:22.460 --> 10:31.910
What I want to do is specifically deploy the community operator for MongoDB chart version 0.10.0.

10:31.940 --> 10:37.160
Your chart version will be different than mine, probably more up to date depending on when you're watching

10:37.160 --> 10:43.880
this video, but for the sake of consistency, please use the same chart version as me.

10:44.060 --> 10:52.740
All right, so what I'll do is I'll say helm install community operator I want to install.

10:52.830 --> 10:56.220
I want to deploy the following helm chart.

10:56.520 --> 10:58.470
I'm going to specify a version.

10:58.470 --> 11:02.070
Use the same version as me 0.10.0.

11:02.070 --> 11:03.930
And I want to deploy.

11:04.470 --> 11:11.310
I want to release the contents of the helm package into my MongoDB namespace.

11:11.340 --> 11:12.060
Okay.

11:14.340 --> 11:15.360
Beautiful.

11:15.810 --> 11:21.690
Now what I want to do is say kubectl get pods n MongoDB to verify the installation.

11:22.440 --> 11:23.700
Operator up and running.

11:23.730 --> 11:25.230
Beautiful.

11:25.410 --> 11:30.720
Now, just to, um, vary things up, we'll say get all dash n MongoDB.

11:32.550 --> 11:33.030
Okay.

11:33.060 --> 11:35.880
Everything is working well.

11:37.470 --> 11:48.540
Now what I want to do is say kubectl logs dash f Kubernetes operator.

11:48.540 --> 11:58.090
When I output the logs of this pod inside of the namespace MongoDB and notice it says watching namespace

11:58.090 --> 11:58.930
MongoDB.

11:58.930 --> 12:00.370
This is really interesting.

12:00.580 --> 12:08.740
Remember that the operator continuously watches for the presence of a custom resource.

12:08.770 --> 12:09.520
Okay.

12:10.120 --> 12:17.200
Um, and it's going to use whatever we defined in that custom resource to know how it's supposed to

12:17.230 --> 12:20.200
deploy our MongoDB instance.

12:20.230 --> 12:20.500
Okay.

12:20.530 --> 12:28.030
So whatever desired state we define in our CRD, the operator is going to create all of the Kubernetes

12:28.030 --> 12:35.560
resources and continuously manage them in a way to ensure that they always match our desired state.

12:35.590 --> 12:42.280
It follows that the CRD we deploy, the custom resource we deploy, needs to be inside the namespace

12:42.280 --> 12:43.210
MongoDB.

12:43.450 --> 12:50.160
If it isn't, the operator isn't going to recognize that it even exists and nothing will happen if it

12:50.160 --> 12:50.730
does.

12:50.760 --> 12:56.130
See the custom resource inside the MongoDB namespace?

12:56.130 --> 13:01.350
Then it's going to start orchestrating the deployment of our MongoDB app.

13:01.350 --> 13:08.790
It's going to deploy all of these Kubernetes resources and ensure that they adhere to our desired application

13:08.790 --> 13:09.420
state.

13:09.450 --> 13:10.260
Okay.

13:11.880 --> 13:15.390
How are we going to deploy a custom resource definition?

13:15.420 --> 13:26.100
Well, this is where I urge you to start getting comfortable going on going online, reading documentation

13:26.100 --> 13:33.900
about whatever operator you're using, what crds it provides, how the crds work, what the different

13:33.900 --> 13:36.600
fields and all the crds mean.

13:36.630 --> 13:42.840
Once you have a clear understanding of how they work, then you can very easily steer your operator

13:42.840 --> 13:45.990
towards a deployment that you want to accomplish.

13:46.020 --> 13:48.610
Okay, so I've already done that.

13:48.640 --> 13:53.770
What I'm going to do is skip ahead towards the MongoDB.

13:53.800 --> 14:03.100
Kubernetes operator repository, which contains a lot of samples that we can use as inspiration to.

14:03.130 --> 14:05.440
Set up our custom resource.

14:05.470 --> 14:10.420
Okay, so you can feel free to go through all of these.

14:10.900 --> 14:14.950
Um, MongoDB community examples.

14:14.950 --> 14:21.850
They demonstrate how the deployment can be manifested in different ways.

14:22.360 --> 14:26.800
Um, this is an another example.

14:27.430 --> 14:29.260
Um, that one looks good.

14:29.290 --> 14:31.090
Let's go ahead and use this one.

14:31.120 --> 14:37.510
So because this video because this code may change with time, probably will.

14:37.510 --> 14:43.480
What I'll do is instead of linking you to the following page, I'm going to just put all of this code

14:43.480 --> 14:46.270
in a file inside of your resources folder.

14:46.300 --> 14:48.320
Feel free to copy it from there.

14:49.610 --> 14:50.750
And then what I'll do.

14:50.780 --> 14:53.480
I'll delete this values.yaml file.

14:56.630 --> 15:05.060
And I'm going to create a new file called MongoDB community dot YAML.

15:05.660 --> 15:06.140
All right.

15:06.170 --> 15:07.280
Paste this in.

15:08.030 --> 15:11.660
This is just a template that we're going to update momentarily.

15:11.690 --> 15:14.930
I'm going to explain to you what all of these fields mean.

15:14.930 --> 15:18.530
I'm able to because in the past I've reviewed the documentation.

15:18.530 --> 15:20.450
I know exactly how everything works here.

15:20.450 --> 15:27.320
So I really want to stress, when you do venture out into the wild and start deploying your own operators

15:27.320 --> 15:33.680
and leveraging their crds, you need to be comfortable reviewing documentation, going on StackOverflow,

15:33.680 --> 15:39.620
going on the GitHub issues, understanding what everything means before you can start configuring the

15:39.620 --> 15:40.370
deployments.

15:40.400 --> 15:47.490
Okay, so in this case we're going to set up the MongoDB community in such a way that it will tell the

15:47.490 --> 15:50.940
operator to deploy a single instance of MongoDB.

15:50.940 --> 15:55.560
So it's pretty cool how we can manage the replica sets over here.

15:55.590 --> 16:00.450
Remember, a replica set is simply an object that dictates how many pods get created.

16:00.450 --> 16:03.900
We just want one MongoDB instance to run.

16:04.050 --> 16:08.220
Um, these pod deployments are really, really heavy.

16:08.250 --> 16:12.690
We don't want to tax our local machine too much.

16:13.080 --> 16:22.830
Um, I'm going to call this, uh, resource, um, MongoDB grade submission.

16:23.550 --> 16:24.690
Okay.

16:25.170 --> 16:32.340
And actually, before I continue, I want to emphasize how cool it is it that we can, uh, create a

16:32.340 --> 16:35.220
MongoDB community object.

16:35.220 --> 16:40.980
So, so far in this course, we've always been deploying the core objects that are native to Kubernetes

16:40.980 --> 16:48.010
deployments, secrets, stateful sets, but operators, what they do is they extend the Kubernetes API,

16:48.010 --> 16:54.850
and they provide us with custom resources that we can use to steer the operator towards a deployment

16:54.850 --> 16:56.140
that we want to accomplish.

16:56.170 --> 17:00.100
Different operators provide different custom resources.

17:00.100 --> 17:07.510
We want to use the MongoDB community resource to steer the operator towards a MongoDB deployment that

17:07.510 --> 17:08.500
suits us.

17:08.530 --> 17:12.130
We're going to leave all of this the way that it is.

17:12.130 --> 17:16.360
I'll explain what Scram authentication is in just a second.

17:16.990 --> 17:26.650
Um, the user that we want to authenticate against, a, let's say, a grades database, we're just

17:26.650 --> 17:36.220
going to call a user, um, and a password secret ref relies on a secret to give this user a password

17:36.220 --> 17:40.450
that it can use to authenticate against the grades database.

17:40.540 --> 17:44.520
So what I'm going to do here is create a MongoDB.

17:45.210 --> 17:48.570
Admin password dot YAML.

17:49.050 --> 17:50.160
Okay.

17:50.820 --> 17:53.610
Uh, we can just autocomplete secret.

17:53.640 --> 18:00.420
Call this um mongo db admin password.

18:02.640 --> 18:03.630
What did I call it?

18:03.660 --> 18:04.530
Admin.

18:04.950 --> 18:09.210
Bad habit MongoDB user password.

18:09.750 --> 18:11.490
I think that makes more sense.

18:12.390 --> 18:13.230
Okay.

18:14.550 --> 18:18.840
And the password I'm just going to make it password 123.

18:18.900 --> 18:27.780
Um, what I'll do is I'll say echo dash n password 123I want a base 64.

18:27.810 --> 18:29.100
Encode it.

18:30.150 --> 18:31.350
All right.

18:35.610 --> 18:41.160
Because remember anything under the data object Kubernetes assumes will be base 64 encoded.

18:41.160 --> 18:48.190
And wherever it gets loaded in will be base base64 decoded, so this will translate to password 123

18:48.220 --> 18:49.990
the following.

18:50.530 --> 18:53.620
Okay, just wrap this thing up in quotes.

18:58.450 --> 18:59.230
Cool.

19:00.400 --> 19:05.140
Now what I can do here is reference MongoDB user password.

19:09.130 --> 19:11.920
It's going to extract the password field.

19:13.990 --> 19:16.450
Give it to the user to authenticate.

19:16.450 --> 19:25.240
And now we want to give the user a role for um the grades database.

19:25.270 --> 19:34.360
Now the MongoDB roles again you can look up there's database user roles database administration roles.

19:34.360 --> 19:40.960
Because our grade submission API, which is authenticating against the grades database, is going to

19:40.960 --> 19:47.220
be reading and writing to the database, removing data, updating data, inserting finding whatever

19:47.250 --> 19:50.700
the read write role makes the most sense.

19:50.700 --> 19:54.990
So we'll go back here and we'll give it a role of read.

19:54.990 --> 20:00.120
Write for the grades database and the scram credentials secret that gets created.

20:00.120 --> 20:06.960
Let's give it a name of MongoDB grade submission scram credentials.

20:07.440 --> 20:10.950
And you're probably thinking, what the heck is this scram thing?

20:10.950 --> 20:11.760
Ryan?

20:11.790 --> 20:14.460
Ryan, um, let me explain.

20:14.670 --> 20:25.830
So, um, on the server side, MongoDB uses this authentication mode to authenticate this user without

20:25.830 --> 20:29.370
the user having to send this password over the network.

20:29.400 --> 20:29.670
Okay.

20:29.700 --> 20:37.140
So you'll remember that in the connection string you've got the username password the host and the port.

20:37.140 --> 20:42.570
And the idea is that the great submission API would use the host and the port to locate the database,

20:42.570 --> 20:48.270
send over the username, but the password doesn't get sent over in plain text.

20:48.300 --> 20:51.390
What happens is these scram credentials.

20:51.390 --> 21:01.650
They are derived based on whatever password we choose, and MongoDB will essentially use the Scram credentials

21:01.650 --> 21:06.510
to basically ask the Great Submission API a question, if you will.

21:06.510 --> 21:12.900
And the API has to compute a response based on the password.

21:12.900 --> 21:16.860
And if MongoDB accepts the response, then authentication occurs.

21:16.860 --> 21:25.650
So ultimately Scram is a secure way of using basic authentication against MongoDB without exposing the

21:25.650 --> 21:27.330
password over the network.

21:27.360 --> 21:28.050
Okay.

21:28.620 --> 21:32.190
Um, it's the standard way of authenticating to MongoDB.

21:32.190 --> 21:38.340
And besides, don't worry, nothing really changes on the great Submission API, and all of the Scram

21:38.340 --> 21:41.470
related authentication is handled on the server side.

21:41.470 --> 21:42.790
On the MongoDB side.

21:42.820 --> 21:43.480
Okay.

21:43.510 --> 21:50.830
All you got to do is give the secret a name and it'll take care of the rest for Statefulset.

21:50.860 --> 21:56.170
I don't think there's anything in particular I want to modify yet.

21:57.370 --> 22:00.880
I'm just going to stick with whatever default values we have.

22:00.910 --> 22:05.080
There's nothing on a specifically customize, so Statefulset.

22:05.110 --> 22:10.150
You'll remember under template is where you specify how every pod will be configured.

22:10.300 --> 22:16.060
Um, no need for volumes for the MongoDB agent.

22:17.650 --> 22:21.190
I'll explain why we need to modify that in just a second.

22:21.370 --> 22:28.660
Especially if you're using a MacBook computer like myself for the same reason as last section.

22:28.660 --> 22:35.020
So let's just go ahead and deploy this MongoDB community resource.

22:35.140 --> 22:38.380
And remember we need to deploy it in the namespace MongoDB.

22:38.830 --> 22:41.040
Otherwise the operator won't recognize it.

22:41.250 --> 22:41.940
But you know what?

22:41.970 --> 22:43.170
Just to mess around.

22:43.200 --> 22:49.680
Let me deploy it in the default namespace first, just to show you that, you know that wouldn't really

22:49.680 --> 22:50.580
do anything.

22:50.610 --> 22:52.620
Am I CD into the right folder?

22:52.770 --> 22:54.000
I'm not.

22:54.450 --> 22:56.610
We'll CD into.

22:58.920 --> 23:00.660
Section 13.

23:00.690 --> 23:01.860
Oh, what am I doing?

23:05.760 --> 23:07.350
Uh, CD into MongoDB.

23:07.380 --> 23:08.040
There.

23:08.040 --> 23:09.480
Clear the output.

23:09.720 --> 23:14.550
Kubectl apply dash f MongoDB community dot YAML.

23:17.280 --> 23:19.380
It gets applied.

23:19.410 --> 23:31.890
Okay, but if I say kubectl get pods and the default namespace, nothing really happens.

23:31.890 --> 23:36.330
If I say kubectl get MongoDB community.

23:38.890 --> 23:40.570
We get the MongoDB.

23:40.600 --> 23:47.860
Great submission custom resource, but again, nothing really happens because the operator didn't recognize

23:47.860 --> 23:47.980
it.

23:47.980 --> 23:51.730
The operator is looking for things inside the MongoDB namespace.

23:52.060 --> 23:53.380
And you know what?

23:53.410 --> 23:57.340
Let me call this file MongoDB.

23:57.370 --> 23:58.570
Great submission dot YAML.

23:58.570 --> 24:00.730
That just seems like a more fitting name.

24:01.600 --> 24:11.140
Okay, so what I'm going to do is cube CTL delete the MongoDB community resource from the default namespace,

24:11.530 --> 24:13.000
clear the output.

24:13.450 --> 24:15.400
I'm going to apply it.

24:17.740 --> 24:19.960
I'm going to apply this deployment.

24:21.400 --> 24:29.350
Make sure it goes in the MongoDB namespace where the operator will recognize it okay.

24:31.540 --> 24:33.880
0-F- file.

24:37.120 --> 24:37.780
All right.

24:37.790 --> 24:46.940
Now, if we go ahead and say cube CTL get uh, MongoDB community dash n MongoDB.

24:48.620 --> 24:49.010
Okay.

24:49.040 --> 24:54.260
At least the operator recognized the resource and I must have made a dumb mistake somewhere.

24:54.290 --> 24:57.680
So when you make dumb mistakes, what do you do?

24:57.710 --> 24:58.550
You debug.

24:58.550 --> 24:59.300
We're all human.

24:59.300 --> 25:00.140
It happens.

25:00.140 --> 25:05.090
So let's describe this resource.

25:07.160 --> 25:12.920
Describe, um, the MongoDB community.

25:15.530 --> 25:16.040
Error.

25:16.070 --> 25:16.520
And.

25:18.950 --> 25:21.950
I knew I would have made a mistake like this.

25:22.010 --> 25:22.670
Let me zoom out.

25:22.670 --> 25:24.470
This is way too zoomed in.

25:25.070 --> 25:28.250
This is called MongoDB user password.

25:28.250 --> 25:31.160
And I referenced that.

25:31.160 --> 25:31.610
That's.

25:31.640 --> 25:34.490
Oh, I didn't actually apply this secret yet.

25:34.520 --> 25:35.450
Dumb dumb.

25:35.840 --> 25:36.080
Okay.

25:36.080 --> 25:37.260
The next one gram.

25:37.260 --> 25:39.000
Secret MongoDB grade submission.

25:39.000 --> 25:39.390
Scram!

25:39.390 --> 25:40.620
Credentials are.

25:40.650 --> 25:41.880
Darn it, I forgot about that.

25:41.880 --> 25:49.140
It automatically appends the scram credentials part, so you really just typically give it the same

25:49.140 --> 25:52.740
name as the MongoDB community resource.

25:52.800 --> 25:54.420
Let me try this again.

25:54.420 --> 25:56.640
Cube ctl delete.

25:57.360 --> 26:02.010
Anyways, I like getting these bugs in front of you because it shows you that you know I'm forgetful,

26:02.010 --> 26:07.800
I'm not perfect, but as long as I'm comfortable debugging and describing my resources, outputting

26:07.800 --> 26:13.290
logs from my operator, etc., looking at documentation, GitHub issues, whatever.

26:13.320 --> 26:15.420
Nothing is insurmountable.

26:15.420 --> 26:17.460
Everything is easy.

26:17.490 --> 26:26.310
Well, not always easy, but you know, manageable cube CTL delete the MongoDB community dash dash all

26:26.340 --> 26:29.340
resource inside of the MongoDB namespace.

26:31.830 --> 26:37.360
Okay, we'll start by applying the secret kubectl apply dash f MongoDB user password.

26:37.390 --> 26:41.410
Actually, before doing that, let me put this in the namespace.

26:43.360 --> 26:44.290
Uh, MongoDB.

26:44.680 --> 26:46.120
Really important.

26:47.860 --> 26:48.430
Okay.

26:48.460 --> 26:53.440
And we'll say kubectl apply dash f MongoDB.

26:53.860 --> 26:56.020
Great submission dot YAML.

26:56.920 --> 26:58.060
Try it out now.

26:58.090 --> 27:03.490
Kubectl get MongoDB community.

27:05.560 --> 27:10.930
Dash n mongo phase pending.

27:10.990 --> 27:12.040
Beautiful.

27:12.610 --> 27:13.690
All right.

27:15.130 --> 27:18.130
Um, I'm going to fill up my cup of water.

27:18.580 --> 27:19.750
I'll see you in a bit.

27:24.430 --> 27:24.820
Okay.

27:24.850 --> 27:26.020
Let's see what we got.

27:27.820 --> 27:29.050
Still pending.

27:29.080 --> 27:29.290
All right.

27:29.290 --> 27:33.190
Let me say kubectl get pods dash n MongoDB.

27:36.510 --> 27:39.210
All right, so we've got, uh, MongoDB.

27:39.240 --> 27:45.780
Great submission pod, uh, MongoDB instance that's been started up by our operator, among many other

27:45.780 --> 27:47.670
Kubernetes resources that it created.

27:47.670 --> 27:52.140
Let me actually say kubectl get all dash n MongoDB.

27:57.390 --> 28:03.210
It created lots and lots of resources, a stateful set of services.

28:03.240 --> 28:05.280
But the main one I'm interested in is the pod.

28:05.280 --> 28:09.270
At the moment there are two containers in this pod.

28:09.270 --> 28:11.280
One of them is running, the other isn't.

28:11.280 --> 28:17.130
I want to know which one isn't so that I can troubleshoot the issue we're debugging live.

28:17.520 --> 28:21.990
If you're using a windows computer, chances are this worked for you.

28:21.990 --> 28:24.270
But you know, just follow along.

28:24.270 --> 28:29.610
Use the same configuration as me anyways because it's going to be compatible with both architectures.

28:30.120 --> 28:30.750
Anyways.

28:30.750 --> 28:31.860
I don't want to spoil the bug.

28:31.860 --> 28:33.690
Let's figure out what it is.

28:33.690 --> 28:38.290
Describe this pod inside of the MongoDB namespace.

28:39.250 --> 28:54.070
Um, and here, um, we can see that it's the MongoDB agent container that is failing.

28:54.100 --> 28:54.970
Okay.

28:55.000 --> 29:03.490
The MongoDB agent, this image specifically isn't compatible with ARM 64.

29:03.610 --> 29:09.490
Um, should run fine on your windows machine windows users, but MacBook, M1, M2, whatever.

29:09.520 --> 29:19.150
We need to override the container for the MongoDB agent to use a different image, one that actually

29:19.150 --> 29:23.560
supports, um, both architectures.

29:23.560 --> 29:30.460
So what I did is I went to the Quay.io registry, went into the MongoDB repository, looked up different

29:30.460 --> 29:37.230
image versions for the MongoDB agent, and eventually I actually ended up finding one that supports

29:37.230 --> 29:38.910
both architectures.

29:39.300 --> 29:41.340
Troubleshooting at its best.

29:41.370 --> 29:48.270
Okay, so this is the registry for all the MongoDB images for the MongoDB agent.

29:48.300 --> 29:51.960
These are different versions of the image.

29:51.960 --> 29:58.950
We can see one right here 12.0 .32.78571.

29:59.010 --> 30:05.730
This image version is compatible with Linux on Amd64 and Linux on ARM 64.

30:05.730 --> 30:10.440
So what I'll do is I'll copy this over.

30:13.440 --> 30:14.460
All right.

30:15.210 --> 30:27.000
And I'm going to update my statefulset such that all of the pods that it manages, um, we want to update

30:27.000 --> 30:36.840
the template such that the MongoDB agent container uses the image from the registry key.io.

30:36.870 --> 30:37.710
Okay.

30:38.610 --> 30:39.420
Um.

30:40.890 --> 30:42.720
Slash MongoDB.

30:42.750 --> 30:44.550
Slash the following.

30:47.430 --> 30:55.200
Uh, eliminating special characters, uh, followed by the image tag that's actually compatible with

30:55.200 --> 30:55.860
both our, uh.

30:55.860 --> 30:57.000
I could have just copied this.

30:57.000 --> 30:59.070
I'm such a knucklehead.

30:59.460 --> 31:00.180
Let me copy it.

31:00.180 --> 31:00.870
Just to be safe.

31:00.870 --> 31:02.070
I don't trust myself.

31:02.100 --> 31:03.000
I'll.

31:03.030 --> 31:03.660
You know what?

31:03.660 --> 31:05.430
You can probably paste this in yourself.

31:05.430 --> 31:07.890
I don't need to put it in the resources folder.

31:08.670 --> 31:16.830
Um, this I will put in the resources folder, the image version that we specifically want.

31:16.830 --> 31:18.150
Or you can feel free to copy.

31:18.180 --> 31:20.070
It's 12.0

31:20.100 --> 31:24.690
.32.7857-1.

31:30.450 --> 31:30.900
Okay.

31:30.900 --> 31:32.800
And that's pretty much it.

31:33.520 --> 31:38.380
Uh, the other container within the pod is working just fine.

31:39.280 --> 31:43.660
Um, so let's go ahead and deploy this thing.

31:44.080 --> 31:48.550
So cube CTL windows users.

31:48.580 --> 31:49.780
Sorry you had to suffer through this.

31:49.810 --> 31:50.980
Yours worked this whole time.

31:50.980 --> 32:00.340
But you know, it doesn't hurt to kubectl delete MongoDB community dash dash all dash n MongoDB.

32:03.130 --> 32:04.900
Or I could have just reapplied it.

32:06.190 --> 32:07.150
Whatever.

32:12.850 --> 32:15.430
And my computer is really slowing down.

32:16.960 --> 32:23.110
Kubectl apply dash f will apply the updated

32:25.090 --> 32:33.600
resource v1 cannot be handled as master unknown field spec dot statefulset.

32:33.990 --> 32:39.870
Oh my bad guys, I, I, um, I ruined the template that we got.

32:39.900 --> 32:44.220
There was originally a spec over here that I removed by mistake.

32:44.220 --> 32:47.580
So we specify the behavior of the stateful set.

32:47.580 --> 32:53.640
And part of that behavior is, um, defining the pod templates.

32:53.640 --> 33:00.990
For each pod template, we specify its runtime requirements, how the containers are going to run.

33:00.990 --> 33:04.650
We specifically overrode the MongoDB agent.

33:05.730 --> 33:06.870
All right.

33:07.440 --> 33:09.090
So this is my own mistake.

33:09.090 --> 33:09.930
I didn't invent this.

33:09.960 --> 33:11.700
It was already present in the template.

33:11.700 --> 33:13.320
I just removed it by mistake.

33:13.350 --> 33:14.010
Okay.

33:14.280 --> 33:18.780
So let's say kubectl get pods dash n MongoDB.

33:19.290 --> 33:21.150
Everything should now work.

33:21.150 --> 33:22.260
It's initializing.

33:22.260 --> 33:23.490
We'll give it some time.

33:25.080 --> 33:26.070
All right.

33:35.680 --> 33:36.790
Try it again.

33:39.490 --> 33:39.940
Okay.

33:39.970 --> 33:41.170
At least there's no error.

33:46.120 --> 33:47.290
Choo choo choo choo choo.

33:57.610 --> 33:59.410
One out of two containers is running.

33:59.410 --> 34:02.470
We need to wait for the other one while we're doing that.

34:02.470 --> 34:10.750
What I'm going to do is set up the URI that the great Submission API is going to need to connect to

34:10.750 --> 34:12.340
the MongoDB instance.

34:12.370 --> 34:20.830
Okay, so here we need to start by specifying a username.

34:20.830 --> 34:26.980
So that's going to be user followed by password 123.

34:27.850 --> 34:35.030
So after we've defined the credentials, then we specify the name of the service.

34:35.060 --> 34:35.300
Okay.

34:35.330 --> 34:39.770
So kubectl get service dash n MongoDB.

34:41.030 --> 34:43.640
Then the name of the service is MongoDB.

34:44.270 --> 34:46.490
Great submission service.

34:46.490 --> 34:48.830
The namespace that it's in is MongoDB.

34:48.830 --> 34:53.210
That doesn't change dot service dot cluster dot local 27017.

34:53.240 --> 34:56.780
Then we're going to say slash grades.

34:56.810 --> 35:09.500
Because remember upon the cluster IP service forwarding our request to the MongoDB database, it's going

35:09.530 --> 35:11.570
to read this connection string.

35:11.570 --> 35:16.430
And it's going to try to authenticate our user against a grades database.

35:16.430 --> 35:24.170
So final URI username password host and port so that we can connect to the database followed by the

35:24.170 --> 35:24.740
database.

35:24.740 --> 35:30.900
We want to connect our user to I did, I buy enough time for the pod to start up.

35:32.490 --> 35:33.450
You know what?

35:33.660 --> 35:36.360
I think this might just be a resourcing issue.

35:36.390 --> 35:41.160
Whether or not the MongoDB agent runs, I don't really care.

35:41.190 --> 35:43.710
We'll still be able to establish the connection.

35:44.220 --> 35:50.130
Kubectl describe pod dash n MongoDB.

35:50.520 --> 35:53.850
Okay, that's all right.

35:53.880 --> 35:55.320
We'll revisit this.

35:55.860 --> 35:59.220
Um, what I want to do is CD out of MongoDB.

35:59.250 --> 36:02.850
CD into the grade submission API folder.

36:03.180 --> 36:11.700
Start by helm uninstalling the grade submission API release that exists in the grade submission namespace.

36:14.250 --> 36:22.050
Then what I'll do is I'll reinstall the helm release using the helm chart in the current directory.

36:22.080 --> 36:24.300
Dash n grade submission.

36:24.300 --> 36:26.370
Let me just check over this again.

36:28.630 --> 36:29.560
Okay.

36:29.590 --> 36:31.210
Mongo dot service.

36:31.210 --> 36:31.750
Dot cluster.

36:31.750 --> 36:32.860
Dot local.

36:33.160 --> 36:34.120
Beautiful.

36:37.390 --> 36:44.350
Now what I'll go ahead and say is kubectl get pods dash n great submission.

36:47.050 --> 36:48.070
Terminating.

36:48.100 --> 36:49.540
Attempting to connect.

36:49.570 --> 36:50.980
We'll give it some time.

36:51.190 --> 36:58.990
Kubectl logs dash f create submission.

37:01.180 --> 37:03.160
Connected to MongoDB.

37:03.430 --> 37:04.450
Beautiful.

37:05.620 --> 37:07.480
And that's pretty much it.

37:07.480 --> 37:07.930
Guys.

37:07.930 --> 37:10.870
You are able to deploy MongoDB using three separate methods.

37:10.870 --> 37:13.930
You created all the deployments yourself at first.

37:13.930 --> 37:17.950
Then you used a helm chart from the Bitnami repository.

37:17.950 --> 37:21.610
And then we're able to use a helm chart to deploy an operator.

37:21.610 --> 37:27.900
And then using a CRD that the operator provides, steer the operator towards a deployment that suited

37:27.900 --> 37:29.430
our purposes.

37:29.460 --> 37:30.060
Okay.

37:30.090 --> 37:35.100
Look at how easy it was to set up such a complex deployment.

37:35.130 --> 37:41.250
We had to do some troubleshooting because Arm64 wasn't supported by the image used originally for the

37:41.250 --> 37:45.720
MongoDB agent, but we were able to fix the issue for windows users.

37:45.720 --> 37:49.950
You wouldn't have had to change anything in the stateful set, you would have been just fine.

37:49.950 --> 38:00.450
And notice how simple your CRD would have been, how easy it was to deploy a MongoDB instance that is

38:00.450 --> 38:04.230
continuously being monitored by an operator.

38:04.230 --> 38:09.120
If an error were to ever happen, the operator is continuously reconciling these errors.

38:09.120 --> 38:14.400
Try to bring it back to the desired state that we specify in our resource right here.

38:14.700 --> 38:20.130
I think I'm probably going to have to uninstall my great submission portal helm chart, reinstall it,

38:20.130 --> 38:22.200
and then test everything out.

38:22.230 --> 38:24.000
I don't feel like testing everything out.

38:24.000 --> 38:25.140
Everything works.

38:25.190 --> 38:29.600
Otherwise the readiness probe wouldn't have deemed this application to be ready.

38:29.600 --> 38:35.450
Let's go ahead and check on our pods in the MongoDB namespace.

38:39.500 --> 38:42.080
Um, unable to connect to server.

38:42.590 --> 38:43.340
Wow.

38:43.340 --> 38:46.880
So my Kubernetes cluster is dead.

38:47.120 --> 38:47.630
Um.

38:48.200 --> 38:50.270
Sorry, guys, nothing I can do.

38:50.300 --> 38:52.580
Computer has run out of resources.

38:52.610 --> 38:56.120
Can't really record and run these apps at the same time.

38:56.120 --> 38:59.240
Oh, finally, our agent is up and running.

38:59.270 --> 39:00.380
Beautiful.

39:00.410 --> 39:05.480
I'm going to stop this demo right here because my computer is heating up.

39:05.480 --> 39:08.480
And if I don't, it might just shut down.

39:08.600 --> 39:10.460
Hope you enjoyed this lesson.

39:10.460 --> 39:13.670
We've accomplished so much in this course.

39:13.730 --> 39:20.390
Next section, we're going to wrap everything up with a very, very fun demo where we deploy our cluster

39:20.390 --> 39:22.040
on AWS.

39:22.160 --> 39:23.960
Okay, see you soon.
