Kubeasy LogoKubeasy

How It Works

Understand the technical architecture behind Kubeasy — from the local cluster to validation.

Kubeasy combines several open-source tools to create a fully local, isolated, and validated Kubernetes learning environment. This page explains how each piece fits together.

Architecture overview

┌────────────────────────────────────────────────────────────┐
│                        Your Machine                         │
│                                                              │
│  ┌──────────────┐                                           │
│  │ Kubeasy CLI  │  (Go + Cobra)                             │
│  │  - Manages   │                                           │
│  │  - Validates │                                           │
│  └──────┬───────┘                                           │
│         │                                                    │
│         │ Creates & Queries                                  │
│         ▼                                                    │
│  ┌─────────────────────────────────────────────────────────┐│
│  │            Kind Cluster (Local Kubernetes)               ││
│  │                                                          ││
│  │  ┌────────────┐ ┌──────────────┐ ┌──────────────────┐  ││
│  │  │  Kyverno   │ │ cert-manager │ │  nginx-ingress   │  ││
│  │  └────────────┘ └──────────────┘ └──────────────────┘  ││
│  │  ┌────────────────────────────────────────────────────┐ ││
│  │  │  Challenge Namespaces (isolated)                   │ ││
│  │  │  • pod-evicted                                     │ ││
│  │  │  • rbac-missing-permissions                        │ ││
│  │  │  • ...                                             │ ││
│  │  └────────────────────────────────────────────────────┘ ││
│  └─────────────────────────────────────────────────────────┘│
└────────────────────────────────────────────────────────────┘

The Kubeasy CLI

The CLI is the central tool. It handles everything: authentication, cluster setup, challenge deployment, validation, and progress submission.

Built with Go and Cobra, it ships as a single binary with no runtime dependencies.

Core responsibilities:

  • Authenticate users via API keys
  • Create and configure the local Kind cluster
  • Install and verify infrastructure components
  • Deploy challenges from OCI artifacts
  • Execute validation logic directly against the cluster
  • Submit results to the Kubeasy platform

Kind — local Kubernetes

Kind (Kubernetes in Docker) runs a real Kubernetes cluster inside Docker containers. When you run kubeasy setup, the CLI:

  1. Creates a single-node cluster named kubeasy running Kubernetes v1.35.0
  2. Configures port mappings: host 8080 → cluster 80 (HTTP) and host 8443 → cluster 443 (HTTPS), used by the nginx-ingress controller
  3. Configures kubectl to point to the cluster

Kind clusters are fast to create, isolated from your system, and behave like real Kubernetes. You can use any standard Kubernetes tooling against them.

Infrastructure components

kubeasy setup installs 7 infrastructure components into the cluster. These support the challenge ecosystem:

ComponentVersionNamespacePurpose
Kyvernov1.17.1kyvernoPolicy engine for bypass prevention
local-path-provisionerv0.0.35local-path-storagePersistentVolume storage
nginx-ingressv1.15.0ingress-nginxIngress controller
Gateway API CRDsv1.5.1Gateway API support
cert-managerv1.20.0cert-managerTLS certificate management
kubeasy-cacert-managerSelf-signed CA + ClusterIssuer
cloud-provider-kindv0.10.0LoadBalancer support

You can inspect any component at any time:

kubectl get pods -n kyverno
kubectl get pods -n ingress-nginx
kubectl get pods -n cert-manager

Kyverno — bypass prevention

Kyverno is a Kubernetes-native policy engine. In Kubeasy, it's used exclusively to prevent cheating — it enforces the rules defined in each challenge's policies/ directory.

For example, a policy might prevent you from swapping the broken application image with a working one. This ensures you solve the actual problem rather than working around it.

# Example: prevents changing the container image
apiVersion: kyverno.io/v1
kind: Policy
metadata:
  name: protect-app-image
  namespace: pod-evicted   # matches the challenge slug
spec:
  validationFailureAction: Enforce
  rules:
    - name: preserve-image
      match:
        resources:
          kinds: ["Deployment"]
      validate:
        message: "Cannot change the container image"
        pattern:
          spec:
            template:
              spec:
                containers:
                  - image: "myapp:broken-v1"

Kyverno is only used for bypass prevention. Challenge validation is handled entirely by the CLI — not Kyverno.

Challenge deployment via OCI

Challenges are packaged as OCI artifacts and stored in the GitHub Container Registry (ghcr.io/kubeasy-dev/challenges). When you run kubeasy challenge start <slug>, the CLI:

  1. Pulls the OCI artifact for that challenge
  2. Creates a dedicated namespace (<slug>)
  3. Applies the challenge manifests (the intentionally broken state)
  4. Applies the Kyverno policies (bypass prevention)
  5. Waits for resources to reach their initial state
  6. Switches your kubectl context to the challenge namespace

This approach requires no cluster-side GitOps tooling — the CLI handles everything directly.

CLI-based validation

When you run kubeasy challenge submit <slug>, the CLI:

  1. Reads the validation objectives from the challenge definition
  2. Executes each validation in parallel against the cluster
  3. Groups and displays results
  4. Sends the structured results to the Kubeasy backend
  5. The backend verifies all objectives are present and passed before awarding XP

Kubeasy supports 8 validation types:

TypeWhat it checks
conditionResource conditions (Pod Ready, Deployment Available)
statusArbitrary status fields with operators (restart count < 3)
logExpected strings in container logs
eventForbidden or required Kubernetes events
connectivityHTTP connectivity between pods or from the CLI
rbacServiceAccount permissions via SubjectAccessReview
specResource manifest fields (spec/metadata paths)
triggeredRun an action then validate the outcome

Challenge lifecycle

Starting a challenge

kubeasy challenge start pod-evicted

         ├── Fetch challenge metadata from API
         ├── Create namespace: pod-evicted
         ├── Pull OCI artifact: ghcr.io/kubeasy-dev/challenges/pod-evicted:latest
         ├── Apply manifests (broken state)
         ├── Apply Kyverno policies
         └── Set kubectl context to pod-evicted namespace

Solving

You now have full access to the cluster namespace. Use any Kubernetes tooling to investigate and fix the problem. The broken state is realistic — you'll find the same kind of evidence (events, logs, conditions) that you would in a real cluster.

Submitting

kubeasy challenge submit pod-evicted

         ├── Load objectives from challenge definition
         ├── Execute each validation against the cluster (parallel)
         ├── Display pass/fail results with messages
         └── POST results to Kubeasy API

                  ├── Backend verifies ALL expected objectives present
                  ├── Backend verifies no extra objectives injected
                  └── Awards XP if all objectives passed

Resetting

# Remove resources and reset backend progress
kubeasy challenge reset pod-evicted

# Remove resources only (keep backend progress)
kubeasy challenge clean pod-evicted

Security and isolation

Local isolation: Each challenge runs in its own Kubernetes namespace. Challenges don't interfere with each other. The Kind cluster is entirely local — no data leaves your machine.

Bypass prevention: Kyverno policies prevent shortcuts like swapping the broken application with a working one. You must solve the actual problem.

Submission integrity: The backend validates submissions by:

  1. Checking that ALL registered objectives are present (you can't skip objectives)
  2. Checking that no unknown objectives were submitted (you can't fabricate results)
  3. Verifying every objective has passed: true before completing the challenge

Philosophy: why CLI-based validation?

Earlier versions of Kubeasy used Rego-based policies and a Kubernetes operator with CRDs. The current CLI-based approach offers several advantages:

  • Simplicity — one challenge.yaml file contains everything, including validation logic
  • No extra infrastructure — the CLI executes all validation directly, no operator needed
  • Easy local testing — challenge authors can test validations without pushing to a registry
  • Better feedback — the CLI produces detailed, actionable failure messages
  • Faster iteration — no reconciliation loop, results are immediate

On this page