Several changes:

- Rename ExcludeSuffix to ExcludedServiceSuffixes
- Rename ServiceSuffix to HostnameSuffix
- Rename HealthAPI to TargetPath
- Add ExcludedServices
This commit is contained in:
TwinProduction 2020-11-11 16:29:30 -05:00
parent a658100da4
commit 3a0a8db898
5 changed files with 99 additions and 60 deletions

View File

@ -22,7 +22,8 @@ core applications: https://status.twinnation.org/
- [Conditions](#conditions)
- [Placeholders](#placeholders)
- [Functions](#functions)
- [Kubernetes Autodiscovery](#kubernetes-autodiscovery)
- [Kubernetes](#kubernetes-alpha)
- [Auto Discovery](#auto-discovery)
- [Alerting](#alerting)
- [Configuring Slack alerts](#configuring-slack-alerts)
- [Configuring PagerDuty alerts](#configuring-pagerduty-alerts)
@ -49,7 +50,7 @@ The main features of Gatus are:
- **Alerting**: While having a pretty visual dashboard is useful to keep track of the state of your application(s), you probably don't want to stare at it all day. Thus, notifications via Slack, PagerDuty and Twilio are supported out of the box with the ability to configure a custom alerting provider for any needs you might have, whether it be a different provider or a custom application that manages automated rollbacks.
- **Metrics**
- **Low resource consumption**: As with most Go applications, the resource footprint that this application requires is negligibly small.
- Auto discover services in Kubernetes.
- **Service auto discovery in Kubernetes** (ALPHA)
## Usage
@ -126,6 +127,8 @@ Note that you can also add environment variables in the configuration file (i.e.
| `security.basic.password-sha512` | Password's SHA512 hash for Basic authentication | Required `""` |
| `disable-monitoring-lock` | Whether to [disable the monitoring lock](#disable-monitoring-lock) | `false` |
For Kubernetes configuration, see [Kubernetes](#kubernetes-alpha)
### Conditions
@ -170,33 +173,6 @@ Here are some examples of conditions you can use:
**NOTE**: Use `pat` only when you need to. `[STATUS] == pat(2*)` is a lot more expensive than `[STATUS] < 300`.
### Kubernetes Autodiscovery
Autodiscovery works by reading all `Service` object from the configured `Namespaces` and appending the `Suffix` and configured `health-api` to the Service name and making an http call.
All auto-discovered services will have the service configuration populated from the `service-template`.
You Can exclude certain services from the dashboard by using the `exclude-suffix`.
```yaml
kubernetes:
cluster-mode: "out"
auto-discover: true
service-suffix: ".services.svc.cluster.local"
exclude-suffix:
- primary
- canary
service-template:
interval: 30s
conditions:
- "[STATUS] == 200"
namespaces:
- name: website
service-suffix: "website.svc.cluster.local"
health-api: "/health"
- name: services
service-suffix: "services.svc.cluster.local"
health-api: "/health"
```
### Alerting
@ -329,6 +305,57 @@ services:
- "[RESPONSE_TIME] < 300"
```
### Kubernetes (ALPHA)
> **WARNING**: This feature is in ALPHA. This means that it is very likely to change in the near future, which means that
> while you can use this feature as you see fit, there may be breaking changes in future releases.
| Parameter | Description | Default |
|:------------------------------------------- |:----------------------------------------------------------------------------- |:-------------- |
| `kubernetes` | Kubernetes configuration | `{}` |
| `kubernetes.auto-discover` | Whether to enable auto discovery | `false` |
| `kubernetes.cluster-mode` | Cluster mode to use for authenticating. Supported values: `in`, `out` | Required `` |
| `kubernetes.service-template` | Service template. See `services[]` in [Configuration](#configuration) | Required `nil` |
| `kubernetes.excluded-service-suffixes` | List of service suffixes to not monitor (e.g. `canary`) | `[]` |
| `kubernetes.namespaces` | List of configurations for the namespaces from which services will be discovered | `[]` |
| `kubernetes.namespaces[].name` | Namespace name | Required `` |
| `kubernetes.namespaces[].hostname-suffix` | Suffix to append to the service name before calling `target-path` | Required `` |
| `kubernetes.namespaces[].target-path` | Path that will be called on the discovered service for the health check | `` |
| `kubernetes.namespaces[].excluded-services` | List of services to not monitor in the given namespace | `[]` |
#### Auto Discovery
Auto discovery works by reading all `Service` resources from the configured `namespaces` and appending the `hostname-suffix` as
well as the configured `target-path` to the service name and making an HTTP call.
All auto-discovered services will have the service configuration populated from the `service-template`.
You can exclude certain services from the dashboard by using `kubernetes.excluded-service-suffixes` or `kubernetes.namespaces[].excluded-services`.
```yaml
kubernetes:
auto-discover: true
cluster-mode: "out"
excluded-service-suffixes:
- canary
service-template:
interval: 30s
conditions:
- "[STATUS] == 200"
namespaces:
- name: default
hostname-suffix: ".default.svc.cluster.local"
target-path: "/health"
excluded-services:
- gatus
- kubernetes
```
Note that `hostname-suffix` could also be something like `.yourdomain.com`, in which case the endpoint that would be
monitored would be `potato.example.com/health`, assuming you have a service named `potato` and a matching ingress
to map `potato.example.com` to the `potato` service.
## Docker

View File

@ -18,7 +18,7 @@ services:
kubernetes:
cluster-mode: "out"
auto-discover: true
exclude-suffix:
excluded-service-suffixes:
- primary
- canary
service-template:
@ -27,5 +27,9 @@ kubernetes:
- "[STATUS] == 200"
namespaces:
- name: default
service-suffix: "default.svc.cluster.local"
health-api: "/health"
hostname-suffix: ".default.svc.cluster.local"
target-path: "/health"
excluded-services:
- gatus
- kubernetes
- twinnation

View File

@ -62,6 +62,7 @@ type Config struct {
// Services List of services to monitor
Services []*core.Service `yaml:"services"`
// Kubernetes is the Kubernetes configuration
Kubernetes *k8s.Config `yaml:"kubernetes"`
}

View File

@ -7,29 +7,32 @@ type Config struct {
// AutoDiscover to discover services to monitor
AutoDiscover bool `yaml:"auto-discover"`
// ServiceTemplate Template for auto discovered services
ServiceTemplate *core.Service `yaml:"service-template"`
// ExcludeSuffix is a slice of service suffixes that should be ignored
ExcludeSuffix []string `yaml:"exclude-suffix"`
// ClusterMode to authenticate with kubernetes
// ClusterMode is the mode to use to authenticate with Kubernetes
ClusterMode ClusterMode `yaml:"cluster-mode"`
// Namespaces from which to discover services
// ServiceTemplate is the template for auto discovered services
ServiceTemplate *core.Service `yaml:"service-template"`
// ExcludedServiceSuffixes is a list of service suffixes that should be ignored
ExcludedServiceSuffixes []string `yaml:"excluded-service-suffixes"`
// Namespaces is a list of configurations for the namespaces from which services will be discovered
Namespaces []*NamespaceConfig `yaml:"namespaces"`
}
// NamespaceConfig level config
type NamespaceConfig struct {
// Name of namespace
// Name of the namespace
Name string `yaml:"name"`
// ServiceSuffix to append to service name
ServiceSuffix string `yaml:"service-suffix"`
// ExcludedServices is a list of services to exclude from the auto discovery
ExcludedServices []string `yaml:"excluded-services"`
// HealthAPI URI to append to service to reach health check API
HealthAPI string `yaml:"health-api"`
// HostnameSuffix is a suffix to append to each service name before calling TargetPath
HostnameSuffix string `yaml:"hostname-suffix"`
// TargetPath Path to append after the HostnameSuffix
TargetPath string `yaml:"target-path"`
}
// ClusterMode is the mode to use to authenticate to Kubernetes

View File

@ -19,13 +19,27 @@ func DiscoverServices(kubernetesConfig *Config) ([]*core.Service, error) {
if err != nil {
return nil, err
}
for _, s := range kubernetesServices {
if isExcluded(kubernetesConfig.ExcludeSuffix, s.Name) {
continue
skipExcluded:
for _, service := range kubernetesServices {
for _, excludedServiceSuffix := range kubernetesConfig.ExcludedServiceSuffixes {
if strings.HasSuffix(service.Name, excludedServiceSuffix) {
continue skipExcluded
}
}
for _, excludedService := range ns.ExcludedServices {
if service.Name == excludedService {
continue skipExcluded
}
}
var url string
if strings.HasPrefix(ns.TargetPath, "/") {
url = fmt.Sprintf("http://%s%s%s", service.Name, ns.HostnameSuffix, ns.TargetPath)
} else {
url = fmt.Sprintf("http://%s%s/%s", service.Name, ns.HostnameSuffix, ns.TargetPath)
}
services = append(services, &core.Service{
Name: s.Name,
URL: fmt.Sprintf("http://%s%s/%s", s.Name, ns.ServiceSuffix, ns.HealthAPI),
Name: service.Name,
URL: url,
Interval: kubernetesConfig.ServiceTemplate.Interval,
Conditions: kubernetesConfig.ServiceTemplate.Conditions,
})
@ -33,13 +47,3 @@ func DiscoverServices(kubernetesConfig *Config) ([]*core.Service, error) {
}
return services, nil
}
// TODO: don't uselessly allocate new things here, just move this inside the DiscoverServices function
func isExcluded(excludeList []string, name string) bool {
for _, x := range excludeList {
if strings.HasSuffix(name, x) {
return true
}
}
return false
}