Run your own FaaS with OpenFaas and .Net Core

A few years ago we all built monolithic applications which where hard to deploy and maintain. Mostly they were pushed to some application server for hosting like IIS or JBoss. Currently everyone is doing micro-services and that often in combination with Docker for easy build and deployment, but the next big thing is right around the corner. Functions-as-a-Service (FaaS) is hot right now in the software development scene and that’s why we have a look at it today.

FaaS

The idea behind functions is to do exactly one thing and that well. FaaS takes away the complexity of building, deploying and hosting such functions. Commercial vendors are already providing FaaS in their server-less offers. The most popular being Azure Functions and AWS Lambda.

But what if you want to run FaaS on premise on your own computer in your companies data center? This is where OpenFaaS comes into the play. OpenFaaS is an open-source function-as-a-service platform which runs on Docker. This means it easy to setup with Docker Swarm or Kubernetes.

In this blog post I’ll show how to setup OpenFaaS locally on your Windows machine with Docker for Windows and Kubernetes. The good thing about Docker for Windows is that it comes with Kubernetes preinstalled. You just need to enable it and your Kubernetes clusters runs.

Kubernetes DfW

Furthermore you need a Docker Hub account to push your Docker images to. Unfortunately Kubernetes does not use the local Docker repository on your computer to search for images.

Install OpenFaaS on Kubernetes

Installing OpenFaaS on a local Kubernetes cluster is pretty straight forward. Clone the repo and deploy to Kubernetes.

git clone https://github.com/openfaas/faas-netes
kubectl apply -f https://raw.githubusercontent.com/openfaas/faas-netes/master/namespaces.yml
cd faas-netes
kubectl apply -f ./yaml

That’s it. Your OpenFaaS in running and ready to be used!

We can access the web UI of OpenFaaS with a browser. Since Kubernetes forwards the OpenFaaS on some random port, we need to get the port on which the service is listening.

kubectl get services --selector="app=gateway" --namespace openfaas

This should show some output like this:

Output:
NAME      TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
gateway   NodePort   10.111.109.152           8080:31112/TCP   22m

This tells us that OpenFaaS runs on localhost:31112. The UI is reachable under http://localhost:3112/ui.

Create a function in C#

Now, lets create a new function in C# with .Net Core. To do so, we need to download the OpenFaas CLI.

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Invoke-WebRequest -Uri https://github.com/openfaas/faas-cli/releases/download/0.6.10/faas-cli.exe -OutFile faas-cli.exe

The function we want to build should return if a given string is a valid domain name. For example, given “google.com”, it should return “google.com is a valid domain name.” and for “google,com” (note the comma) it should return “google,com is not a valid domain name”.

First we create a new project from a template. The project name is valid-domain.

.\faas-cli.exe new --lang csharp valid-domain

After the operation completed, a folder valid-domain which contains a code template and a file valid-domain.yml are in our current directory.

Open the file .\valid-domain\FunctionHandler.cs. The class FunctionHandler contains a method Handle. This method is invoked, every time the function is requested. Change the content to the following.

using System;
using System.Text;

namespace Function
{
    public class FunctionHandler
    {
        public void Handle(string input) {
            input = SanitizeInput(input);

            if(IsValidDomainName(input))
                Console.WriteLine($"{input} is a valid domain name.");
            else
                Console.WriteLine($"{input} is not a valid domain name.");
        }

        private bool IsValidDomainName(string name)
        {
            return Uri.CheckHostName(name) != UriHostNameType.Unknown;
        }

        private string SanitizeInput(string input)
        {
            return input.Trim().Replace("\n", string.Empty).Replace("\r", string.Empty);
        }
    }
}

The function SanitizeInput is necessary, because OpenFaaS adds non-printable characters to the input string. If these characters are evaluated in the IsValidDomainName function, it will always return false. That’s all the code we need.

Now edit the .\valid-domain.yml file to look like this:

provider:
  name: faas
  gateway: http://127.0.0.1:31112

functions:
  valid-domain:
    lang: csharp
    handler: ./valid-domain
    image: docker_hub_name/valid-domain

Replace the port of the gateway with the port where OpenFaaS is listening on your machine. Replace the image prefix with your Docker Hub account name.

The next step is to build the function. This creates a local Docker image called valid-domain.

.\faas-cli.exe build -f .\valid-domain.yml

As mentioned above, Kubernetes doesn’t use the local Docker repository, so we are forced to upload our function to a public one.

$env:DOCKER_ID_USER="docker_hub_username"
docker login
docker tag valid-domain $env:DOCKER_USER_ID/valid-domain
docker push $env:DOCKER_USER_ID/valid-domain

When the image is pushed, we are ready to deploy the function to the local OpenFaaS instance.

.\faas-cli.exe deploy -f .\valid-domain.yml

If the operation was successful, we have to wait a bit until the function is ready to use. You can check the state in the web UI. If the function is ready, we can try it out in the UI.
OpenFaas Example.png
It works! The function can be called over REST such that an easy invoke over PowerShell is possible.

(Invoke-WebRequest -Method Post -Uri http://localhost:31112/function/valid-domain -Body google.com).ToString()

google.com is a valid domain name.

(Invoke-WebRequest -Method Post -Uri http://localhost:31112/function/valid-domain -Body google,com).ToString()

google com is not a valid domain name.

As we can see above, our function works as expected. You can wrap any command line tool that takes input from stdin and outputs to stdout as a function without touching the code!

2 thoughts on “Run your own FaaS with OpenFaas and .Net Core

  1. Hi very interested in what you are doing here. When following along I get the following message when trying to retrieve the services with kubctl “No resources found”. Is there maybe a step missing in trying to get the openfaas service up and running in kube?

    Like

Leave a comment