Using Knative Quarkus Bench to Perform Serverless Experiments on IBM Cloud Code Engine

4 min read

Learn how to easily deploy and run serverless functions from the open source project Knative Quarkus Bench on IBM Cloud Code Engine.

The combination of Quarkus Funqy and IBM Cloud Code Engine is a refreshingly easy way to run containerized serverless workloads. This article demonstrates the ease with which individual tests in the Knative Quarkus Bench can be configured and run on IBM Cloud Code Engine.

The fundamental technologies

Quarkus is a Kubernetes Native Java stack that runs Java in containers using either OpenJDK HotSpot or GraalVM. It offers benefits that include fast startup and low memory usage (for a compelling graphic that illustrates the capabilities, see here). 

Quarkus also provides a framework for easy development of serverless functions with Funqy that can run on a wide variety of platforms, including AWS Lambda, Azure Functions, Google Cloud Functions, Knative, Knative Events and — as described in this post — IBM Cloud Code Engine.

The creation of a Funqy API for serverless computing can be as simple as the following example from the Quarkus Funqy website:

import io.quarkus.funqy.Funq;

public class GreetingFunction {
    @Funq
    public String greet(String name) {
       return "Hello " + name;
    }
}

The Knative framework under Kubernetes is a widely available technology for the deployment of serverless functions like the Funqy API. Although our team uses Knative as our primary benchmarking facility, we were impressed with the simplicity of deploying the same tests on IBM Cloud Code Engine.

The Knative Quarkus Bench

The Knative Quarkus Bench that our team created is a port of the SeBS: Serverless Benchmark Suite originally written by a team of researchers at ETH Zurich. As the name implies, the Knative Quarkus Bench supports both Knative and Quarkus and is used by our team to run primarily on the IBM Cloud environment. 

The benchmark tests documented by the ETH Zurich team include dynamic html and uploader webapps, thumbnailer and video processing multimedia apps, compression and dna visualization utility apps, an image recognition inference app and pagerank, mst and bfs graph scientific apps (for more details, see here).  All tests are designed to run as serverless functions — usually using cloud storage.

Prerequisites and building instructions for the Knative Quarkus Bench, as well as steps for utilizing the individual tests locally, with containers, or with Knative are described here and here. The following section describes how to do the same with IBM Cloud Code Engine.

Running Knative Quarkus Bench on IBM Cloud Code Engine

It is fairly straightforward to use precompiled container images to run these serverless tests on IBM Cloud Code Engine. Our team has provided prebuilt container images here. The Knative Quarkus Bench provides 14 individual tests. Each has slightly different input files and parameter requirements, which are described here

In the interest of simplicity, the steps described here demonstrate how to run tests that do not depend on external input or output files through cloud storage.  These tests are as follows:

  • dynamic-html
  • graph-bfs
  • graph-mst
  • graph-pagerank
  • server-reply
  • sleep

The examples here were run on a RHEL 8 machine, but should also work on other major Linux and Linux-like operating systems. 

The first step is to log in to the IBM Cloud and perform several configuration steps. Initial IBM Cloud CLI configuration is not covered here, but is described in detail here. Likewise, instructions for installing the IBM Cloud Code Engine CLI can be found in the docs. Finally, before using the Code Engine, you should create and select a resource group. General tips can be found here.

The first time you use Code Engine, you'll need to create a project. Then, you need to select this project. Some of the key commands include the following:

  • View currently defined project(s): $ ibmcloud code-engine project list
  • Create a new project: $ ibmcloud code-engine project create -n <PROJECTNAME>
  • Select project: $ ibmcloud code-engine project select -n <PROJECTNAME>
  • Delete project: $ ibmcloud code-engine project delete -n <PROJECTNAME>

Each of the following tests are available as downloadable container images on GitHub with one of two tags (:jvm to use a JVM, or :native to use natively compiled code):

clock-synchronization dna-visualization graph-bfs graph-pagerank network server-reply thumbnailer video-processing compress dynamic-html graph-mst image-recognition sleep uploader

As a simple example, the following commands deploy, run, and delete the graph-pagerank test using a JVM. If you are already using IBM Cloud, once you have configured Code Engine on your Linux machine, you should be able to run these four commands as-is. Give it a try — if you are not already using IBM Cloud, this is a great chance to sign up for a trial:

$ ibmcloud code-engine application create --name graph-pagerank --image ghcr.io/ibm/knative-quarkus-bench/graph-pagerank:jvm
$ URL=$(ibmcloud ce app list | grep graph-pagerank | tr -s ' ' | cut -d ' ' -f 3)
$ curl -s -w "\n" -H 'Content-Type:application/json' -d '{"size":"test"}' -X POST ${URL}/graph-pagerank | jq
$ yes | ibmcloud code-engine application delete --name graph-pagerank

Sample output:

$ ibmcloud code-engine application create --name graph-pagerank --image ghcr.io/ibm/knative-quarkus-bench/graph-pagerank:jvm
Creating application 'graph-pagerank'...
The Route is still working to reflect the latest desired specification.
Configuration 'graph-pagerank' is waiting for a Revision to become ready.
Ingress has not yet been reconciled.
Waiting for load balancer to be ready.
Run 'ibmcloud ce application get -n graph-pagerank' to check the application status.
OK
https://graph-pagerank.sample.us-south.codeengine.appdomain.cloud
$ URL=$(ibmcloud ce app list | grep graph-pagerank | tr -s ' ' | cut -d ' ' -f 3)
$ curl -s -w "\n" -H 'Content-Type:application/json' -d '{"size":"test"}' -X POST ${URL}/graph-pagerank | jq
{
  "result": null,
  "measurement": {
    "compute_time": 0.001103992,
    "graph_generating_time": 0.014557946
  }
}
$ yes | ibmcloud code-engine application delete --name graph-pagerank
Are you sure you want to delete application 'graph-pagerank'? [y/N]> y
Deleting application 'graph-pagerank'...
OK

The example above uses the curl command, which is perfect for verifying functionality. A more detailed analysis of performance could be performed using a command like h2load. For example:

$ echo '{"size":"test"}' > post.dat
$ h2load -n 128 -c 8 -m 4 -H Content-Type:application/json -d post.dat ${URL}/graph-pagerank


spawning thread #0: 4 total client(s). 128 total requests
TLS Protocol: TLSv1.3
Cipher: TLS_AES_128_GCM_SHA256
Server Temp Key: X25519 253 bits
Application protocol: h2
...
finished in 1.42s, 90.05 req/s, 11.59KB/s
requests: 128 total, 128 started, 128 done, 128 succeeded, 0 failed, 0 errored, 0 timeout
status codes: 128 2xx, 0 3xx, 0 4xx, 0 5xx
traffic: 16.47KB (16868) total, 1.53KB (1563) headers (space savings 90.94%), 11.46KB (11739) data
                     min         max         mean         sd        +/- sd
time for request:    15.17ms    661.41ms     42.99ms    111.60ms    96.88%
time for connect:    24.36ms     24.66ms     24.51ms       212us   100.00%
time to 1st byte:   684.10ms    684.27ms    684.18ms       115us   100.00%
req/s           :      45.03       45.64       45.34        0.43   100.00%

To run tests requiring access to cloud storage, you need to prepare the required cloud storage and files.  Access to the cloud storage can be provided to each by specifying environment variables to be used at container run time:

  • ibmcloud ce application update -n <APPLICATIONNAME> --env AWS_ACCESS_KEY_ID=<APPROPRIATEVALUE>
  • ibmcloud ce application update -n <APPLICATIONNAME> --env AWS_SECRET_ACCESS_KEY=<APPROPRIATEVALUE>
  • ibmcloud ce application update -n <APPLICATIONNAME> --env QUARKUS_S3_ENDPOINT_OVERRIDE=<APPROPRIATEVALUE>

Some useful troubleshooting commands for Code Engine applications include the following:

  • ibmcloud code-engine application get -n <APPLICATIONNAME>
  • ibmcloud ce application events -n <APPLICATIONNAME>
  • ibmcloud ce application logs -f -n <APPLICATIONNAME>

Other Code Engine troubleshooting information can be found here.

Conclusion

This blog post has introduced some of the technology behind serverless computing with Kubernetes and shown exactly how to deploy and run an individual serverless benchmark test from the open-source project Knative Quarkus Bench on IBM Cloud Code Engine — including exact commands.

Given the ease with which container-based serverless functionality can be created, measured and destroyed on IBM Cloud Code Engine, anyone can experiment with this new technology. We strongly encourage those who are interested try it out for themselves by logging into IBM Cloud and trying the sample commands described above. It is easy to create a free account to try out services like Code Engine that offer a free tier. For those who want to dive deeper, please take a look at the documentation and implementation of serverless functions in the Knative Quarkus Bench, which is freely accessible on Github.

Be the first to hear about news, product updates, and innovation from IBM Cloud