Skip to content

Commit 239e504

Browse files
authored
Merge pull request #2257 from zroubalik/kedify1
Kedify: Autoscaling HTTP applications on Kubernetes
2 parents 1d69865 + 3ff6f00 commit 239e504

File tree

7 files changed

+561
-0
lines changed

7 files changed

+561
-0
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
---
2+
title: Autoscaling HTTP applications on Kubernetes
3+
4+
draft: true
5+
cascade:
6+
draft: true
7+
8+
minutes_to_complete: 45
9+
10+
who_is_this_for: >
11+
Developers and SREs running HTTP-based workloads on Kubernetes who want to enable intelligent, event-driven autoscaling.
12+
13+
learning_objectives:
14+
- Install Kedify (KEDA build, HTTP Scaler, and Kedify Agent) via Helm
15+
- Verify that the components are running in your cluster
16+
- Deploy a sample HTTP application and test autoscaling behavior
17+
18+
prerequisites:
19+
- A running Kubernetes cluster (local or cloud)
20+
- kubectl and helm installed locally
21+
- Access to the Kedify Service dashboard (https://dashboard.kedify.io/) to obtain Organization ID and API Key — log in or create an account if you don’t have one
22+
23+
author: Zbynek Roubalik
24+
25+
### Tags
26+
skilllevels: Introductory
27+
subjects: Containers and Virtualization
28+
cloud_service_providers: Any
29+
armips:
30+
- Neoverse
31+
operatingsystems:
32+
- Linux
33+
tools_software_languages:
34+
- Kubernetes
35+
- Helm
36+
- KEDA
37+
- Kedify
38+
39+
further_reading:
40+
- resource:
41+
title: Kedify HTTP Scaler
42+
link: https://kedify.io/scalers/http
43+
type: documentation
44+
- resource:
45+
title: Kedify documentation
46+
link: https://docs.kedify.io
47+
type: documentation
48+
- resource:
49+
title: KEDA project
50+
link: https://keda.sh/
51+
type: documentation
52+
53+
54+
### FIXED, DO NOT MODIFY
55+
# =============================================================================
56+
weight: 1 # _index.md always has weight of 1 to order correctly
57+
layout: "learningpathall" # All files under learning paths have this same wrapper
58+
learning_path_main_page: "yes" # This should be surfaced when looking for related content. Only set for _index.md of learning path content.
59+
---
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
# =============================================================================
3+
# FIXED, DO NOT MODIFY THIS FILE
4+
# =============================================================================
5+
weight: 21 # Set to always be larger than the content in this path to be at the end of the navigation.
6+
title: "Next Steps" # Always the same, html page title.
7+
layout: "learningpathall" # All files under learning paths have this same wrapper for Hugo processing.
8+
---
Lines changed: 281 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,281 @@
1+
---
2+
title: "HTTP Scaling for Ingress-Based Applications"
3+
weight: 4
4+
layout: "learningpathall"
5+
---
6+
7+
Use this section to get a quick, hands-on feel for Kedify HTTP autoscaling. We’ll deploy a small web service, expose it through a standard Kubernetes Ingress, and rely on Kedify’s autowiring to route traffic via its proxy so requests are measured and drive scaling.
8+
9+
Scale a real HTTP app exposed through Kubernetes Ingress using Kedify’s [kedify-http](https://docs.kedify.io/scalers/http-scaler/) scaler. You will deploy a simple app, enable autoscaling with a [ScaledObject](https://keda.sh/docs/latest/concepts/scaling-deployments/), generate load, and observe the system scale out and back in (including scale-to-zero when idle).
10+
11+
## How it works
12+
13+
With ingress autowiring enabled, Kedify automatically routes traffic through its proxy before it reaches your Service/Deployment:
14+
15+
```
16+
Ingress → kedify-proxy → Service → Deployment
17+
```
18+
19+
The [Kedify Proxy](https://docs.kedify.io/scalers/http-scaler/#kedify-proxy) gathers request metrics used by the scaler to make decisions.
20+
21+
## What you’ll deploy
22+
23+
- Deployment & Service: an HTTP server with a small response delay to simulate work
24+
- Ingress: public entry using host `application.keda`
25+
- ScaledObject: Kedify HTTP scaler with `trafficAutowire: ingress`
26+
27+
## Step 0 — Set up Ingress IP environment variable
28+
29+
Before testing the application, ensure you have the `INGRESS_IP` environment variable set with your ingress controller's external IP or hostname.
30+
31+
If you followed the [Install Ingress Controller](../install-ingress/) guide, you should already have this set. If not, or if you're using an existing ingress controller, run this command:
32+
33+
```bash
34+
export INGRESS_IP=$(kubectl get service ingress-nginx-controller --namespace=ingress-nginx -o jsonpath='{.status.loadBalancer.ingress[0].ip}{.status.loadBalancer.ingress[0].hostname}')
35+
echo "Ingress IP/Hostname: $INGRESS_IP"
36+
```
37+
You should now have the correct IP address or hostname stored in the `$INGRESS_IP` environment variable. If the command doesn't print any value, please repeat it after some time.
38+
39+
{{% notice Note %}}
40+
If your ingress controller service has a different name or namespace, adjust the command accordingly. For example, some installations use `nginx-ingress-controller` or place it in a different namespace.
41+
{{% /notice %}}
42+
43+
## Step 1 — Create the application and Ingress
44+
45+
Let's start with deploying an application that responds to an incoming HTTP server and is exposed via Ingress. You can check the source code of the application on [GitHub](https://github.com/kedify/examples/tree/main/samples/http-server).
46+
47+
#### Deploy the application
48+
49+
Run the following command to deploy our application:
50+
51+
```bash
52+
cat <<'EOF' | kubectl apply -f -
53+
apiVersion: apps/v1
54+
kind: Deployment
55+
metadata:
56+
name: application
57+
spec:
58+
replicas: 1
59+
selector:
60+
matchLabels:
61+
app: application
62+
template:
63+
metadata:
64+
labels:
65+
app: application
66+
spec:
67+
nodeSelector:
68+
kubernetes.io/arch: arm64
69+
tolerations:
70+
- key: "kubernetes.io/arch"
71+
operator: "Equal"
72+
value: "arm64"
73+
effect: "NoSchedule"
74+
containers:
75+
- name: application
76+
image: ghcr.io/kedify/sample-http-server:latest
77+
imagePullPolicy: Always
78+
ports:
79+
- name: http
80+
containerPort: 8080
81+
protocol: TCP
82+
env:
83+
- name: RESPONSE_DELAY
84+
value: "0.3"
85+
---
86+
apiVersion: v1
87+
kind: Service
88+
metadata:
89+
name: application-service
90+
spec:
91+
ports:
92+
- name: http
93+
protocol: TCP
94+
port: 8080
95+
targetPort: http
96+
selector:
97+
app: application
98+
type: ClusterIP
99+
---
100+
apiVersion: networking.k8s.io/v1
101+
kind: Ingress
102+
metadata:
103+
name: application-ingress
104+
spec:
105+
ingressClassName: nginx
106+
rules:
107+
- host: application.keda
108+
http:
109+
paths:
110+
- path: /
111+
pathType: Prefix
112+
backend:
113+
service:
114+
name: application-service
115+
port:
116+
number: 8080
117+
EOF
118+
```
119+
120+
Notes:
121+
- `RESPONSE_DELAY` adds ~300ms latency per request, making scaling effects easier to see.
122+
- The Ingress uses host `application.keda`. To access this app we will use your ingress controller’s IP with a `Host:` header (shown below).
123+
124+
#### Verify the application is running correctly
125+
126+
Let's check that we have 1 replica of the application deployed and ready:
127+
128+
```bash
129+
kubectl get deployment application
130+
```
131+
132+
In the output we should see 1 replica ready:
133+
```
134+
NAME READY UP-TO-DATE AVAILABLE AGE
135+
application 1/1 1 1 3m44s
136+
```
137+
138+
#### Test the application
139+
Hit the app to confirm the app is ready and routing works:
140+
141+
```bash
142+
curl -I -H "Host: application.keda" http://$INGRESS_IP
143+
```
144+
145+
You should see similar output:
146+
```
147+
HTTP/1.1 200 OK
148+
Date: Thu, 11 Sep 2025 14:11:24 GMT
149+
Content-Type: text/html
150+
Content-Length: 301
151+
Connection: keep-alive
152+
```
153+
154+
## Step 2 — Enable autoscaling with Kedify
155+
156+
The application is currectly running, Now we will enable autoscaling on this app, we will scale from 0 to 10 replicas. No request shall be lost at any moment. To do that, please run the following command to deploy our `ScaledObject`:
157+
158+
```bash
159+
cat <<'EOF' | kubectl apply -f -
160+
apiVersion: keda.sh/v1alpha1
161+
kind: ScaledObject
162+
metadata:
163+
name: application
164+
spec:
165+
scaleTargetRef:
166+
apiVersion: apps/v1
167+
kind: Deployment
168+
name: application
169+
cooldownPeriod: 5
170+
minReplicaCount: 0
171+
maxReplicaCount: 10
172+
fallback:
173+
failureThreshold: 2
174+
replicas: 1
175+
advanced:
176+
restoreToOriginalReplicaCount: true
177+
horizontalPodAutoscalerConfig:
178+
behavior:
179+
scaleDown:
180+
stabilizationWindowSeconds: 5
181+
triggers:
182+
- type: kedify-http
183+
metadata:
184+
hosts: application.keda
185+
pathPrefixes: /
186+
service: application-service
187+
port: "8080"
188+
scalingMetric: requestRate
189+
targetValue: "10"
190+
granularity: 1s
191+
window: 10s
192+
trafficAutowire: ingress
193+
EOF
194+
```
195+
196+
What the key fields do:
197+
- `type: kedify-http` — Use Kedify’s HTTP scaler.
198+
- `hosts`, `pathPrefixes` — Which requests to observe for scaling.
199+
- `service`, `port` — The Service and port receiving traffic.
200+
- `scalingMetric: requestRate` and `targetValue: 10` — Target 1000 req/s (per granularity/window) before scaling out.
201+
- `minReplicaCount: 0` — Allows scale-to-zero when idle.
202+
- `trafficAutowire: ingress` — Lets Kedify auto-wire your Ingress to the kedify-proxy.
203+
204+
After applying, the ScaledObject will appear in the Kedify dashboard (https://dashboard.kedify.io/).
205+
206+
![Kedify Dashboard With ScaledObject](images/scaledobject.png)
207+
208+
## Step 3 — Send traffic and observe scaling
209+
210+
Becuase we are not sending any traffic to our application, after some time, it should be scaled to zero.
211+
212+
#### Verify scale to zero
213+
214+
Run this command and wait until there is 0 replicas:
215+
216+
```bash
217+
watch kubectl get deployment application -n default
218+
```
219+
220+
You should see similar output:
221+
```bash
222+
Every 2,0s: kubectl get deployment application -n default
223+
224+
NAME READY UP-TO-DATE AVAILABLE AGE
225+
application 0/0 0 0 110s
226+
```
227+
228+
#### Verify the app can scale from zero
229+
230+
Now, hit the app again, it should be scaled to 1 replica and return back correct response:
231+
```bash
232+
curl -I -H "Host: application.keda" http://$INGRESS_IP
233+
```
234+
235+
You should see a 200 OK response. Next, generate sustained load. You can use `hey` (or a similar tool):
236+
237+
#### Test higher load
238+
239+
```bash
240+
hey -n 40000 -c 200 -host "application.keda" http://$INGRESS_IP
241+
```
242+
243+
While the load runs, watch replicas change:
244+
245+
```bash
246+
watch kubectl get deployment application -n default
247+
```
248+
249+
For example something like this:
250+
251+
```
252+
Every 2,0s: kubectl get deployment application -n default
253+
254+
NAME READY UP-TO-DATE AVAILABLE AGE
255+
application 5/5 5 5 23m
256+
```
257+
258+
Expected behavior:
259+
- On bursty load, Kedify scales the Deployment up toward `maxReplicaCount`.
260+
- When traffic subsides, replicas scale down. After the cooldown, they can return to zero.
261+
262+
You can also observe traffic and scaling in the Kedify dashboard:
263+
264+
![Kedify Dashboard ScaledObject Detail](images/load.png)
265+
266+
## Clean up
267+
268+
```bash
269+
kubectl delete scaledobject application
270+
kubectl delete ingress application-ingress
271+
kubectl delete service application-service
272+
kubectl delete deployment application
273+
```
274+
275+
## Next steps
276+
277+
Explore the official Kedify [How-to guides](https://docs.kedify.io/how-to/) for more configurations such as Gateway API, Istio VirtualService, or OpenShift Routes.
278+
279+
### See also
280+
281+
- Kedify documentation: https://docs.kedify.io
192 KB
Loading
125 KB
Loading

0 commit comments

Comments
 (0)