Concepts

Flights

Overview

Flights in Yoke are analogous to Charts in Helm. A Chart is a collection of templates packaged as one referencable entity. Similarly, in Yoke, Flights refer to both the code that describes Kubernetes resources and the packaged WebAssembly (wasm) asset representing the executable.

At its core, a Flight is a piece of software that generates Kubernetes resources. In that way, even a Helm Chart is a subset of Flights (Refer to Helm Compatibility for more information). This allows us to view Flights at two levels: High and Low Altitude Flights (High-Level vs Low-Level).

High-Altitude Flights

High-Level Flights are the programs / runtimes / compiled wasm executables that generate the Kubernetes Package Instance for deployment.

Low-Altitude Flights

Low-Level Flights are the building blocks of the software. These are most likely represented as functions that take inputs and return Kubernetes resources. They can be shared via their language's ecosystems: npm, go modules, cargo, gems, and so on.

Why Wasm?

Yoke's goal is to enable software engineers to write packages for Kubernetes as code. The issue is that code is not easy to package, and code itself is useless without its runtime or compiler. Yoke would need to be able to get the appropriate runtime or compiler for any language, and moreover, it would need to get those dependencies compiled for the correct architecture and OS as where Yoke is running. This would be an enormous task.

This leaves us with two options: either accept arbitrary input as packages or find a common target that many languages support. Yoke chooses both options.

Arbitrary Input

The former allows us to support any runtime, even those that do not compile to wasm. This allows us to write Flights in our beloved dynamic languages:

# Deploy a Flight defined in Python
python3 app.py | yoke takeoff my-release

# Or in Javascript
node app.js | yoke takeoff my-release

# Or in Ruby
ruby app.rb | yoke takeoff my-release

# Or directly from a file
yoke takeoff my-release < resources.yaml

However, it comes with serious drawbacks:

Using Wasm

With wasm, we can solve all our problems, including the two mentioned above:

Wasm being sandboxed is a big deal for us. It eliminates side-effects such as IO and makes our programs predictable. It buys us a measure of security too, given that should a supply chain attack happen in the dependencies of your programs, an attacker would not have direct access to your filesystem, the network, or ultimately your K8s cluster.

Example:

GOOS=wasip1 GOARCH=wasm go build -o main.wasm ./my-flight
yoke takeoff my-release ./main.wasm