mirror of
https://github.com/zalando-incubator/kube-metrics-adapter.git
synced 2025-05-12 16:32:00 +00:00
Compare commits
103 Commits
Author | SHA1 | Date | |
---|---|---|---|
49f9f5ffe0 | |||
43dd2e9741 | |||
4aeebc853c | |||
45a09c12a0 | |||
789c2dee79 | |||
bbe5a8a1f7 | |||
32e9a39be0 | |||
afea8de1d9 | |||
a17ad004d3 | |||
ec77258ba4 | |||
3ef92536c1 | |||
ae5c4af76f | |||
b130ce5fa7 | |||
8cd076b01d | |||
15cffaee88 | |||
82a96580a2 | |||
08825c4920 | |||
ac3c500d84 | |||
656a05fe07 | |||
e54f3b88cf | |||
f5124993a2 | |||
7c1339a6f2 | |||
fc2f6aa5df | |||
7448688788 | |||
0e1302a97e | |||
749c1a7e25 | |||
e7eb21a773 | |||
2c3247bf57 | |||
6860217a71 | |||
a66ce04128 | |||
9eabbd53d9 | |||
ec8622c028 | |||
166865edbb | |||
85f1c3e13d | |||
1a5297d6b2 | |||
be0e0d485e | |||
a07eb0b79c | |||
34dc968e77 | |||
9174f2550a | |||
6c4dfd682b | |||
aa3f8ab969 | |||
437bca4de8 | |||
c2fe13d21d | |||
bbfd982fb6 | |||
e9112a7114 | |||
2c526dd498 | |||
29b782160d | |||
28f3d96061 | |||
24b7276282 | |||
542d90d9fe | |||
0f359920af | |||
54e2d2d564 | |||
16ec43c361 | |||
ffcbfcee48 | |||
69f95534e8 | |||
c2179a35ba | |||
35e3fe83e8 | |||
69df60e724 | |||
d171e049bf | |||
b89ca19e6a | |||
a276b64576 | |||
ff6d479f1a | |||
cd986058e4 | |||
d6a33fed63 | |||
b8532b756b | |||
f28653de74 | |||
2f5d3f5a42 | |||
153d754353 | |||
02ec2282ab | |||
65dd585813 | |||
aa7b64e637 | |||
7633ac551e | |||
a103a3295e | |||
f63915f7ff | |||
c4a1e08fdf | |||
61e0336247 | |||
2492bdf5c1 | |||
88b7d747d1 | |||
0794873fcb | |||
e2a922f110 | |||
b631a4fe08 | |||
90fea54307 | |||
8b6a54627d | |||
75738f1eb7 | |||
d8934ebbc1 | |||
17bef811f3 | |||
7a041c991a | |||
979ae68eab | |||
e9a209aa31 | |||
838edd9082 | |||
c50d9ccd18 | |||
c60253e90c | |||
680e0feea1 | |||
070f9ab299 | |||
8ba4d19c35 | |||
37bf73c7fe | |||
d01a3f6347 | |||
50633ba06c | |||
bce27b748c | |||
9e057c1075 | |||
55ce2d8c3d | |||
37969486fe | |||
1be6357c8e |
14
.github/workflows/ci.yaml
vendored
14
.github/workflows/ci.yaml
vendored
@ -1,5 +1,11 @@
|
||||
name: ci
|
||||
on: [push, pull_request]
|
||||
on:
|
||||
push:
|
||||
branches-ignore:
|
||||
- 'gh-pages'
|
||||
pull_request:
|
||||
branches-ignore:
|
||||
- 'gh-pages'
|
||||
jobs:
|
||||
tests:
|
||||
runs-on: ubuntu-latest
|
||||
@ -7,12 +13,10 @@ jobs:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: '^1.18'
|
||||
go-version: '^1.19'
|
||||
- run: go version
|
||||
- run: go install github.com/mattn/goveralls@latest
|
||||
- run: curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin ${GOLANGCI_RELEASE}
|
||||
env:
|
||||
GOLANGCI_RELEASE: v1.46.2
|
||||
- run: go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
|
||||
- run: make build.docker
|
||||
- run: make test
|
||||
- run: make check
|
||||
|
91
.github/workflows/gh-packages.yaml
vendored
Normal file
91
.github/workflows/gh-packages.yaml
vendored
Normal file
@ -0,0 +1,91 @@
|
||||
name: gh-package-deploy
|
||||
permissions: {}
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
tags:
|
||||
- '*'
|
||||
|
||||
env:
|
||||
REGISTRY: ghcr.io
|
||||
IMAGE_NAME: "${{ github.repository }}"
|
||||
|
||||
jobs:
|
||||
docker:
|
||||
if: ${{ github.actor != 'dependabot[bot]' }}
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
# Adding this block will overridw default values to None if not specified in the block
|
||||
# https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs
|
||||
permissions:
|
||||
contents: read
|
||||
actions: read
|
||||
packages: write # to push packages
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
|
||||
|
||||
- uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753
|
||||
with:
|
||||
# https://www.npmjs.com/package/semver#caret-ranges-123-025-004
|
||||
go-version: '^1.21'
|
||||
|
||||
- name: Login to Github Container Registry
|
||||
uses: docker/login-action@465a07811f14bebb1938fbed4728c6a1ff8901fc
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- uses: actions-ecosystem/action-get-latest-tag@b7c32daec3395a9616f88548363a42652b22d435
|
||||
id: get-latest-tag
|
||||
|
||||
- name: Build binaries
|
||||
run: |
|
||||
make build.linux.amd64 build.linux.arm64
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@2b82ce82d56a2a04d2637cd93a637ae1b359c0a7
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@4c0219f9ac95b02789c1075625400b2acbff50b1
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@465a07811f14bebb1938fbed4728c6a1ff8901fc
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Docker meta
|
||||
uses: docker/metadata-action@818d4b7b91585d195f67373fd9cb0332e31a7175
|
||||
id: meta
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
tags: |
|
||||
type=semver,pattern=v{{version}}
|
||||
type=semver,pattern=v{{major}}.{{minor}}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@2eb1c1961a95fc15694676618e422e8ba1d63825
|
||||
with:
|
||||
context: .
|
||||
build-args: BASE_IMAGE=alpine:3
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: ${{ github.event_name != 'pull_request' && startsWith(github.ref, 'refs/tags/v') }}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
|
||||
# Build and push latest tag
|
||||
- name: Build and push latest
|
||||
uses: docker/build-push-action@2eb1c1961a95fc15694676618e422e8ba1d63825
|
||||
with:
|
||||
context: .
|
||||
build-args: BASE_IMAGE=alpine:3
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
27
.github/workflows/release-chart.yml
vendored
Normal file
27
.github/workflows/release-chart.yml
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
name: Release Charts
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Configure Git
|
||||
run: |
|
||||
git config user.name "$GITHUB_ACTOR"
|
||||
git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
|
||||
|
||||
- name: Run chart-releaser
|
||||
uses: helm/chart-releaser-action@v1.4.0
|
||||
with:
|
||||
charts_dir: docs
|
||||
env:
|
||||
CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
@ -1,19 +1,13 @@
|
||||
run:
|
||||
linters-settings:
|
||||
golint:
|
||||
min-confidence: 0.9
|
||||
concurrency: 4
|
||||
|
||||
linters:
|
||||
disable-all: true
|
||||
enable:
|
||||
- staticcheck
|
||||
- ineffassign
|
||||
- golint
|
||||
- goimports
|
||||
- errcheck
|
||||
issues:
|
||||
exclude-rules:
|
||||
# Exclude some staticcheck messages
|
||||
- linters:
|
||||
- staticcheck
|
||||
text: "SA9003:"
|
||||
- errcheck
|
||||
- gosimple
|
||||
- govet
|
||||
- ineffassign
|
||||
- staticcheck
|
||||
- typecheck
|
||||
- unused
|
||||
|
@ -50,7 +50,7 @@ contribution is in line with our goals.
|
||||
- Make sure you sign-off on your commits `git commit -s -m "adding X to change Y"`
|
||||
- Write good commit messages (see below).
|
||||
- Push your changes to a topic branch in your fork of the repository.
|
||||
- As you push your changes, update the pull request with new infomation and tasks as you complete them
|
||||
- As you push your changes, update the pull request with new information and tasks as you complete them
|
||||
- Project maintainers might comment on your work as you progress
|
||||
- When you are done, remove the `work in progess` label and ping the maintainers for a review
|
||||
- Your pull request must receive a :thumbsup: from two [maintainers](MAINTAINERS)
|
||||
|
@ -1,9 +1,11 @@
|
||||
FROM registry.opensource.zalan.do/library/alpine-3.13:latest
|
||||
ARG BASE_IMAGE=registry.opensource.zalan.do/library/alpine-3:latest
|
||||
FROM ${BASE_IMAGE}
|
||||
LABEL maintainer="Team Teapot @ Zalando SE <team-teapot@zalando.de>"
|
||||
|
||||
RUN apk add --no-cache tzdata
|
||||
|
||||
# add binary
|
||||
ADD build/linux/kube-metrics-adapter /
|
||||
ARG TARGETARCH
|
||||
|
||||
ADD build/linux/${TARGETARCH}/kube-metrics-adapter /
|
||||
|
||||
ENTRYPOINT ["/kube-metrics-adapter"]
|
||||
|
13
Makefile
13
Makefile
@ -50,7 +50,9 @@ $(OPENAPI): go.mod
|
||||
|
||||
build.local: build/$(BINARY) $(GENERATED_CRDS)
|
||||
build.linux: build/linux/$(BINARY)
|
||||
build.osx: build/osx/$(BINARY)
|
||||
build.linux.amd64: build/linux/amd64/$(BINARY)
|
||||
build.linux.arm64: build/linux/arm64/$(BINARY)
|
||||
|
||||
|
||||
build/$(BINARY): go.mod $(SOURCES) $(GENERATED)
|
||||
CGO_ENABLED=0 go build -o build/$(BINARY) $(BUILD_FLAGS) -ldflags "$(LDFLAGS)" .
|
||||
@ -58,11 +60,14 @@ build/$(BINARY): go.mod $(SOURCES) $(GENERATED)
|
||||
build/linux/$(BINARY): go.mod $(SOURCES) $(GENERATED)
|
||||
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build $(BUILD_FLAGS) -o build/linux/$(BINARY) -ldflags "$(LDFLAGS)" .
|
||||
|
||||
build/osx/$(BINARY): go.mod $(SOURCES) $(GENERATED)
|
||||
GOOS=darwin GOARCH=amd64 CGO_ENABLED=0 go build $(BUILD_FLAGS) -o build/osx/$(BINARY) -ldflags "$(LDFLAGS)" .
|
||||
build/linux/amd64/$(BINARY): go.mod $(SOURCES)
|
||||
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build $(BUILD_FLAGS) -o build/linux/amd64/$(BINARY) -ldflags "$(LDFLAGS)" .
|
||||
|
||||
build/linux/arm64/$(BINARY): go.mod $(SOURCES)
|
||||
GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build $(BUILD_FLAGS) -o build/linux/arm64/$(BINARY) -ldflags "$(LDFLAGS)" .
|
||||
|
||||
build.docker: build.linux
|
||||
docker build --rm -t "$(IMAGE):$(TAG)" -f $(DOCKERFILE) .
|
||||
docker build --rm -t "$(IMAGE):$(TAG)" -f $(DOCKERFILE) --build-arg TARGETARCH= .
|
||||
|
||||
build.push: build.docker
|
||||
docker push "$(IMAGE):$(TAG)"
|
||||
|
173
README.md
173
README.md
@ -17,7 +17,7 @@ Here's an example of a `HorizontalPodAutoscaler` resource configured to get
|
||||
`requests-per-second` metrics from each pod of the deployment `myapp`.
|
||||
|
||||
```yaml
|
||||
apiVersion: autoscaling/v2beta2
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: myapp-hpa
|
||||
@ -54,10 +54,8 @@ policy](https://kubernetes.io/docs/setup/release/version-skew-policy/) offered
|
||||
for Kubernetes, this project aims to support the latest three minor releases of
|
||||
Kubernetes.
|
||||
|
||||
The default supported API is `autoscaling/v2beta2` (available since `v1.12`).
|
||||
This API MUST be available in the cluster which is the default. However for
|
||||
GKE, this requires GKE v1.15.7 according to this [GKE
|
||||
Issue](https://issuetracker.google.com/issues/135624588).
|
||||
The default supported API is `autoscaling/v2` (available since `v1.23`).
|
||||
This API MUST be available in the cluster which is the default.
|
||||
|
||||
## Building
|
||||
|
||||
@ -99,7 +97,7 @@ This is an example of using the pod collector to collect metrics from a json
|
||||
metrics endpoint of each pod matched by the HPA.
|
||||
|
||||
```yaml
|
||||
apiVersion: autoscaling/v2beta2
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: myapp-hpa
|
||||
@ -219,7 +217,7 @@ with the result of the query.
|
||||
This allows having multiple prometheus queries associated with a single HPA.
|
||||
|
||||
```yaml
|
||||
apiVersion: autoscaling/v2beta2
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: myapp-hpa
|
||||
@ -331,7 +329,7 @@ This is an example of an HPA that will scale based on `requests-per-second` for
|
||||
an ingress called `myapp`.
|
||||
|
||||
```yaml
|
||||
apiVersion: autoscaling/v2beta2
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: myapp-hpa
|
||||
@ -365,7 +363,7 @@ This is an example of an HPA that will scale based on `requests-per-second` for
|
||||
a routegroup called `myapp`.
|
||||
|
||||
```yaml
|
||||
apiVersion: autoscaling/v2beta2
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: myapp-hpa
|
||||
@ -404,6 +402,64 @@ the `backend` label under `matchLabels` for the metric. The ingress annotation
|
||||
where the backend weights can be obtained can be specified through the flag
|
||||
`--skipper-backends-annotation`.
|
||||
|
||||
## External RPS collector
|
||||
|
||||
The External RPS collector, like Skipper collector, is a simple wrapper around the Prometheus collector to
|
||||
make it easy to define an HPA for scaling based on the RPS measured for a given hostname. When
|
||||
[skipper](https://github.com/zalando/skipper) is used as the ingress
|
||||
implementation in your cluster everything should work automatically, in case another reverse proxy is used as ingress, like [Nginx](https://github.com/kubernetes/ingress-nginx) for example, its necessary to configure which prometheus metric should be used through `--external-rps-metric-name <metric-name>` flag. Assuming `skipper-ingress` is being used or the appropriate metric name is passed using the flag mentioned previously this collector provides the correct Prometheus queries out of the
|
||||
box so users don't have to define those manually.
|
||||
|
||||
### Supported metrics
|
||||
|
||||
| Metric | Description | Type | Kind | K8s Versions |
|
||||
| ------------ | -------------- | ------- | -- | -- |
|
||||
| `requests-per-second` | Scale based on requests per second for a certain hostname. | External | | `>=1.12` |
|
||||
|
||||
### Example: External Metric
|
||||
|
||||
This is an example of an HPA that will scale based on `requests-per-second` for the RPS measured in the hostnames called: `www.example1.com` and `www.example2.com`; and weighted by 42%.
|
||||
|
||||
```yaml
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: myapp-hpa
|
||||
annotations:
|
||||
metric-config.external.example-rps.requests-per-second/hostname: www.example1.com,www.example2.com
|
||||
metric-config.external.example-rps.requests-per-second/weight: "42"
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: custom-metrics-consumer
|
||||
minReplicas: 1
|
||||
maxReplicas: 10
|
||||
metrics:
|
||||
- type: External
|
||||
external:
|
||||
metric:
|
||||
name: example-rps
|
||||
selector:
|
||||
matchLabels:
|
||||
type: requests-per-second
|
||||
target:
|
||||
type: AverageValue
|
||||
averageValue: "42"
|
||||
```
|
||||
### Multiple hostnames per metric
|
||||
|
||||
This metric supports a relation of n:1 between hostnames and metrics. The way it works is the measured RPS is the sum of the RPS rate of each of the specified hostnames. This value is further modified by the weight parameter explained below.
|
||||
|
||||
### Metric weighting based on backend
|
||||
|
||||
There are ingress-controllers, like skipper-ingress, that supports sending traffic to different backends based on some kind of configuration, in case of skipper annotations
|
||||
present on the `Ingress` object, or weights on the RouteGroup backends. By
|
||||
default the number of replicas will be calculated based on the full traffic
|
||||
served by these components. If however only the traffic being routed to
|
||||
a specific hostname should be used then the weight for the configured hostname(s) might be specified via the `weight` annotation `metric-config.external.<metric-name>.request-per-second/weight` for the metric being configured.
|
||||
|
||||
|
||||
## InfluxDB collector
|
||||
|
||||
The InfluxDB collector maps [Flux](https://github.com/influxdata/flux) queries to metrics that can be used for scaling.
|
||||
@ -426,7 +482,7 @@ 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
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: myapp-hpa
|
||||
@ -514,7 +570,7 @@ This is an example of an HPA that will scale based on the length of an SQS
|
||||
queue.
|
||||
|
||||
```yaml
|
||||
apiVersion: autoscaling/v2beta2
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: myapp-hpa
|
||||
@ -566,7 +622,7 @@ This is an example of an HPA that will scale based on the specified value
|
||||
exposed by a ZMON check with id `1234`.
|
||||
|
||||
```yaml
|
||||
apiVersion: autoscaling/v2beta2
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: myapp-hpa
|
||||
@ -646,6 +702,95 @@ you need to define a `key` or other `tag` with a "star" query syntax like
|
||||
metric label definitions. If both annotations and corresponding label is
|
||||
defined, then the annotation takes precedence.
|
||||
|
||||
|
||||
## Nakadi collector
|
||||
|
||||
The Nakadi collector allows scaling based on [Nakadi](https://nakadi.io/)
|
||||
Subscription API stats metrics `consumer_lag_seconds` or `unconsumed_events`.
|
||||
|
||||
### Supported metrics
|
||||
|
||||
| Metric Type | Description | Type | K8s Versions |
|
||||
|------------------------|-----------------------------------------------------------------------------|----------|--------------|
|
||||
| `unconsumed-events` | Scale based on number of unconsumed events for a Nakadi subscription | External | `>=1.24` |
|
||||
| `consumer-lag-seconds` | Scale based on number of max consumer lag seconds for a Nakadi subscription | External | `>=1.24` |
|
||||
| ------------ | ------- | -- | -- |
|
||||
| `unconsumed-events` | Scale based on number of unconsumed events for a Nakadi Subscription | External | `>=1.24` |
|
||||
| `consumer-lag-seconds` | Scale based on number of max consumer lag seconds for a Nakadi Subscription | External | `>=1.24` |
|
||||
|
||||
```yaml
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: myapp-hpa
|
||||
annotations:
|
||||
# metric-config.<metricType>.<metricName>.<collectorType>/<configKey>
|
||||
metric-config.external.my-nakadi-consumer.nakadi/interval: "60s" # optional
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: custom-metrics-consumer
|
||||
minReplicas: 0
|
||||
maxReplicas: 8 # should match number of partitions for the event type
|
||||
metrics:
|
||||
- type: External
|
||||
external:
|
||||
metric:
|
||||
name: my-nakadi-consumer
|
||||
selector:
|
||||
matchLabels:
|
||||
type: nakadi
|
||||
subscription-id: "708095f6-cece-4d02-840e-ee488d710b29"
|
||||
metric-type: "consumer-lag-seconds|unconsumed-events"
|
||||
target:
|
||||
# value is compatible with the consumer-lag-seconds metric type.
|
||||
# It describes the amount of consumer lag in seconds before scaling
|
||||
# additionally up.
|
||||
# if an event-type has multiple partitions the value of
|
||||
# consumer-lag-seconds is the max of all the partitions.
|
||||
value: "600" # 10m
|
||||
# averageValue is compatible with unconsumed-events metric type.
|
||||
# This means for every 30 unconsumed events a pod is added.
|
||||
# unconsumed-events is the sum of of unconsumed_events over all
|
||||
# partitions.
|
||||
averageValue: "30"
|
||||
type: AverageValue
|
||||
```
|
||||
|
||||
The `subscription-id` is the Subscription ID of the relevant consumer. The
|
||||
`metric-type` indicates whether to scale on `consumer-lag-seconds` or
|
||||
`unconsumed-events` as outlined below.
|
||||
|
||||
`unconsumed-events` - is the total number of unconsumed events over all
|
||||
partitions. When using this `metric-type` you should also use the target
|
||||
`averageValue` which indicates the number of events which can be handled per
|
||||
pod. To best estimate the number of events per pods, you need to understand the
|
||||
average time for processing an event as well as the rate of events.
|
||||
|
||||
*Example*: You have an event type producing 100 events per second between 00:00
|
||||
and 08:00. Between 08:01 to 23:59 it produces 400 events per second.
|
||||
Let's assume that on average a single pod can consume 100 events per second,
|
||||
then we can define 100 as `averageValue` and the HPA would scale to 1 between
|
||||
00:00 and 08:00, and scale to 4 between 08:01 and 23:59. If there for some
|
||||
reason is a short spike of 800 events per second, then it would scale to 8 pods
|
||||
to process those events until the rate goes down again.
|
||||
|
||||
`consumer-lag-seconds` - describes the age of the oldest unconsumed event for
|
||||
a subscription. If the event type has multiple partitions the lag is defined as
|
||||
the max age over all partitions. When using this `metric-type` you should use
|
||||
the target `value` to indicate the max lag (in seconds) before the HPA should
|
||||
scale.
|
||||
|
||||
*Example*: You have a subscription with a defined SLO of "99.99 of events are
|
||||
consumed within 30 min.". In this case you can define a target `value` of e.g.
|
||||
20 min. (1200s) (to include a safety buffer) such that the HPA only scales up
|
||||
from 1 to 2 if the target of 20 min. is breached and it needs to work faster
|
||||
with more consumers.
|
||||
For this case you should also account for the average time for processing an
|
||||
event when defining the target.
|
||||
|
||||
|
||||
## HTTP Collector
|
||||
|
||||
The http collector allows collecting metrics from an external endpoint specified in the HPA.
|
||||
@ -663,7 +808,7 @@ 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
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: myapp-hpa
|
||||
@ -830,7 +975,7 @@ An HPA can reference the deployed `ClusterScalingSchedule` object as
|
||||
this example:
|
||||
|
||||
```yaml
|
||||
apiVersion: autoscaling/v2beta2
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: "myapp-hpa"
|
||||
|
@ -30,3 +30,17 @@ pipeline:
|
||||
IMAGE=$IMAGE VERSION=$VERSION make build.docker
|
||||
git diff --stat --exit-code
|
||||
IMAGE=$IMAGE VERSION=$VERSION make build.push
|
||||
- desc: Build and push image to Zalando's registry
|
||||
cmd: |
|
||||
if [[ $CDP_TARGET_BRANCH == master && ! $CDP_PULL_REQUEST_NUMBER ]]; then
|
||||
IMAGE=container-registry-test.zalando.net/teapot/kube-metrics-adapter
|
||||
VERSION=$(git describe --tags --always)
|
||||
else
|
||||
IMAGE=container-registry-test.zalando.net/teapot/kube-metrics-adapter-test
|
||||
VERSION=$CDP_BUILD_VERSION
|
||||
fi
|
||||
make build.linux.amd64 build.linux.arm64
|
||||
|
||||
docker buildx create --config /etc/cdp-buildkitd.toml --driver-opt network=host --bootstrap --use
|
||||
docker buildx build --rm --build-arg BASE_IMAGE=container-registry.zalando.net/library/alpine-3:latest -t "${IMAGE}:${VERSION}" --platform linux/amd64,linux/arm64 --push .
|
||||
cdp-promote-image "${IMAGE}:${VERSION}"
|
||||
|
@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.8.0
|
||||
controller-gen.kubebuilder.io/version: v0.9.0
|
||||
creationTimestamp: null
|
||||
name: clusterscalingschedules.zalando.org
|
||||
spec:
|
||||
@ -15,7 +15,12 @@ spec:
|
||||
singular: clusterscalingschedule
|
||||
scope: Cluster
|
||||
versions:
|
||||
- name: v1
|
||||
- additionalPrinterColumns:
|
||||
- description: Whether one or more schedules are currently active.
|
||||
jsonPath: .status.active
|
||||
name: Active
|
||||
type: boolean
|
||||
name: v1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: ClusterScalingSchedule describes a cluster scoped time based
|
||||
@ -51,13 +56,18 @@ spec:
|
||||
properties:
|
||||
date:
|
||||
description: Defines the starting date of a OneTime schedule.
|
||||
It has to be a RFC3339 formated date.
|
||||
It has to be a RFC3339 formatted date.
|
||||
format: date-time
|
||||
type: string
|
||||
durationMinutes:
|
||||
description: The duration in minutes that the configured value
|
||||
will be returned for the defined schedule.
|
||||
description: The duration in minutes (default 0) that the configured
|
||||
value will be returned for the defined schedule.
|
||||
type: integer
|
||||
endDate:
|
||||
description: Defines the ending date of a OneTime schedule.
|
||||
It must be a RFC3339 formatted date.
|
||||
format: date-time
|
||||
type: string
|
||||
period:
|
||||
description: Defines the details of a Repeating schedule.
|
||||
properties:
|
||||
@ -76,6 +86,10 @@ spec:
|
||||
- Sat
|
||||
type: string
|
||||
type: array
|
||||
endTime:
|
||||
description: The endTime has the format HH:MM
|
||||
pattern: (([0-1][0-9])|([2][0-3])):([0-5][0-9])
|
||||
type: string
|
||||
startTime:
|
||||
description: The startTime has the format HH:MM
|
||||
pattern: (([0-1][0-9])|([2][0-3])):([0-5][0-9])
|
||||
@ -103,7 +117,6 @@ spec:
|
||||
format: int64
|
||||
type: integer
|
||||
required:
|
||||
- durationMinutes
|
||||
- type
|
||||
- value
|
||||
type: object
|
||||
@ -111,14 +124,19 @@ spec:
|
||||
required:
|
||||
- schedules
|
||||
type: object
|
||||
status:
|
||||
description: ScalingScheduleStatus is the status section of the ScalingSchedule.
|
||||
properties:
|
||||
active:
|
||||
default: false
|
||||
description: Active is true if at least one of the schedules defined
|
||||
in the scaling schedule is currently active.
|
||||
type: boolean
|
||||
type: object
|
||||
required:
|
||||
- spec
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: []
|
||||
storedVersions: []
|
||||
subresources:
|
||||
status: {}
|
||||
|
@ -22,7 +22,7 @@ spec:
|
||||
serviceAccountName: custom-metrics-apiserver
|
||||
containers:
|
||||
- name: kube-metrics-adapter
|
||||
image: registry.opensource.zalan.do/teapot/kube-metrics-adapter:latest
|
||||
image: ghcr.io/zalando-incubator/kube-metrics-adapter:latest
|
||||
args:
|
||||
# - --v=9
|
||||
- --prometheus-server=http://prometheus.kube-system.svc.cluster.local
|
||||
|
@ -1,6 +1,6 @@
|
||||
apiVersion: v2
|
||||
name: kube-metrics-adapter
|
||||
version: 0.1.18
|
||||
version: 0.2.0
|
||||
description: kube-metrics-adapter helm chart
|
||||
home: https://github.com/zalando-incubator/kube-metrics-adapter
|
||||
maintainers:
|
||||
|
@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.5.0
|
||||
controller-gen.kubebuilder.io/version: v0.8.0
|
||||
creationTimestamp: null
|
||||
name: clusterscalingschedules.zalando.org
|
||||
spec:
|
||||
@ -15,7 +15,12 @@ spec:
|
||||
singular: clusterscalingschedule
|
||||
scope: Cluster
|
||||
versions:
|
||||
- name: v1
|
||||
- additionalPrinterColumns:
|
||||
- description: Whether one or more schedules are currently active.
|
||||
jsonPath: .status.active
|
||||
name: Active
|
||||
type: boolean
|
||||
name: v1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: ClusterScalingSchedule describes a cluster scoped time based
|
||||
@ -36,6 +41,11 @@ spec:
|
||||
spec:
|
||||
description: ScalingScheduleSpec is the spec part of the ScalingSchedule.
|
||||
properties:
|
||||
scalingWindowDurationMinutes:
|
||||
description: Fade the scheduled values in and out over this many minutes.
|
||||
If unset, the default per-cluster value will be used.
|
||||
format: int64
|
||||
type: integer
|
||||
schedules:
|
||||
description: Schedules is the list of schedules for this ScalingSchedule
|
||||
resource. All the schedules defined here will result on the value
|
||||
@ -46,13 +56,18 @@ spec:
|
||||
properties:
|
||||
date:
|
||||
description: Defines the starting date of a OneTime schedule.
|
||||
It has to be a RFC3339 formated date.
|
||||
It has to be a RFC3339 formatted date.
|
||||
format: date-time
|
||||
type: string
|
||||
durationMinutes:
|
||||
description: The duration in minutes that the configured value
|
||||
will be returned for the defined schedule.
|
||||
description: The duration in minutes (default 0) that the configured
|
||||
value will be returned for the defined schedule.
|
||||
type: integer
|
||||
endDate:
|
||||
description: Defines the ending date of a OneTime schedule.
|
||||
It must be a RFC3339 formatted date.
|
||||
format: date-time
|
||||
type: string
|
||||
period:
|
||||
description: Defines the details of a Repeating schedule.
|
||||
properties:
|
||||
@ -71,6 +86,10 @@ spec:
|
||||
- Sat
|
||||
type: string
|
||||
type: array
|
||||
endTime:
|
||||
description: The endTime has the format HH:MM
|
||||
pattern: (([0-1][0-9])|([2][0-3])):([0-5][0-9])
|
||||
type: string
|
||||
startTime:
|
||||
description: The startTime has the format HH:MM
|
||||
pattern: (([0-1][0-9])|([2][0-3])):([0-5][0-9])
|
||||
@ -95,9 +114,9 @@ spec:
|
||||
value:
|
||||
description: The metric value that will be returned for the
|
||||
defined schedule.
|
||||
format: int64
|
||||
type: integer
|
||||
required:
|
||||
- durationMinutes
|
||||
- type
|
||||
- value
|
||||
type: object
|
||||
@ -105,11 +124,22 @@ spec:
|
||||
required:
|
||||
- schedules
|
||||
type: object
|
||||
status:
|
||||
description: ScalingScheduleStatus is the status section of the ScalingSchedule.
|
||||
properties:
|
||||
active:
|
||||
default: false
|
||||
description: Active is true if at least one of the schedules defined
|
||||
in the scaling schedule is currently active.
|
||||
type: boolean
|
||||
type: object
|
||||
required:
|
||||
- spec
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
|
@ -164,6 +164,9 @@ spec:
|
||||
{{- if .Values.skipperIngressMetrics }}
|
||||
- --skipper-ingress-metrics={{ .Values.skipperIngressMetrics }}
|
||||
{{- end}}
|
||||
{{- if .Values.skipperRouteGroupMetrics }}
|
||||
- --skipper-routegroup-metrics={{ .Values.skipperRouteGroupMetrics }}
|
||||
{{- end}}
|
||||
{{- if .Values.log.stderrThreshold }}
|
||||
- --stderrthreshold={{ .Values.log.stderrThreshold }}
|
||||
{{- end}}
|
||||
|
@ -59,12 +59,22 @@ rules:
|
||||
- statefulsets
|
||||
verbs:
|
||||
- get
|
||||
{{- if .Values.skipperRouteGroupMetrics }}
|
||||
- apiGroups:
|
||||
- networking.k8s.io
|
||||
resources:
|
||||
- ingresses
|
||||
verbs:
|
||||
- get
|
||||
{{- end }}
|
||||
{{- if .Values.skipperRouteGroupMetrics }}
|
||||
- apiGroups:
|
||||
- zalando.org
|
||||
resources:
|
||||
- routegroups
|
||||
verbs:
|
||||
- get
|
||||
{{- end }}
|
||||
- apiGroups:
|
||||
- autoscaling
|
||||
resources:
|
||||
@ -83,6 +93,13 @@ rules:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- zalando.org
|
||||
resources:
|
||||
- clusterscalingschedules/status
|
||||
- scalingschedules/status
|
||||
verbs:
|
||||
- update
|
||||
{{- end}}
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
|
@ -3,19 +3,26 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.5.0
|
||||
controller-gen.kubebuilder.io/version: v0.8.0
|
||||
creationTimestamp: null
|
||||
name: scalingschedules.zalando.org
|
||||
spec:
|
||||
group: zalando.org
|
||||
names:
|
||||
categories:
|
||||
- all
|
||||
kind: ScalingSchedule
|
||||
listKind: ScalingScheduleList
|
||||
plural: scalingschedules
|
||||
singular: scalingschedule
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- name: v1
|
||||
- additionalPrinterColumns:
|
||||
- description: Whether one or more schedules are currently active.
|
||||
jsonPath: .status.active
|
||||
name: Active
|
||||
type: boolean
|
||||
name: v1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: ScalingSchedule describes a namespaced time based metric to be
|
||||
@ -36,6 +43,11 @@ spec:
|
||||
spec:
|
||||
description: ScalingScheduleSpec is the spec part of the ScalingSchedule.
|
||||
properties:
|
||||
scalingWindowDurationMinutes:
|
||||
description: Fade the scheduled values in and out over this many minutes.
|
||||
If unset, the default per-cluster value will be used.
|
||||
format: int64
|
||||
type: integer
|
||||
schedules:
|
||||
description: Schedules is the list of schedules for this ScalingSchedule
|
||||
resource. All the schedules defined here will result on the value
|
||||
@ -46,13 +58,18 @@ spec:
|
||||
properties:
|
||||
date:
|
||||
description: Defines the starting date of a OneTime schedule.
|
||||
It has to be a RFC3339 formated date.
|
||||
It has to be a RFC3339 formatted date.
|
||||
format: date-time
|
||||
type: string
|
||||
durationMinutes:
|
||||
description: The duration in minutes that the configured value
|
||||
will be returned for the defined schedule.
|
||||
description: The duration in minutes (default 0) that the configured
|
||||
value will be returned for the defined schedule.
|
||||
type: integer
|
||||
endDate:
|
||||
description: Defines the ending date of a OneTime schedule.
|
||||
It must be a RFC3339 formatted date.
|
||||
format: date-time
|
||||
type: string
|
||||
period:
|
||||
description: Defines the details of a Repeating schedule.
|
||||
properties:
|
||||
@ -71,6 +88,10 @@ spec:
|
||||
- Sat
|
||||
type: string
|
||||
type: array
|
||||
endTime:
|
||||
description: The endTime has the format HH:MM
|
||||
pattern: (([0-1][0-9])|([2][0-3])):([0-5][0-9])
|
||||
type: string
|
||||
startTime:
|
||||
description: The startTime has the format HH:MM
|
||||
pattern: (([0-1][0-9])|([2][0-3])):([0-5][0-9])
|
||||
@ -95,9 +116,9 @@ spec:
|
||||
value:
|
||||
description: The metric value that will be returned for the
|
||||
defined schedule.
|
||||
format: int64
|
||||
type: integer
|
||||
required:
|
||||
- durationMinutes
|
||||
- type
|
||||
- value
|
||||
type: object
|
||||
@ -105,11 +126,22 @@ spec:
|
||||
required:
|
||||
- schedules
|
||||
type: object
|
||||
status:
|
||||
description: ScalingScheduleStatus is the status section of the ScalingSchedule.
|
||||
properties:
|
||||
active:
|
||||
default: false
|
||||
description: Active is true if at least one of the schedules defined
|
||||
in the scaling schedule is currently active.
|
||||
type: boolean
|
||||
type: object
|
||||
required:
|
||||
- spec
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
|
@ -4,7 +4,7 @@ replicas: 1
|
||||
|
||||
registry:
|
||||
image: registry.opensource.zalan.do/teapot/kube-metrics-adapter
|
||||
imageTag: v0.1.10
|
||||
imageTag: v0.2.0
|
||||
imagePullPolicy: IfNotPresent
|
||||
|
||||
service:
|
||||
@ -22,6 +22,7 @@ http2MaxStreamsPerConnection:
|
||||
listerKubeConfig:
|
||||
skipperBackendsAnnotation:
|
||||
skipperIngressMetrics:
|
||||
skipperRouteGroupMetrics:
|
||||
token:
|
||||
vmodule:
|
||||
|
||||
|
@ -97,6 +97,13 @@ rules:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- zalando.org
|
||||
resources:
|
||||
- clusterscalingschedules/status
|
||||
- scalingschedules/status
|
||||
verbs:
|
||||
- update
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
|
@ -3,19 +3,26 @@ apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.8.0
|
||||
controller-gen.kubebuilder.io/version: v0.9.0
|
||||
creationTimestamp: null
|
||||
name: scalingschedules.zalando.org
|
||||
spec:
|
||||
group: zalando.org
|
||||
names:
|
||||
categories:
|
||||
- all
|
||||
kind: ScalingSchedule
|
||||
listKind: ScalingScheduleList
|
||||
plural: scalingschedules
|
||||
singular: scalingschedule
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- name: v1
|
||||
- additionalPrinterColumns:
|
||||
- description: Whether one or more schedules are currently active.
|
||||
jsonPath: .status.active
|
||||
name: Active
|
||||
type: boolean
|
||||
name: v1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: ScalingSchedule describes a namespaced time based metric to be
|
||||
@ -51,13 +58,18 @@ spec:
|
||||
properties:
|
||||
date:
|
||||
description: Defines the starting date of a OneTime schedule.
|
||||
It has to be a RFC3339 formated date.
|
||||
It has to be a RFC3339 formatted date.
|
||||
format: date-time
|
||||
type: string
|
||||
durationMinutes:
|
||||
description: The duration in minutes that the configured value
|
||||
will be returned for the defined schedule.
|
||||
description: The duration in minutes (default 0) that the configured
|
||||
value will be returned for the defined schedule.
|
||||
type: integer
|
||||
endDate:
|
||||
description: Defines the ending date of a OneTime schedule.
|
||||
It must be a RFC3339 formatted date.
|
||||
format: date-time
|
||||
type: string
|
||||
period:
|
||||
description: Defines the details of a Repeating schedule.
|
||||
properties:
|
||||
@ -76,6 +88,10 @@ spec:
|
||||
- Sat
|
||||
type: string
|
||||
type: array
|
||||
endTime:
|
||||
description: The endTime has the format HH:MM
|
||||
pattern: (([0-1][0-9])|([2][0-3])):([0-5][0-9])
|
||||
type: string
|
||||
startTime:
|
||||
description: The startTime has the format HH:MM
|
||||
pattern: (([0-1][0-9])|([2][0-3])):([0-5][0-9])
|
||||
@ -103,7 +119,6 @@ spec:
|
||||
format: int64
|
||||
type: integer
|
||||
required:
|
||||
- durationMinutes
|
||||
- type
|
||||
- value
|
||||
type: object
|
||||
@ -111,14 +126,19 @@ spec:
|
||||
required:
|
||||
- schedules
|
||||
type: object
|
||||
status:
|
||||
description: ScalingScheduleStatus is the status section of the ScalingSchedule.
|
||||
properties:
|
||||
active:
|
||||
default: false
|
||||
description: Active is true if at least one of the schedules defined
|
||||
in the scaling schedule is currently active.
|
||||
type: boolean
|
||||
type: object
|
||||
required:
|
||||
- spec
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
status:
|
||||
acceptedNames:
|
||||
kind: ""
|
||||
plural: ""
|
||||
conditions: []
|
||||
storedVersions: []
|
||||
subresources:
|
||||
status: {}
|
||||
|
@ -1,4 +1,4 @@
|
||||
FROM registry.opensource.zalan.do/library/alpine-3.13:latest
|
||||
FROM registry.opensource.zalan.do/library/alpine-3:latest
|
||||
LABEL maintainer="Team Teapot @ Zalando SE <team-teapot@zalando.de>"
|
||||
|
||||
# add binary
|
||||
|
153
go.mod
153
go.mod
@ -1,123 +1,128 @@
|
||||
module github.com/zalando-incubator/kube-metrics-adapter
|
||||
|
||||
require (
|
||||
github.com/aws/aws-sdk-go v1.44.25
|
||||
github.com/aws/aws-sdk-go v1.48.10
|
||||
github.com/influxdata/influxdb-client-go v0.2.0
|
||||
github.com/kubernetes-sigs/custom-metrics-apiserver v0.0.0-20201216091021-1b9fa998bbaa
|
||||
github.com/prometheus/client_golang v1.12.2
|
||||
github.com/prometheus/common v0.34.0
|
||||
github.com/sirupsen/logrus v1.8.1
|
||||
github.com/spf13/cobra v1.4.0
|
||||
github.com/spyzhov/ajson v0.7.1
|
||||
github.com/stretchr/testify v1.7.1
|
||||
github.com/szuecs/routegroup-client v0.21.0
|
||||
github.com/zalando-incubator/cluster-lifecycle-manager v0.0.0-20220201095549-bbdeecaa4fc1
|
||||
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b
|
||||
k8s.io/api v0.23.0
|
||||
k8s.io/apimachinery v0.23.0
|
||||
k8s.io/apiserver v0.23.0
|
||||
k8s.io/client-go v0.23.0
|
||||
k8s.io/code-generator v0.23.0
|
||||
k8s.io/component-base v0.23.0
|
||||
github.com/prometheus/client_golang v1.17.0
|
||||
github.com/prometheus/common v0.45.0
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/spf13/cobra v1.8.0
|
||||
github.com/spyzhov/ajson v0.9.0
|
||||
github.com/stretchr/testify v1.8.4
|
||||
github.com/szuecs/routegroup-client v0.21.1
|
||||
github.com/zalando-incubator/cluster-lifecycle-manager v0.0.0-20230601114834-6ed1bba3c85d
|
||||
golang.org/x/net v0.19.0
|
||||
golang.org/x/oauth2 v0.13.0
|
||||
golang.org/x/sync v0.5.0
|
||||
k8s.io/api v0.24.17
|
||||
k8s.io/apimachinery v0.24.17
|
||||
k8s.io/apiserver v0.24.17
|
||||
k8s.io/client-go v0.24.17
|
||||
k8s.io/code-generator v0.24.17
|
||||
k8s.io/component-base v0.24.17
|
||||
k8s.io/klog v1.0.0
|
||||
k8s.io/kube-openapi v0.0.0-20220124234850-424119656bbf
|
||||
k8s.io/metrics v0.21.9
|
||||
sigs.k8s.io/controller-tools v0.8.0
|
||||
k8s.io/kube-openapi v0.0.0-20230614213217-ba0abe644833
|
||||
k8s.io/metrics v0.24.17
|
||||
sigs.k8s.io/controller-tools v0.9.0
|
||||
sigs.k8s.io/custom-metrics-apiserver v1.24.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/NYTimes/gziphandler v1.1.1 // indirect
|
||||
github.com/PuerkitoBio/purell v1.1.1 // indirect
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/blang/semver v3.5.1+incompatible // indirect
|
||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
github.com/blang/semver/v4 v4.0.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/coreos/go-semver v0.3.0 // indirect
|
||||
github.com/coreos/go-systemd/v22 v22.3.2 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/emicklei/go-restful v2.14.3+incompatible // indirect
|
||||
github.com/emicklei/go-restful v2.16.0+incompatible // indirect
|
||||
github.com/evanphx/json-patch v4.12.0+incompatible // indirect
|
||||
github.com/fatih/color v1.13.0 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.2 // indirect
|
||||
github.com/fsnotify/fsnotify v1.5.1 // indirect
|
||||
github.com/go-logr/logr v1.2.2 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
||||
github.com/go-openapi/jsonreference v0.19.6 // indirect
|
||||
github.com/go-openapi/swag v0.21.1 // indirect
|
||||
github.com/gobuffalo/flect v0.2.3 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.3 // indirect
|
||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||
github.com/go-logr/logr v1.2.4 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.6 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.2 // indirect
|
||||
github.com/go-openapi/swag v0.22.4 // indirect
|
||||
github.com/gobuffalo/flect v0.2.5 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/google/go-cmp v0.5.7 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/google/gnostic v0.6.9 // indirect
|
||||
github.com/google/go-cmp v0.5.9 // indirect
|
||||
github.com/google/gofuzz v1.2.0 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/googleapis/gnostic v0.5.5 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect
|
||||
github.com/imdario/mergo v0.3.6 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.0.0 // indirect
|
||||
github.com/imdario/mergo v0.3.16 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/influxdata/line-protocol v0.0.0-20210922203350-b1ad95c89adf // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mattn/go-colorable v0.1.12 // indirect
|
||||
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.17 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/client_model v0.2.0 // indirect
|
||||
github.com/prometheus/procfs v0.7.3 // indirect
|
||||
github.com/spf13/afero v1.8.1 // indirect
|
||||
github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16 // indirect
|
||||
github.com/prometheus/procfs v0.11.1 // indirect
|
||||
github.com/rogpeppe/go-internal v1.11.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
go.etcd.io/etcd/api/v3 v3.5.1 // indirect
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.1 // indirect
|
||||
go.etcd.io/etcd/client/v3 v3.5.0 // indirect
|
||||
go.etcd.io/etcd/api/v3 v3.5.9 // indirect
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.9 // indirect
|
||||
go.etcd.io/etcd/client/v2 v2.305.7 // indirect
|
||||
go.etcd.io/etcd/client/v3 v3.5.9 // indirect
|
||||
go.opentelemetry.io/contrib v0.20.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0 // indirect
|
||||
go.opentelemetry.io/otel v0.20.0 // indirect
|
||||
go.opentelemetry.io/otel v1.14.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp v0.20.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v0.20.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v0.20.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk/export/metric v0.20.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk/metric v0.20.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v0.20.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.14.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v0.7.0 // indirect
|
||||
go.uber.org/atomic v1.7.0 // indirect
|
||||
go.uber.org/multierr v1.6.0 // indirect
|
||||
go.uber.org/zap v1.19.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838 // indirect
|
||||
golang.org/x/mod v0.5.1 // indirect
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
|
||||
golang.org/x/sys v0.0.0-20220209214540-3681064d5158 // indirect
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect
|
||||
golang.org/x/tools v0.1.9 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||
go.uber.org/atomic v1.9.0 // indirect
|
||||
go.uber.org/multierr v1.8.0 // indirect
|
||||
go.uber.org/zap v1.21.0 // indirect
|
||||
golang.org/x/crypto v0.16.0 // indirect
|
||||
golang.org/x/mod v0.12.0 // indirect
|
||||
golang.org/x/sys v0.15.0 // indirect
|
||||
golang.org/x/term v0.15.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
golang.org/x/time v0.3.0 // indirect
|
||||
golang.org/x/tools v0.11.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa // indirect
|
||||
google.golang.org/grpc v1.43.0 // indirect
|
||||
google.golang.org/protobuf v1.27.1 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
||||
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect
|
||||
google.golang.org/grpc v1.56.3 // indirect
|
||||
google.golang.org/protobuf v1.31.0 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
||||
k8s.io/apiextensions-apiserver v0.23.0 // indirect
|
||||
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c // indirect
|
||||
k8s.io/klog/v2 v2.40.1 // indirect
|
||||
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 // indirect
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.27 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
k8s.io/apiextensions-apiserver v0.24.0 // indirect
|
||||
k8s.io/gengo v0.0.0-20211129171323-c02415ce4185 // indirect
|
||||
k8s.io/klog/v2 v2.100.1 // indirect
|
||||
k8s.io/utils v0.0.0-20230711102312-30195339c3c7 // indirect
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.37 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
|
||||
sigs.k8s.io/yaml v1.3.0 // indirect
|
||||
)
|
||||
|
||||
go 1.18
|
||||
replace (
|
||||
go.opentelemetry.io/cotrib v0.20.0 => go.opentelemetry.io/contrib v0.44.0
|
||||
go.opentelemetry.io/otel => go.opentelemetry.io/otel v0.20.0
|
||||
go.opentelemetry.io/otel/sdk => go.opentelemetry.io/otel/sdk v0.20.0
|
||||
go.opentelemetry.io/otel/trace => go.opentelemetry.io/otel/trace v0.20.0
|
||||
k8s.io/kube-openapi => k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42
|
||||
)
|
||||
|
||||
go 1.21
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
autoscalingv2 "k8s.io/api/autoscaling/v2beta2"
|
||||
autoscalingv2 "k8s.io/api/autoscaling/v2"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -4,7 +4,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
autoscalingv2 "k8s.io/api/autoscaling/v2beta2"
|
||||
autoscalingv2 "k8s.io/api/autoscaling/v2"
|
||||
)
|
||||
|
||||
func TestParser(t *testing.T) {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -13,11 +13,16 @@ import (
|
||||
// ScalingSchedule describes a namespaced time based metric to be used
|
||||
// in autoscaling operations.
|
||||
// +k8s:deepcopy-gen=true
|
||||
// +kubebuilder:resource:categories=all
|
||||
// +kubebuilder:printcolumn:name="Active",type=boolean,JSONPath=`.status.active`,description="Whether one or more schedules are currently active."
|
||||
// +kubebuilder:subresource:status
|
||||
type ScalingSchedule struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec ScalingScheduleSpec `json:"spec"`
|
||||
// +optional
|
||||
Status ScalingScheduleStatus `json:"status"`
|
||||
}
|
||||
|
||||
// +genclient
|
||||
@ -28,12 +33,17 @@ type ScalingSchedule struct {
|
||||
// ClusterScalingSchedule describes a cluster scoped time based metric
|
||||
// to be used in autoscaling operations.
|
||||
// +k8s:deepcopy-gen=true
|
||||
// +kubebuilder:resource:categories=all
|
||||
// +kubebuilder:printcolumn:name="Active",type=boolean,JSONPath=`.status.active`,description="Whether one or more schedules are currently active."
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:resource:scope=Cluster
|
||||
type ClusterScalingSchedule struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec ScalingScheduleSpec `json:"spec"`
|
||||
// +optional
|
||||
Status ScalingScheduleStatus `json:"status"`
|
||||
}
|
||||
|
||||
// ScalingScheduleSpec is the spec part of the ScalingSchedule.
|
||||
@ -58,11 +68,16 @@ type Schedule struct {
|
||||
// +optional
|
||||
Period *SchedulePeriod `json:"period,omitempty"`
|
||||
// Defines the starting date of a OneTime schedule. It has to
|
||||
// be a RFC3339 formated date.
|
||||
// be a RFC3339 formatted date.
|
||||
// +optional
|
||||
Date *ScheduleDate `json:"date,omitempty"`
|
||||
// The duration in minutes that the configured value will be
|
||||
// Defines the ending date of a OneTime schedule. It must be
|
||||
// a RFC3339 formatted date.
|
||||
// +optional
|
||||
EndDate *ScheduleDate `json:"endDate,omitempty"`
|
||||
// The duration in minutes (default 0) that the configured value will be
|
||||
// returned for the defined schedule.
|
||||
// +optional
|
||||
DurationMinutes int `json:"durationMinutes"`
|
||||
// The metric value that will be returned for the defined schedule.
|
||||
Value int64 `json:"value"`
|
||||
@ -90,6 +105,10 @@ type SchedulePeriod struct {
|
||||
// The startTime has the format HH:MM
|
||||
// +kubebuilder:validation:Pattern="(([0-1][0-9])|([2][0-3])):([0-5][0-9])"
|
||||
StartTime string `json:"startTime"`
|
||||
// The endTime has the format HH:MM
|
||||
// +kubebuilder:validation:Pattern="(([0-1][0-9])|([2][0-3])):([0-5][0-9])"
|
||||
// +optional
|
||||
EndTime string `json:"endTime"`
|
||||
// The days that this schedule will be active.
|
||||
Days []ScheduleDay `json:"days"`
|
||||
// The location name corresponding to a file in the IANA
|
||||
@ -116,6 +135,16 @@ const (
|
||||
// +kubebuilder:validation:Format="date-time"
|
||||
type ScheduleDate string
|
||||
|
||||
// ScalingScheduleStatus is the status section of the ScalingSchedule.
|
||||
// +k8s:deepcopy-gen=true
|
||||
type ScalingScheduleStatus struct {
|
||||
// Active is true if at least one of the schedules defined in the
|
||||
// scaling schedule is currently active.
|
||||
// +kubebuilder:default:=false
|
||||
// +optional
|
||||
Active bool `json:"active"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// ScalingScheduleList is a list of namespaced scaling schedules.
|
||||
|
@ -31,6 +31,7 @@ func (in *ClusterScalingSchedule) DeepCopyInto(out *ClusterScalingSchedule) {
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
out.Status = in.Status
|
||||
return
|
||||
}
|
||||
|
||||
@ -91,6 +92,7 @@ func (in *ScalingSchedule) DeepCopyInto(out *ScalingSchedule) {
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
out.Status = in.Status
|
||||
return
|
||||
}
|
||||
|
||||
@ -173,6 +175,22 @@ func (in *ScalingScheduleSpec) DeepCopy() *ScalingScheduleSpec {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ScalingScheduleStatus) DeepCopyInto(out *ScalingScheduleStatus) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScalingScheduleStatus.
|
||||
func (in *ScalingScheduleStatus) DeepCopy() *ScalingScheduleStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ScalingScheduleStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Schedule) DeepCopyInto(out *Schedule) {
|
||||
*out = *in
|
||||
@ -186,6 +204,11 @@ func (in *Schedule) DeepCopyInto(out *Schedule) {
|
||||
*out = new(ScheduleDate)
|
||||
**out = **in
|
||||
}
|
||||
if in.EndDate != nil {
|
||||
in, out := &in.EndDate, &out.EndDate
|
||||
*out = new(ScheduleDate)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -61,6 +61,10 @@ func (c *Clientset) Discovery() discovery.DiscoveryInterface {
|
||||
func NewForConfig(c *rest.Config) (*Clientset, error) {
|
||||
configShallowCopy := *c
|
||||
|
||||
if configShallowCopy.UserAgent == "" {
|
||||
configShallowCopy.UserAgent = rest.DefaultKubernetesUserAgent()
|
||||
}
|
||||
|
||||
// share the transport between all clients
|
||||
httpClient, err := rest.HTTPClientFor(&configShallowCopy)
|
||||
if err != nil {
|
||||
|
@ -37,14 +37,14 @@ var localSchemeBuilder = runtime.SchemeBuilder{
|
||||
// AddToScheme adds all types of this clientset into the given scheme. This allows composition
|
||||
// of clientsets, like in:
|
||||
//
|
||||
// import (
|
||||
// "k8s.io/client-go/kubernetes"
|
||||
// clientsetscheme "k8s.io/client-go/kubernetes/scheme"
|
||||
// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme"
|
||||
// )
|
||||
// import (
|
||||
// "k8s.io/client-go/kubernetes"
|
||||
// clientsetscheme "k8s.io/client-go/kubernetes/scheme"
|
||||
// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme"
|
||||
// )
|
||||
//
|
||||
// kclientset, _ := kubernetes.NewForConfig(c)
|
||||
// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme)
|
||||
// kclientset, _ := kubernetes.NewForConfig(c)
|
||||
// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme)
|
||||
//
|
||||
// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types
|
||||
// correctly.
|
||||
|
@ -37,14 +37,14 @@ var localSchemeBuilder = runtime.SchemeBuilder{
|
||||
// AddToScheme adds all types of this clientset into the given scheme. This allows composition
|
||||
// of clientsets, like in:
|
||||
//
|
||||
// import (
|
||||
// "k8s.io/client-go/kubernetes"
|
||||
// clientsetscheme "k8s.io/client-go/kubernetes/scheme"
|
||||
// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme"
|
||||
// )
|
||||
// import (
|
||||
// "k8s.io/client-go/kubernetes"
|
||||
// clientsetscheme "k8s.io/client-go/kubernetes/scheme"
|
||||
// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme"
|
||||
// )
|
||||
//
|
||||
// kclientset, _ := kubernetes.NewForConfig(c)
|
||||
// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme)
|
||||
// kclientset, _ := kubernetes.NewForConfig(c)
|
||||
// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme)
|
||||
//
|
||||
// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types
|
||||
// correctly.
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user