Welcome back everybody.
Let's discuss another very cool benefit that Kubernetes provides.
And that is configuration management.
The ability to separate application specific configuration from environment related deployment details
okay.
So if you take a look at what we've got so far, we're mixing parameters and settings that are specific
to the application with deployment details that describe how the app should be deployed in its environment.
We're doing that in the Great submission API deployment and the great Submission portal deployment.
We're doing that in the stateful set as well.
Here we have uh, parameters and settings that are specific to configuring the MongoDB app itself.
And we're entangling that with environment related deployment details.
So how persistent volume claims will be bound to each container, how persistent persistent volumes
will be mounted.
The amount of replicas we're going to have.
So these are things that belong in a deployment manifest.
Uh, application specific configuration.
Do not.
Why?
Here are some, uh, obvious examples, uh, updating database credentials, changing them every now
and then is a very common practice.
Okay.
You don't want to reconfigure the entire stateful set re-update the entire stateful set every time we
change the username and password.
That's one.
Number two is let's just say the great submission API ends up relying on a lot more environment variables,
maybe eight, 10 or 12.
Are you going to flood the deployment with all of these environment variables?
Um, if you do that, things just become really, really hard to maintain.
You never want to entangle Application specific configuration with environment related deployment details.
You want to have a clear separation of concerns, and that's where configmap and secrets are very useful.
We can store Non-confidential configuration data in Configmaps, and we can store and base64 encode
sensitive configuration data inside of secrets.
And then we can reference the Configmaps and secrets in our deployment manifest, leaving our deployment
completely devoid of configuration data and only containing deployment details.
So expanding on that, a Configmap only contains Non-confidential configuration data using usually in
plain text, and then the deployment now just contains deployment details, and it can reference the
values that it needs from the config map.
Same thing over here.
The deployment just contains the deployment details and it can reference whatever sensitive information
the secret has to set up authentication or even to authenticate.
All right.
So now what I can do is copy and paste section seven.
Call it section eight.
2222.
Oh.
Before you start please do this.
Delete every deployment stateful set PVC delete everything from the great submission namespace.
Trust me, if you don't, you're going to get really weird results throughout this lesson because we're
basically rewiring everything and we don't want to have any loose ends.
Okay, so make sure to delete every single object that we have so far in the great submission namespace.
You can leave the services.
They're harmless.
And before we do anything we're going to add a few more files.
And things are already starting Actually guys, give me one second.
I'll be back.
There's a lot of construction noise in the background.
All right, all right, I'm back.
I forgot what I was talking about, but anyways, I'll go ahead and split everything up into folders.
Create submission API.
Uh, one folder.
Great submission portal.
That's going to contain all the great submission portal objects.
One folder called MongoDB.
We move those here, move, move those here.
Move and move those here.
All right.
So the deployment's got, um, these parameters and settings and this username and password, we want
to put these in a config map, put these in a secret and reference them accordingly.
Let's create a new file called Great Submission API Config.yaml.
Um, call this config map.
Don't forget to.
Well, obviously you won't get the config map and name.
One thing you shouldn't forget is the namespace.
Okay?
If you don't put the config map in the same namespace as your deployment, your deployment is not going
to be able to find it.
All right.
So grade submission, it must be in the same namespace as the deployment.
So that the deployment can is able to reference it and load in all of its values in real time and give
its values to the application.
So here we can just say MongoDB host equals MongoDB.
So yeah, we can just specify our environment variables as key value pairs okay.
Sorry guys.
And remove any white space Okay.
And now inside of our deployment, instead of referencing our environment variables like that, I can
just say environment from we're going to get all of our environment variables from a config map.
So I'm going to say config map ref.
We're going to reference the config map named great submission API config in order in order for the
deployment.
To successfully reference this config map, they need to be in the same namespace.
And now we need to put these in a secret.
So great submission API secret dot YAML.
We'll say secret.
We'll call this secret great submission API secret.
Make sure it's in the same namespace as our He meant all right.
And now the fields that we're going to put our MongoDB user in MongoDB password inside of our secret
and later reference from our deployment, so we can specify them as simple key value pairs.
MongoDB user.
And you can't actually store things in plain text under the secrets as data object.
I'll get to that in a second.
They need to be base64 encoded.
Why?
I'll explain in just one second.
Let's just put these here for now.
All right.
So any value, any sensitive value that we place under the data object Kubernetes is going to assume
it's base64 encoded.
Don't believe me?
Hover over data object.
The serialized form of the secret data is a base64 encoded string.
If you want it to store your sensitive data in plain text, then you would put things under string data.
But I don't see why you would do that.
And so yeah, we can't simply write these in plain text.
They need to be base64 encoded.
Let's do that right now.
We can do that straight from the command line.
Notice I'm already keyed into section eight.
Make sure to do that as well.
I'm going to say echo dash n and this plain text value I want to convert into base64.
This password value.
In a base64 encoded as well.
Okay.
So Kubernetes is going to assume this is base64 encoded and interprets.
It's going to get back the value password 123.
Okay.
So you need to make sure that your password is base64 encoded because that's what Kubernetes is expecting
it to be, because it's going to decode it back into its plaintext value when giving it back to our
container that needs it.
All right.
We haven't referenced the secret yet, but why do we base64 encode?
Well, if we have a password with many with many special characters that can't be written in plain text
in a YAML file.
Base64 converts that really complex password into a set of 64 safe Ascii characters A to Z 0 to 9,
ensuring that we can use whatever password we want.
Because look, some special characters you simply can't write in plain text.
They need to be base64 encoded and passwords tend to have these characters.
So that's why in a secret, Kubernetes assumes everything you write is going to be base64 encoded,
and it's going to decode it upon it being injected within whatever container you want to give that data
to.
So here we reference all the environment variables in the secret that's named Great Submission API secret.
And that's it guys.
Um, I'm not going to deploy anything yet, but nothing changed.
All right.
Before we had environment variables specified over here.
Now we're referencing these environment variables from a config map, which stores the variables in
plain text and from a secret which stores the base64 encoded version.
So this is assumed to be password 123.
And this is interpreted as admin.
All right.
Same thing for the great submission portal here I just need a config map, because I don't think the
great submission portal has any sensitive data or relies on any sensitive data.
Config map call it great submission portal config.
Not API config in the namespace create submission.
Remember, it must be in the same namespace in order for the deployment to find it, and the values
it's going to have are the following.
We can just copy and paste that over here, and we can write our environment variables as key value
pairs.
Config.
We can just use plain text.
Simple as that.
Again make sure you've got no trailing white space no special characters.
Otherwise you'll end up getting these really weird errors.
Okay.
And environment variables.
We're going to get them from
a
config map that we reference using its name grade submission portal config.
Right.
And we don't have to specify any application specific configuration within the deployment.
We just reference whatever environment variables are inside of this config map.
There could be one, there could be 20.
Doesn't matter.
We just reference it and inject these environment variables into the application that needs it.
Now our deployments are devoid of parameters and settings specific to the app, and only contain the
necessary deployment details that it needs to know how to run, how to deploy our application in its
environment.
Now we do the same thing for MongoDB.
This one only needs a secret MongoDB secret YAML.
I'll say secret over here.
Call it MongoDB secret and namespace.
Great submission.
And once again, everything here is expected to be base64 encoded.
We already did the base64 encoding over here, so I can copy over the values, but the keys themselves
will be different because the Mongo app itself expects a certain um environment variable a certain set
of environment variables for uh to in order for it to set up security.
Namely these ones.
All right.
So mongo init db root username.
Which uh should map to the value admin.
But we're going to put in the base64 encoded version because that's what is expected inside of the data
object of a secret.
And the Mongo db root password we store.
The base64 encoded is going to map to password one two, three.
But we're not going to write password 123.
We're going to write the base64 encoded version because Kubernetes will interpret it and convert it
back into plain text when we give it to whatever app is referencing it.
Okay.
So in this case, our MongoDB app is going to get password one, two, three.
It's going to be base64 decoded at the container runtime back into its plaintext value.
Now we reference the secret, not the environment variables.
So we'll get the environment variables from uh, secret that we reference using its name MongoDB secret.
All right.
And that's it.
Nothing changed guys.
All we did was we separated configuration from deployment.
And now whenever I need to update my usernames or passwords or whatever, I don't need to drill in my
entire deployment manifest.
I can just update it within its config file.
Okay.
All right.
Again I want to emphasize this.
Make sure that you've deleted all your deployment stateful PVCs whatever.
Do it now if you haven't done so already.
Not just your stateful sets, all the associated PVCs as well.
Once you see that everything has been deleted.
Then go ahead and CD into section eight.
Um, sorry guys.
Before moving on, I really want to make sure I don't have any loose ends because this lesson is a bit
tedious.
So the secret has been defined properly.
It's got all the variables that it needs to inject into the MongoDB app.
We're referencing the MongoDB secret.
Let's make sure the name is consistent.
It is there in the same namespace.
All right.
This one is fine.
This one is fine as well.
Okay.
Well this one API config API secret same namespace.
All the right values being referenced over here.
Okay, no sense in worrying if we get bugs.
We just describe our pod's, output the logs and try to debug.
So we apply everything in the MongoDB folder first and foremost.
All right.
Kubectl get pods dash n.
Great submission.
Okay.
The MongoDB pod has been started up.
I'm going to say kubectl apply dash f everything in the grade submission API folder.
So now I expect my grade submission API to have received the host and port that it needs to connect
to the MongoDB service, and once connected that it receives the correct username and password, which
will be base64 decoded back to admin and password 123 that it needs to authenticate against the MongoDB
statefulset.
Let's make sure container is still creating.
Wow, that was a cliffhanger.
Not a cliffhanger, but anticlimactic.
Kubectl get pods dash n great submission.
Let's try it again.
Come on.
Container.
Create.
Beautiful.
It's running now.
It's trying to connect to the MongoDB database kubectl logs dash f.
Make sure it's able to authenticate.
We want to view the logs for this pod.
That's in the great submission namespace a tried connecting.
It didn't, but then it finally did.
So now I expect the readiness endpoint to have sent back positive responses to the readiness probe,
which means our app should be ready.
All right.
There was an application restart for this one.
Weird.
Uh, the liveness probe must have sent back a negative response at some point, triggering an application
restart.
Anyway, now we apply the great submission portal.
So the reason I did this order is because the MongoDB is kind of like standalone.
The great submission API relies on connecting to MongoDB, and the Great Submission portal relies on
connecting to the Great Submission API.
Great submission portal usually always works from the first try.
That one doesn't have any complexities to it.
And great submission.
Okay, it's not ready yet.
I guess it hasn't fully connected to the great submission API, because I have a readiness endpoint
in there that sends back a negative response or a status 500.
If the portal can't connect to the API.
Wonder why it can't?
I can, I just spoke too soon.
Okay, so it's really important that you delete it.
Everything.
First, all the deployment, stateful sets and PVCs and started from scratch.
All right.
To make sure everything works.
Um, let's just go to localhost 32,000.
If we get a smooth user experience, then everything has been connected to each other seamlessly, which
means nothing changed.
All we did was separate the configuration data, but everything still works smoothly.
I did delete all the PVCs and whatnot, so their corresponding PV should have been deleted as well.
So we should see no data if I go to grades.
So if I go ahead and submit some new grades.
It's so slow.
My computer is really sluggish right now.
Harry Potter give him a 43 and potions.
Fingers crossed guys, that was a very tedious video to produce.
Let's end on a good note.
All right.
Beautiful.
So that's all for separating configuration data from your deployment manifests, we place sensitive
configuration data inside of secrets, ensuring that their base64 encoded upon them being injected into
whatever app relies on them.
They will be base64 decoded back into their plain text value during container runtime, and we place
non-confidential configuration data in config maps in plain text, and we just reference the config
map using a config map ref ref and all of its environment variables will be loaded in to the app that
needs them within the same container at container runtime.
All right, that's it for, uh, configuration management with Kubernetes.
Hope you can see how just uh, loosely coupled it makes everything and how awesome it is to be relying
on a platform like Kubernetes that provides so many benefits.
The next one is really exciting, where we discuss horizontal scaling.
I'll see you then.