CRI-O
Quick start
The GitHub repo contains scripts and Github Actions for running our example apps on CRI-O.
- Simple WebAssembly example Quick start | Github Actions | Successful run
- HTTP service example Quick start | Github Actions | Successful run
In the sections below, we will explain the steps in the quick start scripts.
- Install CRI-O
- Configure CRI-O and crun
- Example 1: Simple WebAssembly
- Example 2: HTTP server in WebAssembly
Install CRI-O
Use the following commands to install CRI-O on your system.
1. export OS="xUbuntu_20.04"
2. export VERSION="1.21"
3. apt update
4. apt install -y libseccomp2 || sudo apt update -y libseccomp2
5. echo "deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/ /" > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
6. echo "deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable:/cri-o:/$VERSION/$OS/ /" > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable:cri-o:$VERSION.list
8. curl -L https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable:cri-o:$VERSION/$OS/Release.key | apt-key add -
9. curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/Release.key | apt-key add -
11. apt-get update
12. apt-get install criu libyajl2
13. apt-get install cri-o cri-o-runc cri-tools containernetworking-plugins
14. systemctl start crio
Configure CRI-O to use crun
CRI-O uses the runc runtime by default and we need to configure it to use crun instead. That is done by adding to two configuration files.
Make sure that you have built and installed the crun binary with WasmEdge support before starting the following steps.
First, create a /etc/crio/crio.conf file and add the following lines as its content. It tells CRI-O to use crun by default.
1. [crio.runtime]
2. default_runtime = "crun"
The crun runtime is in turn defined in the /etc/crio/crio.conf.d/01-crio-runc.conf file.
1. [crio.runtime.runtimes.runc]
2. runtime_path = "/usr/lib/cri-o-runc/sbin/runc"
3. runtime_type = "oci"
4. runtime_root = "/run/runc"
5. # The above is the original content
7. # Add our crunw runtime here
8. [crio.runtime.runtimes.crun]
9. runtime_path = "/usr/bin/crun"
10. runtime_type = "oci"
11. runtime_root = "/run/crun"
Next, restart CRI-O to apply the configuration changes.
1. systemctl restart crio
Run a simple WebAssembly app
Now, we can run a simple WebAssembly program using CRI-O. A separate article explains how to compile, package, and publish the WebAssembly program as a container image to Docker hub. In this section, we will start off pulling this WebAssembly-based container image from Docker hub using CRI-O tools.
1. sudo crictl pull docker.io/hydai/wasm-wasi-example:with-wasm-annotation
Next, we need to create two simple configuration files that specifies how CRI-O should run this WebAssembly image in a sandbox. We already have those two files container_wasi.json and sandbox_config.json. You can just download them to your local directory as follows.
1. wget https://raw.githubusercontent.com/second-state/wasmedge-containers-examples/main/crio/sandbox_config.json
2. wget https://raw.githubusercontent.com/second-state/wasmedge-containers-examples/main/crio/container_wasi.json
Now you can use CRI-O to create a pod and a container using the specified configurations.
1. # Create the POD. Output will be different from example.
2. $ sudo crictl runp sandbox_config.json
3. 7992e75df00cc1cf4bff8bff660718139e3ad973c7180baceb9c84d074b516a4
4. # Set a helper variable for later use.
5. $ POD_ID=7992e75df00cc1cf4bff8bff660718139e3ad973c7180baceb9c84d074b516a4
7. # Create the container instance. Output will be different from example.
8. $ sudo crictl create $POD_ID container_wasi.json sandbox_config.json
9. # Set a helper variable for later use.
10. CONTAINER_ID=1d056e4a8a168f0c76af122d42c98510670255b16242e81f8e8bce8bd3a4476f
Starting the container would execute the WebAssembly program. You can see the output in the console.
1. # List the container, the state should be `Created`
2. $ sudo crictl ps -a
3. CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID
4. 1d056e4a8a168 hydai/wasm-wasi-example:with-wasm-annotation About a minute ago Created podsandbox1-wasm-wasi 0 7992e75df00cc
6. # Start the container
7. $ sudo crictl start $CONTAINER_ID
9. # Check the container status again.
10. # If the container is not finishing its job, you will see the Running state
11. # Because this example is very tiny. You may see Exited at this moment.
12. $ sudo crictl ps -a
13. CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID
14. 1d056e4a8a168 hydai/wasm-wasi-example:with-wasm-annotation About a minute ago Running podsandbox1-wasm-wasi 0 7992e75df00cc
16. # When the container is finished. You can see the state becomes Exited.
17. $ sudo crictl ps -a
18. CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID
19. 1d056e4a8a168 hydai/wasm-wasi-example:with-wasm-annotation About a minute ago Exited podsandbox1-wasm-wasi 0 7992e75df00cc
21. # Check the container's logs. It should show outputs from the WebAssembly programs
22. $ sudo crictl logs $CONTAINER_ID
24. Test 1: Print Random Number
25. Random number: 960251471
27. Test 2: Print Random Bytes
28. Random bytes: [50, 222, 62, 128, 120, 26, 64, 42, 210, 137, 176, 90, 60, 24, 183, 56, 150, 35, 209, 211, 141, 146, 2, 61, 215, 167, 194, 1, 15, 44, 156, 27, 179, 23, 241, 138, 71, 32, 173, 159, 180, 21, 198, 197, 247, 80, 35, 75, 245, 31, 6, 246, 23, 54, 9, 192, 3, 103, 72, 186, 39, 182, 248, 80, 146, 70, 244, 28, 166, 197, 17, 42, 109, 245, 83, 35, 106, 130, 233, 143, 90, 78, 155, 29, 230, 34, 58, 49, 234, 230, 145, 119, 83, 44, 111, 57, 164, 82, 120, 183, 194, 201, 133, 106, 3, 73, 164, 155, 224, 218, 73, 31, 54, 28, 124, 2, 38, 253, 114, 222, 217, 202, 59, 138, 155, 71, 178, 113]
30. Test 3: Call an echo function
31. Printed from wasi: This is from a main function
32. This is from a main function
34. Test 4: Print Environment Variables
35. The env vars are as follows.
36. PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
37. TERM: xterm
38. HOSTNAME: crictl_host
39. PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
40. The args are as follows.
41. /var/lib/containers/storage/overlay/006e7cf16e82dc7052994232c436991f429109edea14a8437e74f601b5ee1e83/merged/wasi_example_main.wasm
42. 50000000
44. Test 5: Create a file `/tmp.txt` with content `This is in a file`
46. Test 6: Read the content from the previous file
47. File content is This is in a file
49. Test 7: Delete the previous file
Next, you can try to run the app in Kubernetes!
Run a HTTP server app
Finally, we can run a simple WebAssembly-based HTTP micro-service in CRI-O. A separate article explains how to compile, package, and publish the WebAssembly program as a container image to Docker hub. In this section, we will start off pulling this WebAssembly-based container image from Docker hub using CRI-O tools.
1. sudo crictl pull docker.io/avengermojo/http_server:with-wasm-annotation
Next, we need to create two simple configuration files that specifies how CRI-O should run this WebAssembly image in a sandbox. We already have those two files container_http_server.json and sandbox_config.json. You can just download them to your local directory as follows.
The
sandbox_config.jsonfile is the same for the simple WASI example and the HTTP server example. The othercontainer_*.jsonfile is application specific as it contains the application’s Docker Hub URL.
1. wget https://raw.githubusercontent.com/second-state/wasmedge-containers-examples/main/crio/sandbox_config.json
2. wget https://raw.githubusercontent.com/second-state/wasmedge-containers-examples/main/crio/http_server/container_http_server.json
Now you can use CRI-O to create a pod and a container using the specified configurations.
1. # Create the POD. Output will be different from example.
2. $ sudo crictl runp sandbox_config.json
3. 7992e75df00cc1cf4bff8bff660718139e3ad973c7180baceb9c84d074b516a4
4. # Set a helper variable for later use.
5. $ POD_ID=7992e75df00cc1cf4bff8bff660718139e3ad973c7180baceb9c84d074b516a4
7. # Create the container instance. Output will be different from example.
8. $ sudo crictl create $POD_ID container_http_server.json sandbox_config.json
9. # Set a helper variable for later use.
10. CONTAINER_ID=1d056e4a8a168f0c76af122d42c98510670255b16242e81f8e8bce8bd3a4476f
Starting the container would execute the WebAssembly program. You can see the output in the console.
1. # Start the container
2. $ sudo crictl start $CONTAINER_ID
4. # Check the container status. It should be Running.
5. # If not, wait a few seconds and check again
6. $ sudo crictl ps -a
7. CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID
8. 4eeddf8613691 avengermojo/http_server:with-wasm-annotation Less than a second ago Running http_server 0 1d84f30e7012e
10. # Check the container's logs to see the HTTP server is listening at port 1234
11. $ sudo crictl logs $CONTAINER_ID
12. new connection at 1234
14. # Get the IP address assigned to the container
15. $ sudo crictl inspect $CONTAINER_ID | grep IP.0 | cut -d: -f 2 | cut -d'"' -f 2
16. 10.85.0.2
18. # Test the HTTP service at that IP address
19. $ curl -d "name=WasmEdge" -X POST http://10.85.0.2:1234
20. echo: name=WasmEdge
Next, you can try to run it in Kubernetes!
