Building Serverless on Kubernetes with OpenFaaS and JFrog Artifactory

Serverless (as an operational construct) and Kubernetes (as a powerful platform and enabler) are rapidly transforming how companies operate. Just looking at KubeCon + CloudNativeCon EU 2019 with close to 8000 attendees and the sold out Serverless Practitioners Summit as a pre-conference event shows how strongly developers feel the need to use them together well. 

In my talk “Duct Tape and String: Continuously Delivering Serverless Microservices” at swampUP 2019, I got to talk about some best practice for the project that got me excited about both serverless and K8s: OpenFaaS!

What is OpenFaaS?

OpenFaaS is a Function-as-a-Service framework for building Serverless functions with Docker and Kubernetes. It enables you to build both microservices and functions in any language with  the flexibility of containers to run on any cloud or on-premises hardware. Using K8s to figure out the hard bits of building event-driven and scalable apps lets the developers focus on what they do best: create business value.

Where Artifactory fits

With OpenFaaS you’re deploying containers to Kubernetes and that’s where Artifactory can serve as your Docker registry. Artifactory provides the Kubernetes Docker Registry that powers your K8s clusters with the container images you create.

Using Artifactory is a good thing, because any app that you create, whether serverless or not, still requires you to think about the dependencies and their builds. Artifactory helps you manage those too, through proxy repositories for dependencies that provide a speedy cache and help assure you’re always building with the version you expect. OpenFaaS leaves you free to choose the language you like, so Artifactory’s support for 25 package technologies has you covered.

Of course, you also gain the full traceability of each of your Docker images for OpenFaaS by publishing build information, and you can even help keep out security vulnerabilities with JFrog Xray scanning those images. That means Artifactory can be the single, trusted place where you can store everything for your apps.

Best practice: Tying them together

Let’s walk through the same scenario I built on stage at swampUP. 

To start, I created a new template to get Go modules from Artifactory. The lines 26 to 30 cover the connectivity with Artifactory. In order, the lines cover:

  1. Configuring the JFrog CLI to connect to Artifactory
  2. Building the Go app
  3. Publishing the app and dependencies to Artifactory 
  4. Collecting the build-info, and publishing that build-info to Artifactory.

To get the template and create the outline of the app, you’ll need to run two commands:

# Get the template
faas-cli template pull https://github.com/retgits/of-templates

# Create a new app called holidays using that template
faas-cli new --lang go-arti-http holidays

Those commands generate a folder called holidays and a file called holidays.yml. The YAML file is the deployment descriptor that describes what your app is. In that file, you’ll see a YAML tag called “image”, which you’ll have to update to reference the Docker image in Artifactory. The form of that will be: <artifactory host>/<virtual repo>/<docker image>:<tag> (for example, myartifactory/docker/holidays:latest).

By default, the module name is set to my-function. If you want to change that (and you probably should) update it in the go.mod file. 

Next, add a new dependency to the code using go get. To do that, run go get:

package function

import (
	"encoding/json"
	"net/http"

	"github.com/openfaas-incubator/go-function-sdk"
	"github.com/retgits/checkiday"
)

// Handle a function invocation
func Handle(req handler.Request) (handler.Response, error) {
	var err error

	// Check the holidays of today
	days, err := checkiday.Today()
	// Turn it into a JSON payload
	payload, err := json.Marshal(days.Holidays)

	// Add the JSON payload to the response
	return handler.Response{
		Body:       payload,
		StatusCode: http.StatusOK,
	}, err
}

To build and deploy the function to the OpenFaaS runtime, you need to run one more command. That command will have a few specific parameters to make sure the connection to Artifactory is set up properly. 

  • APP_VERSION: the version of your app which will also be the build number in Artifactory;
  • APP_NAME: the name of your app which will also be the build name in Artifactory;
  • ARTIFACTORY_URL: the URL to your Artifactory server
  • ARTIFACTORY_USER: the user that you log in to Artifactory with;
  • ARTIFACTORY_PASSWD: the password of the user.

Combined into a single line, that looks like:

faas-cli up -f holidays.yml
  -b APP_VERSION= \
  -b APP_NAME= \
  -b ARTIFACTORY_URL= \
  -b ARTIFACTORY_USER= \
  -b ARTIFACTORY_PASSWD=

The result of the command shows a URL you can use to invoke your function and see the holidays of the day (it was National Eat an Oreo Day when I did the presentation). You can invoke the function using either curl or faas-cli.

# using curl
curl --request GET --url https://my.openfaas.gateway/function/holidays

# using faas-cli
echo "" | faas-cli invoke holidays

Which resulted in:

[
    ...
    
        "name": "National Eat an Oreo Day",
        "url": "https://www.checkiday.com/f49c89ec9ad6e802c7a0adffb1d19ed2/national-eat-an-oreo-day"
    
    ...
]

What’s next?

If you want to try these steps out too, check out the test drive option we have. That will give you access to both Artifactory and Xray (really useful for scanning the functions you just built) for four days without requiring you to install anything on your local machine. As always, let me know your thoughts, comments, and feedback on Twitter!