This repository, offers a Kubernetes Operator that automatically deploys and configures the HealthChecks UI in k8s and also monitors labeled services that expose healthchecks in a given namespace.
The operator also has a namespaced service watcher that can detect new services and report them back to the UI and also tracks services modifications and removals so the UI always represents the latest desired state.
We offer a installer tool for windows and linux, that will install all necessary resources to have your operator up and running in seconds in the healthchecks namespace.
You can download the differente releases from this links:
Note: If you execute the tool with --delete parameters, a resource cleanup will be triggered and all the operator related resources including the crd will be removed.
You can deploy healthchecks operator in your cluster by cloning the repository and applying the yaml definition files:
-
Apply the custom resource definition: healthcheck-crd
kubectl apply -f deploy/operator/crd/healthcheck-crd.yaml
-
Apply the rest of definition yamls
kubectl apply -f ./deploy/operator
The HealthCheck operator definition, has the following fields to be configured:
Field | Description |
---|---|
name | Name of the healthcheck resource |
scope | Cluster / Namespaced |
servicesLabel | The label the operator service watcher will use to detected healthchecks endpoints |
The scope field (Cluster or Namespaced) is mandatory and will specify to the operator whether it should watch for healthchecks services in the same namespace where the UI resource is created or watch to all services in all namespaces.
If you wan't to have different UI's for different namespaced services you should use Namespaced
If you wan't to have a single UI that monitors all the healthchecks from the cluster you should use Cluster
Note: The UI resources created by the operator (deployment, service, configmap, secret, etc) will always be created in the metadata specified namespace.
Field | Description | Default |
---|---|---|
serviceType | How the UI should be published (ClusterIP, LoadBalancer or NodePort) | ClusterIP |
portNumber | What port will be used to expose the UI service | 80 |
uiPath | Location where the UI frontend will be served | /healthchecks |
uiApiPath | Location where the UI backend API will be served | UI defaults |
uiResourcesPath | Location where the UI static files resources will be served | UI defaults |
uiWebhooksPath | Location where the Webhooks api | UI defaults |
uiNoRelativePaths | Disable UI front-end relative paths | false |
healthChecksPath | Path where the UI will collect health from endpoints | /health (Can be overriden with a service annotation) |
healthChecksScheme | Scheme to be used to collect health from endpoints | http (Can be overriden with a service annotation) |
image | Image to be used by the UI | xabarilcoding/healthchecksui:latest |
imagePullPolicy | Deployment image pull policy | Always |
stylesheetContent | css content used to brand the UI | none |
serviceAnnotations | name / value array to use custom annotations in UI service | none |
deploymentAnnotations | name / value array to use custom annotations in UI Deployment | none |
webhooks | webhook array object (name, uri, payload and restoredPayload) | none |
tolerations | toleration array object (key, operator, value, effect and seconds) | none |
Let's start by creating a demo namespace:
kubectl create ns demo
And then, create a healthchecks-ui.yaml file with the following contents:
apiVersion: "aspnetcore.ui/v1"
kind: HealthCheck
metadata:
name: healthchecks-ui
namespace: demo
spec:
name: healthchecks-ui
scope: Namespaced #The UI will be created at specified namespace (demo) and will watch healthchecks services in demo namespace only
#scope: Cluster The UI will be created at specified namespace (demo) but will watch healthcheck services across all namespaces
servicesLabel: HealthChecks
serviceType: LoadBalancer
stylesheetContent: >
:root {
--primaryColor: #2a3950;
--secondaryColor: #f4f4f4;
--bgMenuActive: #e1b015;
--bgButton: #e1b015;
--logoImageUrl: url('https://upload.wikimedia.org/wikipedia/commons/thumb/e/eb/WoW_icon.svg/1200px-WoW_icon.svg.png');
--bgAside: var(--primaryColor);
}
serviceAnnotations:
- name: service.beta.kubernetes.io/azure-load-balancer-internal
value: "true"
Let's apply the HealthCheck definition with the created file:
kubectl apply -f healthchecks-ui.yaml
You can now check your created HealthCheck resource using:
kubectl get healthcheck -n demo
Once you apply a HealthCheck kind resource, the operator will automatically create some resources in the namespace. The UI deployment and service to expose the dashboard, a secret that enables secure communication from the operator to the UI service, and an optional configmap volume source depending if you configured the stylesheetContent branding.
All this resources are created using OwnerReferences so that means if you delete the HealthCheck resource, all the child resources will be automatically purged with it.
The operator also starts services watchers per namespace that will monitor creation, modification of labels and annotations and also services themselves. If a monitored application is added or removed and has the HealthChecks label annotation, the UI will automatically react to this events.
The next step is creating an AspNetCore core uses some HealthChecks. We are going to use a sample app that is already deployed in dockerhub (carloslanderas/hc-website) using the following code:
using HealthChecks.UI.Client;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.HealthChecks;
namespace hc_website
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services
.AddRouting()
.AddHealthChecks()
.AddProcessAllocatedMemoryHealthCheck(maximumMegabytesAllocated: 50)
.AddCheck("self", () => HealthCheckResult.Healthy());
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health", new HealthCheckOptions
{
Predicate = r => true,
ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
});
});
}
}
}
The next step, is deploying this application using a deployment yaml definition like this:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: hc-website-deploy
namespace: demo
labels:
app: hc-website
spec:
selector:
matchLabels:
app: hc-website
replicas: 1
template:
metadata:
labels:
app: hc-website
spec:
containers:
- name: hc-website
image: carloslanderas/hc-website
imagePullPolicy: Always
ports:
- name: http
containerPort: 80
env:
- name: Logging__LogLevel__Default
value: Debug
- name: Logging__LogLevel__Microsoft
value: Warning
- name: Logging__LogLevel__hc_website
value: Debug
---
kind: Service
apiVersion: v1
metadata:
name: hc-website-svc
namespace: demo
labels:
HealthChecks: enabled
spec:
selector:
app: hc-website
type: ClusterIP
ports:
- name: http
port: 80
targetPort: 80
Note the HealthChecks : enabled label to tell the operator this is a healthchecked application:
labels:
HealthChecks: enabled
Create a deployment.yaml
file with above contents and apply it:
kubectl apply -f deployment.yaml
You can use HealthChecksPath
and HealthChecksScheme
annotations in HealthChecks services to override the default Path and Scheme crd definition.
Once you applied the HealthCheck definition, the operator has automatically created some resources to setup your UI service and you can now access the healthchecks dashboard after inspecting it's address:
kubectl get svc -n demo
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hc-website-svc ClusterIP 10.0.145.224 80/TCP 16h
healthchecks-ui-svc LoadBalancer 10.0.20.73 51.138.24.168 80:31343/TCP 16h
Your UI endpoint will be listening in http://51.138.24.168/healthchecks and the labeled service should appear automatically.
You can configure webhook notifications by using the webhooks yaml array element. Each webhook definition requires a name, a uri and unhealthy notification and restore payloads.
The UI hosted service will automatically trigger configured webhooks with the defined payload
whenever a healthcheck reports unhealthy and will use restoredPayload
to notify the healthcheck is up and running again.
apiVersion: "aspnetcore.ui/v1"
kind: HealthCheck
metadata:
name: healthchecks-ui
spec:
name: healthchecks-ui
servicesLabel: HealthChecks
stylesheetContent: >
:root {
--primaryColor: #0f519f;
--secondaryColor: #f4f4f4;
--bgMenuActive: #0f519f;
--bgButton: #0f519f;
--bgAside: var(--primaryColor);
}
webhooks:
- name: requestcatcher1
uri: https://healthchecks.requestcatcher.com
payload: '{ message: "Webhook report for [[LIVENESS]]: [[FAILURE]] - Description: [[DESCRIPTIONS]]"}'
restoredPayload: '{ message: "[[LIVENESS]] is back to life"}'
- name: requestcatcher2
uri: https://healthchecks2.requestcatcher.com
payload: '{ message: "Webhook report for [[LIVENESS]]: [[FAILURE]] - Description: [[DESCRIPTIONS]]"}'
restoredPayload: '{ message: "[[LIVENESS]] is back to life"}'
Once your webhooks are specified in the yaml definition, you can check if they are correctly configured in the UI webhooks section: