Using Kubernetes readiness and liveness probes for health checks with ASP.NET Core 2.2 on OpenShift

.NET Core 2.2 has been released. You can try it on Red Hat Enterprise Linux (RHEL) and OpenShift. One of the new features of ASP.NET Core is the Health Checks API.

In this article, which was written for C# Advent Calendar 2018, I show an example of how the API works with OpenShift by implementing two health checks for the Kubernetes liveness and readiness probes. Since OpenShift includes Kubernetes, this example also works well with Kubernetes.

Example code

This new Health Checks API quite works well with Kubernetes liveness and readiness probes. These probes are available in OpenShift, too.

Here is my example application to explain the Health Checks API.

And below is an example of configuring two health checks: one for the liveness probe and one for the readiness probe.

public void ConfigureServices(IServiceCollection services) { ... services.AddHealthChecks() .AddCheck("Liveness", failureStatus: null) .AddCheck("Readiness", failureStatus: null); } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { ... app.UseHealthChecks("/health/live", new HealthCheckOptions() { Predicate = check => check.Name == "Liveness" }); app.UseHealthChecks("/health/ready", new HealthCheckOptions() { Predicate = check => check.Name == "Readiness", }); ... }

In the ConfigureServices method, you can enable health checks and add as many checks as you want. LivenessHealthCheck and ReadinessHealthCheck are the classes that define how to check the application’s health in this project. I’ll show you these classes later.

In the Configure method, you can define which health checks are responsible for the specified path. In my example, the health check whose name is Liveness is executed for /health/live and the health check whose name is Readiness is executed for /health/ready .

Below is an example implementation of the LivenessHealthCheck class. You can return the application’s health status in the CheckHealthAsync method. My example returns Unhealth when the application status defined in HealthStatusData.IsLiveness is false. This status can be updated by the POST method.

For more details, please refer to the code.

internal class LivenessHealthCheck : IHealthCheck { private HealthStatusData data; public LivenessHealthCheck(HealthStatusData data) { this.data = data; } public Task CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default(CancellationToken)) { if (data.IsLiveness) { return Task.FromResult(HealthCheckResult.Healthy()); } else { return Task.FromResult(HealthCheckResult.Unhealthy("Error")); } } }

Everything you need to grow your career. With your free Red Hat Developer program membership, unlock our library of cheat sheets and ebooks on next-generation application development. SIGN UP

Working with OpenShift

My example code can be run on a local machine. However, you can try it with Kubernetes or OpenShift. If you want to try it with OpenShift, please import the ASP.NET Core 2.2 s2i image by following this document. After importing the .NET Core 2.2 s2i image, you can deploy my app to your cluster, as follows:

$ oc new-project aspnetcore22 $ oc new-app --name=healthcheckexample 'dotnet:2.2~https://github.com/tanaka-takayoshi/HealthCheckExample.git' --build-env DOTNET_STARTUP_PROJECT=HealthCheckExample $ oc expose svc/healthcheckexample

After the deployment configuration is created, you can enable health checks in the OpenShift web console.

If you edit the deploymentconfig YAML file, the probes should be the following.

spec: ... template: ... spec: containers: - image: >- ... livenessProbe: failureThreshold: 3 httpGet: path: /health/live port: 8080 scheme: HTTP periodSeconds: 10 successThreshold: 1 timeoutSeconds: 1 readinessProbe: failureThreshold: 3 httpGet: path: /health/ready port: 8080 scheme: HTTP periodSeconds: 10 successThreshold: 1 timeoutSeconds: 1 ...

Now, here is the application status in the web console.

First, let’s make the readiness probe unhealthy. Soon after that, you can see in the monitoring page of the web console that the readiness check has failed.





You can see the same thing by using the oc get event -w command.

When the readiness check fails, the pod is still running but it stops routing the traffic. Since this application has only one pod, you can’t access the application.

You can easily scale up this application by clicking the upper arrow next to the number of the pods.

Now, since one of the two pods is healthy, you can access the application.

Next, scale down the app to one pod and make the liveness probe unhealthy.





When the liveness probe fails, the pod is killed and a new one is created. You can see the sequence of events.

Summary

In this article, I described how the Health Checks API in ASP.NET Core 2.2 works with OpenShift (Kubernetes) probes. You can define your appropriate logic in a class that implements the IHealthCheck interface. The readiness probe can be used when the pod is ready to serve the request. The liveness probe can be used when the pod is running.

Other resources