Several weeks ago, I was taking part in a meetup about Kubernetes, when one of the attendees made a remark that resonated deeply with me…
Hey, Horacio, that Kubernetes thing is rather cool, but what I would have loved to see is a Functions-as-a-Service platform. Most of my apps could be easily done with a database and several serverless functions!
It wasn’t the first time I’d got that question…
Being, above all, a web developer, I can definitely relate. Kubernetes is a wonderful product – you can install complicated web architectures with a click – but what about the database + some functions model?
Well, you can also do it with Kubernetes!
That’s the beauty of the rich Kubernetes ecosystem: you can find projects to address many different use cases, from game servers with Agones to FaaS platforms…
There is an Helm chart for that!
Saying “You can do it with Kubernetes!” is almost the new “There is an app for that!”, but it doesn’t help a lot of people who are looking for solutions. As the question had come up several times, we decided to prepare a small tutorial on how to deploy and use a FaaS platform on OVH Managed Kubernetes.
We began by testing several FaaS platform on our Kubernetes. Our objective was to find the following solution:
- Easy to deploy (ideally with a simple Helm chart)
- Manageable with both an UI and a CLI, because different customers have different needs
- Auto-scalable, in both the upscaling and downscaling senses
- Supported by comprehensive documentation
We tested lots of platforms, like Kubeless, OpenWhisk, OpenFaaS and Fission, and I must say that all of them performed quite well. In the end though, the one that scored the best in terms of our objectives was OpenFaaS, so we decided to use it as the reference for this blog post.
OpenFaaS – a Kubernetes-native FaaS platform
OpenFaaS is an open-source framework for building serverless functions with Docker and Kubernetes. The project is already mature, popular and active, with more than 14k stars on GitHub, hundreds of contributors, and lots of users (both corporate and private).
OpenFaaS is very simple to deploy, using a Helm chart (including an operator for CRDs, i.e. kubectl get functions
). It has both a CLI and a UI, manages auto-scaling effectively, and its documentation is really comprehensive (with a Slack channel to discuss it, as a nice bonus!).
Technically, OpenFaaS is composed of several functional blocks:
- The Function Watchdog. A tiny golang HTTP server that transforms any Docker image into a serverless function
- The API Gateway, which provides an external route into functions and collects metrics
- The UI Portal, which creates and invokes functions
- The CLI (essentially a REST client for the API Gateway), which can deploy any container as a function
Functions can be written in many languages (although I mainly used JavaScript, Go and Python for testing purposes), using handy templates or a simple Dockerfile.
Deploying OpenFaaS on OVH Managed Kubernetes
There are several ways to install OpenFaaS on a Kubernetes cluster. In this post we’re looking at the easiest one: installing with Helm.
If you need information on how to install and use Helm on your OVH Managed Kubernetes cluster, you can follow our tutorial.
The official Helm chart for OpenFaas is available on the faas-netes repository.
Adding the OpenFaaS Helm chart
The OpenFaaS Helm chart isn’t available in Helm’s standard stable
repository, so you’ll need to add their repository to your Helm installation:
helm repo add openfaas https://openfaas.github.io/faas-netes/
helm repo update
Creating the namespaces
OpenFaaS guidelines recommend creating two namespaces, one for OpenFaaS core services and one for the functions:
kubectl apply -f https://raw.githubusercontent.com/openfaas/faas-netes/master/namespaces.yml
Generating secrets
A FaaS platform that’s open to the internet seems like a bad idea. That’s why we are generating secrets, to enable authentication on the gateway:
# generate a random password
PASSWORD=$(head -c 12 /dev/urandom | shasum| cut -d' ' -f1)
kubectl -n openfaas create secret generic basic-auth \
--from-literal=basic-auth-user=admin \
--from-literal=basic-auth-password="$PASSWORD"
Note: you will need this password later in the tutorial (to access the UI portal, for example). You can view it at any point in the terminal session with
echo $PASSWORD
.
Deploying the Helm chart
The Helm chart can be deployed in three modes: LoadBalancer
, NodePort
and Ingress
. For our purposes, the simplest way is simply using our external Load Balancer, so we will deploy it in LoadBalancer
, with the --set serviceType=LoadBalancer
option.
If you want to better understand the difference between these three modes, you can read our Getting external traffic into Kubernetes – ClusterIp, NodePort, LoadBalancer, and Ingress blog post.
Deploy the Helm chart as follows:
helm upgrade openfaas --install openfaas/openfaas \
--namespace openfaas \
--set basic_auth=true \
--set functionNamespace=openfaas-fn \
--set serviceType=LoadBalancer
As suggested in the install message, you can verify that OpenFaaS has started by running:
kubectl --namespace=openfaas get deployments -l "release=openfaas, app=openfaas"
If it’s working, you should see a list of the available OpenFaaS deployment
objects:
$ kubectl --namespace=openfaas get deployments -l "release=openfaas, app=openfaas"
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
alertmanager 1 1 1 1 33s
faas-idler 1 1 1 1 33s
gateway 1 1 1 1 33s
nats 1 1 1 1 33s
prometheus 1 1 1 1 33s
queue-worker 1 1 1 1 33s
Install the FaaS CLI and log in to the API Gateway
The easiest way to interact with your new OpenFaaS platform is by installing faas-cli
, the command line client for OpenFaaS on a Linux or Mac (or in a WSL linux terminal in Windows):
curl -sL https://cli.openfaas.com | sh
You can now use the CLI to log in to the gateway. The CLI will need the public URL of the OpenFaaS LoadBalancer
, which you can get via kubectl
:
kubectl get svc -n openfaas gateway-external -o wide
Export the URL to an OPENFAAS_URL
variable:
export OPENFAAS_URL=[THE_URL_OF_YOUR_LOADBALANCER]:[THE_EXTERNAL_PORT]
Note: you will need this URL later on the tutorial, for example to access the UI portal. You can see it at any moment in the terminal session by doing
echo $OPENFAAS_URL
.
And connect to the gateway:
echo -n $PASSWORD | ./faas-cli login -g $OPENFAAS_URL -u admin --password-stdin
Now your’re connected to the gateway, and you can send commands to the OpenFaaS platform.
By default, there is no function installed on your OpenFaaS platform, as you can verify with the faas-cli list
command.
In my own deployment (URLs and IP changed for this example), the preceding operations gave:
$ kubectl get svc -n openfaas gateway-external -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
gateway-external LoadBalancer 10.3.xxx.yyy xxxrt657xx.lb.c1.gra.k8s.ovh.net 8080:30012/TCP 9m10s app=gateway
$ export OPENFAAS_URL=xxxrt657xx.lb.c1.gra.k8s.ovh.net:8080
$ echo -n $PASSWORD | ./faas-cli login -g $OPENFAAS_URL -u admin --password-stdin
Calling the OpenFaaS server to validate the credentials...
WARNING! Communication is not secure, please consider using HTTPS. Letsencrypt.org offers free SSL/TLS certificates.
credentials saved for admin http://xxxrt657xx.lb.c1.gra.k8s.ovh.net:8080
$ ./faas-cli version
___ _____ ____
/ _ \ _ __ ___ _ __ | ___|_ _ __ _/ ___|
| | | | '_ \ / _ \ '_ \| |_ / _` |/ _` \___ \
| |_| | |_) | __/ | | | _| (_| | (_| |___) |
\___/| .__/ \___|_| |_|_| \__,_|\__,_|____/
|_|
CLI:
commit: b42d0703b6136cac7b0d06fa2b212c468b0cff92
version: 0.8.11
Gateway
uri: http://xxxrt657xx.lb.c1.gra.k8s.ovh.net:8080
version: 0.13.0
sha: fa93655d90d1518b04e7cfca7d7548d7d133a34e
commit: Update test for metrics server
Provider
name: faas-netes
orchestration: kubernetes
version: 0.7.5
sha: 4d3671bae8993cf3fde2da9845818a668a009617
$ ./faas-cli list Function Invocations Replicas
Deploying and invoking functions
You can easily deploy functions on your OpenFaaS platform using the CLI, with this command: faas-cli up
.
Let’s try out some sample functions from the OpenFaaS repository:
./faas-cli deploy -f https://raw.githubusercontent.com/openfaas/faas/master/stack.yml
Running a faas-cli list
command now will show the deployed functions:
$ ./faas-cli list
Function Invocations Replicas
base64 0 1
echoit 0 1
hubstats 0 1
markdown 0 1
nodeinfo 0 1
wordcount 0 1
As an example, let’s invoke wordcount
(a function that takes the syntax of the unix wc
command, giving us the number of lines, words and characters of the input data):
echo 'I love when a plan comes together' | ./faas-cli invoke wordcount
$ echo 'I love when a plan comes together' | ./faas-cli invoke wordcount
1 7 34
Invoking a function without the CLI
You can use the faas-cli describe
command to get the public URL of your function, and then call it directly with your favorite HTTP library (or the good old curl
):
$ ./faas-cli describe wordcount
Name: wordcount
Status: Ready
Replicas: 1
Available replicas: 1
Invocations: 1
Image: functions/alpine:latest
Function process:
URL: http://xxxxx657xx.lb.c1.gra.k8s.ovh.net:8080/function/wordcount
Async URL: http://xxxxx657xx.lb.c1.gra.k8s.ovh.net:8080/async-function/wordcount
Labels: faas_function : wordcount
Annotations: prometheus.io.scrape : false
$ curl -X POST --data-binary "I love when a plan comes together" "http://xxxxx657xx.lb.c1.gra.k8s.ovh.net:8080/function/wordcount"
0 7 33
Containers everywhere…
The most attractive part of a FaaS platform is being able to deploy your own functions.
In OpenFaaS, you can write your these function in many languages, not just the usual suspects (JavaScript, Python, Go etc.). This is because in OpenFaaS, you can deploy basically any container as a function, although this does mean you need to package your functions as containers in order to deploy them.
That also means that in order to create your own functions, you need to have Docker installed on your workstation, and you will need to push the images in a Docker registry (either the official one or a private one).
If you need a private registry, you can install one on your OVH Managed Kubernetes cluster. For this tutorial we are choosing to deploy our image on the official Docker registry.
Writing our first function
For our first example, we are going to create and deploy a hello word function in JavaScript, using NodeJS. Let’s begin by creating and scaffolding the function folder:
mkdir hello-js-project
cd hello-js-project
../faas-cli new hello-js --lang node
The CLI will download a JS function template from OpenFaaS repository, generate a function description file (hello-js.yml
in this case) and a folder for the function source code (hello-js
). For NodeJS, you will find a package.json
(to declare eventual dependencies to your function, for example) and a handler.js
(the function main code) in this folder.
Edit hello-js.yml
to set the name of the image you want to upload to the Docker registry:
version: 1.0
provider:
name: openfaas
gateway: http://6d6rt657vc.lb.c1.gra.k8s.ovh.net:8080
functions:
hello-js:
lang: node
handler: ./hello-js
image: ovhplatform/openfaas-hello-js:latest
The function described in the handler.js
file is really simple. It exports a function with two parameters: a context
where you will receive the request data, and a callback
that you will call at the end of your function and where you will pass the response data.
"use strict"
module.exports = (context, callback) => {
callback(undefined, {status: "done"});
}
Let’s edit it to send back our hello world message:
"use strict"
module.exports = (context, callback) => {
callback(undefined, {message: 'Hello world'});
}
Now you can build the Docker image and push it to the public Docker registry:
# Build the image
../faas-cli build -f hello-js.yml
# Login at Docker Registry, needed to push the image
docker login
# Push the image to the registry
../faas-cli push -f hello-js.yml
With the image in the registry, let’s deploy and invoke the function with the OpenFaaS CLI:
# Deploy the function
../faas-cli deploy -f hello-js.yml
# Invoke the function
../faas-cli invoke hello-js
Congratulations! You have just written and deployed your first OpenFaaS function.
Using the OpenFaaS UI Portal
You can test the UI Portal by pointing your browser to your OpenFaaS gateway URL (the one you have set on the $OPENFAAS_URL
variable), and entering the admin
user and the password you have set on the $PASSWORD
variable when prompted to.
In the UI Portal, you will find the list of the deployed functions. For each function, you can find its description, invoke it and see the result.
Where do we go from here?
So you now have a working OpenFaaS platform on your OVH Managed Kubernetes cluster.
To learn more about OpenFaaS, and how you can get the most out of it, please refer to the official OpenFaaS documentation. You can also follow the OpenFaaS workshops for more practical tips and advice.