Self-hosted service
stakater/IngressMonitorController avatar
stakater/IngressMonitorController

IngressMonitorController keeps uptime monitors in step with your ingresses

A Kubernetes controller to watch ingresses and create liveness alerts for your apps/microservices in UptimeRobot, StatusCake, Pingdom, etc. – [✩Star] if you're using it!

748 stars123 forksGoApache-2.0

At a glance

What is it?
The Stakater Ingress Monitor Controller is a Kubernetes operator that watches ingresses and OpenShift routes and creates and removes the matching monitors in services like UptimeRobot and Pingdom, so the two lists cannot drift apart.
Who is it for?
IngressMonitorController suits a platform team running many ingresses across several clouds who has to keep external uptime checks in step with what is actually deployed, and it suits OpenShift users for whom the route objects are the thing to watch.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 24, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem is a list on a dashboard that nobody maintains

The stated problem is narrow and real. You want to monitor ingresses in a Kubernetes cluster and routes in an OpenShift cluster through any uptime checker, but the problem is having to manually check for new ingresses or routes and removed ones and add them to the checker or remove them. The readme also puts the burden in the other direction, that the operator has to check for new or removed ingresses and routes and add or remove them, and that the operator is not being updated for a long time, and that the operator is still not being updated and has not had any updates for a long time. The solution is a controller that continuously watches ingresses and routes based on a defined EndpointMonitor custom resource and automatically adds and removes monitors in any of the uptime checkers. The value is not the checking, since the checking service already exists, it is that the list of what is being checked stays correct without a person editing it.

Eight checker backends, each with its own configuration file

The supported uptime checkers are listed with a link to a per-provider configuration document for each one. They are UptimeRobot, Pingdom, which is noted as not fully tested, StatusCake, Uptime, Updown, Application Insights, gcloud for Google Cloud Monitoring uptime checks, and Grafana through its synthetic monitoring app. The provider list is matched by the dependencies in the go.mod, which include the StatusCake Go client, an Updown client, two Pingdom clients, the Azure SDK for Application Insights, the Google monitoring API, and both the Grafana synthetic monitoring agent and its API client. The Grafana case is the unusual one, since it is not a hosted checker but a synthetic monitoring agent you run, which makes the operator more of a config generator than an API caller in that case.

The EndpointMonitor resource points at a URL or at a cluster object

The custom resource is apiVersion endpointmonitor.stakater.com/v1alpha1, kind EndpointMonitor, and it comes in three shapes. The first specifies a url directly.

yaml
apiVersion: endpointmonitor.stakater.com/v1alpha1
kind: EndpointMonitor
metadata:
  name: stakater
spec:
  forceHttps: true
  url: https://stakater.com

The second references a route by name.

yaml
apiVersion: endpointmonitor.stakater.com/v1alpha1
kind: EndpointMonitor
metadata:
  name: frontend
spec:
  forceHttps: true
  urlFrom:
    routeRef:
      name: frontend

The third references an ingress, with the same shape but an ingressRef key. The distinction matters operationally, because a resource with a direct url is a fixed endpoint that the controller will not update when your ingress moves, while a resource with a reference follows the object, and the operator exists for the second case. The forceHttps flag is the only field in the spec shown here, and provider specific additional configuration is handled outside the resource, in the docs directory.

Provider credentials live in a base64 secret, not in the resource

The controller configuration is not in the custom resource. You configure the uptime checker in a config.yaml, base64 encode it, and store it in a secret named imc-config.

yaml
kind: Secret
apiVersion: v1
metadata:
  name: imc-config
data:
  config.yaml: >-
    <BASE64_ENCODED_CONFIG.YAML>
type: Opaque

The secret name can be changed with the CONFIG_SECRET_NAME environment variable, and sample config.yaml files for each provider are in the examples/configs directory. The controller-level options then live in that same file. The providers array lists the uptime providers to add to the controller. enableMonitorDeletion is a safeguard flag to enable or disable monitor deletion on ingress deletion, and the readme explains why you would want it off in production environments where you do not want the monitor removed when the ingress is deleted. resyncPeriod is a period in seconds that re-syncs the monitors with the routes and defaults to 0, meaning disabled. creationDelay is a duration string that delays creating a new monitor, for example to let DNS catch up first. And monitorNameTemplate is the template for the monitor name, with the example given as {{.Namespace}}-{{.Name}}.

Two install paths and three environment variables

The Helm path installs the CRDs first and then the chart, and the CRD is applied from a raw GitHub URL.

sh
# Install CRDs
kubectl apply -f https://raw.githubusercontent.com/stakater/IngressMonitorController/master/charts/ingressmonitorcontroller/crds/endpointmonitor.stakater.com_endpointmonitors.yaml

# Install chart
helm repo add stakater https://stakater.github.io/stakater-charts

helm repo update

helm install stakater/ingressmonitorcontroller

The vanilla path is to clone the repository and run make deploy to deploy the dependencies, the CRDs. The three environment variables are WATCH_NAMESPACE, which is the namespace the operator is deployed in and takes a comma separated list of namespaces or an empty value to watch all namespaces in cluster scope, CONFIG_SECRET_NAME which defaults to im-config and holds the name of the secret with the configuration, and REQUEUE_TIME, an integer number of seconds after which the resource should be reconciled again, defaulting to 300 seconds. The repository root also has a bundle.Dockerfile and a bundle/ directory for the operator bundle, a Dockerfile for the manager, a Makefile with the usual bundle targets, and a goreleaser configuration.

Where the controller does not help

Three limits are worth naming. The first is that it automates a bookkeeping task, and if you have four ingresses the bookkeeping is a page of configuration, so the operator is overhead until the ingress count grows. The second is the split of configuration across two places. The custom resource says which endpoint to watch and how to name it, while the provider credentials and the checker specific settings live in a base64 blob in a secret, so changing a checker setting means editing a file, encoding it and updating a secret, rather than editing a resource in the cluster with kubectl apply. The third is what a monitor actually checks. The operator creates and removes entries in an external service, and it does not know whether your service is healthy, only that an ingress exists, so the alert quality is still the uptime checker's business. The readme also notes that Pingdom support is not fully tested, which is a small but real signal about how the provider support is distributed across the list.

Editorial conclusion

IngressMonitorController suits a platform team running many ingresses across several clouds who has to keep external uptime checks in step with what is actually deployed, and it suits OpenShift users for whom the route objects are the thing to watch. It is the wrong tool for a small cluster where a handful of static monitors are easier to maintain by hand, and it is the wrong tool if you need the monitors to carry configuration the custom resource does not model, because provider specific settings live in a separate config file rather than in the resource. Before deploying it, read the configuration parameters carefully, since enableMonitorDeletion, resyncPeriod and creationDelay are the three settings that decide how the controller behaves when a service appears, disappears or moves to a new address. The last push was on 2026-10-17 and the current release is v2.2.13 from 2026-05-06.

Frequently asked questions

What does the IngressMonitorController do?

It is a Kubernetes operator that continuously watches ingresses and OpenShift routes based on an EndpointMonitor custom resource and automatically adds and removes monitors in supported uptime checkers, so you do not have to register and de-register checks by hand as services come and go.

How do I configure the uptime checker credentials for IngressMonitorController?

You write a config.yaml for your provider, base64 encode it, and store it in a secret named imc-config with the encoded value under the config.yaml key. The secret name can be changed with the CONFIG_SECRET_NAME environment variable, and sample config files for each provider are in the examples/configs directory.

Which uptime checkers does the IngressMonitorController support?

UptimeRobot, Pingdom, which is noted as not fully tested, StatusCake, Uptime, Updown, Application Insights, gcloud for Google Cloud Monitoring uptime checks, and Grafana through its synthetic monitoring app. Each has its own configuration document in the docs directory.

Official sources

  1. License: Apache-2.0
  2. Project website
  3. README
  4. Releases
  5. stakater/IngressMonitorController on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/stakater-ingressmonitorcontroller.svg)](https://hysenlabs.com/projects/stakater-ingressmonitorcontroller)

Was this useful?