Share

[[{“value”:”

If you’ve tried to spin up a Kyma runtime on SAP BTP trial recently, you’ll have hit the same wall as the rest of us: the Kyma trial has been suspended for the foreseeable future. No ETA.

For anyone actively building skills around Kyma — whether that’s for BTP development, cert prep, or just keeping pace with where SAP is heading — this is genuinely frustrating. You can read the docs all day, but without something to deploy to, you’re not really learning anything.

So here’s what I did instead: I ran Kyma locally using k3d (k3s in Docker) on my MacBook. It’s not a perfect substitute for BTP Kyma runtime, but it’s close enough to work through real scenarios, debug real problems, and actually understand how the stack fits together.

This post covers what it takes to get there — including the parts the official docs glide past.


What You Need


Step 1 — Spin Up the Cluster

The k3d cluster creation command is doing several things at once, so it’s worth understanding before you paste and run:

k3d cluster create kyma 
  --kubeconfig-switch-context 
  -p '30080:80@loadbalancer' 
  -p '30443:443@loadbalancer' 
  --k3s-arg '--disable=traefik@server:*' 
  --k3s-arg '--tls-san=host.docker.internal@server:*'
  • The port mappings (3008080, 30443443) expose the ingress gateway on localhost ports that don’t require elevated privileges
  • Traefik is disabled because Kyma uses Istio as its ingress — you don’t want them fighting over traffic
  • The tls-san flag adds host.docker.internal as a valid TLS hostname, which matters later

Then create the required namespace:

kubectl create ns kyma-system

Step 2 — Install the Modules

Kyma is modular. You don’t have to install everything — pick what you need. For a useful local setup, I’d recommend starting with at minimum Istio, API Gateway, and Serverless.

Istio (the service mesh — everything else depends on this):

kubectl label namespace kyma-system istio-injection=enabled --overwrite
kubectl apply -f https://github.com/kyma-project/istio/releases/latest/download/istio-manager.yaml
kubectl apply -f https://github.com/kyma-project/istio/releases/latest/download/istio-default-cr.yaml

Serverless (for Functions):

kubectl apply -f https://github.com/kyma-project/serverless-manager/releases/latest/download/serverless-operator.yaml
kubectl apply -f https://github.com/kyma-project/serverless-manager/releases/latest/download/default-serverless-cr.yaml -n kyma-system

API Gateway (exposes your functions externally via APIRules):

kubectl label namespace kyma-system istio-injection=enabled --overwrite
kubectl apply -f https://github.com/kyma-project/api-gateway/releases/latest/download/api-gateway-manager.yaml
kubectl apply -f https://github.com/kyma-project/api-gateway/releases/latest/download/apigateway-default-cr.yaml

Give everything a couple of minutes to come up. You can watch progress with:

kubectl get pods -n kyma-system --watch

Step 3 — Fix CoreDNS (The Bit the Docs Mention but Don’t Emphasise Enough)

This is the step that will silently break everything if you skip it.

By default, local.kyma.dev subdomains don’t resolve to anything useful inside the cluster. You need to tell CoreDNS to rewrite them to point at the Istio ingress gateway:

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
  name: coredns-custom
  namespace: kube-system
data:
  kyma.override: |
    rewrite name regex (.*).local.kyma.dev istio-ingressgateway.istio-system.svc.cluster.local
EOF

kubectl rollout restart deployment -n kube-system coredns

Without this, you’ll spend a while wondering why curl is timing out and nslookup is returning nothing — which brings me to the next section.


Step 4 — Deploy a Function and Test It

Once everything is running, deploy a simple test function. Here’s a minimal Node.js example:

apiVersion: serverless.kyma-project.io/v1alpha2
kind: Function
metadata:
  name: hello-kyma
  namespace: default
spec:
  runtime: nodejs20
  source:
    inline:
      source: |
        module.exports = { main: function (event, context) {
          return "Hello from local Kyma!";
        }}

Apply it, wait for it to reach Running state, then create an APIRule to expose it. Once that’s in place, test with:

curl http://hello-kyma.local.kyma.dev:30080

Note the port — because of the k3d port mapping, HTTP traffic goes through 30080, not 80 directly.


What I Actually Ran Into

The official quick-start docs are accurate, but they assume a fairly smooth path. Here’s what debugging actually looked like once I had everything deployed but couldn’t get a response through the gateway.

The problem wasn’t Kyma. It was a combination of:

  1. DNS not resolvingnslookup hello-kyma.local.kyma.dev was returning nothing. Root cause: CoreDNS rewrite not applied (see Step 3).

  2. Port confusion — I’d been curling port 80 and 443 directly, which don’t work from the host. The k3d port mappings mean you need 30080 for HTTP and 30443 for HTTPS from outside the cluster.

  3. Istio mTLS — Once DNS was working, I hit RBAC: access denied. This turned out to be Istio’s strict mTLS mode combined with an AuthorizationPolicy that wasn’t correctly matching the ingress gateway’s service account. Checking kubectl get authorizationpolicy -n default -o yaml and cross-referencing the actual service account name on the ingress gateway pod sorted it.

The fix that confirmed everything was working:

curl http://hello-kyma.local.kyma.dev:30080

Response: Hello from local Kyma!


A Note on HTTPS

HTTP works cleanly with the setup above. HTTPS on a local k3d cluster involves self-signed certificates and some extra trust configuration on the host side — that’s a separate infrastructure problem rather than a Kyma one, and deserves its own post.


Why Bother?

Running Kyma locally isn’t a replacement for BTP Kyma runtime — you won’t be able to bind real BTP services without the BTP Operator pointing at a real subaccount. But for understanding how Functions, API Gateway, Istio, and service mesh concepts actually hang together, it’s genuinely valuable. You can break things, fix things, and read actual logs — which is where the learning happens.

If SAP is going to keep Kyma trial offline for a while, this is the next best thing.


Tested on macOS (Apple Silicon) with k3d v5.7, Kyma Istio module latest, and API Gateway module latest.

“}]] 

  Read More Technology Blog Posts by Members articles 

#abap

By ali

Leave a Reply