Kubernetes + CRI-O

Quick start

The GitHub repo contains scripts and Github Actions for running our example apps on Kubernetes + CRI-O.

In the rest of this section, we will explain the steps in detail. We will assume that you have already installed and configured CRI-O to work with WasmEdge container images.

Install and start Kubernetes

Run the following commands from a terminal window. It sets up Kubernetes for local development.

  1. # Install go
  2. $ wget https://golang.org/dl/go1.17.1.linux-amd64.tar.gz
  3. $ sudo rm -rf /usr/local/go
  4. sudo tar -C /usr/local -xzf go1.17.1.linux-amd64.tar.gz
  5. source /home/${USER}/.profile
  6. # Clone k8s
  7. git clone https://github.com/kubernetes/kubernetes.git
  8. cd kubernetes
  9. git checkout v1.22.2
  10. # Install etcd with hack script in k8s
  11. sudo CGROUP_DRIVER=systemd CONTAINER_RUNTIME=remote CONTAINER_RUNTIME_ENDPOINT='unix:///var/run/crio/crio.sock' ./hack/install-etcd.sh
  12. export PATH="/home/${USER}/kubernetes/third_party/etcd:${PATH}"
  13. sudo cp third_party/etcd/etcd* /usr/local/bin/
  14. # After run the above command, you can find the following files: /usr/local/bin/etcd /usr/local/bin/etcdctl /usr/local/bin/etcdutl
  15. # Build and run k8s with CRI-O
  16. sudo apt-get install -y build-essential
  17. sudo CGROUP_DRIVER=systemd CONTAINER_RUNTIME=remote CONTAINER_RUNTIME_ENDPOINT='unix:///var/run/crio/crio.sock' ./hack/local-up-cluster.sh
  18. ... ...
  19. Local Kubernetes cluster is running. Press Ctrl-C to shut it down.

Do NOT close your terminal window. Kubernetes is running!

Run WebAssembly container images in Kubernetes

Finally, we can run WebAssembly programs in Kubernetes as containers in pods. In this section, we will start from another terminal window and start using the cluster.

  1. export KUBERNETES_PROVIDER=local
  2. sudo cluster/kubectl.sh config set-cluster local --server=https://localhost:6443 --certificate-authority=/var/run/kubernetes/server-ca.crt
  3. sudo cluster/kubectl.sh config set-credentials myself --client-key=/var/run/kubernetes/client-admin.key --client-certificate=/var/run/kubernetes/client-admin.crt
  4. sudo cluster/kubectl.sh config set-context local --cluster=local --user=myself
  5. sudo cluster/kubectl.sh config use-context local
  6. sudo cluster/kubectl.sh

Let’s check the status to make sure that the cluster is running.

  1. $ sudo cluster/kubectl.sh cluster-info
  2. # Expected output
  3. Cluster "local" set.
  4. User "myself" set.
  5. Context "local" created.
  6. Switched to context "local".
  7. Kubernetes control plane is running at https://localhost:6443
  8. CoreDNS is running at https://localhost:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
  9. To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

A simple WebAssembly app

A separate article explains how to compile, package, and publish a simple WebAssembly WASI program as a container image to Docker hub. Run the WebAssembly-based image from Docker Hub in the Kubernetes cluster as follows.

  1. sudo cluster/kubectl.sh run -it --rm --restart=Never wasi-demo --image=hydai/wasm-wasi-example:with-wasm-annotation --annotations="module.wasm.image/variant=compat" /wasi_example_main.wasm 50000000

The output from the containerized application is printed into the console.

  1. Random number: 401583443
  2. Random bytes: [192, 226, 162, 92, 129, 17, 186, 164, 239, 84, 98, 255, 209, 79, 51, 227, 103, 83, 253, 31, 78, 239, 33, 218, 68, 208, 91, 56, 37, 200, 32, 12, 106, 101, 241, 78, 161, 16, 240, 158, 42, 24, 29, 121, 78, 19, 157, 185, 32, 162, 95, 214, 175, 46, 170, 100, 212, 33, 27, 190, 139, 121, 121, 222, 230, 125, 251, 21, 210, 246, 215, 127, 176, 224, 38, 184, 201, 74, 76, 133, 233, 129, 48, 239, 106, 164, 190, 29, 118, 71, 79, 203, 92, 71, 68, 96, 33, 240, 228, 62, 45, 196, 149, 21, 23, 143, 169, 163, 136, 206, 214, 244, 26, 194, 25, 101, 8, 236, 247, 5, 164, 117, 40, 220, 52, 217, 92, 179]
  3. Printed from wasi: This is from a main function
  4. This is from a main function
  5. The env vars are as follows.
  6. The args are as follows.
  7. /wasi_example_main.wasm
  8. 50000000
  9. File content is This is in a file
  10. pod "wasi-demo-2" deleted

A WebAssembly-based HTTP service

A separate article explains how to compile, package, and publish a simple WebAssembly HTTP service application as a container image to Docker hub. Since the HTTP service container requires networking support provided by Kubernetes, we will use a k8s-http_server.yaml file to specify its exact configuration.

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: http-server
  5. namespace: default
  6. annotations:
  7. module.wasm.image/variant: compat
  8. spec:
  9. hostNetwork: true
  10. containers:
  11. - name: http-server
  12. image: avengermojo/http_server:with-wasm-annotation
  13. command: [ "/http_server.wasm" ]
  14. ports:
  15. - containerPort: 1234
  16. protocol: TCP
  17. livenessProbe:
  18. tcpSocket:
  19. port: 1234
  20. initialDelaySeconds: 3
  21. periodSeconds: 30

Run the WebAssembly-based image from Docker Hub using the above k8s-http_server.yaml file in the Kubernetes cluster as follows.

  1. sudo ./kubernetes/cluster/kubectl.sh apply -f k8s-http_server.yaml

Use the following command to see the running container applications and their IP addresses. Since we are using hostNetwork in the yaml configuration, the HTTP server image is running on the local network with IP address 127.0.0.1.

  1. $ sudo cluster/kubectl.sh get pod --all-namespaces -o wide
  2. NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
  3. default http-server 1/1 Running 1 (26s ago) 60s 127.0.0.1 127.0.0.1 <none> <none>

Now, you can use the curl command to access the HTTP service.

  1. $ curl -d "name=WasmEdge" -X POST http://127.0.0.1:1234
  2. echo: name=WasmEdge

That’s it!