docs
This commit is contained in:
75
docs/DESIGN.md
Normal file
75
docs/DESIGN.md
Normal file
@ -0,0 +1,75 @@
|
||||
# Design for FaaSO
|
||||
|
||||
## Introduction
|
||||
|
||||
This should explain the high-level plan. Of course once I start
|
||||
writing the thing it will change, because I am *agile* like that.
|
||||
|
||||
So, here it is:
|
||||
|
||||
## Function Builder
|
||||
|
||||
Take the function code, some ancillary files, and build a docker
|
||||
image using a template so that it can be executed.
|
||||
|
||||
Additionally:
|
||||
|
||||
* The image should be runnable with a standard `docker run` command
|
||||
* A test can be defined to check if the function is working
|
||||
|
||||
## Function Runner
|
||||
|
||||
Given a description of what functions should be made available at
|
||||
which endpoints, like
|
||||
|
||||
/sum -> sum
|
||||
/mul -> multiply
|
||||
|
||||
It should:
|
||||
|
||||
* Start those functions via docker, running in specific ports
|
||||
* Create a reverse proxy that routes the paths to the correct function
|
||||
* Start/reload/configure the proxy as needed
|
||||
* Periodically check the functions are still running
|
||||
|
||||
Intentionally: No HA yet, no multiple instances of functions, no
|
||||
up/downscaling, no multiple versions routed by header.
|
||||
|
||||
Specifically: no downscaling to zero. It makes everything MUCH
|
||||
more complicated.
|
||||
|
||||
# Function structure
|
||||
|
||||
Example using crystal, but it could be anything. Any function has
|
||||
an associated runtime, for example "crystal" or "python".
|
||||
|
||||
That runtime has a template (see `templates/crystal` for example).
|
||||
|
||||
To build the function image, the builder will:
|
||||
|
||||
* Create a tmp directory
|
||||
* Copy the template files to the tmp directory
|
||||
* Overlay the function files on top of the template
|
||||
* Build using the template Dockerfile
|
||||
|
||||
For docker that implies:
|
||||
|
||||
* Use an alpine builder, install crystal, shards, whatever
|
||||
* Run "shards isntall" to get the dependencies
|
||||
* Run "shards build" to build the function
|
||||
* Copy the function binary to ~app
|
||||
|
||||
When running, it will just run that binary and map a port to port 3000.
|
||||
|
||||
Template metadata:
|
||||
|
||||
Probably some `metadata.yml` that is *not* in the template.
|
||||
|
||||
* Additional packages to install in the alpine builder
|
||||
* Files that should be copied along the function
|
||||
* Whatever
|
||||
|
||||
# Implementation Ideas
|
||||
|
||||
* caddy for proxy? It's simple, fast, API-configurable.
|
||||
* Local docker registry for images? See https://www.docker.com/blog/how-to-use-your-own-registry-2/ (maybe later)
|
71
docs/funkos.md
Normal file
71
docs/funkos.md
Normal file
@ -0,0 +1,71 @@
|
||||
# Funkos What, Why, How
|
||||
|
||||
A funko is the equivalent of a AWS lambda. It's the unit
|
||||
of deployment for FaaSO.
|
||||
|
||||
A funko is a folder containing a metadata `funko.yml` file
|
||||
and source code in any language supported by a *runtime*
|
||||
|
||||
Think of a runtime as a template that gets merged with yout
|
||||
funko and produces a full containerized application.
|
||||
|
||||
FaaSO can use your funko and its runtime to create a Docker image.
|
||||
|
||||
That docker image can be built in a server by the FaaSO proxy or it can be
|
||||
built locally just like any docker image.
|
||||
|
||||
Then we can start it, either locally or in the server, using the proxy.
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
subgraph funko_hello
|
||||
A(fa:fa-code Metadata)
|
||||
B(fa:fa-code Code in language X)
|
||||
end
|
||||
|
||||
R(runtime for X)
|
||||
|
||||
C(fa:fa-box Containerized Application)
|
||||
D(fa:fa-image Docker Image)
|
||||
E(fa:fa-server FaaSO Proxy)
|
||||
F(Container Instance Running In Server)
|
||||
G(Container Instance Running Locally)
|
||||
|
||||
funko_hello --> C -- faaso build --> D
|
||||
R --> C
|
||||
D --> E -- faaso up --> F
|
||||
D -- faaso up -l --> G
|
||||
```
|
||||
|
||||
How is that application reached? FaaSO will usually run the image
|
||||
in a *opinionated* way. All funkos listen in port 3000 in their own
|
||||
container instances, and they are all segregated into a network called
|
||||
faaso-net.
|
||||
|
||||
The faaso-proxy container will automatically proxy all requests so if you access the URL `http://faaso-proxy:8888/funko/hello/foo` that will be
|
||||
proxied to `/foo` in the `hello` funko.
|
||||
|
||||
This is all done via naming conventions. You can create your own `faaso-whatever` container, add it to the `faaso-net` and faaso will
|
||||
happily consider it a funko.
|
||||
|
||||
In the same way all funkos are simply docker containers running in that
|
||||
network, with names following that convention. There is zero magic
|
||||
involved.
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
subgraph faaso-net
|
||||
faaso-proxy
|
||||
faaso-funko1
|
||||
faaso-funko2
|
||||
faaso-hello
|
||||
end
|
||||
|
||||
client -- GET /funko/hello/foo --> faaso-proxy
|
||||
|
||||
faaso-proxy -- GET /foo --> faaso-hello
|
||||
```
|
||||
|
||||
The dynamic proxying is achieved by reading the current state of
|
||||
Docker and just adapt to it using the naming conventions mentioned
|
||||
above.
|
Reference in New Issue
Block a user