Welcome back everybody.
I always praise Kubernetes because it makes it so easy to manage our cloud native apps.
If you really learn how to navigate the Kubernetes ecosystem, you can harness a very powerful platform
because it just provides so many benefits out of the box.
One of the core benefits that we witnessed was resiliency and self-healing.
You'll remember that we saw a scenario that when the process, when the application itself terminates,
when it gets fully killed, for whatever reason, whether that's an out of memory exception or an internal
null pointer exception or a stack overflow exception, whatever it may be, when the application gets
fully killed off when the process is dead, Kubernetes will detect that the process was terminated,
so it will restart the container and try to bring it back to life.
Resurrect it back to a healthy state where it can continue to serve traffic.
That's why when we deploy containers to Kubernetes, they automatically become resilient and self-healing.
But now what about scenarios when the application hasn't actually been fully terminated?
It's still technically running.
It's still consuming CPU and memory, but the application itself isn't operational.
It's not live.
In which case what we can do is employ a liveness probe, a Kubernetes liveness probe that continuously
probes the application to see if it's actually operational, and if the liveness probe deems the application
to be not operational, then it's going to restart the container in order to resurrect the application
back to a healthy state.
So the liveness probe allows Kubernetes to go beyond just restarting containers.
If the app gets fully killed off, it can actually check if the app itself is working, and restart
the container accordingly.
But now what about scenarios where the app is fully operational?
Everything is fine, but the external components that it relies on, they themselves are down.
That could be an external database or whatever that the app relies on in order to serve traffic.
In that case, what we can do is employ readiness probes.
A Kubernetes readiness probe will continuously probe the application to check and see if it's ready
to serve traffic.
Okay, so an application could be operational but not ready to serve traffic.
If the readiness probe deems the application to be not ready, then what it can do is prevent any traffic
from reaching the pod that the application is in.
If you look at a diagram the developer who programmed the containerized application could be a developer.
A team of developers doesn't matter.
They have complete authority over how the liveness endpoint gets programmed.
So it could be programmed to be exposed on the path.
Slash health slash liveness.
Doesn't really matter.
Ultimately, what this liveness endpoint does is it checks to see if everything within the application
is functioning properly, if everything internal to the app is fine.
So that could be internal components like internal queues that process asynchronous operations, that
could be internal caches that um, as a store frequently accessed data doesn't really matter.
Depends on what the application is.
Using the liveness endpoint will check if all of the internal components within the app are actually
responsive.
It's going to see if any of the background tasks.
Any of the vital background tasks running in the app are actually active.
It could check for resource thresholds like disk space or heap size.
If everything is fine, we didn't reach a 90% threshold or whatever.
The application can be deemed healthy and fully operational, but if any of these checks were to fail,
then what the liveness endpoint is going to do is send back a negative response, an internal server
error with a status of 500, and when the when the liveness probe receives a negative response, it's
going to deem the application to be not operational, not working.
And essentially we've signaled to the liveness probe that, hey, please can you restart our application
so that we can potentially bring it back to a healthy state?
And this automated way of restarting the app based on criterias that we use to determine if the app
is healthy or not is what makes Kubernetes really, really powerful.
We can automate this self-healing based on criterias that we determine essential for the application
to run.
These.
These criterias can vary from one application to the next, and it's up to the team of developers to
determine what constitutes a healthy application and operational application.
The readiness endpoint will check if any external components that the app relies on is actually functioning.
If the app relies on external dependencies like databases, um, Kafka data stores, or MQ brokers,
whatever.
If any of these external dependencies isn't functioning and the app can't fully serve requests without
them.
Again, we send back that negative response, telling the readiness probe to prevent any traffic from
reaching the pod that this container is in.
Okay, but if everything is fine, the readiness endpoint will continuously send back the readiness
probe.
Positive responses.
Everything is fine.
Don't do anything.
Okay, so it's pretty cool how, using our own criterias, we can determine if an app is live, otherwise
restart it.
If an app is ready to serve traffic, otherwise prevent any traffic to it.
That's enough theory.
Let's go ahead and implement it.
So what I want to do is copy and paste section five.
We'll call it section six and two.
We're not quite ready to work with the stateful app.
So we'll revert this to be stateless okay.
Um yeah that's pretty much it.
Um, I can see the out of section five CD into section six.
I'm going to say cube CTL.
Let's just delete all the pods for now with dash dash all and the namespace.
Great submission.
Why am I saying pods?
I'm going to delete all the deployments.
I just want to start off on a clean state.
Slate will keep the services because I don't anticipate anything will change and by virtue of deleting
all the deployments, all of their corresponding pods will get deleted as well.
We can verify this.
They're terminating okay.
So now in the deployment.
So we've got a great submission API app running within the confines of a container.
And this app I programmed it to have a liveness and readiness endpoint.
So it's got all of these endpoints with business logic for storing great data and retrieving great data.
And it's also got these endpoints that pretty much monitor the health of the app and monitor the external
dependencies that the app relies on in order to function.
Okay, so we've got the liveness and readiness endpoints.
Let's probe them using Kubernetes.
Liveness and readiness probes.
Right here I'll specify a liveness probe.
And this probe is going to make continuous get requests to the liveness endpoint exposed by this great
submission API.
Okay.
It's going to make continuous get requests to the path slash Health's.
Okay.
So I programmed this application to expose an endpoint at the path slash Health's on on port 3000.
If the app's endpoint sends back a positive response to our liveness probe, if it keeps sending positive
responses, then nothing happens.
The app is healthy.
We're good.
If it sends back negative responses or at least one negative response, the liveness probe will restart
the container, and we want to modify this probe to have an initial delay of at least, um, five seconds
while the application is starting up.
You know what?
Let's do 15 seconds.
So when the liveness probe, if it tries to make a request in the first second, for example, then
what could happen is if the app isn't actually started up, the liveness probe is going to be like,
whoa, I couldn't reach the health endpoint.
We need to restart the container.
And so it's going to go through this vicious process of always restarting the container over and over
and over and over.
And you don't want to do that.
You want to specify a reasonable initial delay, giving the application time to start up before we start
probing its endpoint.
We don't want the liveness probe to think that the app was created, but the health's endpoint was simply
unresponsive.
Right.
And then we can specify a period in seconds.
We can say after the initial delay keep probing this endpoint every five seconds.
All right.
That's pretty much it.
We've been able to leverage the liveness probe.
If our health endpoint ever sends back a negative response our container will automatically restart.
Uh, we can set up a readiness endpoint readiness probe as well.
That continuously makes get requests to the Great submission API at its path slash Redis.
Okay, I programmed this app to have a liveness, a readiness endpoint at the path slash Redis, and
the app is running on port 3000.
And whether or not we put an initial delay for the readiness probe isn't as important as setting it
up for the liveness probe because, um, while the app hasn't started up yet, um, if the readiness
probe simply can't access this path at all, then it's just going to deem the app not ready to receive
traffic, which isn't a big deal.
And when the app does start up, when it's able to make these requests, it'll deem the app to be ready
to receive traffic and allow requests to go in.
Okay, you know what?
Let me put an initial delay just to show you something.
I'm going to put an initial delay in seconds.
Uh, we'll say ten and we'll put a period of five seconds.
So every five seconds check.
Um, so every five seconds we want the readiness probe to probe the readiness endpoint of our great
submission API.
What I'm going to do is copy the following.
But for the great submission portal deployment, right under where do we put it?
Let's be consistent.
Right here.
Nope.
I forgot one thing.
Okay.
I'm not going to mess around here.
Let's just remove the initial delay from the start.
Um, the port is 5001, so I also programmed the great submission portal to have a liveness endpoint
exposed at the path Slash Health's.
And that's it.
I'm just going to start by deploying the Great Submission API deployment to keep things simple.
Great submission.
Uh kubectl apply dash f great submission API deployment.yaml unknown field spec dot temp liveness probe
dot Initial delay.
Seconds.
Uh, man.
Sorry if you got frustrated watching this video the whole time while I clearly misspelled initial.
Okay, let's try this again.
If I say kubectl get pods dash n great submission.
Um, notice how the pod itself is running, but it's deemed not ready to receive traffic, mainly because
our readiness probe is waiting 10s before it can probe the application for for readiness.
And while the app while both pods are deemed not ready, uh, the readiness probe will block any traffic
from going into them.
Okay, now 10s have passed and I'm pretty sure the readiness probe has probed these endpoints by now.
So if I say kubectl get pods again now you can see that both pods are ready.
All right.
We can do the same thing for the great submission portal kubectl apply dash f.
Great submission portal deployment.
Kubectl get pods dash n great submission.
And we only want to query the pods that have the following label.
App dot Kubernetes.io slash instance.
Great submission portal.
Put an equal sign here.
And once again we see that our great submission portal application is running.
And in this case our readiness probe didn't have an initial delay.
So it was able to quickly probe the readiness endpoint, which keeps sending back positive responses.
So the readiness probe has no reason to deem the app not ready.
And as you can see, none of our applications are being restarted, which means they are live as well.
They're fully operational.
The liveness endpoint is not sending back any red flags.
That's it for liveness and readiness.
The implementation of the liveness and readiness endpoints really depends on the team of developers
and how they design the app, and what they feel are the most appropriate criteria for an for their
app to be deemed live or ready.
All we have to do from the Kubernetes side is set up these liveness and readiness probes in order to
instrument Kubernetes to restart the app accordingly.
If the liveness endpoint sends back red flags or prevent any traffic from going into the pod, if the
readiness endpoint programmed by these developers sends back any red flags, that's it for liveness
and readiness.
I'll see you in the next one.