Article

Table of Contents
Theme:
Was this article helpful?
Try Vultr Today with

$50 Free on Us!

Want to contribute?

You could earn up to $600 by adding new articles.

Self Hosted Serverless Functions with OpenFaaS and Kubernetes

Author: Hitesh Jethva

Last Updated: Mon, Oct 16, 2023
DevOps Kubernetes

Header Image

Introduction

Serverless computing is a cloud application development model that allows developers to build and run code without managing the underlying infrastructure. It allows developers to focus solely on code and application development while server management tasks are effectively handled by applying tools such as OpenFaas.

OpenFaaS is an open-source framework that allows developers to write code in the form of functions and deploy it as Docker containers in a Kubernetes cluster. It offers a web interface and a command line interface (faas-cli) to deploy, manage and monitor functions. OpenFaas leverages Kubernetes capabilities to manage containerized functions and handle tasks such as scaling, load balancing, and high availability.

This article explains how you can run self-hosted serverless functions with OpenFaas in a Vultr Kubernetes Engine (VKE) cluster.

Prerequisites

Before you begin:

On the management server:

Install OpenFaaS

To install OpenFaas on your Kubernetes Cluster. Create a new namespace, and use the helm package manager to install OpenFaas in the cluster as described in the steps below.

  1. Create a new namespaces.yml file to define the OpenFaas namespaces

    $ nano namespaces.yml
    
  2. Add the following contents to the file

    apiVersion: v1
    
    kind: Namespace
    
    metadata:
    
      name: openfaas-kube
    
      annotations:
    
        linkerd.io/inject: enabled
    
        config.linkerd.io/skip-inbound-ports: "4222"
    
        config.linkerd.io/skip-outbound-ports: "4222"
    
      labels:
    
        role: openfaas-system
    
        access: openfaas-system
    
        istio-injection: enabled
    
    ---
    
    apiVersion: v1
    
    kind: Namespace
    
    metadata:
    
      name: openfaas-func
    
      annotations:
    
        linkerd.io/inject: enabled
    
        config.linkerd.io/skip-inbound-ports: "4222"
    
        config.linkerd.io/skip-outbound-ports: "4222"
    
      labels:
    
        istio-injection: enabled
    
        role: openfaas-func
    

    Save and close the file

  3. Apply the namespaces to your cluster

    $ kubectl apply -f namespaces.yml
    
  4. Verify that the namespaces are active and available

    $ kubectl get namespaces
    

    Output:

    openfaas-func     Active   58m
    
    openfaas-kube     Active   58m
    
  5. Using helm, add the OpenFaaS repository to your local repositories

    $ helm repo add openfaas https://openfaas.github.io/faas-netes/
    
  6. Update your Helm repositories

    $ helm repo update
    
  7. Create a values.yaml file to customize the OpenFaas helm chart parameters

    $ nano values.yaml
    
  8. Add the following contents to the file. Replace openfass.example.com with your actual domain

    functionNamespace: openfaas-func
    
    generateBasicAuth: true
    
    
    
    ingress:
    
      enabled: true
    
      annotations:
    
        kubernetes.io/ingress.class: "nginx"
    
      hosts:
    
        - host: openfaas.example.com
    
          serviceName: gateway
    
          servicePort: 8080
    
          path: /
    
  9. Install OpenFaaS to the openfaas-kube namespace

    $ helm upgrade openfaas --install openfaas/openfaas --namespace openfaas-kube -f values.yaml
    

    When the deployment is successful, your output should look like the one below:

    NAME: openfaas
    
    LAST DEPLOYED: Fri Sep  1 11:52:18 2023
    
    NAMESPACE: openfaas-kube
    
    STATUS: deployed
    
    REVISION: 1
    
    TEST SUITE: None
    
    NOTES:
    
    To verify that openfaas has started, run:
    
    
    
      kubectl -n openfaas-kube get deployments -l "release=openfaas, app=openfaas"
    
    
    
    To retrieve the admin password, run:
    
    
    
      echo $(kubectl -n openfaas-kube get secret basic-auth -o jsonpath="{.data.basic-auth-password}" | base64 --decode)
    
  10. View the OpenFaaS administrator account password

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

    Your password should display in a plain format like the one below

    vusipdumobCT
    
  11. Verify the OpenFaaS deployment status

    $ kubectl -n openfaas-kube get deployments -l "release=openfaas, app=openfaas"
    

    Output:

    NAME           READY   UP-TO-DATE   AVAILABLE   AGE
    
    alertmanager   1/1     1            1           62s
    
    gateway        1/1     1            1           62s
    
    nats           1/1     1            1           62s
    
    prometheus     1/1     1            1           62s
    
    queue-worker   1/1     1            1           62s
    

    Verify that all OpenFaas deployments are ready and available

  12. Using a web browser of your choice such as Microsoft Edge, visit your OpenFaas domain name to access the web interface

    http://openfaas.example.com
    

    When prompted, enter the following administrator details:

    USERNAME: admin

    PASSWORD: Generated-Password-You-Copied-Earlier

    When logged in, the OpenFaas dashboard should display

    OpenFaaS Dashboard

Secure OpenFaaS

To secure and serve incoming OpenFaas requests using HTTPS, generate a Let's Encrypt SSL certificate using CertManager as described below.

  1. Create a new Cluster Issuer file openfaas-issuer.yaml

    $ nano openfaas_issuer.yaml
    
  2. Add the following contents to the file

    apiVersion: cert-manager.io/v1
    
    kind: ClusterIssuer
    
    metadata:
    
      name: letsencrypt-prod
    
    spec:
    
      acme:
    
        # Email address used for ACME registration
    
        email: hello@example.com
    
        server: https://acme-v02.api.letsencrypt.org/directory
    
        privateKeySecretRef:
    
          # Name of a secret used to store the ACME account private key
    
          name: openfaas-crt
    
        # Add a single challenge solver, HTTP01 using nginx
    
        solvers:
    
        - http01:
    
            ingress:
    
              class: nginx
    

    Save and close the file

  3. Apply the issuer resource

    $ kubectl apply -f openfaas_issuer.yaml
    
  4. Rename and back up the values.yaml file

    $ mv values.yaml orig-values.yaml
    
  5. Recreate the file

    $ nano values.yaml
    
  6. Add the following contents to the file. Replace openfaas.example.com with your actual domain

    functionNamespace: openfaas-func
    
    generateBasicAuth: true
    
    
    
    ingress:
    
      enabled: true
    
      annotations:
    
        kubernetes.io/ingress.class: "nginx"
    
        cert-manager.io/cluster-issuer: letsencrypt-prod
    
      tls:
    
        - hosts:
    
            - openfaas.example.com
    
          secretName: openfaas-crt
    
      hosts:
    
        - host: openfaas.example.com
    
          serviceName: gateway
    
          servicePort: 8080
    
          path: /
    

    Save and close the file

  7. Using helm, apply the configuration changes to your cluster

    $ helm upgrade openfaas --install openfaas/openfaas --namespace openfaas-kube  -f values.yaml
    
  8. Verify the SSL certificate status

    $ kubectl get certificates -n openfaas-kube
    

    Output:

    NAME           READY   SECRET         AGE
    
    openfaas-crt   True    openfaas-crt   22h
    

    Verify that the certificate status is Ready. If False, describe the certificate to view the issuance process.

    $ kubectl describe certificate openfaas-crt -n openfaas-kube
    

    Output:

    Normal  Generated  2m13s  cert-manager-certificates-key-manager      Stored new private key in temporary Secret resource "openfaas-crt-4htkh"
    
    Normal  Requested  2m13s  cert-manager-certificates-request-manager  Created new CertificateRequest resource "openfaas-crt-2thsw"
    
    Normal  Issuing    109s   cert-manager-certificates-issuing          The certificate has been successfully issued
    
  9. In a new web browser window, verify that you can securely access your OpenFaas web interface using HTTPS

    https://openfaas.example.com
    

Install OpenFaaS CLI

faas-cli is a command-line tool that provides a convenient way to interact with the OpenFaaS application in your cluster. It allows you to create, deploy, manage, and invoke serverless functions in your terminal session instead of the web interface. Install the CLI tool to create and manage functions as described below.

  1. Export the OPENFAAS_URL environment variable with your OpenFaas HTTPS URL

    export OPENFAAS_URL=https://openfaas.example.com
    

    To permanently save the environment variable. Edit the .bash_profile file in your user home directory, and add the export directive at the end of the file. Then, run the source /home/example_user/.bash_profile command to load the environment variable.

  2. Install the faas-cli tool

    $ curl -sSL https://cli.openfaas.com | sudo sh
    

    Output:

    CLI:
    
     commit:  869d236be5bf71cc32231a4317ccfcd950de35ef
    
     version: 0.16.13
    
  3. Log in to OpenFaaS using the faas-cli login command. Replace vusipdumobCT with the actual administrator password you generated earlier

    $ faas-cli login --username admin --password vusipdumobCT
    

    Output:

    Calling the OpenFaaS server to validate the credentials...
    
    credentials saved for admin https://openfaas.example.com
    

Create and Manage serverless Functions

In this section, use the faas-cli tool to create a new Node.js function, and deploy it to your DockerHub repository and Kubernetes cluster as described below.

  1. Verify that Docker is available on your server

    $ docker --version
    

    Output:

    Docker version 24.0.5, build 24.0.5-0ubuntu1~22.04.1
    

    If the command fails returns an error, add your user account to the Docker group

    $ sudo usermod -aG docker example_user
    

    Activate the new Docker group membership

    $ newgrp docker
    
  2. Log in to your DockerHub account

    $ docker login
    

    When prompted, enter your DockerHub credentials to build and push new images

    Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
    
    Username: YOUR_DOCKER_HUB_ID
    
    Password: YOUR_DOCKER_HUB_PASSWORD
    
  3. Create a new function directory

    $ mkdir new-function
    
  4. Switch to the function directory

    $ cd new-function
    
  5. Populate the directory with the Node.js template function

    $ faas new function-js --lang node
    

    The above command creates a new function-js.yml configuration file, a function-js directory with the handler.js and package.json files. When successful, your output should look like the one below:

    Folder: function-js created.
    
    
    
    Function created in folder: function-js
    
    Stack file written: function-js.yml
    
  6. Edit the handler.js file

    $ nano function-js/handler.js
    
  7. Change the done placeholder value to your desired status code such as <h1>Hello Good Morning!</h1>

    "use strict"
    
    
    
    module.exports = async (context, callback) => {
    
        return {status: "<h1>Hello Good Morning!</h1>"}
    
    }
    

    The above function returns a Hello Good Morning! response each time the function runs

  8. Edit the function-js.yml file

    $ nano function-js.yml
    
  9. Change the gateway directive to match your OpenFaas domain URL and include your DockerHub before the function-js:latest declaration to set up a new repository

    version: 1.0
    
    provider:
    
      name: openfaas
    
      gateway: https://openfaas.example.com
    
    functions:
    
      function-js:
    
        lang: node
    
        handler: ./function-js
    
        image: example_user/function-js:latest
    

    Save and close the file

  10. Using the faas up command, build the Docker image, push it to Docker Hub, and deploy it to your Kubernetes cluster

    $ faas up -f function-js.yml
    

    When successful, your output should look like the one below:

    [0] < Pushing function-js [example_user/function-js:latest] done.
    
    [0] Worker done.
    
    Deploying: function-js.
    
    
    
    Deployed. 202 Accepted.
    
    URL: https://openfaas.onlustech.com/function/function-js
    
  11. In your web browser, load your new function using the OpenFaas URL

    https://openfaas.example.com/function/function-js
    

    When successful, your Hello, Good Morning status code should display on the page

    Verify deployed function

    Or, use the faas invoke command to verify the deployed function

    $ faas invoke function-js
    

    Output:

    Reading from STDIN - hit (Control + D) to stop.
    
    {"status":"<h1>Hello Good Morning!</h1>"}
    

    Press CTRL + D to close the output

  12. To list all deployed functions, run the faas list command

    $ faas list
    

    Output:

    Function                      Invocations    Replicas
    
    function-js                     3              1    
    
  13. To view information about your function, run the faas describe command

    $ faas describe function-js
    

    Output:

    Name:               function-js
    
    Status:             Ready
    
    Replicas:           1
    
    Available Replicas: 1
    
    Invocations:        2
    
    Image:              example_user/function-js:latest
    
    Function Process:   node index.js
    
    URL:                https://openfaas.example.com/function/function-js
    
    Async URL:          https://openfaas.example.com/async-function/function-js
    
    Labels:
    
     faas_function: function-js
    
    Annotations:
    
     prometheus.io.scrape: false
    
  14. To delete a function, use the faas remove command

    $ faas remove function-js
    

Conclusion

In this article, you installed OpenFaaS on a Vultr Kubernetes Engine (VKE) cluster and created serverless functions using the faas-cli tool. You can use the tool to create and deploy new functions using different programming languages to your Kubernetes cluster for access through the OpenFaas web interface. For more information, visit the OpenFaaS documentation.

Want to contribute?

You could earn up to $600 by adding new articles.