Skip to content

Docs: fix outdated containerd config and add service exposure in kind tutorial #923

Description

@HARSHVARANDANI

Summary

docs/tutorials/Running-urunc-with-kind.md has two problems that make it impossible to follow end-to-end on a current kind node image:

  1. The containerd config snippet in Step 3.9 targets a plugin ID (io.containerd.grpc.v1.cri) that no longer exists in the CRI plugin config schema shipped by current containerd releases. Appending it does nothing.
  2. The tutorial stops at "the pod is Running and logs look fine" (Steps 6, 7). It never gives the reader a way to actually send a request to the NGINX unikernel and see a response, even though the whole point of the example image is that it's a web server. Because kind nodes run inside Docker containers, ClusterIP/pod IPs aren't reachable from the host without extra kind/Service config.

Problem 1: outdated containerd config snippet

Root cause

Current containerd config (schema version = 4, generated by containerd config default) splits the old monolithic CRI plugin into two plugins:

  • io.containerd.cri.v1.images
  • io.containerd.cri.v1.runtime
    Runtime handlers now live under:
plugins.'io.containerd.cri.v1.runtime'.containerd.runtimes.<name>

not under plugins."io.containerd.grpc.v1.cri".containerd.runtimes.<name> as the tutorial's tee -a snippet assumes. This is documented in containerd's own CRI Plugin Config Guide, which shows the version = 3 / io.containerd.cri.v1.runtime example (the schema split further to version = 4 in later releases, keeping the same io.containerd.cri.v1.* plugin IDs).

Fix

Instead of blindly tee -a-ing a hardcoded old-schema block, add the urunc entry as a sibling of the existing runc entry under the runtime plugin that's actually present in the generated config.

Proposed replacement for Step 3.9 (Add urunc to containerd):

python3 - <<'EOF'
import re
 
path = "/etc/containerd/config.toml"
with open(path) as f:
    cfg = f.read()
 
urunc_block = '''
[plugins.'io.containerd.cri.v1.runtime'.containerd.runtimes.urunc]
  runtime_type = "io.containerd.urunc.v2"
  pod_annotations = ["com.urunc.unikernel.*"]
  container_annotations = ["com.urunc.unikernel.*"]
  snapshotter = "overlayfs"
  sandboxer = "podsandbox"
'''
 
marker = "[plugins.'io.containerd.cri.v1.runtime'.containerd.runtimes.runc.options]"
idx = cfg.index(marker)
end = cfg.index("\n\n", idx)
cfg = cfg[:end] + "\n" + urunc_block + cfg[end:]
 
with open(path, "w") as f:
    f.write(cfg)
EOF
 
systemctl restart containerd || (pkill containerd; containerd &)

(PS this is just a suggestion, we need to discuss with the maintainers about how to properly document this containerd config version issue because this will keep arising everytime new version of the config drops)

Problem 2: no way to verify the server actually responds

Root cause

kind nodes are Docker containers on a private Docker network. A Pod's IP and a plain ClusterIP Service are only reachable from inside that network (or via kubectl port-forward), never directly from the host's browser/curl. The tutorial's kind-config.yaml (Step 2) also has no port mapping out of the container, so even a NodePort Service wouldn't be reachable without editing that file too.

Fix

Two small additions, kept consistent with the reader's already-created urunc-test cluster name:

Step 2: extend kind-config.yaml with a host port mapping:

kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
  - role: control-plane
    extraMounts:
      - hostPath: /dev/kvm
        containerPath: /dev/kvm
    extraPortMappings:
      - containerPort: 30080   # must match the Service's nodePort below
        hostPort: 8080
        protocol: TCP

Step 5: add a NodePort Service alongside the existing nginx-urunc.yaml Pod manifest:

# nginx-urunc-nodeport.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-urunc-svc
spec:
  type: NodePort
  selector:
    run: nginx-urunc
  ports:
    - port: 80
      targetPort: 80
      nodePort: 30080   # must match containerPort in kind-config.yaml
kubectl apply -f nginx-urunc-nodeport.yaml

New verification step (append after Step 6, before/alongside Step 7):

curl http://localhost:8080

Expected: the NGINX unikernel's default HTML response, confirming urunc is not just "Running" per kubectl get pods but actually serving traffic end-to-end.

Problem 3: The urunc lconing URL is still nubificus/urunc

The urunc repo has been moved from nubificus/urunc to urunc-dev/urunc but the cloning step in the documentation still mentions the old URL. Although the URL redirects to the actual repo but this also should be update.

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentationenhancementNew feature or request

    Type

    No type

    Projects

    Status
    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions