Skip to content

feat: Add new KEDA excercise#873

Open
avirdi1 wants to merge 3 commits into
masterfrom
anmol/keda_exercise
Open

feat: Add new KEDA excercise#873
avirdi1 wants to merge 3 commits into
masterfrom
anmol/keda_exercise

Conversation

@avirdi1
Copy link
Copy Markdown

@avirdi1 avirdi1 commented Apr 30, 2026

Adds a new exercise under HPAs introducing KEDA. Covers installation, ScaledObjects with a CPU trigger, load testing, and combining a Cron trigger to show event-driven scaling beyond what native HPAs support.

Summary by CodeRabbit

  • Documentation
    • Added a new Kubernetes course module on KEDA with structured metadata and estimated reading time.
    • Included step-by-step KEDA exercises: install, verify operator/CRDs, create CPU-triggered ScaledObject, generate load, observe scaling, and troubleshoot.
    • Added guidance for combining triggers (CPU + Cron), validating behavior, and updated navigation to include the new KEDA section.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 30, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1035a354-71d8-4abd-9b32-ffb2308456a3

📥 Commits

Reviewing files that changed from the base of the PR and between 125cb49 and 77c745c.

📒 Files selected for processing (1)
  • docs/9-kubernetes-container-orchestration/9.5.1-keda.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • docs/9-kubernetes-container-orchestration/9.5.1-keda.md

📝 Walkthrough

Walkthrough

Adds a new KEDA course module and navigation entry: front-matter with exercises, an overview of KEDA vs native HPA, Helm install steps, CPU ScaledObject walkthrough, troubleshooting, load-testing instructions, multi-trigger (Cron+CPU) extension, and deliverables/prompts.

Changes

KEDA Course Documentation

Layer / File(s) Summary
Front-matter / Exercises
docs/9-kubernetes-container-orchestration/9.5.1-keda.md
Adds YAML front-matter (category, reading time) and an exercises array detailing install, CPU ScaledObject, load tests, and multi-trigger Cron extension.
Overview / Concepts
docs/9-kubernetes-container-orchestration/9.5.1-keda.md
Introduces KEDA’s event-driven autoscaling model, table comparing ScaledObject vs ScaledJob, and rules for multi-trigger semantics.
Install / Verification
docs/9-kubernetes-container-orchestration/9.5.1-keda.md
Provides Helm install steps and checks for operator pods, webhooks, and required CRDs.
Create ScaledObject / HPA Interaction
docs/9-kubernetes-container-orchestration/9.5.1-keda.md
Steps to remove competing HPA, apply a CPU-triggered ScaledObject (min=1,max=5, CPU>65%), and verify the KEDA-created HPA.
Troubleshooting
docs/9-kubernetes-container-orchestration/9.5.1-keda.md
Guidance to use kubectl describe scaledobject, operator logs, and Metrics Server checks for CPU scaler issues.
Load Testing / Observation
docs/9-kubernetes-container-orchestration/9.5.1-keda.md
Adds busybox HTTP loop instructions, monitoring commands (kubectl get ... --watch) to observe scaling up/down and HPA TARGETS.
Multi-trigger (Cron) Extension
docs/9-kubernetes-container-orchestration/9.5.1-keda.md
Instructions to extend an existing ScaledObject with a Cron trigger (local timezone, start/end, desiredReplicas=3) and validate combined-trigger behavior.
Deliverables / Prompts
docs/9-kubernetes-container-orchestration/9.5.1-keda.md
Adds deliverable questions comparing KEDA vs native HPA, multi-trigger semantics, and Metrics Server dependency.
Docs Navigation / Index
docs/README.md, docs/_sidebar.md
Adds README front-matter entry for the new KEDA page and inserts a sidebar link for 9.5.1-keda.md under the existing HPA section.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 A little rabbit hops to scale by key and cron,
Helm installs hum, the operator is on.
Triggers wake pods, then gentle rest begins,
CPU and clocks together — blossoms on the bins.
Happy KEDA hops, the cluster softly grins.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: Add new KEDA excercise' is directly related to the changeset, which adds a new KEDA module with comprehensive exercises and documentation. However, it contains a spelling error ('excercise' should be 'exercise').
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch anmol/keda_exercise

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 0/1 reviews remaining, refill in 60 minutes.

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
docs/9-kubernetes-container-orchestration/9.5.1-keda.md (1)

41-105: ⚡ Quick win

Doc heading levels: replace most H2 (##) with H3 (###).

Per repo docs guidelines, use H3 as the default within documentation pages; reserve H2 for the navigation table of contents. This page currently uses multiple H2 section headers (e.g., “KEDA in Kubernetes”, “Install KEDA”, “Create a ScaledObject”, etc.). Consider downgrading them to ### to avoid unintended TOC behavior/noise.

♻️ Proposed changes (heading level adjustments)
-## KEDA in Kubernetes
+### KEDA in Kubernetes
@@
-## Install KEDA
+### Install KEDA
@@
-## Create a ScaledObject
+### Create a ScaledObject
@@
-## KEDA Troubleshooting
+### KEDA Troubleshooting
@@
-## Increase Server Load
+### Increase Server Load
@@
-## Decrease Server Load
+### Decrease Server Load
@@
-## ScaledObjects with Multiple Triggers
+### ScaledObjects with Multiple Triggers
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/9-kubernetes-container-orchestration/9.5.1-keda.md` around lines 41 -
105, Change the majority of H2 headers to H3 to follow repo docs guidelines:
replace the leading "##" with "###" for the headers "KEDA in Kubernetes",
"Install KEDA", "Create a ScaledObject", "KEDA Troubleshooting", "Increase
Server Load", "Decrease Server Load", and "ScaledObjects with Multiple Triggers"
so the page uses H3 as the default section level (reserve H2 only for the
top-level navigation/TOC if present).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/9-kubernetes-container-orchestration/9.5.1-keda.md`:
- Around line 54-61: Update step 3 of "Install KEDA" to clarify CRDs are
cluster-scoped and not tied to the keda namespace: replace the phrase "by
listing API resources in the keda namespace" with instructions to explicitly
check for the KEDA CRDs such as ScaledObject and ScaledJob (e.g., using kubectl
get crd for the keda.sh CRDs) or alternatively list API resources without
implying namespace scoping; reference the resource names ScaledObject and
ScaledJob so readers know what to verify.
- Around line 99-104: Replace the ambiguous instruction "Exit the busybox pod."
(Decrease Server Load step 1) with a deterministic action: tell students to stop
the load generator by either pressing Ctrl+C in the terminal where they ran
kubectl run -i --tty ... --rm (which will terminate and remove the pod) or, if
they started it elsewhere or prefer to delete it explicitly, run kubectl delete
pod <pod-name> from another shell (use kubectl get pods to find the busybox pod
name).

---

Nitpick comments:
In `@docs/9-kubernetes-container-orchestration/9.5.1-keda.md`:
- Around line 41-105: Change the majority of H2 headers to H3 to follow repo
docs guidelines: replace the leading "##" with "###" for the headers "KEDA in
Kubernetes", "Install KEDA", "Create a ScaledObject", "KEDA Troubleshooting",
"Increase Server Load", "Decrease Server Load", and "ScaledObjects with Multiple
Triggers" so the page uses H3 as the default section level (reserve H2 only for
the top-level navigation/TOC if present).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7bbfe079-03ee-4218-8c12-c0266caf40f9

📥 Commits

Reviewing files that changed from the base of the PR and between fd189bc and 125cb49.

📒 Files selected for processing (3)
  • docs/9-kubernetes-container-orchestration/9.5.1-keda.md
  • docs/README.md
  • docs/_sidebar.md

Comment thread docs/9-kubernetes-container-orchestration/9.5.1-keda.md
Comment on lines +99 to +104
1. Exit the busybox pod.

2. Watch the ScaledObject status with `kubectl get scaledobject --watch`.

3. After a few minutes, check the number of replicas in the `php-apache` deployment. How does the scale-down cooldown compare to the native HPA?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Clarify “Exit the busybox pod” to avoid ambiguity.

“Decrease Server Load” step 1 (Lines 99-100) says “Exit the busybox pod.” Since the load generator was started via kubectl run -i --tty ... --rm, students may not know whether to press Ctrl+C, or how to delete the pod explicitly. Make the instruction deterministic.

🛠️ Proposed fix
-1. Exit the busybox pod.
+1. Stop the load generator pod:
+   - In the terminal running the `kubectl run ...` command, press Ctrl+C, or
+   - run `kubectl delete pod load-generator`
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/9-kubernetes-container-orchestration/9.5.1-keda.md` around lines 99 -
104, Replace the ambiguous instruction "Exit the busybox pod." (Decrease Server
Load step 1) with a deterministic action: tell students to stop the load
generator by either pressing Ctrl+C in the terminal where they ran kubectl run
-i --tty ... --rm (which will terminate and remove the pod) or, if they started
it elsewhere or prefer to delete it explicitly, run kubectl delete pod
<pod-name> from another shell (use kubectl get pods to find the busybox pod
name).


## KEDA in Kubernetes

KEDA (Kubernetes Event-Driven Autoscaler) extends Kubernetes' native autoscaling capabilities to cover event sources far beyond CPU and memory — queues, streams, databases, HTTP traffic, cron schedules, and more. Rather than replacing the HPA, KEDA works alongside it: when you create a ScaledObject, KEDA provisions and manages an HPA under the hood, enriching it with richer trigger logic pulled from external sources.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@avirdi1 We jump righ;t into content. I would like to add some hypothetical situation before we jump in. Some foundational context that walks readers through a hypothetical event driven system that is suffering due to the limits of HPA. Use that to situation to introduce why KEDA is needed (please also include some graphics to break up the walls of text)

Comment on lines +43 to +50
KEDA (Kubernetes Event-Driven Autoscaler) extends Kubernetes' native autoscaling capabilities to cover event sources far beyond CPU and memory — queues, streams, databases, HTTP traffic, cron schedules, and more. Rather than replacing the HPA, KEDA works alongside it: when you create a ScaledObject, KEDA provisions and manages an HPA under the hood, enriching it with richer trigger logic pulled from external sources.

The two primary KEDA resources are:

| Resource | Purpose |
|---|---|
| ScaledObject | Targets a workload (Deployment, StatefulSet, etc.), defines scaling bounds, and lists one or more triggers |
| ScaledJob | Same idea, but scales Kubernetes Jobs instead of long-running workloads |
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@avirdi1 I think somewhere in here we need to introduce Scalers as they are the key to making KEDA such a versatile HPA

Copy link
Copy Markdown
Collaborator

@jburns24 jburns24 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The exercises need to be reworked. The current implementation uses CPU and Cron triggers, which are functionally indistinguishable from a native HPA — students finish this section without ever experiencing what makes KEDA genuinely valuable: scaling from external event sources before resource pressure materializes.

Proposed rework:

Create a companion example repository built around a realistic e-commerce order processing system. The repo should be self-contained and include a k3d cluster config, a Taskfile orchestrating all operations, application code with Dockerfiles, Kubernetes manifests managed with Kustomize, and load generation scripts. The exercises should be structured as a progressive discovery:


Exercise 1 — Meet the system

Introduce two services: a checkout-service that produces order events whenever a customer completes a purchase, and an order-processor that consumes those events and fulfills each order (validating inventory, calculating totals, updating records). Explain that this producer/consumer pattern is one of the most common architectures in distributed systems — it decouples the rate at which work arrives from the rate at which it gets done, which makes both services independently deployable and scalable. (These should be the simplest examples of these application, the system is the interesting thing here not the business logic)

Deploy the baseline system using the Taskfile and verify both services are running.


Exercise 2 — Simulate peak traffic and watch the system fail

Run the provided load generation script, which simulates a flash sale: a sudden surge of customers checking out simultaneously. Watch the order-processor fall behind. The queue depth grows. Orders start timing out or failing. The system is unhealthy.

The order-processor is doing CPU-bound work per order (inventory checks, pricing logic) — given enough sustained load, CPU will spike. But by the time that happens, the damage is already done.


Exercise 3 — Attempt a fix with native HPA

Kubernetes has a built-in autoscaling primitive: the HPA. Create a CPU-based HPA targeting the order-processor and run the load generation script again. Observe that the system gets further — the HPA does eventually scale out — but it still degrades under the surge. The HPA is reacting to CPU pressure that only materializes after the queue has already grown dangerously deep. By the time new replicas are ready, the backlog has compounded. The root cause is that CPU is a lagging indicator of the real problem: queue depth.


Exercise 4 — Introduce KEDA

KEDA (Kubernetes Event-Driven Autoscaler) extends Kubernetes autoscaling to support external event sources as scaling triggers — including the message queue sitting between the checkout-service and order-processor. Rather than waiting for CPU to spike, KEDA can scale the order-processor based on how many unprocessed orders are waiting in the queue. The system can scale proactively, before resource pressure ever builds.

Remove the native HPA (KEDA will manage its own), then have participants install KEDA


Exercise 5 — Analyze the system and create a ScaledObject

Examine the order-processor deployment manifests and the message queue configuration in the example repo. Using the KEDA documentation, identify the appropriate scaler for this queue type and create a ScaledObject that:

  • Targets the order-processor Deployment
  • Sets a sensible minimum and maximum replica count
  • Scales based on queue depth with a threshold that reflects a realistic per-replica processing capacity

Apply the ScaledObject and verify KEDA has accepted it.


Exercise 6 — Run the load test again

Re-run the same flash sale simulation. Watch the order-processor scale out ahead of CPU pressure as the queue begins to fill. Orders are processed. The queue stays shallow. The system remains healthy under the same load that previously caused it to fail.


Deliverables

  • Why did the native HPA fail to protect the system under a sudden surge, even after it scaled out?
  • What does KEDA use as its scaling signal in this exercise, and why is it a more appropriate metric than CPU for this workload?
  • In the producer/consumer pattern, what are the tradeoffs of scaling the consumer based on queue depth vs. scaling it based on CPU utilization?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants