🇬🇧 Borg Collective, Toys to learn Knative

Resistence is futile

In my quest of learning Knative, I made some progress, and quickly I realized that I needed some tools to ease my developer learning workflow. If I can experiment fast, I can experiment with a lot of things (even silly elements) and then accelerate my education.

First, I need to be able to create a Kubernetes cluster quickly and easily install Knative on it. I want to destroy and recreate it several times a day (we all know that Kubernetes is made for that 😉).

So, I started to create some "toy projects" to help me in my Knative quest. They all live in this GitLab group: https://gitlab.com/borg-collective

These are right now usable (not complete, not lovable, but soon):

  • Unimatrix 0: all what you need to create a K3S mono-cluster and install Knative on it
  • 7of9: a container runtime to deploy some kind of function quickly on Knative Serving platform without the step of container image building, and then ease the "discovery process" (🖐️ it's not a FaaS). I based 7of9 on GraalVM + Vert.x + Kotlin and uses the embedded languages of GraalVM (JavaScript, Python, Ruby).
  • Locutus.wip: a container runtime to play with Knative Eventing. Once again, I created this runtime to avoid the container image building step. Locutus.wip is based on NodeJS + Express + CloudEvents SDK. Why ".wip"? The CloudEvents specification is a work in progress, and the JavaScript SDK is not complete.
  • Soon: Borg.Queen, a little bit like 7of9 but using the Kotlin script engine - stay tuned.

Unimatrix 0

It's here: https://gitlab.com/borg-collective/unimatrix-0

So, Unimatrix 0 is a set of scripts to create a K3S cluster and install Knative components on it. It's straightforward to use, I use Multipass (I run it on OSX, but theoretically it should work with Linux and Windows - Tests are coming...):

git clone git@gitlab.com:borg-collective/unimatrix-0.git
cd unimatrix-0
./create-vm.sh
./knative-serving.sh
./knative-dns.sh
./knative-eventing.sh
./enable-broker.sh
./knative-monitoring.sh

Tha's all! (you can tune the size of the vm by editing the vm.config file before running the creation script).

The script will generate a k3s.yml file in the /config directory, so you can connect on your cluster from outside with kubectl:

export KUBECONFIG=$PWD/config/k3s.yaml
kubectl get pods --all-namespaces
# or even run K9S
k9s --all-namespaces 

7of9 for playing with Knative Serving

Now you have a running Knative platform, and you want to deploy a new service on it. First, you need kubectl and the Knative CLI kn (see Installing the Knative CLI), once all is installed, it's effortless:

Create a hello.js file:

function hello(params) {
  return {
    message: "Hello World",
    total: 42,
    author: "@k33g_org",
    params: params.getString("name")
  }
}

Create the service:

kubectl create namespace k-apps

# create or update the service
kn service create --force hello-service \
--namespace k-apps \
--env FUNCTION_NAME="hello" \
--env LANG="js" \
--env FUNCTION_CODE="$(cat ./hello.js)" \
--env CONTENT_TYPE="application/json;charset=UTF-8" \
--image registry.gitlab.com/borg-collective/7of9:latest

Wait a moment, and you should obtain an URL for your service like this one:

http://hello-service.k-apps.192.168.64.70.xip.io

192.168.64.70 is the IP of my local cluster

curl -d '{"name":"Bob"}' \
-H "Content-Type: application/json" \
-X POST http://hello-service.k-apps.192.168.64.70.xip.io

Easy! No?

Locutus.wip for playing with Knative Eventing

It's my baby steps with Eventing, and I find Eventing more challenging to understand than Serving (probably because I mostly develop web application). So, to facilitate my experiments and understanding, I created Locutus.wip, and it's easy to use (IMHO).

Here it is a simple example, (stay tuned, I will write some more complex):

First, we need to create a service and a piece of code to handle the received event (params) and the response event (evant):

read -d '' CODE << EOF
let hello = (event, params) => {

  console.log("🦊", params)

  return event
    .type('dev.knative.demo')
    .source('[Locutus]')
    .time(new Date())
}
EOF

kn service create --force locutus-wip-1 \
  --env FUNCTION_NAME="hello" \
  --env FUNCTION_CODE="$CODE" \
  --image registry.gitlab.com/borg-collective/locutus.wip:latest 

the broker was injected on the default namespace during the installation of Knative with Unimatrix-0 project with this command kubectl label namespace default knative-eventing-injection=enabled

Then, create a "source" (see it as an event emitter), create a source.yml file:

apiVersion: sources.knative.dev/v1alpha2
kind: PingSource
metadata:
  name: test-ping-source
spec:
  schedule: "* * * * *"
  jsonData: '{"message": "Hello world 😃 "}'
  sink:
    ref:
      apiVersion: serving.knative.dev/v1
      kind: Service
      name: locutus-wip-1

And publish the source:

kubectl apply -f source.yml

Now, check regularly your service:

kubectl logs -l serving.knative.dev/service=locutus-wip-1 -c user-container --since=1m

you should obtain something like that:

🖐️ received data: { message: 'Hello world 😃 ' }
🦊 { message: 'Hello world 😃 ' }
👋 reply cloud event: {
  "specversion": "1.0",
  "id": "f38a6135-5e71-4e1b-a46d-9aa905ee83f3",
  "type": "dev.knative.demo",
  "source": "[Locutus]",
  "time": "2020-05-30T09:00:00.031Z"
}

That's all for this time. I need to prepare a talk about all of this, so the documentation of the projects will evolve.

Have a beautiful day.

Last Articles

Last Updated: 5/30/2020, 12:30:18 PM