/IngressMonitorController

A kubernetes controller to watch your ingresses and create liveness alerts for your endpoints

Primary LanguageGoApache License 2.0Apache-2.0

Ingress Monitor Controller

Get started with Stakater

Problem Statement

How do I get notified if any of my services is down?

We want to get notified in a slack channel & email if any of our services become unhealthy!

We want to monitor ingresses in a kubernetes cluster via any uptime checker but the problem is to manually check for new ingresses / removed ingresses and add them to the checker or remove them. There isn't any out of the box solution for this as of now.

Solution

This controller will continuously watch ingresses in the namespace it is running, and automatically add / remove monitors in any of the uptime checkers. With the help of this solution, you can keep a check on your services and see whether they're up and running and live.

Supported Uptime Checkers

Currently we support the following monitors:

Deploying to Kubernetes

Vanilla Manifests

You have to first clone or download the repository contents. The kubernetes deployment and files are provided inside kubernetes/manifests folder.

Enabling

By default, the controller ignores the ingresses without a specific annotation on it. You will need to add the following annotation on your ingresses so that the controller is able to recognize and monitor the ingresses.

"monitor.stakater.com/enabled": "true"

The annotation key is monitor.stakater.com/enabled and you can toggle the value of this annotation between true and false to enable or disable monitoring of that specific ingress.

Configuring

First of all you need to modify configmap.yaml's config.yaml file. Following are the available options that you can use to customize the controller:

Key Description
providers An array of uptime providers that you want to add to your controller
enableMonitorDeletion A safeguard flag that is used to enable or disable monitor deletion on ingress deletion (Useful for prod environments where you don't want to remove monitor on ingress deletion)

For the list of providers, there's a number of options that you need to specify. The table below lists them:

Key Description
name Name of the provider (From the list of supported uptime checkers)
apiKey ApiKey of the provider
apiURL Base url of the ApiProvider
alertContacts A - separated list of contact id's that you want to add to the monitors

Note: Follow this guide to see how to fetch alertContacts from UpTimeRobot

Deploying

You can deploy the controller in the namespace you want to monitor by running the following kubectl commands:

kubectl apply -f configmap.yaml -n <namespace>
kubectl apply -f rbac.yaml -n <namespace>
kubectl apply -f deployment.yaml -n <namespace>

Note: Before applying rbac.yaml, You need to modify the namespace in the RoleBinding subjects section to the namespace you want to apply rbac.yaml to.

Helm Charts

Or alternatively if you configured helm on your cluster, you can deploy the controller via helm chart located under kubernetes/chart folder.

Adding support for a new Monitor

You can easily implement a new monitor and use it via the controller. First of all, you will need to create a new service struct that implements the following monitor service interface

type MonitorService interface {
    GetAll() []Monitor
    Add(m Monitor)
    Update(m Monitor)
    GetByName(name string) (*Monitor, error)
    Remove(m Monitor)
    Setup(apiKey string, url string, alertContacts string)
}

Once the implementation of your service is done, you have to open up monitor-proxy.go and add a new case inside OfType method for your new monitor. Lets say you have named your service MyNewMonitorService, then you have to add the case like in the example below:

func (mp *MonitorServiceProxy) OfType(mType string) MonitorServiceProxy {
    mp.monitorType = mType
    switch mType {
    case "UptimeRobot":
        mp.monitor = &UpTimeMonitorService{}
    case "MyNewMonitor":
        mp.monitor = &MyNewMonitorService{}
    default:
        log.Panic("No such provider found")
    }
    return *mp
}

Note that the name you specify here for the case will be the key for your new monitor which you can add it in ConfigMap.

Also in case of handling custom api objects for the monitor api, you can create mappers that map from the api objects to the generic Monitor objects. The way you have to create these is to create a file named monitorname-mappers.go and add mapping functions in that file. An example of a mapping function is found below:

func UptimeMonitorMonitorToBaseMonitorMapper(uptimeMonitor UptimeMonitorMonitor) *Monitor {
    var m Monitor

    m.name = uptimeMonitor.FriendlyName
    m.url = uptimeMonitor.URL
    m.id = strconv.Itoa(uptimeMonitor.ID)

    return &m
}

Help

Got a question? File a GitHub issue, or send us an email.

Talk to us on Slack

Join and talk to us on the #tools-imc channel for discussing the Ingress Monitor Controller

Join Slack Chat

Contributing

Bug Reports & Feature Requests

Please use the issue tracker to report any bugs or file feature requests.

Developing

PRs are welcome. In general, we follow the "fork-and-pull" Git workflow.

  1. Fork the repo on GitHub
  2. Clone the project to your own machine
  3. Commit changes to your own branch
  4. Push your work back up to your fork
  5. Submit a Pull request so that we can review your changes

NOTE: Be sure to merge the latest from "upstream" before making a pull request!

Changelog

View our closed Pull Requests.

License

Apache2 © Stakater

About

The IngressMonitorController is maintained by Stakater. Like it? Please let us know at hello@stakater.com

See our other projects or contact us in case of professional services and queries on hello@stakater.com

Contributers

Waseem Hassan Hazim Rasheed Amir
Waseem Hassan Hazim Rasheed Amir