Profiles: Advanced Provider Configuration

Note: Only the Kubernetes provider currently supports Profiles!

The OpenFaaS design allows it to provide a standard API across several different container ochestration tools: Kubernetes, Docker Swarm, ContainerD, etc. These faas-providers generally implement the same core features and allow your to functions to remain portable and be deployed on any certified OpenFaaS installation regardless of the orchestration layer. However, there are certain workloads or deployments that require more advanced features or fine tuning of configuration. To allow maximum flexibility without overloading the OpenFaaS function configuration, we have introduced the concept of Profiles. This is simply a reserved function annotation that the faas-provider can detect and use to apply the advanced configuration.

Note: The general design is inspired by StorageClasses and IngressClasses in Kubernetes. If you are familiar with Kubernetes, these comparisons may be helpful, but they are not required to understand Profiles in OpenFaaS.

Using Profiles When You Deploy a Function

If you are a function author, using a Profile is a simple as adding an annotation to your function:

  1. com.openfaas.profile: <profile_name>

You can do this with the faas-cli flags:

  1. faas-cli deploy --annotation com.openfaas.profile=<profile_name>

Or in the stack YAML:

  1. functions:
  2. foo:
  3. image: "..."
  4. fprocess: "..."
  5. annotations:
  6. com.openfaas.profile: <profile_name>

If you need multiple profiles, you can use a comma separated value:

  1. com.openfaas.profile: <profile_name1>,<profile_name2>

Note: You must ask your cluster administrator which, if any profiles, are available.

Creating Profiles

Profiles must be pre-created, similar to Secrets, by the cluster admin. The OpenFaaS API does not provide a way to create Profiles because they are hyper specific to the orchestration tool.

Because Kubernetes is the only provider currently supporting Profiles, the follwing walk-through documents the process and options for Kubernetes.

Enable Profiles

When installing OpenFaaS on Kubernetes, Profiles use a CRD. This must be installed during or prior to start the OpenFaaS controller. When using the official Helm chart this will happen automatically. Alternatively, you can apply this YAML to install the CRD.

Note: Profiles requires faas-netes version >= 0.12.0 and/or Helm chart version >= 6.0.0.

Available Options

Profiles in Kubernetes work by injecting the supplied configuration directly into the correct locations of the Function’s Deployment. This allows us to directly expose the underlying API without any additional modifications. Currently, it exposes the following Pod and Container options from the Kubernetes API

The configuration use the exact options that you find in the Kubernetes documentation.

Examples

Use an Alternative RuntimeClass

A popular alternative container runtime class is gVisor that provides additional sandboxing between containers. If you have created a cluster that is using gVisor, you will need to set the runTimeClass on the Pods that are created. This is not exposed in the OpenFaaS API, but it can be set via a Profile.

  1. Install the latest faas-netes release and the CRD. The is most easily done with arkade

    1. arkade install openfaas

    This default installation will enable Profiles.

  2. Create a Profile to apply the runtime class

    1. kubectl apply -f- << EOF
    2. kind: Profile
    3. apiVersion: openfaas.com/v1
    4. metadata:
    5. name: gvisor
    6. namespace: openfaas
    7. spec:
    8. runtimeClassName: gvisor
    9. EOF
  3. Let your developers know that they need to use this annotation

    1. com.openfaas.profile: gvisor

The following stack file will deploy a SHA512 generating file in a cluster with gVisor

  1. provider:
  2. name: openfaas
  3. gateway: http://127.0.0.1:8080
  4. functions:
  5. stronghash:
  6. skip_build: true
  7. image: functions/alpine:latest
  8. fprocess: "sha512sum"
  9. annotations:
  10. com.openfaas.profile: gvisor

Use Tolerations and Affinity to Separate Workloads

The OpenFaaS API exposes the Kubernetes NodeSelector via constraints. This provides a very simple selection based on labels on Nodes.

The Kubernetes API also exposes two features affinity/anti-affinity and taint/tolerations that further expand the types of constraints you can express. OpenFaaS Profiles allow you to set these options, allowing you to more accurately isolate workloads, keep certain workloads together on the same nodes, or to keep certain workloads separate.

For example, a mixture of taints and affinity can put less critical functions on preemptable vms that are cheaper while keeping critical functions on standard nodes with higher availability guarantees.

In this example, we create a Profile using taints and affinity to place functions on the node with a GPU. We will also ensure that only functions that require the GPU are scheduled on these nodes. This ensures that the functions that need to use the GPU are not blocked by other standard functions taking resources on these special nodes.

  1. Install the latest faas-netes release and the CRD. The is most easily done with arkade

    1. arkade install openfaas

    This default installation will enable Profiles.

  2. Label and Taint the node with the GPU

    1. kubectl labels nodes node1 gpu=installed
    2. kubectl taint nodes node1 gpu:NoSchedule
  3. Create a Profile to that allows functions to run on this node

    1. kubectl apply -f- << EOF
    2. kind: Profile
    3. apiVersion: openfaas.com/v1
    4. metadata:
    5. name: withgpu
    6. namespace: openfaas
    7. spec:
    8. tolerations:
    9. - key: "gpu"
    10. operator: "Exists"
    11. effect: "NoSchedule"
    12. affinity:
    13. nodeAffinity:
    14. requiredDuringSchedulingIgnoredDuringExecution:
    15. nodeSelectorTerms:
    16. - matchExpressions:
    17. - key: gpu
    18. operator: In
    19. values:
    20. - installed
    21. EOF
  4. Let your developers creating functions that need GPU support, they must use this annotation

    1. com.openfaas.profile: withgpu