Go Functions as a Service With Kubernetes and OpenFaaS

OpenFaaS is an open source functions as a service framework for Kubernetes. This guide illustrates the deployment of a Go function with auto-scaling and metrics.

August 24, 2022 in Go

As an open framework that relies on free and open source technologies such as Docker and the OCI format, OpenFaaS democratizes what usually involves a vendor lock-in: functions as a service. Deployed to Kubernetes, it offers auto-scaling, metrics, and a built-in UI out of the box.

Prerequisites

To set everything up in your local machine, make sure you have the following tools at your hand:

Install OpenFaaS on Kubernetes

First, create two new Kubernetes namespaces — one for the OpenFaaS deployments and one for the custom functions. This will create the openfaas and openfaas-fn namespaces.

kubectl apply -f https://raw.githubusercontent.com/openfaas/faas-netes/master/namespaces.yml

Next, add the OpenFaaS Helm repository.

helm repo add openfaas https://openfaas.github.io/faas-netes/

Complete the installation by deploying OpenFaaS from the added Helm chart. After installing the release, there should be several OpenFaaS services deployed in your openfaas namespace.

helm install openfaas openfaas/openfaas \
    --namespace openfaas \
    --set functionNamespace=openfaas-fn \
    --set generateBasicAuth=true

Connect with OpenFaaS

Because OpenFaaS is running isolated inside the minikube cluster, port forwarding is needed to expose the Kubernetes service to the host. Establish the port forwarding in a seperate terminal window and keep it running:

kubectl port-forward -n openfaas svc/gateway 8080:8080

Installing the chart created a secret containing the admin credentials. Store this password in an environment variable called OPENFAAS_PASSWORD.

OPENFAAS_PASSWORD=$(kubectl -n openfaas get secret basic-auth -o jsonpath="{.data.basic-auth-password}" | base64 --decode)

You can now use this password to log in to OpenFaaS using the CLI, assuming that the service has been exposed on port 8080 as shown above.

echo -n $PASSWORD | faas-cli login -g http://127.0.0.1:8080 -u admin --password-stdin

Create a Custom Go Function

Create a local directory for your functions, for example functions. The OpenFaaS CLI provides a command for scaffolding new functions in a variety of languages. We're going to create a function called print-name that prints a simple message.

First, we're going to pull one of the official OpenFaaS templates for Go. I've decided to use the golang-http template here, which provides a Lambda-like API.

faas-cli template store pull golang-http

This template can now be used to create a new function:

faas-cli new --lang golang-http print-name

Inside the print-name directory created by this command, edit the file print-name/handler.go. This is the actual function handler.

package function

import (
    "fmt"
    "net/http"

    handler "github.com/openfaas/templates-sdk/go-http"
)

func Handle(request handler.Request) (handler.Response, error) {
    message := fmt.Sprintf("Hello %s", string(request))

    return handler.Response{
        Body:       []byte(message),
        StatusCode: http.StatusOK,
    }, nil
}

The handler assumes that the request payload is a name and returns a greeting with this name. Next up, open the file print-name.yml, where the function deployment is defined:

version: 1.0
provider:
  name: openfaas
  gateway: http://127.0.0.1:8080
functions:
  print-name:
    lang: go
    handler: ./print-name
    image: print-name:latest

Prefix the image name with your Docker Hub username: <user>/print-name:latest. It will be published to Docker Hub in the next step, where it will be available to minikube. It is possible to use local Docker images as well, but I've found images pushed to a registry more convenient.

Build and Publish the Function

The penultimate step is to build the function, creating a corresponding Docker image:

faas-cli build -f print-name.yml

Pushing the built function will publish the image to Docker Hub.

faas-cli push -f print-name.yml

Finally, deploy the function to OpenFaaS. This will print the URL of the deployed function — you can use this URL to invoke the function locally, or you can invoke the function via the UI.

faas-cli deploy -f print-name.yml

Invoke the Function

Invoking the function using curl works as follows, with "Alice" being the request payload:

curl 127.0.0.1:8080/function/print-name -d "Alice"
Hello Alice

Alternatively, you might visit the UI at 127.0.0.1:8080/ui/ and invoke the function there. Note that the UI reports useful additional information such as the function status, the number of replicas, and the invocation count.

💫graph: A library for creating generic graph data structures and modifying, analyzing, and visualizing them.
💫
graph: A library for creating generic graph data structures and modifying, analyzing, and visualizing them.