Skip to content

Tutorial: build your first stack

Goes one level up from the Hello-world cell tutorial: you'll build a stack with two cells in the same space, and see that they can reach each other over the bridge.

Goal

Two cells, one stack:

  • web — an nginx container, serves HTTP.
  • client — a busybox container that wgets the web cell.

Both cells live in one stack (demo) inside one space (tutorial) inside the default user realm.

Realm: default
└── Space: tutorial           (new)
    └── Stack: demo           (new)
        ├── Cell: web         (nginx)
        └── Cell: client      (busybox + wget)

1. Write the manifest

Save this as tutorial.yaml:

apiVersion: v1beta1
kind: Space
metadata:
  name: tutorial
spec:
  realmId: default
---
apiVersion: v1beta1
kind: Stack
metadata:
  name: demo
spec:
  id: demo
  realmId: default
  spaceId: tutorial
---
apiVersion: v1beta1
kind: Cell
metadata:
  name: web
spec:
  id: web
  realmId: default
  spaceId: tutorial
  stackId: demo
  containers:
    - id: nginx
      image: docker.io/library/nginx:alpine
---
apiVersion: v1beta1
kind: Cell
metadata:
  name: client
spec:
  id: client
  realmId: default
  spaceId: tutorial
  stackId: demo
  containers:
    - id: wget
      image: docker.io/library/busybox:latest
      command: /bin/sh
      args:
        - -c
        - "while true; do wget -qO- http://web 2>/dev/null || true; sleep 5; done"

2. Apply it

sudo kuke apply -f tutorial.yaml

Kukeon creates the space, stack, and two cells in dependency order. The nginx cell gets one IP on the tutorial space's bridge; the busybox cell gets another.

3. Check the network

Each cell has its own IP on the same bridge (kuke-default-tutorial or similar — it was truncated to fit the 15-char kernel limit):

$ ip -4 addr show type bridge | grep kuke
<n>: kuke-default-tu: <BROADCAST,MULTICAST,UP,LOWER_UP> ...
    inet 10.88.0.1/16 ...

4. Watch the client hit the web cell

The client's busybox is in a loop. Attach to its task:

sudo ctr -n kukeon-default tasks attach client_wget

You should see nginx's default HTML stream by every 5 seconds. Press Ctrl-C to detach from the task without killing it.

Reaching web by name

In this example wget http://web works because the space's bridge has a resolver, and the web cell's root container registers itself by name. If your space has DNS turned off, you can replace the URL with the cell IP (find it via kuke get cells --realm default --space tutorial --stack demo -o yaml and look under status.containers[].ip).

5. Tear it down

# Cascade-delete the whole stack (both cells and their containers)
sudo kuke delete stack demo --realm default --space tutorial --cascade

# Then the space (if you're done with it)
sudo kuke delete space tutorial --realm default --cascade

What you just learned

  • Multi-document YAML gets applied in dependency order, so one file can describe an entire stack.
  • Cells in the same space share a bridge — they can reach each other at the IP layer.
  • delete --cascade reliably removes a whole subtree without leaving orphans.

Next