Compare commits

...

109 Commits

Author SHA1 Message Date
b7aa886546 Namespace external metrics (#259)
Signed-off-by: Mikkel Oscar Lyderik Larsen <mikkel.larsen@zalando.de>
2021-02-19 11:11:29 +01:00
942e753f87 Use Github actions instead of travis (#270)
Signed-off-by: Mikkel Oscar Lyderik Larsen <mikkel.larsen@zalando.de>
2021-02-19 10:31:20 +01:00
86ed6ec102 Merge pull request #269 from zalando-incubator/update-dependencies-2021-02-01
Update dependencies
2021-02-01 18:49:22 +01:00
b313c963b6 Update dependencies
Signed-off-by: Mikkel Oscar Lyderik Larsen <mikkel.larsen@zalando.de>
2021-02-01 10:26:01 +01:00
ca20ef3a3b Merge pull request #256 from zalando-incubator/label-maintainer
Use non-deprecated Dockerfile syntax
2021-01-15 14:56:27 +01:00
f2179846c5 Use non-deprecated Dockerfile syntax
Signed-off-by: Mikkel Oscar Lyderik Larsen <mikkel.larsen@zalando.de>
2021-01-15 14:21:26 +01:00
85089c4773 Merge pull request #253 from tanersener/master
Fix the namespace of horizontal-pod-autoscaler service account used in the helm chart
2021-01-14 19:31:02 +01:00
2ac9dd29d8 Fix the namespace of horizontal-pod-autoscaler service account in the helm chart
Signed-off-by: Taner Sener <tanersener@gmail.com>
2021-01-13 14:54:43 +00:00
2bfc85ff3d Merge pull request #251 from zalando-incubator/fix-aws-collector
Don't check for metric name on AWS init
2021-01-05 16:49:31 +01:00
d55a551bd8 Don't check for metric name on AWS init
Signed-off-by: Mikkel Oscar Lyderik Larsen <mikkel.larsen@zalando.de>
2021-01-05 11:52:44 +01:00
3174100f5a Merge pull request #250 from zalando-incubator/base-image
Switch to compliant base image
2021-01-05 09:03:47 +01:00
16808f012d Switch to compliant base image
Use compliant base image according to our tech rules of play:
- KDP-1: use an approved Docker base image and version from the list of
    allowed Docker Base Images under the pierone namespace ‘library’.

Signed-off-by: Jonathan Juares Beber <jonathanbeber@gmail.com>
2021-01-05 08:57:15 +01:00
2531ddcbe3 Merge pull request #238 from tanersener/master
Add a kubernetes helm chart
2021-01-04 16:07:52 +01:00
8ff2e3985b keep non-helm deployment files
Signed-off-by: Taner Sener <tanersener@gmail.com>
2021-01-04 13:11:33 +00:00
dab5a66556 Update dependencies (#249)
Signed-off-by: Mikkel Oscar Lyderik Larsen <mikkel.larsen@zalando.de>
2021-01-04 09:59:04 +01:00
995ec54aa5 re-organize helm deployment files as a helm chart
Signed-off-by: Taner Sener <tanersener@gmail.com>
2020-12-19 10:12:33 +00:00
6f71e9c6b0 Merge pull request #236 from zalando-incubator/update-deps-2020-12-01
Update dependencies
2020-12-01 12:42:34 +01:00
ed16830a77 Update dependencies
Signed-off-by: Mikkel Oscar Lyderik Larsen <mikkel.larsen@zalando.de>
2020-12-01 11:16:09 +01:00
7f84bc75f4 UPDATED to use NewSessionWithConfig instead of NewSession (#230)
NewSession is being deprecated, NewSessionWithConfig handles things
such as role arns. This fixes permissions issues for users using
role arns for service accounts.

Signed-off-by: Ewan Valentine <ewan.valentine89@gmail.com>
2020-11-21 19:49:49 +01:00
b5fbb1beae Merge pull request #228 from zalando-incubator/prometheus-fix-query-mapping
Fix mapping of Prometheus query for new metric configuration
2020-11-16 17:52:56 +01:00
4506701b7c Fix mapping of Prometheus query for new metric configuration
Signed-off-by: Mikkel Oscar Lyderik Larsen <mikkel.larsen@zalando.de>
2020-11-16 17:44:06 +01:00
df0ed1fca4 Use labels for mapping metric types to metrics (#219)
* Use labels for mapping metric types to metrics

Signed-off-by: Mikkel Oscar Lyderik Larsen <mikkel.larsen@zalando.de>

* Log warning when old format is used

Signed-off-by: Mikkel Oscar Lyderik Larsen <mikkel.larsen@zalando.de>

* Test NewCollector logic for external metrics

Signed-off-by: Mikkel Oscar Lyderik Larsen <mikkel.larsen@zalando.de>
2020-11-04 20:40:53 +01:00
bb107b678c Merge pull request #224 from zalando-incubator/update-deps-2020-11-02
Update dependencies
2020-11-02 09:56:51 +01:00
8d7dc13bbd Update dependencies
Signed-off-by: Mikkel Oscar Lyderik Larsen <mikkel.larsen@zalando.de>
2020-11-02 09:04:08 +01:00
20f0042017 Merge pull request #217 from zalando-incubator/fix-openapi
Fix openapi serving
2020-10-27 11:27:07 +01:00
c732851b6b Fix openapi serving
Signed-off-by: Mikkel Oscar Lyderik Larsen <mikkel.larsen@zalando.de>
2020-10-27 10:43:16 +01:00
2e09132f95 [prom collector ] Documenting scrape interval (#215)
There is a way to configure scrape interval

Signed-off-by: Muaaz Saleem <muhammad.muaaz.saleem@zalando.de>
2020-10-26 17:37:24 +01:00
95f22dc398 Bump github.com/aws/aws-sdk-go from 1.35.0 to 1.35.13 (#212)
Bumps [github.com/aws/aws-sdk-go](https://github.com/aws/aws-sdk-go) from 1.35.0 to 1.35.13.
- [Release notes](https://github.com/aws/aws-sdk-go/releases)
- [Changelog](https://github.com/aws/aws-sdk-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-go/compare/v1.35.0...v1.35.13)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-10-26 10:31:24 +01:00
eed5c78fb3 Use upstream version of custom-metrics-apiserver (#211)
Signed-off-by: Mikkel Oscar Lyderik Larsen <mikkel.larsen@zalando.de>
2020-10-23 10:51:10 +02:00
e61071a36d Merge pull request #164 from zalando-incubator/openapi-fork
Use OpenAPI spec fork
2020-10-06 22:30:46 +02:00
c108fab55a Use OpenAPI spec fork
Signed-off-by: Mikkel Oscar Lyderik Larsen <mikkel.larsen@zalando.de>
2020-10-02 11:06:21 +02:00
be7567efea Fix handling of invalid/empty json response (#209)
Signed-off-by: Mikkel Oscar Lyderik Larsen <mikkel.larsen@zalando.de>
2020-10-02 10:57:53 +02:00
b677e814be Update dependencies (#200)
Signed-off-by: Mikkel Oscar Lyderik Larsen <mikkel.larsen@zalando.de>
2020-10-02 10:55:42 +02:00
deec4727ee Merge pull request #192 from zalando-incubator/extend-jsonpath-support
Support bracket notation in jsonPath
2020-09-30 12:18:39 +02:00
cf369639d8 Support bracket notation in jsonPath
Signed-off-by: Mikkel Oscar Lyderik Larsen <mikkel.larsen@zalando.de>
2020-08-13 09:51:05 +02:00
262a35c2ec Merge pull request #177 from zalando-incubator/update-deps
Update dependencies
2020-07-15 17:45:01 +02:00
607386834b Update dependencies
Signed-off-by: Mikkel Oscar Lyderik Larsen <mikkel.larsen@zalando.de>
2020-07-15 17:00:13 +02:00
4bdce4da4d Merge pull request #176 from zalando-incubator/ingress-weights-float64
Correctly treat ingress weight values as float64
2020-07-15 16:56:33 +02:00
801e5d7a47 Correctly treat ingress weight values as float64
Signed-off-by: Mikkel Oscar Lyderik Larsen <mikkel.larsen@zalando.de>
2020-07-15 15:42:59 +02:00
4df21ae2b4 Merge pull request #174 from zalando-incubator/dependabot/add-v2-config-file
Create Dependabot config file
2020-07-10 13:31:55 +02:00
7f639baeee Create Dependabot config file 2020-07-10 09:49:34 +00:00
88ddb6f10e Merge pull request #173 from zalando-incubator/arjun-has-left-the-zalando
Update MAINTAINERS
2020-07-01 15:14:25 +02:00
d9cf2e0858 Update MAINTAINERS
Signed-off-by: Arjun Naik <arjun@arjunnaik.in>
2020-07-01 15:04:31 +02:00
c3b18e784b Update client-go (#162)
Signed-off-by: Mikkel Oscar Lyderik Larsen <mikkel.larsen@zalando.de>
2020-06-27 18:39:12 +02:00
c3a03fd758 Merge pull request #157 from zalando-incubator/dependabot/go_modules/github.com/aws/aws-sdk-go-1.31.7
Bump github.com/aws/aws-sdk-go from 1.30.24 to 1.31.7
2020-06-02 09:43:49 +02:00
05704c0a6b Merge pull request #158 from zalando-incubator/dependabot/go_modules/github.com/stretchr/testify-1.6.0
Bump github.com/stretchr/testify from 1.5.1 to 1.6.0
2020-06-02 09:43:27 +02:00
f3a608fcf7 Merge pull request #159 from zalando-incubator/dependabot/go_modules/github.com/prometheus/common-0.10.0
Bump github.com/prometheus/common from 0.9.1 to 0.10.0
2020-06-02 09:43:03 +02:00
223ec9fd89 Bump github.com/prometheus/common from 0.9.1 to 0.10.0
Bumps [github.com/prometheus/common](https://github.com/prometheus/common) from 0.9.1 to 0.10.0.
- [Release notes](https://github.com/prometheus/common/releases)
- [Commits](https://github.com/prometheus/common/compare/v0.9.1...v0.10.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-01 10:47:03 +00:00
81255aa956 Bump github.com/stretchr/testify from 1.5.1 to 1.6.0
Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.5.1 to 1.6.0.
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.5.1...v1.6.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-01 10:46:34 +00:00
dac44965e3 Bump github.com/aws/aws-sdk-go from 1.30.24 to 1.31.7
Bumps [github.com/aws/aws-sdk-go](https://github.com/aws/aws-sdk-go) from 1.30.24 to 1.31.7.
- [Release notes](https://github.com/aws/aws-sdk-go/releases)
- [Changelog](https://github.com/aws/aws-sdk-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-go/compare/v1.30.24...v1.31.7)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-06-01 10:46:23 +00:00
dbed1570ba Merge pull request #156 from zalando-incubator/networking.k8s.io
Add support for Ingress of API Group networking.k8s.io
2020-05-26 15:09:18 +02:00
ef24244074 Add support for networking.k8s.io
Signed-off-by: Mikkel Oscar Lyderik Larsen <mikkel.larsen@zalando.de>
2020-05-26 14:47:46 +02:00
cadf2dff3c Merge pull request #153 from doyshinda/custom_timeouts
Add support for custom timeouts
2020-05-18 10:27:17 +02:00
db83268343 Merge pull request #150 from zalando-incubator/dependabot/go_modules/github.com/aws/aws-sdk-go-1.30.24
Bump github.com/aws/aws-sdk-go from 1.30.19 to 1.30.24
2020-05-18 10:25:50 +02:00
78c2ef742b Merge pull request #152 from doyshinda/parallel_get_metrics
Fetch pod metrics in parallel
2020-05-18 09:26:14 +02:00
f0b817629c Add support for custom timeouts
Allow configuration per metric for connect and request timeouts
when querying pods for JSON metrics.

Signed-off-by: Abe Friesen <2319792+doyshinda@users.noreply.github.com>
2020-05-16 07:15:58 -06:00
3e7b66070c Fetch pod metrics in parallel
Fetching metrics from pods sequentially, with a large number of
pods, can result in poor performance when some of those pods have
been terminated by the HPA in a normal scale down event.

Signed-off-by: Abe Friesen <2319792+doyshinda@users.noreply.github.com>
2020-05-16 06:47:13 -06:00
f3d33b6132 Bump github.com/aws/aws-sdk-go from 1.30.19 to 1.30.24
Bumps [github.com/aws/aws-sdk-go](https://github.com/aws/aws-sdk-go) from 1.30.19 to 1.30.24.
- [Release notes](https://github.com/aws/aws-sdk-go/releases)
- [Changelog](https://github.com/aws/aws-sdk-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-go/compare/v1.30.19...v1.30.24)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-11 10:18:26 +00:00
7b7af889fb Merge pull request #148 from zalando-incubator/dependabot/go_modules/github.com/aws/aws-sdk-go-1.30.19
Bump github.com/aws/aws-sdk-go from 1.30.14 to 1.30.19
2020-05-06 12:45:54 +02:00
2bcaa80ce0 Merge pull request #147 from zalando-incubator/dependabot/go_modules/github.com/prometheus/client_golang-1.6.0
Bump github.com/prometheus/client_golang from 1.5.1 to 1.6.0
2020-05-06 12:45:46 +02:00
a2e6980b25 Merge pull request #146 from zalando-incubator/dependabot/go_modules/github.com/sirupsen/logrus-1.6.0
Bump github.com/sirupsen/logrus from 1.5.0 to 1.6.0
2020-05-06 12:45:23 +02:00
f0783dcdd8 Bump github.com/aws/aws-sdk-go from 1.30.14 to 1.30.19
Bumps [github.com/aws/aws-sdk-go](https://github.com/aws/aws-sdk-go) from 1.30.14 to 1.30.19.
- [Release notes](https://github.com/aws/aws-sdk-go/releases)
- [Changelog](https://github.com/aws/aws-sdk-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-go/compare/v1.30.14...v1.30.19)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-04 09:59:27 +00:00
560fb40dae Bump github.com/prometheus/client_golang from 1.5.1 to 1.6.0
Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.5.1 to 1.6.0.
- [Release notes](https://github.com/prometheus/client_golang/releases)
- [Changelog](https://github.com/prometheus/client_golang/blob/master/CHANGELOG.md)
- [Commits](https://github.com/prometheus/client_golang/compare/v1.5.1...v1.6.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-04 09:58:05 +00:00
41229e370d Bump github.com/sirupsen/logrus from 1.5.0 to 1.6.0
Bumps [github.com/sirupsen/logrus](https://github.com/sirupsen/logrus) from 1.5.0 to 1.6.0.
- [Release notes](https://github.com/sirupsen/logrus/releases)
- [Changelog](https://github.com/sirupsen/logrus/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sirupsen/logrus/compare/v1.5.0...v1.6.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-05-04 09:57:46 +00:00
338393c11e Merge pull request #145 from zalando-incubator/dependabot/go_modules/github.com/aws/aws-sdk-go-1.30.14
Bump github.com/aws/aws-sdk-go from 1.30.9 to 1.30.14
2020-05-02 21:28:27 +02:00
8e7d1bc0d6 Bump github.com/aws/aws-sdk-go from 1.30.9 to 1.30.14
Bumps [github.com/aws/aws-sdk-go](https://github.com/aws/aws-sdk-go) from 1.30.9 to 1.30.14.
- [Release notes](https://github.com/aws/aws-sdk-go/releases)
- [Changelog](https://github.com/aws/aws-sdk-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-go/compare/v1.30.9...v1.30.14)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-27 10:18:59 +00:00
dc7fb5875b Merge pull request #143 from zalando-incubator/dependabot/go_modules/github.com/aws/aws-sdk-go-1.30.9
Bump github.com/aws/aws-sdk-go from 1.30.7 to 1.30.9
2020-04-21 06:20:06 +02:00
8f70d3493e Bump github.com/aws/aws-sdk-go from 1.30.7 to 1.30.9
Bumps [github.com/aws/aws-sdk-go](https://github.com/aws/aws-sdk-go) from 1.30.7 to 1.30.9.
- [Release notes](https://github.com/aws/aws-sdk-go/releases)
- [Changelog](https://github.com/aws/aws-sdk-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-go/compare/v1.30.7...v1.30.9)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-20 10:00:12 +00:00
97ec13d010 Update Travis to Go 1.14 (#140)
Signed-off-by: Gábor Lipták <gliptak@gmail.com>
2020-04-12 22:54:49 +02:00
5e20dcd961 Merge pull request #139 from zalando-incubator/dependabot/go_modules/github.com/aws/aws-sdk-go-1.30.7
Bump github.com/aws/aws-sdk-go from 1.30.3 to 1.30.7
2020-04-09 15:52:18 +02:00
f27dbc3939 Bump github.com/aws/aws-sdk-go from 1.30.3 to 1.30.7
Bumps [github.com/aws/aws-sdk-go](https://github.com/aws/aws-sdk-go) from 1.30.3 to 1.30.7.
- [Release notes](https://github.com/aws/aws-sdk-go/releases)
- [Changelog](https://github.com/aws/aws-sdk-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-go/compare/v1.30.3...v1.30.7)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-09 08:48:10 +00:00
6443613930 Merge pull request #135 from zalando-incubator/dependabot/go_modules/github.com/aws/aws-sdk-go-1.30.3
Bump github.com/aws/aws-sdk-go from 1.30.2 to 1.30.3
2020-04-03 12:35:00 +02:00
d9c2e50f2c Bump github.com/aws/aws-sdk-go from 1.30.2 to 1.30.3
Bumps [github.com/aws/aws-sdk-go](https://github.com/aws/aws-sdk-go) from 1.30.2 to 1.30.3.
- [Release notes](https://github.com/aws/aws-sdk-go/releases)
- [Changelog](https://github.com/aws/aws-sdk-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-go/compare/v1.30.2...v1.30.3)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-03 08:48:22 +00:00
a8cd761f85 Merge pull request #122 from zalando-incubator/http-collector
Add basic HTTP collector
2020-04-02 14:34:47 +02:00
43fa626ca1 Merge pull request #134 from zalando-incubator/dependabot/go_modules/github.com/aws/aws-sdk-go-1.30.2
Bump github.com/aws/aws-sdk-go from 1.30.0 to 1.30.2
2020-04-02 12:01:48 +02:00
2d3ddc53ef Add and HTTP metrics collector
Signed-off-by: Arjun Naik <arjun.rn@gmail.com>
2020-04-02 11:05:37 +02:00
02880fad2d Bump github.com/aws/aws-sdk-go from 1.30.0 to 1.30.2
Bumps [github.com/aws/aws-sdk-go](https://github.com/aws/aws-sdk-go) from 1.30.0 to 1.30.2.
- [Release notes](https://github.com/aws/aws-sdk-go/releases)
- [Changelog](https://github.com/aws/aws-sdk-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-go/compare/v1.30.0...v1.30.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-04-02 08:34:49 +00:00
405e347620 Merge pull request #132 from zalando-incubator/dependabot/go_modules/github.com/aws/aws-sdk-go-1.30.0
Bump github.com/aws/aws-sdk-go from 1.29.33 to 1.30.0
2020-03-31 19:14:02 +02:00
f15aacad5c Merge pull request #123 from zalando-incubator/dependabot/go_modules/github.com/spf13/cobra-0.0.7
Bump github.com/spf13/cobra from 0.0.6 to 0.0.7
2020-03-31 19:13:31 +02:00
c0a9f525b8 Merge pull request #131 from vetinari/patch-1
fix error to not contain twice the namespace
2020-03-31 19:13:05 +02:00
24207d285c Merge pull request #126 from zalando-incubator/dependabot/go_modules/github.com/prometheus/client_golang-1.5.1
Bump github.com/prometheus/client_golang from 1.0.0 to 1.5.1
2020-03-31 19:12:03 +02:00
860aba807e fix error to not contain twice the namespace
but to contain also the name of the pod

Signed-off-by: Hanno Hecker <hanno@zalando.de>
2020-03-31 10:44:55 +02:00
73659f8ac6 Bump github.com/aws/aws-sdk-go from 1.29.33 to 1.30.0
Bumps [github.com/aws/aws-sdk-go](https://github.com/aws/aws-sdk-go) from 1.29.33 to 1.30.0.
- [Release notes](https://github.com/aws/aws-sdk-go/releases)
- [Changelog](https://github.com/aws/aws-sdk-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-go/compare/v1.29.33...v1.30.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-31 08:42:58 +00:00
280d358538 Bump github.com/prometheus/client_golang from 1.0.0 to 1.5.1
Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.0.0 to 1.5.1.
- [Release notes](https://github.com/prometheus/client_golang/releases)
- [Changelog](https://github.com/prometheus/client_golang/blob/master/CHANGELOG.md)
- [Commits](https://github.com/prometheus/client_golang/compare/v1.0.0...v1.5.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-30 09:50:33 +00:00
735bb164e2 Bump github.com/spf13/cobra from 0.0.6 to 0.0.7
Bumps [github.com/spf13/cobra](https://github.com/spf13/cobra) from 0.0.6 to 0.0.7.
- [Release notes](https://github.com/spf13/cobra/releases)
- [Commits](https://github.com/spf13/cobra/compare/v0.0.6...0.0.7)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-30 09:49:38 +00:00
d28712abd1 Merge pull request #110 from zalando-incubator/update-dependencies
Updated dependencies based on version 1.17
2020-03-27 11:05:59 +01:00
670692b23c Updated dependencies based on version 1.17
Signed-off-by: Arjun Naik <arjun.rn@gmail.com>
2020-03-27 10:54:06 +01:00
33683fe88d Merge pull request #121 from zalando-incubator/dependabot/go_modules/github.com/aws/aws-sdk-go-1.29.33
Bump github.com/aws/aws-sdk-go from 1.29.31 to 1.29.33
2020-03-27 10:23:34 +01:00
abaef5e491 Bump github.com/aws/aws-sdk-go from 1.29.31 to 1.29.33
Bumps [github.com/aws/aws-sdk-go](https://github.com/aws/aws-sdk-go) from 1.29.31 to 1.29.33.
- [Release notes](https://github.com/aws/aws-sdk-go/releases)
- [Changelog](https://github.com/aws/aws-sdk-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-go/compare/v1.29.31...v1.29.33)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-27 08:31:09 +00:00
670f081a5e Merge pull request #115 from zalando-incubator/dependabot/go_modules/github.com/spf13/cobra-0.0.6
Bump github.com/spf13/cobra from 0.0.3 to 0.0.6
2020-03-26 12:10:03 +01:00
55a743e5ac Merge pull request #119 from zalando-incubator/dependabot/go_modules/github.com/aws/aws-sdk-go-1.29.31
Bump github.com/aws/aws-sdk-go from 1.29.30 to 1.29.31
2020-03-25 14:06:01 +01:00
830d385a4a Bump github.com/spf13/cobra from 0.0.3 to 0.0.6
Bumps [github.com/spf13/cobra](https://github.com/spf13/cobra) from 0.0.3 to 0.0.6.
- [Release notes](https://github.com/spf13/cobra/releases)
- [Commits](https://github.com/spf13/cobra/compare/v0.0.3...v0.0.6)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-25 12:27:25 +00:00
f2638c6843 Bump github.com/aws/aws-sdk-go from 1.29.30 to 1.29.31
Bumps [github.com/aws/aws-sdk-go](https://github.com/aws/aws-sdk-go) from 1.29.30 to 1.29.31.
- [Release notes](https://github.com/aws/aws-sdk-go/releases)
- [Changelog](https://github.com/aws/aws-sdk-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-go/compare/v1.29.30...v1.29.31)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-25 08:33:33 +00:00
b77fba2e7b Merge pull request #114 from zalando-incubator/dependabot/go_modules/github.com/stretchr/testify-1.5.1
Bump github.com/stretchr/testify from 1.4.0 to 1.5.1
2020-03-24 10:49:11 +01:00
e77d51f97a Merge pull request #112 from zalando-incubator/dependabot/go_modules/github.com/influxdata/influxdb-client-go-0.1.5
Bump github.com/influxdata/influxdb-client-go from 0.1.4 to 0.1.5
2020-03-24 10:48:43 +01:00
69ac42ed7d Merge pull request #111 from zalando-incubator/dependabot/go_modules/github.com/prometheus/client_golang-0.9.4
Bump github.com/prometheus/client_golang from 0.9.2 to 0.9.4
2020-03-24 10:48:02 +01:00
582f05539c Bump github.com/sirupsen/logrus from 1.4.2 to 1.5.0 (#117)
Bumps [github.com/sirupsen/logrus](https://github.com/sirupsen/logrus) from 1.4.2 to 1.5.0.
- [Release notes](https://github.com/sirupsen/logrus/releases)
- [Changelog](https://github.com/sirupsen/logrus/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sirupsen/logrus/compare/v1.4.2...v1.5.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-03-24 10:46:59 +01:00
46f2e5c4fd Bump github.com/aws/aws-sdk-go from 1.29.4 to 1.29.30 (#116)
Bumps [github.com/aws/aws-sdk-go](https://github.com/aws/aws-sdk-go) from 1.29.4 to 1.29.30.
- [Release notes](https://github.com/aws/aws-sdk-go/releases)
- [Changelog](https://github.com/aws/aws-sdk-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-go/compare/v1.29.4...v1.29.30)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2020-03-24 10:46:51 +01:00
31bc1771df Bump github.com/sirupsen/logrus from 1.4.2 to 1.5.0
Bumps [github.com/sirupsen/logrus](https://github.com/sirupsen/logrus) from 1.4.2 to 1.5.0.
- [Release notes](https://github.com/sirupsen/logrus/releases)
- [Changelog](https://github.com/sirupsen/logrus/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sirupsen/logrus/compare/v1.4.2...v1.5.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-24 08:49:15 +00:00
836c78d08b Bump github.com/stretchr/testify from 1.4.0 to 1.5.1
Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.4.0 to 1.5.1.
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.4.0...v1.5.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-22 14:21:19 +00:00
6f5ab042e6 Bump github.com/influxdata/influxdb-client-go from 0.1.4 to 0.1.5
Bumps [github.com/influxdata/influxdb-client-go](https://github.com/influxdata/influxdb-client-go) from 0.1.4 to 0.1.5.
- [Release notes](https://github.com/influxdata/influxdb-client-go/releases)
- [Commits](https://github.com/influxdata/influxdb-client-go/compare/v0.1.4...v0.1.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-22 14:20:20 +00:00
5abc7388fb Bump github.com/prometheus/client_golang from 0.9.2 to 0.9.4
Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 0.9.2 to 0.9.4.
- [Release notes](https://github.com/prometheus/client_golang/releases)
- [Changelog](https://github.com/prometheus/client_golang/blob/master/CHANGELOG.md)
- [Commits](https://github.com/prometheus/client_golang/compare/v0.9.2...v0.9.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-03-22 14:19:58 +00:00
5bf87cb10e Add support for passing URL query params to pod metric endpoints (#109)
Adds a new metric-config option named `rawQuery`. The value of
this option will be appended to the metric `path` as URL query
parameters to be used by the pod's application. E.g.,:
```
metric-config.pods.requests-per-second.json-path/rawQuery: "foo=bar&baz=bop"
```
will apppend `?foo=bar&baz=bop` to the URL.

Signed-off-by: Abe Friesen <2319792+doyshinda@users.noreply.github.com>
2020-03-10 10:45:28 +01:00
c6610750e4 Merge pull request #107 from affo/fix/influxdb-token-org-swap
fix(influxdb): fix swap of org/token
2020-02-24 09:27:34 +01:00
04ae6d955e fix(influxdb): fix swap of org/token parameter passing to
InfluxDBCollector

Convert from `orgID` to `org`.

Signed-off-by: Lorenzo Affetti <lorenzo.affetti@gmail.com>
2020-02-21 19:13:17 +01:00
2d56c202a7 Update AWS SDK to support AWS IAM solution (#106)
Fix #105

Signed-off-by: Mikkel Oscar Lyderik Larsen <mikkel.larsen@zalando.de>
2020-02-18 09:59:31 +01:00
c9fa15c7d4 Updated the tests (#103)
Signed-off-by: Arjun Naik <arjun.rn@gmail.com>
2020-02-04 09:48:50 +01:00
e3330dcf43 Reuse the HTTP client for scraping pods (#102)
Signed-off-by: Arjun Naik <arjun.rn@gmail.com>
2020-01-30 17:49:22 +01:00
8e4662b26c Permit disregarding incompatible HPAs (#95)
* This commit adds a --disregard-incompatible-hpas that makes the HPA
provider stop erroring out when a collector cannot be created for a
metric in a HPA. Useful when kube-metrics-adapter runs alongside another
metrics provider. Fixes issue #94.

Signed-off-by: Tomás Pinho <me@tomaspinho.com>

* Make tests pass

Signed-off-by: Tomás Pinho <me@tomaspinho.com>

* Wraps the Plugin Not Found error in a new type that can be checked by the caller of a function to determine if its contents should be logged or added as an event to the HPA, when this HPA is incompatible.
The disregardIncompatibleHPAs is now targetting only the log or addition of the same event.

Signed-off-by: Tomás Pinho <me@tomaspinho.com>

* Invert if expression to select when we should log
CreateNewMetricsCollector errors: don't log when both conditions are true - it's not a PluginNotFoundError
and disregardIncompatibleHPAs flag is set to true. This way, if an error
is NOT PluginNotFoundError it will always be logged, and when it IS
PluginNotFoundError it will only be logged when
disregardIncompatibleHPAs is false.

Signed-off-by: Tomás Pinho <me@tomaspinho.com>

* Remove redundant "whether to"

Signed-off-by: Tomás Pinho <me@tomaspinho.com>

* Add test case for updating HPAs via HPA Provider while disregarding
incompatible HPAs.

Signed-off-by: Tomás Pinho <me@tomaspinho.com>
2020-01-30 11:33:15 +01:00
54 changed files with 18300 additions and 851 deletions

35
.github/CODEOWNERS vendored
View File

@ -1,35 +0,0 @@
# These owners will be the default owners for everything in
# the repo.
* @arjunrn
# Samples for assigning codeowners below:
# Order is important; the last matching pattern takes the most
# precedence. When someone opens a pull request that only
# modifies JS files, only @js-owner and not the global
# owner(s) will be requested for a review.
# *.js @js-owner
# You can also use email addresses if you prefer. They'll be
# used to look up users just like we do for commit author
# emails.
# *.go docs@example.com
# In this example, @doctocat owns any files in the build/logs
# directory at the root of the repository and any of its
# subdirectories.
# /build/logs/ @doctocat
# The `docs/*` pattern will match files like
# `docs/getting-started.md` but not further nested files like
# `docs/build-app/troubleshooting.md`.
# docs/* docs@example.com
# In this example, @octocat owns any file in an apps directory
# anywhere in your repository.
# apps/ @octocat
# In this example, @doctocat owns any file in the `/docs`
# directory in the root of your repository.
# /docs/ @doctocat

14
.github/dependabot.yml vendored Normal file
View File

@ -0,0 +1,14 @@
version: 2
updates:
- package-ecosystem: gomod
directory: "/"
schedule:
interval: monthly
time: "07:00"
open-pull-requests-limit: 10
- package-ecosystem: docker
directory: "/"
schedule:
interval: monthly
time: "07:00"
open-pull-requests-limit: 10

25
.github/workflows/ci.yaml vendored Normal file
View File

@ -0,0 +1,25 @@
name: ci
on: [push, pull_request]
env:
GO111MODULE: on
jobs:
tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-go@v2
with:
go-version: '^1.16'
- run: go version
- run: go get github.com/mattn/goveralls
env:
GO111MODULE: off
- run: curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go env GOPATH)/bin ${GOLANGCI_RELEASE}
env:
GOLANGCI_RELEASE: v1.37.0
- run: make build.docker
- run: make test
- run: make check
- run: goveralls -coverprofile=profile.cov -service=github
env:
COVERALLS_TOKEN: ${{ secrets.GITHUB_TOKEN }}

1
.gitignore vendored
View File

@ -1,4 +1,5 @@
build/
apiserver.local.config/
.idea/
profile.cov
vendor/

View File

@ -1,20 +0,0 @@
language: go
dist: xenial
go:
- "1.13.x"
env:
- GO111MODULE=on GOLANGCI_RELEASE="v1.21.0"
before_install:
- GO111MODULE=off go get github.com/mattn/goveralls
- GO111MODULE=off go get github.com/lawrencewoodman/roveralls
- curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go env GOPATH)/bin ${GOLANGCI_RELEASE}
script:
- make test
- make build.docker
- make check
- roveralls
- goveralls -v -coverprofile=roveralls.coverprofile -service=travis-ci

View File

@ -1,5 +1,5 @@
FROM registry.opensource.zalan.do/stups/alpine:latest
MAINTAINER Team Teapot @ Zalando SE <team-teapot@zalando.de>
FROM registry.opensource.zalan.do/library/alpine-3.12:latest
LABEL maintainer="Team Teapot @ Zalando SE <team-teapot@zalando.de>"
# add binary
ADD build/linux/kube-metrics-adapter /

View File

@ -1,3 +1,2 @@
Mikkel Larsen <mikkel.larsen@zalando.de>
Arjun Naik <arjun.naik@zalando.de>
Team Teapot <team-teapot@zalando.de>

View File

@ -8,31 +8,45 @@ SOURCES = $(shell find . -name '*.go')
DOCKERFILE ?= Dockerfile
GOPKGS = $(shell go list ./...)
BUILD_FLAGS ?= -v
OPENAPI ?= pkg/api/generated/openapi/zz_generated.openapi.go
LDFLAGS ?= -X main.version=$(VERSION) -w -s
default: build.local
clean:
rm -rf build
rm -rf $(OPENAPI)
test:
go test -v $(GOPKGS)
go test -v -coverprofile=profile.cov $(GOPKGS)
check:
go mod download
golangci-lint run --timeout=2m ./...
$(OPENAPI): go.mod
go run k8s.io/kube-openapi/cmd/openapi-gen \
--go-header-file hack/boilerplate.go.txt \
--logtostderr \
-i k8s.io/metrics/pkg/apis/custom_metrics,k8s.io/metrics/pkg/apis/custom_metrics/v1beta1,k8s.io/metrics/pkg/apis/custom_metrics/v1beta2,k8s.io/metrics/pkg/apis/external_metrics,k8s.io/metrics/pkg/apis/external_metrics/v1beta1,k8s.io/metrics/pkg/apis/metrics,k8s.io/metrics/pkg/apis/metrics/v1beta1,k8s.io/apimachinery/pkg/apis/meta/v1,k8s.io/apimachinery/pkg/api/resource,k8s.io/apimachinery/pkg/version,k8s.io/api/core/v1 \
-p pkg/api/generated/openapi \
-o . \
-O zz_generated.openapi \
-r /dev/null
build.local: build/$(BINARY)
build.linux: build/linux/$(BINARY)
build.osx: build/osx/$(BINARY)
build/$(BINARY): go.mod $(SOURCES)
build/$(BINARY): go.mod $(SOURCES) $(OPENAPI)
CGO_ENABLED=0 go build -o build/$(BINARY) $(BUILD_FLAGS) -ldflags "$(LDFLAGS)" .
build/linux/$(BINARY): go.mod $(SOURCES)
build/linux/$(BINARY): go.mod $(SOURCES) $(OPENAPI)
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build $(BUILD_FLAGS) -o build/linux/$(BINARY) -ldflags "$(LDFLAGS)" .
build/osx/$(BINARY): go.mod $(SOURCES)
build/osx/$(BINARY): go.mod $(SOURCES) $(OPENAPI)
GOOS=darwin GOARCH=amd64 CGO_ENABLED=0 go build $(BUILD_FLAGS) -o build/osx/$(BINARY) -ldflags "$(LDFLAGS)" .
build.docker: build.linux

159
README.md
View File

@ -10,7 +10,7 @@ It supports scaling based on [Prometheus metrics](https://prometheus.io/), [SQS
It discovers Horizontal Pod Autoscaling resources and starts to collect the
requested metrics and stores them in memory. It's implemented using the
[custom-metrics-apiserver](https://github.com/kubernetes-incubator/custom-metrics-apiserver)
[custom-metrics-apiserver](https://github.com/kubernetes-sigs/custom-metrics-apiserver)
library.
Here's an example of a `HorizontalPodAutoscaler` resource configured to get
@ -22,7 +22,7 @@ kind: HorizontalPodAutoscaler
metadata:
name: myapp-hpa
annotations:
# metric-config.<metricType>.<metricName>.<collectorName>/<configKey>
# metric-config.<metricType>.<metricName>.<collectorType>/<configKey>
metric-config.pods.requests-per-second.json-path/json-key: "$.http_server.rps"
metric-config.pods.requests-per-second.json-path/path: /metrics
metric-config.pods.requests-per-second.json-path/port: "9090"
@ -104,7 +104,7 @@ kind: HorizontalPodAutoscaler
metadata:
name: myapp-hpa
annotations:
# metric-config.<metricType>.<metricName>.<collectorName>/<configKey>
# metric-config.<metricType>.<metricName>.<collectorType>/<configKey>
metric-config.pods.requests-per-second.json-path/json-key: "$.http_server.rps"
metric-config.pods.requests-per-second.json-path/path: /metrics
metric-config.pods.requests-per-second.json-path/port: "9090"
@ -142,7 +142,7 @@ example the following JSON data would be expected:
```
The json-path query support depends on the
[github.com/oliveagle/jsonpath](https://github.com/oliveagle/jsonpath) library.
[github.com/spyzhov/ajson](https://github.com/spyzhov/ajson) library.
See the README for possible queries. It's expected that the metric you query
returns something that can be turned into a `float64`.
@ -155,6 +155,25 @@ values of JSONPath expressions that evaluate to arrays/slices of numbers.
It's optional but when the expression evaluates to an array/slice, it's absence will
produce an error. The supported aggregation functions are `avg`, `max`, `min` and `sum`.
The `raw-query` configuration option specifies the query params to send along to the endpoint:
```yaml
metric-config.pods.requests-per-second.json-path/path: /metrics
metric-config.pods.requests-per-second.json-path/port: "9090"
metric-config.pods.requests-per-second.json-path/raw-query: "foo=bar&baz=bop"
```
will create a URL like this:
```
http://<podIP>:9090/metrics?foo=bar&baz=bop
```
There are also configuration options for custom (connect and request) timeouts when querying pods for metrics:
```yaml
metric-config.pods.requests-per-second.json-path/request-timeout: 2s
metric-config.pods.requests-per-second.json-path/connect-timeout: 500ms
```
The default for both of the above values is 15 seconds.
## Prometheus collector
The Prometheus collector is a generic collector which can map Prometheus
@ -183,15 +202,24 @@ the trade-offs between the two approaches.
| `prometheus-query` | Generic metric which requires a user defined query. | External | | `>=1.12` |
| *custom* | No predefined metrics. Metrics are generated from user defined queries. | Object | *any* | `>=1.12` |
### Configure Scrape Interval
There is a way to set the interval via an annotation like:
```yaml
metric-config.external.prometheus-query.prometheus/interval: 30s
```
Default is 1 minute.
### Example: External Metric
This is an example of an HPA configured to get metrics based on a Prometheus
query. The query is defined in the annotation
`metric-config.external.prometheus-query.prometheus/processed-events-per-second`
`metric-config.external.processed-events-per-second.prometheus/query`
where `processed-events-per-second` is the query name which will be associated
with the result of the query. A matching `query-name` label must be defined in
the `matchLabels` of the metric definition. This allows having multiple
prometheus queries associated with a single HPA.
with the result of the query.
This allows having multiple prometheus queries associated with a single HPA.
```yaml
apiVersion: autoscaling/v2beta2
@ -202,10 +230,9 @@ metadata:
# This annotation is optional.
# If specified, then this prometheus server is used,
# instead of the prometheus server specified as the CLI argument `--prometheus-server`.
metric-config.external.prometheus-query.prometheus/prometheus-server: http://prometheus.my-namespace.svc
# metric-config.<metricType>.<metricName>.<collectorName>/<configKey>
# <configKey> == query-name
metric-config.external.prometheus-query.prometheus/processed-events-per-second: |
metric-config.external.processed-events-per-second.prometheus/prometheus-server: http://prometheus.my-namespace.svc
# metric-config.<metricType>.<metricName>.<collectorType>/<configKey>
metric-config.external.processed-events-per-second.prometheus/query: |
scalar(sum(rate(event-service_events_count{application="event-service",processed="true"}[1m])))
spec:
scaleTargetRef:
@ -218,10 +245,10 @@ spec:
- type: External
external:
metric:
name: prometheus-query
name: processed-events-per-second
selector:
matchLabels:
query-name: processed-events-per-second
type: prometheus
target:
type: AverageValue
averageValue: "10"
@ -252,7 +279,7 @@ kind: HorizontalPodAutoscaler
metadata:
name: myapp-hpa
annotations:
# metric-config.<metricType>.<metricName>.<collectorName>/<configKey>
# metric-config.<metricType>.<metricName>.<collectorType>/<configKey>
metric-config.object.processed-events-per-second.prometheus/query: |
scalar(sum(rate(event-service_events_count{application="event-service",processed="true"}[1m])))
metric-config.object.processed-events-per-second.prometheus/per-replica: "true"
@ -353,10 +380,9 @@ we only support Flux instead of InfluxQL.
This is an example of an HPA configured to get metrics based on a Flux query.
The query is defined in the annotation
`metric-config.external.flux-query.influxdb/queue_depth`
where `queue_depth` is the query name which will be associated with the result of the query.
A matching `query-name` label must be defined in the `matchLabels` of the metric definition.
This allows having multiple flux queries associated with a single HPA.
`metric-config.external.<metricName>.influxdb/query` where `<metricName>` is
the query name which will be associated with the result of the query. This
allows having multiple flux queries associated with a single HPA.
```yaml
apiVersion: autoscaling/v2beta2
@ -369,13 +395,14 @@ metadata:
# instead of using the ones specified via CLI. Respectively:
# - --influxdb-address
# - --influxdb-token
# - --influxdb-org-id
metric-config.external.flux-query.influxdb/address: "http://influxdbv2.my-namespace.svc"
metric-config.external.flux-query.influxdb/token: "secret-token"
metric-config.external.flux-query.influxdb/org-id: "deadbeef"
# metric-config.<metricType>.<metricName>.<collectorName>/<configKey>
# - --influxdb-org
metric-config.external.queue-depth.influxdb/address: "http://influxdbv2.my-namespace.svc"
metric-config.external.queue-depth.influxdb/token: "secret-token"
# This could be either the organization name or the ID.
metric-config.external.queue-depth.influxdb/org: "deadbeef"
# metric-config.<metricType>.<metricName>.<collectorType>/<configKey>
# <configKey> == query-name
metric-config.external.flux-query.influxdb/queue_depth: |
metric-config.external.queue-depth.influxdb/query: |
from(bucket: "apps")
|> range(start: -30s)
|> filter(fn: (r) => r._measurement == "queue_depth")
@ -395,10 +422,10 @@ spec:
- type: External
external:
metric:
name: flux-query
name: queue-depth
selector:
matchLabels:
query-name: queue_depth
type: influxdb
target:
type: Value
value: "1"
@ -460,9 +487,10 @@ spec:
- type: External
external:
metric:
name: sqs-queue-length
name: my-sqs
selector:
matchLabels:
type: sqs-queue-length
queue-name: foobar
region: eu-central-1
target:
@ -501,9 +529,9 @@ kind: HorizontalPodAutoscaler
metadata:
name: myapp-hpa
annotations:
# metric-config.<metricType>.<metricName>.<collectorName>/<configKey>
metric-config.external.zmon-check.zmon/key: "custom.*"
metric-config.external.zmon-check.zmon/tag-application: "my-custom-app-*"
# metric-config.<metricType>.<metricName>.<collectorType>/<configKey>
metric-config.external.my-zmon-check.zmon/key: "custom.*"
metric-config.external.my-zmon-check.zmon/tag-application: "my-custom-app-*"
spec:
scaleTargetRef:
apiVersion: apps/v1
@ -515,17 +543,18 @@ spec:
- type: External
external:
metric:
name: zmon-check
name: my-zmon-check
selector:
matchLabels:
type: zmon
check-id: "1234" # the ZMON check to query for metrics
key: "custom.value"
tag-application: my-custom-app
aggregators: avg # comma separated list of aggregation functions, default: last
duration: 5m # default: 10m
target:
averageValue: "30"
type: AverageValue
target:
averageValue: "30"
type: AverageValue
```
The `check-id` specifies the ZMON check to query for the metrics. `key`
@ -567,9 +596,65 @@ specify a duration of `5m` then the query will return metric points for the
last 5 minutes and apply the specified aggregation with the same duration .e.g
`max(5m)`.
The annotations `metric-config.external.zmon-check.zmon/key` and
`metric-config.external.zmon-check.zmon/tag-<name>` can be optionally used if
The annotations `metric-config.external.my-zmon-check.zmon/key` and
`metric-config.external.my-zmon-check.zmon/tag-<name>` can be optionally used if
you need to define a `key` or other `tag` with a "star" query syntax like
`values.*`. This *hack* is in place because it's not allowed to use `*` in the
metric label definitions. If both annotations and corresponding label is
defined, then the annotation takes precedence.
## HTTP Collector
The http collector allows collecting metrics from an external endpoint specified in the HPA.
Currently only `json-path` collection is supported.
### Supported metrics
| Metric | Description | Type | K8s Versions |
| ------------ | -------------- | ------- | -- |
| *custom* | No predefined metrics. Metrics are generated from user defined queries. | Pods | `>=1.12` |
### Example
This is an example of using the HTTP collector to collect metrics from a json
metrics endpoint specified in the annotations.
```yaml
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: myapp-hpa
annotations:
# metric-config.<metricType>.<metricName>.<collectorType>/<configKey>
metric-config.external.unique-metric-name.json-path/json-key: "$.some-metric.value"
metric-config.external.unique-metric-name.json-path/endpoint: "http://metric-source.app-namespace:8080/metrics"
metric-config.external.unique-metric-name.json-path/aggregator: "max"
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: myapp
minReplicas: 1
maxReplicas: 10
metrics:
- type: External
external:
metric:
name: unique-metric-name
selector:
matchLabels:
type: json-path
target:
averageValue: 1
type: AverageValue
```
The HTTP collector similar to the Pod Metrics collector. The metric name should always be `http`.
This value is also used in the annotations to configure the metrics adapter to query the required
target. The following configuration values are supported:
- `json-key` to specify the JSON path of the metric to be queried
- `endpoint` the fully formed path to query for the metric. In the above example a Kubernetes _Service_
in the namespace `app-namespace` is called.
- `aggregator` is only required if the metric is an array of values and specifies how the values
are aggregated. Currently this option can support the values: `sum`, `max`, `min`, `avg`.

9
docs/helm/Chart.yaml Normal file
View File

@ -0,0 +1,9 @@
apiVersion: v2
name: kube-metrics-adapter
version: 0.1.9
description: kube-metrics-adapter helm chart
home: https://github.com/zalando-incubator/kube-metrics-adapter
maintainers:
- name: The Zalando Incubator
email: opensource@zalando.de
url: https://github.com/zalando-incubator

View File

@ -0,0 +1,15 @@
{{- if .Values.enableCustomMetricsApi }}
apiVersion: apiregistration.k8s.io/v1beta1
kind: APIService
metadata:
name: v1beta1.custom.metrics.k8s.io
spec:
service:
name: kube-metrics-adapter
namespace: {{ .Values.namespace }}
group: custom.metrics.k8s.io
version: v1beta1
insecureSkipTLSVerify: {{ .Values.tls.skipTLSVerify }}
groupPriorityMinimum: 100
versionPriority: 100
{{- end}}

View File

@ -0,0 +1,191 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: kube-metrics-adapter
namespace: {{ .Values.namespace }}
labels:
application: kube-metrics-adapter
version: {{ .Values.registry.imageTag }}
spec:
replicas: {{ .Values.replicas }}
selector:
matchLabels:
application: kube-metrics-adapter
template:
metadata:
labels:
application: kube-metrics-adapter
version: {{ .Values.registry.imageTag }}
spec:
serviceAccountName: kube-metrics-adapter
containers:
- name: kube-metrics-adapter
image: {{ .Values.registry.image}}:{{ .Values.registry.imageTag }}
args:
{{- if .Values.addDirectoryHeader }}
- --add_dir_header={{ .Values.addDirectoryHeader }}
{{- end}}
{{- if .Values.log.alsoToStderr }}
- --alsologtostderr={{ .Values.log.alsoToStderr }}
{{- end}}
{{- if .Values.authentication.kubeConfig }}
- --authentication-kubeconfig={{ .Values.authentication.kubeConfig }}
{{- end}}
{{- if .Values.authentication.skipLookup }}
- --authentication-skip-lookup={{ .Values.authentication.skipLookup }}
{{- end}}
{{- if .Values.authentication.tokenWebhookCacheTtl }}
- --authentication-token-webhook-cache-ttl={{ .Values.authentication.tokenWebhookCacheTtl }}
{{- end}}
{{- if .Values.authentication.tolerateLookupFailure }}
- --authentication-tolerate-lookup-failure={{ .Values.authentication.tolerateLookupFailure }}
{{- end}}
{{- if .Values.authorization.alwaysAllowPaths }}
- --authorization-always-allow-paths={{ .Values.authorization.alwaysAllowPaths }}
{{- end}}
{{- if .Values.authorization.kubeConfig }}
- --authorization-kubeconfig={{ .Values.authorization.kubeConfig }}
{{- end}}
{{- if .Values.authorization.webhookCache.authorizedTtl }}
- --authorization-webhook-cache-authorized-ttl={{ .Values.authorization.webhookCache.authorizedTtl }}
{{- end}}
{{- if .Values.authorization.webhookCache.unauthorizedTtl }}
- --authorization-webhook-cache-unauthorized-ttl={{ .Values.authorization.webhookCache.unauthorizedTtl }}
{{- end}}
{{- if .Values.aws.externalMetrics }}
- --aws-external-metrics={{ .Values.aws.externalMetrics }}
{{- end}}
{{- if .Values.aws.region }}
- --aws-region={{ .Values.aws.region }}
{{- end}}
{{- if .Values.tls.certificateDirectory }}
- --cert-dir={{ .Values.tls.certificateDirectory }}
{{- end}}
{{- if .Values.tls.clientCaFile }}
- --client-ca-file={{ .Values.tls.clientCaFile }}
{{- end}}
{{- if .Values.contentionProfiling }}
- --contention-profiling={{ .Values.contentionProfiling }}
{{- end}}
{{- if .Values.credentialsDirectory }}
- --credentials-dir={{ .Values.credentialsDirectory }}
{{- end}}
{{- if .Values.disregardIncompatibleHPAs }}
- --disregard-incompatible-hpas={{ .Values.disregardIncompatibleHPAs }}
{{- end}}
{{- if .Values.enableCustomMetricsApi }}
- --enable-custom-metrics-api={{ .Values.enableCustomMetricsApi }}
{{- end}}
{{- if .Values.enableExternalMetricsApi }}
- --enable-external-metrics-api={{ .Values.enableExternalMetricsApi }}
{{- end}}
{{- if .Values.http2MaxStreamsPerConnection }}
- --http2-max-streams-per-connection={{ .Values.http2MaxStreamsPerConnection }}
{{- end}}
{{- if .Values.influxDB.address }}
- --influxdb-address={{ .Values.influxDB.address }}
{{- end}}
{{- if .Values.influxDB.organization }}
- --influxdb-org={{ .Values.influxDB.organization }}
{{- end}}
{{- if .Values.influxDB.token }}
- --influxdb-token={{ .Values.influxDB.token }}
{{- end}}
{{- if .Values.listerKubeConfig }}
- --lister-kubeconfig={{ .Values.listerKubeConfig }}
{{- end}}
{{- if .Values.log.flushFrequency }}
- --log-flush-frequency={{ .Values.log.flushFrequency }}
{{- end}}
{{- if .Values.log.backtraceAtTraceLocation }}
- --log_backtrace_at={{ .Values.log.backtraceAtTraceLocation }}
{{- end}}
{{- if .Values.log.directory }}
- --log_dir={{ .Values.log.directory }}
{{- end}}
{{- if .Values.log.file }}
- --log_file={{ .Values.log.file }}
{{- end}}
{{- if .Values.log.fileMaxSize }}
- --log_file_max_size={{ .Values.log.fileMaxSize }}
{{- end}}
{{- if .Values.log.toStderr }}
- --logtostderr={{ .Values.log.toStderr }}
{{- end}}
{{- if .Values.prometheus.metricsAddress }}
- --metrics-address={{ .Values.prometheus.metricsAddress }}
{{- end}}
{{- if .Values.profiling }}
- --profiling={{ .Values.profiling }}
{{- end}}
{{- if .Values.prometheus.server }}
- --prometheus-server={{ .Values.prometheus.server }}
{{- end}}
{{- if .Values.requestHeader.allowedNames }}
- --requestheader-allowed-names={{ .Values.requestHeader.allowedNames }}
{{- end}}
{{- if .Values.requestHeader.clientCaFile }}
- --requestheader-client-ca-file={{ .Values.requestHeader.clientCaFile }}
{{- end}}
{{- if .Values.requestHeader.extraHeadersPrefix }}
- --requestheader-extra-headers-prefix={{ .Values.requestHeader.extraHeadersPrefix }}
{{- end}}
{{- if .Values.requestHeader.groupHeaders }}
- --requestheader-group-headers={{ .Values.requestHeader.groupHeaders }}
{{- end}}
{{- if .Values.requestHeader.usernameHeaders }}
- --requestheader-username-headers={{ .Values.requestHeader.usernameHeaders }}
{{- end}}
- --secure-port={{ .Values.service.internalPort }}
{{- if .Values.log.skipHeaders }}
- --skip_headers={{ .Values.log.skipHeaders }}
{{- end}}
{{- if .Values.log.skipLogHeaders }}
- --skip_log_headers={{ .Values.log.skipLogHeaders }}
{{- end}}
{{- if .Values.skipperBackendsAnnotation }}
- --skipper-backends-annotation={{ .Values.skipperBackendsAnnotation }}
{{- end}}
{{- if .Values.skipperIngressMetrics }}
- --skipper-ingress-metrics={{ .Values.skipperIngressMetrics }}
{{- end}}
{{- if .Values.log.stderrThreshold }}
- --stderrthreshold={{ .Values.log.stderrThreshold }}
{{- end}}
{{- if .Values.tls.certFile }}
- --tls-cert-file={{ .Values.tls.certFile }}
{{- end}}
{{- if .Values.tls.cipherSuites }}
- --tls-cipher-suites={{ .Values.tls.cipherSuites }}
{{- end}}
{{- if .Values.tls.minVersion }}
- --tls-min-version={{ .Values.tls.minVersion }}
{{- end}}
{{- if .Values.tls.privateKeyFile }}
- --tls-private-key-file={{ .Values.tls.privateKeyFile }}
{{- end}}
{{- if .Values.tls.sniCertKey }}
- --tls-sni-cert-key={{ .Values.tls.sniCertKey }}
{{- end}}
{{- if .Values.token }}
- --token={{ .Values.token }}
{{- end}}
{{- if .Values.log.level }}
- --v={{ .Values.log.level }}
{{- end}}
{{- if .Values.vmodule }}
- --vmodule={{ .Values.vmodule }}
{{- end}}
{{- if .Values.zmon.kariosdbEndpoint }}
- --zmon-kariosdb-endpoint={{ .Values.zmon.kariosdbEndpoint }}
{{- end}}
{{- if .Values.zmon.tokenName }}
- --zmon-token-name={{ .Values.zmon.tokenName }}
{{- end}}
resources:
limits:
cpu: {{ .Values.resources.limits.cpu }}
memory: {{ .Values.resources.limits.memory }}
requests:
cpu: {{ .Values.resources.requests.cpu }}
memory: {{ .Values.resources.requests.memory }}

View File

@ -0,0 +1,15 @@
{{- if .Values.enableExternalMetricsApi }}
apiVersion: apiregistration.k8s.io/v1beta1
kind: APIService
metadata:
name: v1beta1.external.metrics.k8s.io
spec:
service:
name: kube-metrics-adapter
namespace: {{ .Values.namespace }}
group: external.metrics.k8s.io
version: v1beta1
insecureSkipTLSVerify: {{ .Values.tls.skipTLSVerify }}
groupPriorityMinimum: 100
versionPriority: 100
{{- end}}

View File

@ -0,0 +1,154 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kube-metrics-adapter-server-resources
rules:
- apiGroups:
- custom.metrics.k8s.io
resources: ["*"]
verbs: ["*"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: external-metrics-server-resources
rules:
- apiGroups:
- external.metrics.k8s.io
resources: ["*"]
verbs: ["*"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kube-metrics-adapter-resource-reader
rules:
- apiGroups:
- ""
resources:
- namespaces
- pods
- services
- configmaps
verbs:
- get
- list
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kube-metrics-adapter-resource-collector
rules:
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
- apiGroups:
- ""
resources:
- pods
verbs:
- list
- apiGroups:
- apps
resources:
- deployments
- statefulsets
verbs:
- get
- apiGroups:
- extensions
resources:
- ingresses
verbs:
- get
- apiGroups:
- autoscaling
resources:
- horizontalpodautoscalers
verbs:
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: hpa-controller-custom-metrics
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: kube-metrics-adapter-server-resources
subjects:
- kind: ServiceAccount
name: horizontal-pod-autoscaler
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: hpa-controller-external-metrics
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: external-metrics-server-resources
subjects:
- kind: ServiceAccount
name: horizontal-pod-autoscaler
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: kube-metrics-adapter-auth-reader
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: extension-apiserver-authentication-reader
subjects:
- kind: ServiceAccount
name: kube-metrics-adapter
namespace: {{ .Values.namespace }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: custom-metrics:system:auth-delegator
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:auth-delegator
subjects:
- kind: ServiceAccount
name: kube-metrics-adapter
namespace: {{ .Values.namespace }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: kube-metrics-adapter-resource-collector
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: kube-metrics-adapter-resource-collector
subjects:
- kind: ServiceAccount
name: kube-metrics-adapter
namespace: {{ .Values.namespace }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: kube-metrics-adapter-resource-reader
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: kube-metrics-adapter-resource-reader
subjects:
- kind: ServiceAccount
name: kube-metrics-adapter
namespace: {{ .Values.namespace }}

View File

@ -0,0 +1,5 @@
kind: ServiceAccount
apiVersion: v1
metadata:
name: kube-metrics-adapter
namespace: {{ .Values.namespace }}

View File

@ -0,0 +1,11 @@
apiVersion: v1
kind: Service
metadata:
name: kube-metrics-adapter
namespace: {{ .Values.namespace }}
spec:
ports:
- port: {{ .Values.service.port }}
targetPort: {{ .Values.service.internalPort }}
selector:
application: kube-metrics-adapter

94
docs/helm/values.yaml Normal file
View File

@ -0,0 +1,94 @@
namespace: kube-system
replicas: 1
registry:
image: registry.opensource.zalan.do/teapot/kube-metrics-adapter
imageTag: v0.1.9
imagePullPolicy: IfNotPresent
service:
port: 443
internalPort: 443
addDirectoryHeader:
contentionProfiling:
profiling:
enableCustomMetricsApi:
enableExternalMetricsApi:
credentialsDirectory:
disregardIncompatibleHPAs:
http2MaxStreamsPerConnection:
listerKubeConfig:
skipperBackendsAnnotation:
skipperIngressMetrics:
token:
vmodule:
authentication:
kubeConfig:
skipLookup:
tokenWebhookCacheTtl:
tolerateLookupFailure:
authorization:
kubeConfig:
alwaysAllowPaths:
webhookCache:
authorizedTtl:
unauthorizedTtl:
aws:
externalMetrics:
region:
influxDB:
address:
organization:
token:
log:
alsoToStderr:
toStderr:
flushFrequency:
backtraceAtTraceLocation:
directory:
file:
fileMaxSize:
level:
stderrThreshold:
skipHeaders:
skipLogHeaders:
prometheus:
server: http://prometheus.kube-system.svc.cluster.local
metricsAddress:
requestHeader:
allowedNames:
clientCaFile:
extraHeadersPrefix:
groupHeaders:
usernameHeaders:
tls:
skipTLSVerify: true
certificateDirectory:
clientCaFile:
certFile:
cipherSuites:
minVersion:
privateKeyFile:
sniCertKey:
zmon:
kariosdbEndpoint:
tokenName:
resources:
limits:
cpu: 100m
memory: 100Mi
requests:
cpu: 100m
memory: 100Mi

View File

@ -6,7 +6,7 @@ metadata:
labels:
application: custom-metrics-consumer
annotations:
# metric-config.<metricType>.<metricName>.<collectorName>/<configKey>
# metric-config.<metricType>.<metricName>.<collectorType>/<configKey>
metric-config.pods.queue-length.json-path/json-key: "$.queue.length"
metric-config.pods.queue-length.json-path/path: /metrics
metric-config.pods.queue-length.json-path/port: "9090"
@ -50,9 +50,10 @@ spec:
- type: External
external:
metric:
name: sqs-queue-length
name: app-queue-length
selector:
matchLabels:
type: sqs-queue-length
queue-name: foobar
region: eu-central-1
target:

51
go.mod
View File

@ -2,31 +2,32 @@ module github.com/zalando-incubator/kube-metrics-adapter
require (
github.com/NYTimes/gziphandler v1.0.1 // indirect
github.com/aws/aws-sdk-go v1.16.6
github.com/coreos/go-systemd v0.0.0-20180705093442-88bfeed483d3 // indirect
github.com/golang/groupcache v0.0.0-20180513044358-24b0969c4cb7 // indirect
github.com/googleapis/gnostic v0.2.0 // indirect
github.com/grpc-ecosystem/grpc-gateway v1.4.1 // indirect
github.com/influxdata/influxdb-client-go v0.1.4
github.com/kubernetes-incubator/custom-metrics-apiserver v0.0.0-20190918110929-3d9be26a50eb
github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852
github.com/prometheus/client_golang v0.9.2
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275
github.com/sirupsen/logrus v1.4.2
github.com/soheilhy/cmux v0.1.4 // indirect
github.com/spf13/cobra v0.0.3
github.com/stretchr/testify v1.3.0
github.com/tmc/grpc-websocket-proxy v0.0.0-20171017195756-830351dc03c6 // indirect
github.com/aws/aws-sdk-go v1.37.1
github.com/go-openapi/spec v0.20.2
github.com/influxdata/influxdb-client-go v0.2.0
github.com/influxdata/line-protocol v0.0.0-20201012155213-5f565037cbc9 // indirect
github.com/kubernetes-sigs/custom-metrics-apiserver v0.0.0-20201216091021-1b9fa998bbaa
github.com/mattn/go-colorable v0.1.4 // indirect
github.com/mattn/go-isatty v0.0.10 // indirect
github.com/onsi/gomega v1.8.1 // indirect
github.com/prometheus/client_golang v1.9.0
github.com/prometheus/common v0.15.0
github.com/sirupsen/logrus v1.7.0
github.com/spf13/cobra v0.0.7
github.com/spyzhov/ajson v0.4.2
github.com/stretchr/testify v1.7.0
github.com/zalando-incubator/cluster-lifecycle-manager v0.0.0-20180921141935-824b77fb1f84
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
gopkg.in/inf.v0 v0.9.1 // indirect
k8s.io/api v0.0.0-20190918155943-95b840bb6a1f
k8s.io/apimachinery v0.0.0-20190913080033-27d36303b655
k8s.io/apiserver v0.0.0-20190918160949-bfa5e2e684ad // indirect
k8s.io/client-go v0.0.0-20190918160344-1fbdaa4c8d90
k8s.io/component-base v0.0.0-20190918160511-547f6c5d7090
k8s.io/klog v0.4.0
k8s.io/metrics v0.0.0-20190226180357-f3f09b9076d1
golang.org/x/crypto v0.0.0-20201124201722-c8d3bf9c5392 // indirect
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
k8s.io/api v0.20.0
k8s.io/apimachinery v0.20.0
k8s.io/apiserver v0.20.0
k8s.io/client-go v0.20.0
k8s.io/component-base v0.20.0
k8s.io/klog v1.0.0
k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd
k8s.io/metrics v0.20.0
)
go 1.13
go 1.15

885
go.sum

File diff suppressed because it is too large Load Diff

16
hack/boilerplate.go.txt Normal file
View File

@ -0,0 +1,16 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

6
hack/tools.go Normal file
View File

@ -0,0 +1,6 @@
// +build tools
// This package imports things required by build scripts, to force `go mod` to see them as dependencies
package tools
import _ "k8s.io/kube-openapi/cmd/openapi-gen"

View File

@ -18,6 +18,7 @@ package main
import (
"flag"
_ "net/http/pprof"
"os"
"runtime"

View File

@ -15,7 +15,7 @@ const (
)
type AnnotationConfigs struct {
CollectorName string
CollectorType string
Configs map[string]string
PerReplica bool
Interval time.Duration
@ -64,14 +64,14 @@ func (m AnnotationConfigMap) Parse(annotations map[string]string) error {
config, ok := m[key]
if !ok {
config = &AnnotationConfigs{
CollectorName: metricCollector,
CollectorType: metricCollector,
Configs: map[string]string{},
}
m[key] = config
}
// TODO: fail if collector name doesn't match
if config.CollectorName != metricCollector {
if config.CollectorType != metricCollector {
continue
}

View File

@ -86,6 +86,21 @@ func TestParser(t *testing.T) {
"org-id": "deadbeef",
},
},
{
Name: "http metrics",
Annotations: map[string]string{
"metric-config.external.http.json/json-key": "$.metric.value",
"metric-config.external.http.json/endpoint": "http://metric-source.source-namespace.svc.cluster.local:8000/metrics",
"metric-config.external.http.json/aggregator": "avg",
},
MetricName: "http",
MetricType: autoscalingv2.ExternalMetricSourceType,
ExpectedConfig: map[string]string{
"json-key": "$.metric.value",
"endpoint": "http://metric-source.source-namespace.svc.cluster.local:8000/metrics",
"aggregator": "avg",
},
},
} {
t.Run(tc.Name, func(t *testing.T) {
hpaMap := make(AnnotationConfigMap)

File diff suppressed because it is too large Load Diff

View File

@ -33,12 +33,7 @@ func NewAWSCollectorPlugin(sessions map[string]*session.Session) *AWSCollectorPl
// NewCollector initializes a new skipper collector from the specified HPA.
func (c *AWSCollectorPlugin) NewCollector(hpa *autoscalingv2.HorizontalPodAutoscaler, config *MetricConfig, interval time.Duration) (Collector, error) {
switch config.Metric.Name {
case AWSSQSQueueLengthMetric:
return NewAWSSQSCollector(c.sessions, config, interval)
}
return nil, fmt.Errorf("metric '%s' not supported", config.Metric.Name)
return NewAWSSQSCollector(c.sessions, hpa, config, interval)
}
type AWSSQSCollector struct {
@ -47,11 +42,12 @@ type AWSSQSCollector struct {
region string
queueURL string
queueName string
namespace string
metric autoscalingv2.MetricIdentifier
metricType autoscalingv2.MetricSourceType
}
func NewAWSSQSCollector(sessions map[string]*session.Session, config *MetricConfig, interval time.Duration) (*AWSSQSCollector, error) {
func NewAWSSQSCollector(sessions map[string]*session.Session, hpa *autoscalingv2.HorizontalPodAutoscaler, config *MetricConfig, interval time.Duration) (*AWSSQSCollector, error) {
if config.Metric.Selector == nil {
return nil, fmt.Errorf("selector for queue is not specified")
}
@ -85,6 +81,7 @@ func NewAWSSQSCollector(sessions map[string]*session.Session, config *MetricConf
interval: interval,
queueURL: aws.StringValue(resp.QueueUrl),
queueName: name,
namespace: hpa.Namespace,
metric: config.Metric,
metricType: config.Type,
}, nil
@ -108,7 +105,8 @@ func (c *AWSSQSCollector) GetMetrics() ([]CollectedMetric, error) {
}
metricValue := CollectedMetric{
Type: c.metricType,
Namespace: c.namespace,
Type: c.metricType,
External: external_metrics.ExternalMetricValue{
MetricName: c.metric.Name,
MetricLabels: c.metric.Selector.MatchLabels,

View File

@ -4,12 +4,17 @@ import (
"fmt"
"time"
log "github.com/sirupsen/logrus"
"github.com/zalando-incubator/kube-metrics-adapter/pkg/annotations"
autoscalingv2 "k8s.io/api/autoscaling/v2beta2"
"k8s.io/metrics/pkg/apis/custom_metrics"
"k8s.io/metrics/pkg/apis/external_metrics"
)
const (
typeLabelKey = "type"
)
type ObjectReference struct {
autoscalingv2.CrossVersionObjectReference
Namespace string
@ -19,6 +24,7 @@ type CollectorFactory struct {
podsPlugins pluginMap
objectPlugins objectPluginMap
externalPlugins map[string]CollectorPlugin
logger *log.Entry
}
type objectPluginMap struct {
@ -39,6 +45,7 @@ func NewCollectorFactory() *CollectorFactory {
Named: map[string]*pluginMap{},
},
externalPlugins: map[string]CollectorPlugin{},
logger: log.WithFields(log.Fields{"collector": "true"}),
}
}
@ -46,6 +53,14 @@ type CollectorPlugin interface {
NewCollector(hpa *autoscalingv2.HorizontalPodAutoscaler, config *MetricConfig, interval time.Duration) (Collector, error)
}
type PluginNotFoundError struct {
metricTypeName MetricTypeName
}
func (p *PluginNotFoundError) Error() string {
return fmt.Sprintf("no plugin found for %s", p.metricTypeName)
}
func (c *CollectorFactory) RegisterPodsCollector(metricCollector string, plugin CollectorPlugin) error {
if metricCollector == "" {
c.podsPlugins.Any = plugin
@ -104,7 +119,7 @@ func (c *CollectorFactory) NewCollector(hpa *autoscalingv2.HorizontalPodAutoscal
switch config.Type {
case autoscalingv2.PodsMetricSourceType:
// first try to find a plugin by format
if plugin, ok := c.podsPlugins.Named[config.CollectorName]; ok {
if plugin, ok := c.podsPlugins.Named[config.CollectorType]; ok {
return plugin.NewCollector(hpa, config, interval)
}
@ -115,7 +130,7 @@ func (c *CollectorFactory) NewCollector(hpa *autoscalingv2.HorizontalPodAutoscal
case autoscalingv2.ObjectMetricSourceType:
// first try to find a plugin by kind
if kinds, ok := c.objectPlugins.Named[config.ObjectReference.Kind]; ok {
if plugin, ok := kinds.Named[config.CollectorName]; ok {
if plugin, ok := kinds.Named[config.CollectorType]; ok {
return plugin.NewCollector(hpa, config, interval)
}
@ -126,7 +141,7 @@ func (c *CollectorFactory) NewCollector(hpa *autoscalingv2.HorizontalPodAutoscal
}
// else try to find a default plugin for this kind
if plugin, ok := c.objectPlugins.Any.Named[config.CollectorName]; ok {
if plugin, ok := c.objectPlugins.Any.Named[config.CollectorType]; ok {
return plugin.NewCollector(hpa, config, interval)
}
@ -134,12 +149,26 @@ func (c *CollectorFactory) NewCollector(hpa *autoscalingv2.HorizontalPodAutoscal
return c.objectPlugins.Any.Any.NewCollector(hpa, config, interval)
}
case autoscalingv2.ExternalMetricSourceType:
if plugin, ok := c.externalPlugins[config.Metric.Name]; ok {
// First type to get metric type from the `type` label,
// otherwise fall back to the legacy metric name based mapping.
var pluginKey string
if config.Metric.Selector != nil && config.Metric.Selector.MatchLabels != nil {
if typ, ok := config.Metric.Selector.MatchLabels[typeLabelKey]; ok {
pluginKey = typ
}
}
if pluginKey == "" {
pluginKey = config.Metric.Name
c.logger.Warnf("HPA %s/%s is using deprecated metric type identifier '%s'", hpa.Namespace, hpa.Name, config.Metric.Name)
}
if plugin, ok := c.externalPlugins[pluginKey]; ok {
return plugin.NewCollector(hpa, config, interval)
}
}
return nil, fmt.Errorf("no plugin found for %s", config.MetricTypeName)
return nil, &PluginNotFoundError{metricTypeName: config.MetricTypeName}
}
type MetricTypeName struct {
@ -148,9 +177,10 @@ type MetricTypeName struct {
}
type CollectedMetric struct {
Type autoscalingv2.MetricSourceType
Custom custom_metrics.MetricValue
External external_metrics.ExternalMetricValue
Type autoscalingv2.MetricSourceType
Namespace string
Custom custom_metrics.MetricValue
External external_metrics.ExternalMetricValue
}
type Collector interface {
@ -160,7 +190,7 @@ type Collector interface {
type MetricConfig struct {
MetricTypeName
CollectorName string
CollectorType string
Config map[string]string
ObjectReference custom_metrics.ObjectReference
PerReplica bool
@ -220,7 +250,7 @@ func ParseHPAMetrics(hpa *autoscalingv2.HorizontalPodAutoscaler) ([]*MetricConfi
annotationConfigs, present := parser.GetAnnotationConfig(typeName.Metric.Name, typeName.Type)
if present {
config.CollectorName = annotationConfigs.CollectorName
config.CollectorType = annotationConfigs.CollectorType
config.Interval = annotationConfigs.Interval
config.PerReplica = annotationConfigs.PerReplica
// configs specified in annotations takes precedence

View File

@ -0,0 +1,129 @@
package collector
import (
"testing"
"time"
"github.com/stretchr/testify/require"
autoscalingv2 "k8s.io/api/autoscaling/v2beta2"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
type mockCollectorPlugin struct {
Name string
}
func (c *mockCollectorPlugin) NewCollector(hpa *autoscalingv2.HorizontalPodAutoscaler, config *MetricConfig, interval time.Duration) (Collector, error) {
return &mockCollector{Name: c.Name}, nil
}
type mockCollector struct {
Name string
}
func (c *mockCollector) GetMetrics() ([]CollectedMetric, error) {
return nil, nil
}
func (c *mockCollector) Interval() time.Duration {
return 0
}
func TestNewCollector(t *testing.T) {
for _, tc := range []struct {
msg string
hpa *autoscalingv2.HorizontalPodAutoscaler
expectedCollector string
}{
{
msg: "should get create collector type from legacy metric name",
hpa: &autoscalingv2.HorizontalPodAutoscaler{
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{},
},
Spec: autoscalingv2.HorizontalPodAutoscalerSpec{
Metrics: []autoscalingv2.MetricSpec{
{
Type: autoscalingv2.ExternalMetricSourceType,
External: &autoscalingv2.ExternalMetricSource{
Metric: autoscalingv2.MetricIdentifier{
Name: "external-1",
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{"x": "y"},
},
},
},
},
},
},
},
expectedCollector: "external-1",
},
{
msg: "should get create collector type from type label (ignore legacy metric name)",
hpa: &autoscalingv2.HorizontalPodAutoscaler{
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{},
},
Spec: autoscalingv2.HorizontalPodAutoscalerSpec{
Metrics: []autoscalingv2.MetricSpec{
{
Type: autoscalingv2.ExternalMetricSourceType,
External: &autoscalingv2.ExternalMetricSource{
Metric: autoscalingv2.MetricIdentifier{
Name: "external-1",
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{"type": "external-2"},
},
},
},
},
},
},
},
expectedCollector: "external-2",
},
{
msg: "should not find collector when no collector matches",
hpa: &autoscalingv2.HorizontalPodAutoscaler{
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{},
},
Spec: autoscalingv2.HorizontalPodAutoscalerSpec{
Metrics: []autoscalingv2.MetricSpec{
{
Type: autoscalingv2.ExternalMetricSourceType,
External: &autoscalingv2.ExternalMetricSource{
Metric: autoscalingv2.MetricIdentifier{
Name: "external-3",
},
},
},
},
},
},
expectedCollector: "",
},
} {
t.Run(tc.msg, func(t *testing.T) {
collectorFactory := NewCollectorFactory()
for _, collector := range []string{"1", "2"} {
collectorFactory.RegisterExternalCollector([]string{"external-" + collector}, &mockCollectorPlugin{Name: "external-" + collector})
}
configs, err := ParseHPAMetrics(tc.hpa)
require.NoError(t, err)
require.Len(t, configs, 1)
collector, err := collectorFactory.NewCollector(tc.hpa, configs[0], 0)
if tc.expectedCollector == "" {
require.Error(t, err)
} else {
require.NoError(t, err)
c, ok := collector.(*mockCollector)
require.True(t, ok)
require.Equal(t, tc.expectedCollector, c.Name)
}
})
}
}

View File

@ -0,0 +1,108 @@
package collector
import (
"fmt"
"net/url"
"time"
"github.com/zalando-incubator/kube-metrics-adapter/pkg/collector/httpmetrics"
"k8s.io/api/autoscaling/v2beta2"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/metrics/pkg/apis/external_metrics"
)
const (
HTTPJSONPathType = "json-path"
HTTPMetricNameLegacy = "http"
HTTPEndpointAnnotationKey = "endpoint"
HTTPJsonPathAnnotationKey = "json-key"
identifierLabel = "identifier"
)
type HTTPCollectorPlugin struct{}
func NewHTTPCollectorPlugin() (*HTTPCollectorPlugin, error) {
return &HTTPCollectorPlugin{}, nil
}
func (p *HTTPCollectorPlugin) NewCollector(hpa *v2beta2.HorizontalPodAutoscaler, config *MetricConfig, interval time.Duration) (Collector, error) {
collector := &HTTPCollector{
namespace: hpa.Namespace,
}
var (
value string
ok bool
)
if value, ok = config.Config[HTTPJsonPathAnnotationKey]; !ok {
return nil, fmt.Errorf("config value %s not found", HTTPJsonPathAnnotationKey)
}
jsonPath := value
if value, ok = config.Config[HTTPEndpointAnnotationKey]; !ok {
return nil, fmt.Errorf("config value %s not found", HTTPEndpointAnnotationKey)
}
var err error
collector.endpoint, err = url.Parse(value)
if err != nil {
return nil, err
}
collector.interval = interval
collector.metricType = config.Type
if config.Metric.Selector == nil || config.Metric.Selector.MatchLabels == nil {
return nil, fmt.Errorf("no label selector specified for metric: %s", config.Metric.Name)
}
if _, ok := config.Metric.Selector.MatchLabels[identifierLabel]; !ok {
return nil, fmt.Errorf("%s is not specified as a label for metric %s", identifierLabel, config.Metric.Name)
}
collector.metric = config.Metric
var aggFunc httpmetrics.AggregatorFunc
if val, ok := config.Config["aggregator"]; ok {
aggFunc, err = httpmetrics.ParseAggregator(val)
if err != nil {
return nil, err
}
}
jsonPathGetter, err := httpmetrics.NewJSONPathMetricsGetter(httpmetrics.DefaultMetricsHTTPClient(), aggFunc, jsonPath)
if err != nil {
return nil, err
}
collector.metricsGetter = jsonPathGetter
return collector, nil
}
type HTTPCollector struct {
endpoint *url.URL
interval time.Duration
namespace string
metricType v2beta2.MetricSourceType
metricsGetter *httpmetrics.JSONPathMetricsGetter
metric v2beta2.MetricIdentifier
}
func (c *HTTPCollector) GetMetrics() ([]CollectedMetric, error) {
metric, err := c.metricsGetter.GetMetric(*c.endpoint)
if err != nil {
return nil, err
}
value := CollectedMetric{
Namespace: c.namespace,
Type: c.metricType,
External: external_metrics.ExternalMetricValue{
MetricName: c.metric.Name,
MetricLabels: c.metric.Selector.MatchLabels,
Timestamp: metav1.Time{
Time: time.Now(),
},
Value: *resource.NewMilliQuantity(int64(metric*1000), resource.DecimalSI),
},
}
return []CollectedMetric{value}, nil
}
func (c *HTTPCollector) Interval() time.Duration {
return c.interval
}

Some files were not shown because too many files have changed in this diff Show More