Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
#-------------------------------------------------------------------------------------------------------------

FROM golang:1.24.3
FROM golang:1.24.7

# Avoid warnings by switching to noninteractive
ENV DEBIAN_FRONTEND=noninteractive
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build_canary.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
packages: write
id-token: write # needed for signing the images with GitHub OIDC Token **not production ready**

container: ghcr.io/kedacore/keda-tools:1.24.3
container: ghcr.io/kedacore/keda-tools:1.24.7
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v4

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build_release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
packages: write
id-token: write # needed for signing the images with GitHub OIDC Token **not production ready**

container: ghcr.io/kedacore/keda-tools:1.24.3
container: ghcr.io/kedacore/keda-tools:1.24.7
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v4

Expand Down
22 changes: 12 additions & 10 deletions .github/workflows/e2e-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ jobs:
strategy:
fail-fast: false
matrix:
kubernetesVersion: [v1.32, v1.31, v1.30]
kubernetesVersion: [v1.33, v1.32, v1.31]
include:
- kubernetesVersion: v1.33
kindImage: kindest/node:v1.33.4@sha256:25a6018e48dfcaee478f4a59af81157a437f15e6e140bf103f85a2e7cd0cbbf2
- kubernetesVersion: v1.32
kindImage: kindest/node:v1.32.0@sha256:c48c62eac5da28cdadcf560d1d8616cfa6783b58f0d94cf63ad1bf49600cb027
kindImage: kindest/node:v1.32.8@sha256:abd489f042d2b644e2d033f5c2d900bc707798d075e8186cb65e3f1367a9d5a1
- kubernetesVersion: v1.31
kindImage: kindest/node:v1.31.4@sha256:2cb39f7295fe7eafee0842b1052a599a4fb0f8bcf3f83d96c7f4864c357c6c30
- kubernetesVersion: v1.30
kindImage: kindest/node:v1.30.8@sha256:17cd608b3971338d9180b00776cb766c50d0a0b6b904ab4ff52fd3fc5c6369bf
kindImage: kindest/node:v1.31.12@sha256:0f5cc49c5e73c0c2bb6e2df56e7df189240d83cf94edfa30946482eb08ec57d2
steps:
- name: Install prerequisites
run: |
Expand All @@ -49,6 +49,7 @@ jobs:
with:
node_image: ${{ matrix.kindImage }}
cluster_name: cluster
version: v0.30.0

- name: Generate images and push to the cluster
run: |
Expand Down Expand Up @@ -96,14 +97,14 @@ jobs:
strategy:
fail-fast: false
matrix:
kubernetesVersion: [v1.32, v1.31, v1.30]
kubernetesVersion: [v1.33, v1.32, v1.31]
include:
- kubernetesVersion: v1.33
kindImage: kindest/node:v1.33.4@sha256:25a6018e48dfcaee478f4a59af81157a437f15e6e140bf103f85a2e7cd0cbbf2
- kubernetesVersion: v1.32
kindImage: kindest/node:v1.32.0@sha256:c48c62eac5da28cdadcf560d1d8616cfa6783b58f0d94cf63ad1bf49600cb027
kindImage: kindest/node:v1.32.8@sha256:abd489f042d2b644e2d033f5c2d900bc707798d075e8186cb65e3f1367a9d5a1
- kubernetesVersion: v1.31
kindImage: kindest/node:v1.31.4@sha256:2cb39f7295fe7eafee0842b1052a599a4fb0f8bcf3f83d96c7f4864c357c6c30
- kubernetesVersion: v1.30
kindImage: kindest/node:v1.30.8@sha256:17cd608b3971338d9180b00776cb766c50d0a0b6b904ab4ff52fd3fc5c6369bf
kindImage: kindest/node:v1.31.12@sha256:0f5cc49c5e73c0c2bb6e2df56e7df189240d83cf94edfa30946482eb08ec57d2
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v4

Expand All @@ -119,6 +120,7 @@ jobs:
with:
node_image: ${{ matrix.kindImage }}
cluster_name: ${{ runner.name }}
version: v0.30.0

- name: Push images to the cluster
run: |
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/images.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ permissions:
jobs:
build_scaler:
runs-on: ubuntu-latest
container: ghcr.io/kedacore/keda-tools:1.24.3
container: ghcr.io/kedacore/keda-tools:1.24.7
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v4
- name: Register workspace path
Expand All @@ -25,7 +25,7 @@ jobs:

build_operator:
runs-on: ubuntu-latest
container: ghcr.io/kedacore/keda-tools:1.24.3
container: ghcr.io/kedacore/keda-tools:1.24.7
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v4
- name: Register workspace path
Expand All @@ -37,7 +37,7 @@ jobs:

build_interceptor:
runs-on: ubuntu-latest
container: ghcr.io/kedacore/keda-tools:1.24.3
container: ghcr.io/kedacore/keda-tools:1.24.7
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v4
- name: Register workspace path
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
validate:
name: validate - ${{ matrix.name }}
runs-on: ${{ matrix.runner }}
container: ghcr.io/kedacore/keda-tools:1.24.3
container: ghcr.io/kedacore/keda-tools:1.24.7
strategy:
matrix:
include:
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,4 @@ We are a Cloud Native Computing Foundation (CNCF) graduated project.
## Code of Conduct

Please refer to the organization-wide [Code of Conduct document](https://github.com/kedacore/.github/blob/main/CODE_OF_CONDUCT.md).
# Force push marker - will be removed
5 changes: 3 additions & 2 deletions docs/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,9 @@ helm upgrade kedahttp ./charts/keda-add-ons-http \

| HTTP Add-On version | KEDA version | Kubernetes version |
|---------------------|-------------------|--------------------|
| main | v2.16 | v1.30 - v1.32 |
| 0.10.0 | v2.16 | v1.30 - v1.32 |
| main | v2.17 | v1.31 - v1.33 |
| 0.11.0 | v2.17 | v1.31 - v1.33 |
| 0.10.0 | v2.16 | v1.20 - v1.32 |
| 0.9.0 | v2.16 | v1.29 - v1.31 |
| 0.8.0 | v2.14 | v1.27 - v1.29 |
| 0.7.0 | v2.13 | v1.27 - v1.29 |
Expand Down
20 changes: 20 additions & 0 deletions docs/operate.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,26 @@ The OTEL exporter can be enabled by setting the `OTEL_EXPORTER_OTLP_METRICS_ENAB

If you need to provide any headers such as authentication details in order to utilise your OTEL collector you can add them into the `OTEL_EXPORTER_OTLP_HEADERS` environment variable. The frequency at which the metrics are exported can be configured by setting `OTEL_METRIC_EXPORT_INTERVAL` to the number of seconds you require between each export interval (`30` by default).

# Configuring DNS for the KEDA HTTP Add-on interceptor proxy

By default, the interceptor proxy uses short DNS names (e.g., `service.namespace`) when routing requests to backend services. In some cluster configurations, you may need to use fully qualified domain names (FQDN) instead.

You can configure the cluster domain suffix by setting the `KEDA_HTTP_CLUSTER_DOMAIN` environment variable on the interceptor deployment. When set, this value will be appended to the short DNS name to form an FQDN.

Examples:
- **Default behavior** (empty/not set): Routes to `service.namespace:port`
- **Standard Kubernetes cluster** (`svc.cluster.local`): Routes to `service.namespace.svc.cluster.local:port`
- **Custom cluster domain** (`svc.my-domain.com`): Routes to `service.namespace.svc.my-domain.com:port`

```yaml
# Example interceptor deployment configuration
env:
- name: KEDA_HTTP_CLUSTER_DOMAIN
value: "svc.cluster.local"
```

> **Note:** According to the [Kubernetes DNS specification](https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/), both short names (`service.namespace`) and FQDNs (`service.namespace.svc.cluster.local`) should resolve identically in most Kubernetes clusters. However, certain DNS policies, network policies, or custom DNS configurations may require the use of FQDNs. If you're experiencing DNS resolution issues, check your cluster's `dnsPolicy` and `NetworkPolicy` settings.

# Configuring TLS for the KEDA HTTP Add-on interceptor proxy

The interceptor proxy has the ability to run both a HTTP and HTTPS server simultaneously to allow you to scale workloads that use either protocol. By default, the interceptor proxy will only serve over HTTP, but this behavior can be changed by configuring the appropriate environment variables on the deployment.
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/kedacore/http-add-on

go 1.24.3
go 1.24.7

require (
github.com/go-logr/logr v1.4.3
Expand Down
2 changes: 1 addition & 1 deletion interceptor/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM --platform=${BUILDPLATFORM} ghcr.io/kedacore/keda-tools:1.24.3 as builder
FROM --platform=${BUILDPLATFORM} ghcr.io/kedacore/keda-tools:1.24.7 as builder
WORKDIR /workspace
COPY go.* .
RUN go mod download
Expand Down
4 changes: 4 additions & 0 deletions interceptor/config/serving.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ type Serving struct {
TLSPort int `envconfig:"KEDA_HTTP_PROXY_TLS_PORT" default:"8443"`
// ProfilingAddr if not empty, pprof will be available on this address, assuming host:port here
ProfilingAddr string `envconfig:"PROFILING_BIND_ADDRESS" default:""`
// ClusterDomain is the Kubernetes cluster domain (e.g., "svc.cluster.local")
// If empty, uses short form DNS (service.namespace)
// If set, uses FQDN (service.namespace.ClusterDomain)
ClusterDomain string `envconfig:"KEDA_HTTP_CLUSTER_DOMAIN" default:""`
}

// Parse parses standard configs using envconfig and returns a pointer to the
Expand Down
6 changes: 5 additions & 1 deletion interceptor/forward_wait_func.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ type forwardWaitFunc func(context.Context, string, string) (bool, error)
func workloadActiveEndpoints(endpoints discov1.EndpointSlice) int {
total := 0
for _, e := range endpoints.Endpoints {
total += len(e.Addresses)
if e.Conditions.Ready == nil || *e.Conditions.Ready {
// null should be treated as ready, per:
// https://github.com/kubernetes/api/blob/1446cdecbe6b6afe81373ddedc4dfdb86a7f0bcd/discovery/v1/types.go#L136-L158
total += len(e.Addresses)
}
}
return total
}
Expand Down
6 changes: 4 additions & 2 deletions interceptor/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ func main() {

setupLog.Info("starting the proxy server with TLS enabled", "port", proxyTLSPort)

if err := runProxyServer(ctx, ctrl.Log, queues, waitFunc, routingTable, svcCache, timeoutCfg, proxyTLSPort, proxyTLSEnabled, proxyTLSConfig, tracingCfg); !util.IsIgnoredErr(err) {
if err := runProxyServer(ctx, ctrl.Log, queues, waitFunc, routingTable, svcCache, timeoutCfg, proxyTLSPort, proxyTLSEnabled, proxyTLSConfig, tracingCfg, servingCfg.ClusterDomain); !util.IsIgnoredErr(err) {
setupLog.Error(err, "tls proxy server failed")
return err
}
Expand All @@ -212,7 +212,7 @@ func main() {
setupLog.Info("starting the proxy server with TLS disabled", "port", proxyPort)

k8sSharedInformerFactory.WaitForCacheSync(ctx.Done())
if err := runProxyServer(ctx, ctrl.Log, queues, waitFunc, routingTable, svcCache, timeoutCfg, proxyPort, false, nil, tracingCfg); !util.IsIgnoredErr(err) {
if err := runProxyServer(ctx, ctrl.Log, queues, waitFunc, routingTable, svcCache, timeoutCfg, proxyPort, false, nil, tracingCfg, servingCfg.ClusterDomain); !util.IsIgnoredErr(err) {
setupLog.Error(err, "proxy server failed")
return err
}
Expand Down Expand Up @@ -409,6 +409,7 @@ func runProxyServer(
tlsEnabled bool,
tlsConfig map[string]interface{},
tracingConfig *config.Tracing,
clusterDomain string,
) error {
dialer := kedanet.NewNetDialer(timeouts.Connect, timeouts.KeepAlive)
dialContextFunc := kedanet.DialContextWithRetry(dialer, timeouts.DefaultBackoff())
Expand Down Expand Up @@ -456,6 +457,7 @@ func runProxyServer(
upstreamHandler,
svcCache,
tlsEnabled,
clusterDomain,
)

if tracingConfig.Enabled {
Expand Down
3 changes: 3 additions & 0 deletions interceptor/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ func TestRunProxyServerCountMiddleware(t *testing.T) {
false,
map[string]interface{}{},
&tracingCfg,
"",
)
})
// wait for server to start
Expand Down Expand Up @@ -234,6 +235,7 @@ func TestRunProxyServerWithTLSCountMiddleware(t *testing.T) {
true,
map[string]interface{}{"certificatePath": "../certs/tls.crt", "keyPath": "../certs/tls.key", "skipVerify": true},
&tracingCfg,
"",
)
})

Expand Down Expand Up @@ -384,6 +386,7 @@ func TestRunProxyServerWithMultipleCertsTLSCountMiddleware(t *testing.T) {
true,
map[string]interface{}{"certstorePaths": "../certs"},
&tracingCfg,
"",
)
})

Expand Down
21 changes: 14 additions & 7 deletions interceptor/middleware/routing.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,17 @@ type Routing struct {
upstreamHandler http.Handler
svcCache k8s.ServiceCache
tlsEnabled bool
clusterDomain string
}

func NewRouting(routingTable routing.Table, probeHandler http.Handler, upstreamHandler http.Handler, svcCache k8s.ServiceCache, tlsEnabled bool) *Routing {
func NewRouting(routingTable routing.Table, probeHandler http.Handler, upstreamHandler http.Handler, svcCache k8s.ServiceCache, tlsEnabled bool, clusterDomain string) *Routing {
return &Routing{
routingTable: routingTable,
probeHandler: probeHandler,
upstreamHandler: upstreamHandler,
svcCache: svcCache,
tlsEnabled: tlsEnabled,
clusterDomain: clusterDomain,
}
}

Expand Down Expand Up @@ -109,19 +111,24 @@ func (rm *Routing) streamFromHTTPSO(ctx context.Context, httpso *httpv1alpha1.HT
if err != nil {
return nil, fmt.Errorf("failed to get port: %w", err)
}

// Build the host part with optional cluster domain
host := fmt.Sprintf("%s.%s", reference.GetServiceName(), httpso.GetNamespace())
if rm.clusterDomain != "" {
host = fmt.Sprintf("%s.%s", host, rm.clusterDomain)
}

if rm.tlsEnabled {
return url.Parse(fmt.Sprintf(
"https://%s.%s:%d",
reference.GetServiceName(),
httpso.GetNamespace(),
"https://%s:%d",
host,
port,
))
}
//goland:noinspection HttpUrlsUsage
return url.Parse(fmt.Sprintf(
"http://%s.%s:%d",
reference.GetServiceName(),
httpso.GetNamespace(),
"http://%s:%d",
host,
port,
))
}
Expand Down
Loading