An Intro to Serverless Functions using OpenFaas

Ambidextrous
5 min readJun 2, 2023

--

Simply put, Serverless architecture is a way of designing and developing applications without managing infrastructure. This is the next step in the evolution of software development from monoliths to microservices to serverless. The concept of serverless computing has been present for a while, but it really took off with the introduction of AWS Lambda in 2018. AWS Lambda popularized the use case for event-driven short-lived functions which perform a single task. The developer just has to write the business logic, and all the infrastructure provisioning and management is taken care of by the provider. Another major benefit of a serverless platform is that the functions only run when they are invoked. After the execution has finished, the functions are recycled after some time of inactivity; leading to reduced cost.

All of the major cloud providers have serverless platforms such as AWS Lambda, Google Cloud Functions, and Azure Functions. However, what about the private cloud, do we have any good open-source serverless platforms available which provide all the benefits of serverless computing without the risks of vendor lock-in? This is the question that I recently explored. I looked into three major options:

After a detailed analysis, I decided to move forward with OpenFaas. OpenFaas has good community support and supported the triggers which I was interested in. OpenFaaS is a popular open-source serverless platform for creating event-driven serverless functions. It is currently deployable to various container orchestration platforms such as Kubernetes and OpenShift. There was also a version deployable on Docker Swarm, but it got archived due to a lack of community support.

OpenFaas comes in two different — Community Edition (CE) and Open Faas Pro. The Pro distribution is targeted for production workloads and comes with Single Sign-On (SSO), connectors for triggering functions (such as Kafka, SNS, Cron, etc.), exclusive dashboards, improved autoscaling, and much more. The whole list of differences can be found here.

Deploying OpenFaas

We will use helm to deploy OpenFaas using the openfaas helm chart. First, create two namespaces — openfaas and openfaas-fn. openfaas namespace will contain all the core services of OpenFaas, while the openfaas-fn namespace contains the functions hosted on the platform. During helm deployment, you can override the settings by providing your own file or just go ahead with the default options.

# Create two namespaces - openfaas and openfaas-fn
kubectl apply -f https://raw.githubusercontent.com/openfaas/faas-netes/master/namespaces.yml

# Add Chart Repository
helm repo add openfaas https://openfaas.github.io/faas-netes/

# Deploy app
helm repo update \
&& helm upgrade openfaas \
--install openfaas/openfaas \
--namespace openfaas
--values values.yaml

This will deploy the OpenFaas in the provided namespace. A quick look at the namespace shows that it has the following major components:

  1. Alert Manager: Monitors metrics via Prometheus and fires alerts based on the traffic patterns to scale the functions accordingly
  2. Gateway: Provides a route to access our functions, which can be external or internal depending on the configuration
  3. NATS: Open source messaging system used by OpenFaas to invoke functions asynchronously
  4. Prometheus: Collects metrics from various components of the app
  5. QueueWorker: Processes invocation requests for async functions
OpenFaas components in Kuberentes

OpenFaas has a CLI faas-cli’ which can be used to build and deploy functions to OpenFaas. Install and configure the faas-cli using the following bash script:

# install
curl -sSL https://cli.openfaas.com | sudo -E sh

# configure
export OPENFAAS_URL=http://$NODEIP:$NODEPORT
echo -n $PASSWORD | faas-cli login -g $OPENFAAS_URL -u admin --password-stdin

#verify faas-cli setup
faas-cli version

OpenFaas provides built-in templates for popular programming languages such as Python, Go, NodeJS, etc. In case, the programming language of choice is not on the list, we can create our own template as well. OpenFaas has good documentation on creating a first Python example function. We will reference it to create a function and test it.

# create a new folder for functions
mkdir openfaas-fn
cd openfaas-fn

# create a new python function
faas-cli new --lang python hello-python

This will create a directory hello-python which will contain two files handler.py and requirements.txt. The handler file will contain a Python method handle(req), which contains the code which will be invoked while the requirements file will contain the required dependencies.

Then, we can use faas-cli to build, deploy and test our function:

# Build the function into local docker library
faas-cli build -f ./hello-python.yml

# Push the local image to a remote container registry such as DockerHub or private one
faas-cli push -f ./hello-python.yml

# Deploy the function to the cluster
faas-cli deploy -f ./hello-python.yml

# Test the function
curl $OPENFAAS_URL/function/hello-python -d "World"
Hello! You said: World

OpenFaas functions can be invoked via HTTP requests, CLI, or through events. OpenFaas Pro comes with inbuilt connectors for Apache Kafka, AWS SQS, AWS SNS, Postgres, and Cron. There is also a growing community of third-party connectors such as NATS, RabbitMQ, and CloudEvents. I was able to utilize the third-party RabbitMQ connector to invoke the serverless functions based on the messages published to a specific RabbitMQ queue. More details about the integration with RabbitMQ and the deployment of the serverless functions can be found on my GitHub.

OpenFaas allows invoking functions synchronously and asynchronously. In case of a synchronous invocation, the HTTP request first hits the Kubernetes ingress controller, which redirects it to the respective service, which in turn redirects the request to one of the pods which then executes the function as per the passed parameters.

Sync Invocation

However, there is also an option for async functions. These are especially useful for long-running tasks. In this case, the gateway acts as a publisher and writes the serialized request in a NATS queue. The queue-worker application is the consumer of this queue, reads the message, deserializes it, and then calls the respective service either directly or through the gateway.

Async Invocation

By default, OpenFaas comes with a UI that is accessible at http://$OPENFAAS_URL in the browser. The UI can be used to deploy and invoke functions. It is protected by credentials that can be found in the ‘basic-auth’ secret in your namespace in Kubernetes.

OpenFaas UI

Hopefully, this is helpful for you. All of the code samples for this exercise are available on GitHub for reference.

References:

  1. https://docs.openfaas.com/

--

--