Skip to content

Commit

Permalink
feat: Add support for any resource which implementes /scale subreso…
Browse files Browse the repository at this point in the history
…urce (#852)
  • Loading branch information
JorTurFer authored Dec 13, 2023
1 parent 1bbbd17 commit 2144312
Show file tree
Hide file tree
Showing 61 changed files with 1,262 additions and 644 deletions.
6 changes: 5 additions & 1 deletion .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ issues:
exclude-rules:
- path: _test\.go
linters:
- gomnd
- dupl
- unparam
# Exclude gci check for //+kubebuilder:scaffold:imports comments. Waiting to
Expand All @@ -60,6 +59,11 @@ issues:
- path: operator/main.go
linters:
- gci
# Exlude httpso.Spec.ScaleTargetRef.Deployment until we remove it in v0.9.0
- linters:
- staticcheck
text: "SA1019: httpso.Spec.ScaleTargetRef.Deployment"

linters-settings:
funlen:
lines: 80
Expand Down
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ This changelog keeps track of work items that have been completed and are ready

### New

- **General**: TODO ([#TODO](https://github.com/kedacore/http-add-on/issues/TODO))
- **General**: Support any resource which implements `/scale` subresource ([#438](https://github.com/kedacore/http-add-on/issues/438))

### Improvements

Expand All @@ -37,7 +37,7 @@ You can find all deprecations in [this overview](https://github.com/kedacore/htt

New deprecation(s):

- **General**: TODO ([#TODO](https://github.com/kedacore/http-add-on/issues/TODO))
- **General**: Deprecated `KEDA_HTTP_DEPLOYMENT_CACHE_POLLING_INTERVAL_MS` in favor of `KEDA_HTTP_ENDPOINTS_CACHE_POLLING_INTERVAL_MS` ([#438](https://github.com/kedacore/http-add-on/issues/438))

Previously announced deprecation(s):

Expand Down
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,9 @@ KUSTOMIZE = $(shell pwd)/bin/kustomize
kustomize: ## Download kustomize locally if necessary.
GOBIN=$(shell pwd)/bin go install sigs.k8s.io/kustomize/kustomize/v5

install: manifests kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config.
$(KUSTOMIZE) build config/crd | kubectl apply -f -

deploy: manifests kustomize ## Deploy to the K8s cluster specified in ~/.kube/config.
cd config/interceptor && \
$(KUSTOMIZE) edit set image ghcr.io/kedacore/http-add-on-interceptor=${IMAGE_INTERCEPTOR_VERSIONED_TAG}
Expand Down
11 changes: 8 additions & 3 deletions config/crd/bases/http.keda.sh_httpscaledobjects.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,15 @@ spec:
description: The name of the deployment to route HTTP requests to
(and to autoscale).
properties:
apiVersion:
type: string
deployment:
description: The name of the deployment to scale according to
HTTP traffic
description: 'Deprecated: The name of the deployment to scale
according to HTTP traffic'
type: string
kind:
type: string
name:
type: string
port:
description: The port to route to
Expand All @@ -114,7 +120,6 @@ spec:
description: The name of the service to route to
type: string
required:
- deployment
- port
- service
type: object
Expand Down
2 changes: 1 addition & 1 deletion config/interceptor/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ spec:
value: "500ms"
- name: KEDA_CONDITION_WAIT_TIMEOUT
value: "20s"
- name: KEDA_HTTP_DEPLOYMENT_CACHE_POLLING_INTERVAL_MS
- name: KEDA_HTTP_ENDPOINTS_CACHE_POLLING_INTERVAL_MS
value: "1000"
- name: KEDA_HTTP_FORCE_HTTP2
value: "false"
Expand Down
4 changes: 2 additions & 2 deletions config/interceptor/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ metadata:
name: interceptor
rules:
- apiGroups:
- apps
- ""
resources:
- deployments
- endpoints
verbs:
- get
- list
Expand Down
8 changes: 0 additions & 8 deletions config/scaler/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,6 @@ rules:
- get
- list
- watch
- apiGroups:
- apps
resources:
- deployments
verbs:
- get
- list
- watch
- apiGroups:
- http.keda.sh
resources:
Expand Down
2 changes: 1 addition & 1 deletion docs/design.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ The [operator](../operator) runs inside the Kubernetes namespace to which they'r

- Update an internal routing table that maps incoming HTTP hostnames to internal applications.
- Furnish this routing table information to interceptors so that they can properly route requests.
- Create a [`ScaledObject`](https://keda.sh/docs/2.3/concepts/scaling-deployments/#scaledobject-spec) for the `Deployment` specified in the `HTTPScaledObject` resource.
- Create a [`ScaledObject`](https://keda.sh/docs/latest/concepts/scaling-deployments/#scaledobject-spec) for the `Deployment` specified in the `HTTPScaledObject` resource.

When the `HTTPScaledObject` is deleted, the operator reverses all of the aforementioned actions.

Expand Down
4 changes: 2 additions & 2 deletions docs/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Why does this project route HTTP requests?

In order to autoscale a `Deployment`, KEDA-HTTP needs to be involved with routing HTTP requests. However, the project is minimally involved with routing and we're working on ways to get out of the "critical path" of an HTTP request as much as possible. For more information, please see our [scope](./scope.md) document.
In order to autoscale a workload, KEDA-HTTP needs to be involved with routing HTTP requests. However, the project is minimally involved with routing and we're working on ways to get out of the "critical path" of an HTTP request as much as possible. For more information, please see our [scope](./scope.md) document.

## How is this project similar or different from [Osiris](https://github.com/deislabs/osiris)?

Expand All @@ -13,7 +13,7 @@ Osiris and KEDA-HTTP have similar features:

However, Osiris and KEDA-HTTP differ in several ways:

- Autoscaling concerns are implemented separately from the application resources - `Service`, `Ingress`, `Deployment` and more in KEDA-HTTP. With Osiris, those concerns are baked into each app resource.
- Autoscaling concerns are implemented separately from the application resources - `Service`, `Ingress`, `Deployment`, `StatefulSet`, `/scale` and more in KEDA-HTTP. With Osiris, those concerns are baked into each app resource.
- The KEDA-HTTP operator can automatically deploy and configure networking and compute resources necessary for an HTTP application to autoscale. Osiris does not have this functionality.
- Osiris is currently archived in GitHub.

Expand Down
63 changes: 63 additions & 0 deletions docs/ref/v0.6.0/http_scaled_object.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# The `HTTPScaledObject`

>This document reflects the specification of the `HTTPScaledObject` resource for the `v0.7.0` version.
Each `HTTPScaledObject` looks approximately like the below:

```yaml
kind: HTTPScaledObject
apiVersion: http.keda.sh/v1alpha1
metadata:
name: xkcd
spec:
hosts:
- myhost.com
pathPrefixes:
- /test
scaleTargetRef:
deployment: xkcd
service: xkcd
port: 8080
replicas:
min: 5
max: 10

```

This document is a narrated reference guide for the `HTTPScaledObject`, and we'll focus on the `spec` field.

## `hosts`

These are the hosts to apply this scaling rule to. All incoming requests with one of these values in their `Host` header will be forwarded to the `Service` and port specified in the below `scaleTargetRef`, and that same `scaleTargetRef`'s workload will be scaled accordingly.

## `pathPrefixes`

These are the paths to apply this scaling rule to. All incoming requests with one of these values as path prefix will be forwarded to the `Service` and port specified in the below `scaleTargetRef`, and that same `scaleTargetRef`'s workload will be scaled accordingly.

## `scaleTargetRef`

This is the primary and most important part of the `spec` because it describes:

1. The incoming host to apply this scaling rule to.
2. What workload to scale.
3. The service to which to route HTTP traffic.

### `deployment`

This is the name of the `Deployment` to scale. It must exist in the same namespace as this `HTTPScaledObject` and shouldn't be managed by any other autoscaling system. This means that there should not be any `ScaledObject` already created for this `Deployment`. The HTTP Add-on will manage a `ScaledObject` internally.

### `service`

This is the name of the service to route traffic to. The add-on will create autoscaling and routing components that route to this `Service`. It must exist in the same namespace as this `HTTPScaledObject` and should route to the same `Deployment` as you entered in the `deployment` field.

### `port`

This is the port to route to on the service that you specified in the `service` field. It should be exposed on the service and should route to a valid `containerPort` on the `Deployment` you gave in the `deployment` field.

### `targetPendingRequests`

>Default: 100
This is the number of _pending_ (or in-progress) requests that your application needs to have before the HTTP Add-on will scale it. Conversely, if your application has below this number of pending requests, the HTTP add-on will scale it down.

For example, if you set this field to 100, the HTTP Add-on will scale your app up if it sees that there are 200 in-progress requests. On the other hand, it will scale down if it sees that there are only 20 in-progress requests. Note that it will _never_ scale your app to zero replicas unless there are _no_ requests in-progress. Even if you set this value to a very high number and only have a single in-progress request, your app will still have one replica.
77 changes: 77 additions & 0 deletions docs/ref/v0.7.0/http_scaled_object.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# The `HTTPScaledObject`

>This document reflects the specification of the `HTTPScaledObject` resource for the `v0.7.0` version.
Each `HTTPScaledObject` looks approximately like the below:

```yaml
kind: HTTPScaledObject
apiVersion: http.keda.sh/v1alpha1
metadata:
name: xkcd
spec:
hosts:
- myhost.com
pathPrefixes:
- /test
scaleTargetRef:
name: xkcd
kind: Deployment
apiVersion: apps/v1
service: xkcd
port: 8080
replicas:
min: 5
max: 10

```

This document is a narrated reference guide for the `HTTPScaledObject`, and we'll focus on the `spec` field.

## `hosts`

These are the hosts to apply this scaling rule to. All incoming requests with one of these values in their `Host` header will be forwarded to the `Service` and port specified in the below `scaleTargetRef`, and that same `scaleTargetRef`'s workload will be scaled accordingly.

## `pathPrefixes`

These are the paths to apply this scaling rule to. All incoming requests with one of these values as path prefix will be forwarded to the `Service` and port specified in the below `scaleTargetRef`, and that same `scaleTargetRef`'s workload will be scaled accordingly.

## `scaleTargetRef`

This is the primary and most important part of the `spec` because it describes:

1. The incoming host to apply this scaling rule to.
2. What workload to scale.
3. The service to which to route HTTP traffic.

### `deployment` (DEPRECTATED: removed as part of v0.9.0)

This is the name of the `Deployment` to scale. It must exist in the same namespace as this `HTTPScaledObject` and shouldn't be managed by any other autoscaling system. This means that there should not be any `ScaledObject` already created for this `Deployment`. The HTTP Add-on will manage a `ScaledObject` internally.

### `name`

This is the name of the workload to scale. It must exist in the same namespace as this `HTTPScaledObject` and shouldn't be managed by any other autoscaling system. This means that there should not be any `ScaledObject` already created for this workload. The HTTP Add-on will manage a `ScaledObject` internally.

### `kind`

This is the kind of the workload to scale.

### `apiVersion`

This is the apiVersion of the workload to scale.

### `service`

This is the name of the service to route traffic to. The add-on will create autoscaling and routing components that route to this `Service`. It must exist in the same namespace as this `HTTPScaledObject` and should route to the same `Deployment` as you entered in the `deployment` field.

### `port`

This is the port to route to on the service that you specified in the `service` field. It should be exposed on the service and should route to a valid `containerPort` on the `Deployment` you gave in the `deployment` field.

### `targetPendingRequests`

>Default: 100
This is the number of _pending_ (or in-progress) requests that your application needs to have before the HTTP Add-on will scale it. Conversely, if your application has below this number of pending requests, the HTTP add-on will scale it down.

For example, if you set this field to 100, the HTTP Add-on will scale your app up if it sees that there are 200 in-progress requests. On the other hand, it will scale down if it sees that there are only 20 in-progress requests. Note that it will _never_ scale your app to zero replicas unless there are _no_ requests in-progress. Even if you set this value to a very high number and only have a single in-progress request, your app will still have one replica.
8 changes: 4 additions & 4 deletions docs/use_cases.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ Moving this application to Kubernetes may make sense for several reasons, but th

If the application _is_ being moved to Kubernetes, you would follow these steps to get it autoscaling and routing with KEDA-HTTP:

- Create a `Deployment` and `Service`
- Create a workload and `Service`
- [Install](./install.md) the HTTP Add-on
- Create a single `HTTPScaledObject` in the same namespace as the `Deployment` and `Service` you created
- Create a single `HTTPScaledObject` in the same namespace as the workload and `Service` you created

At that point, the operator will create the proper autoscaling and routing infrastructure behind the scenes and the application will be ready to scale.
At that point, the operator will create the proper autoscaling and routing infrastructure behind the scenes and the application will be ready to scale. Any request received by the interceptor with the proper host will be routed to the proper backend.

## Current HTTP Server in Kubernetes

Expand All @@ -36,6 +36,6 @@ In this case, the reasoning for adding the HTTP Add-on would be clear - adding a
Getting the HTTP Add-on working can be done transparently and without downtime to the application:

- [Install](./install.md) the add-on. This step will have no effect on the running application.
- Create a new `HTTPScaledObject`. This step activates autoscaling for the `Deployment` that you specify and the application will immediately start scaling up and down based on incoming traffic through the interceptor that was created.
- Create a new `HTTPScaledObject`. This step activates autoscaling for the workload that you specify and the application will immediately start scaling up and down based on incoming traffic through the interceptor that was created.

[Go back to landing page](./)
12 changes: 7 additions & 5 deletions docs/walkthrough.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ You'll need to install a `Deployment` and `Service` first. You'll tell the add-o
$ helm install xkcd ./examples/xkcd -n ${NAMESPACE}
```

You'll need to clone the repository to get access to this chart. If you have your own `Deployment` and `Service` installed, you can go right to creating an `HTTPScaledObject` in the next section.
You'll need to clone the repository to get access to this chart. If you have your own workload and `Service` installed, you can go right to creating an `HTTPScaledObject` in the next section.

>If you are running KEDA and the HTTP Add-on in cluster-global mode, you can install the XKCD chart in any namespace you choose. If you do so, make sure you add `--set ingressNamespace=${NAMESPACE}` to the above installation command.
Expand All @@ -25,10 +25,10 @@ You'll need to clone the repository to get access to this chart. If you have you
You interact with the operator via a CRD called `HTTPScaledObject`. This CRD object instructs interceptors to forward requests for a given host to your app's backing `Service`. To get an example app up and running, read the notes below and then run the subsequent command from the root of this repository.

```console
$ kubectl create -n $NAMESPACE -f examples/v0.3.0/httpscaledobject.yaml
$ kubectl create -n $NAMESPACE -f examples/v0.7.0/httpscaledobject.yaml
```

>If you'd like to learn more about this object, please see the [`HTTPScaledObject` reference](./ref/v0.3.0/http_scaled_object.md).
>If you'd like to learn more about this object, please see the [`HTTPScaledObject` reference](./ref/v0.7.0/http_scaled_object.md).
## Testing Your Installation

Expand All @@ -40,13 +40,13 @@ $ kubectl port-forward svc/keda-add-ons-http-interceptor-proxy -n ${NAMESPACE} 8

### Routing to the Right `Service`

As said above, you need to route your HTTP traffic to the `Service` that the add-on has created. If you have existing systems - like an ingress controller - you'll need to anticipate the name of these created `Service`s. Each one will be named consistently like so, in the same namespace as the `HTTPScaledObject` and your application (i.e. `$NAMESPACE`):
As said above, you need to route your HTTP traffic to the `Service` that the add-on has created during the installation. If you have existing systems - like an ingress controller - you'll need to anticipate the name of these created `Service`s. Each one will be named consistently like so, in the same namespace as the `HTTPScaledObject` and your application (i.e. `$NAMESPACE`):

```console
keda-add-ons-http-interceptor-proxy
```

>This is installed by the [Helm chart](https://github.com/kedacore/charts/tree/master/http-add-on) as a `ClusterIP` `Service` by default.
> This is installed by the [Helm chart](https://github.com/kedacore/charts/tree/master/http-add-on) as a `ClusterIP` `Service` by default.
#### Installing and Using the [ingress-nginx](https://kubernetes.github.io/ingress-nginx/deploy/#using-helm) Ingress Controller

Expand All @@ -64,6 +64,8 @@ helm install ingress-nginx ingress-nginx/ingress-nginx -n ${NAMESPACE}

An [`Ingress`](https://kubernetes.io/docs/concepts/services-networking/ingress/) resource was already created as part of the [xkcd chart](../examples/xkcd/templates/ingress.yaml), so the installed NGINX ingress controller will initialize, detect the `Ingress`, and begin routing to the xkcd interceptor `Service`.

>NOTE: You may have to create an external service `type: ExternalName` pointing to the interceptor namespace and use it from `Ingress` manifest.
When you're ready, please run `kubectl get svc -n ${NAMESPACE}`, find the `ingress-nginx-controller` service, and copy and paste its `EXTERNAL-IP`. This is the IP address that your application will be running at on the public internet.

>Note: you should go further and set your DNS records appropriately and set up a TLS certificate for this IP address. Instructions to do that are out of scope of this document, though.
Expand Down
16 changes: 16 additions & 0 deletions examples/v0.6.0/httpscaledobject.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
kind: HTTPScaledObject
apiVersion: http.keda.sh/v1alpha1
metadata:
name: xkcd
spec:
hosts:
- myhost.com
pathPrefixes:
- /test
scaleTargetRef:
name: xkcd
service: xkcd
port: 8080
replicas:
min: 5
max: 10
18 changes: 18 additions & 0 deletions examples/v0.7.0/httpscaledobject.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
kind: HTTPScaledObject
apiVersion: http.keda.sh/v1alpha1
metadata:
name: xkcd
spec:
hosts:
- myhost.com
pathPrefixes:
- /test
scaleTargetRef:
name: xkcd
kind: Deployment
apiVersion: apps/v1
service: xkcd
port: 8080
replicas:
min: 5
max: 10
9 changes: 9 additions & 0 deletions examples/xkcd/templates/externalservice.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "xkcd.fullname" . }}-proxy
labels:
{{- include "xkcd.labels" . | nindent 4 }}
spec:
type: ExternalName
externalName: keda-http-add-on-interceptor-proxy.keda
Loading

0 comments on commit 2144312

Please sign in to comment.