Skip to content
Branch: master
Find file History
stefanprodan and alexellis Restrict pod security policy capabilities
Allow NET_ADMIN and NET_RAW so that OpenFaaS can run under Istio or Linkerd

Signed-off-by: stefanprodan <>
Latest commit a0fa32e Jul 8, 2019

OpenFaaS - Serverless Functions Made Simple

OpenFaaS Logo

OpenFaaS (Functions as a Service) is a framework for building serverless functions with Docker and Kubernetes which has first class support for metrics. Any process can be packaged as a function enabling you to consume a range of web events without repetitive boiler-plate coding.


  • Ease of use through UI portal and one-click install
  • Write functions in any language for Linux or Windows and package in Docker/OCI image format
  • Portable - runs on existing hardware or public/private cloud. Native Kubernetes support, Docker Swarm also available
  • Operator / CRD option available
  • faas-cli available with stack.yml for creating and managing functions
  • Auto-scales according to metrics from Prometheus
  • Scales to zero and back again and can be tuned at a per-function level
  • Works with service-mesh
    • Tested with Istio including mTLS
    • Tested with Linkerd2 including mTLS

Deploy OpenFaaS

Note: If your cluster is not configured with role-based access control, then pass --set rbac=false. For further information, see Kubernetes: RBAC.

Note: If you can not use helm with Tiller, you can still use the helm CLI to generate custom YAML without server-side components.


See also: Install Helm

We recommend creating two namespaces, one for the OpenFaaS core services and one for the functions:

kubectl apply -f

You will now have openfaas and openfaas-fn. If you want to change the names or to install into multiple installations then edit namespaces.yml from the faas-netes repo.

Add the OpenFaaS helm chart:

helm repo add openfaas

Generate secrets so that we can enable basic authentication for the gateway:

# generate a random password
PASSWORD=$(head -c 12 /dev/urandom | shasum| cut -d' ' -f1)

kubectl -n openfaas create secret generic basic-auth \
--from-literal=basic-auth-user=admin \

Now decide how you want to expose the services and edit the helm upgrade command as required.

  • To use NodePorts (default) pass no additional flags
  • To use a LoadBalancer add --set serviceType=LoadBalancer
  • To use an IngressController add --set ingress.enabled=true

Note: even without a LoadBalancer or IngressController you can access your gateway at any time via kubectl port-forward.

Now deploy OpenFaaS from the helm chart repo:

helm repo update \
 && helm upgrade openfaas --install openfaas/openfaas \
    --namespace openfaas  \
    --set basic_auth=true \
    --set functionNamespace=openfaas-fn

The above command will also update your helm repo to pull in any new releases.

Tuning cold-start

The concept of a cold-start in OpenFaaS only applies if you A) use faas-idler and B) set a specific function to scale to zero.

There are two ways to reduce the Kubernetes cold-start for a pre-pulled image, which is 1-2 seconds.

  1. Don't set the function to scale down to zero, just set it a minimum availability i.e. 1/1 replicas
  2. Use async invocations via the /async/function/<name> route
  3. Tune the readinessProbes to be aggressively low values. This will reduce the cold-start at the cost of more kubelet CPU usage

To achieve around 1s coldstart, set values.yaml:


# redacted
    initialDelaySeconds: 0
    timeoutSeconds: 1
    periodSeconds: 1
    initialDelaySeconds: 0
    timeoutSeconds: 1
    periodSeconds: 1
# redacted
  imagePullPolicy: "IfNotPresent"    # Image pull policy for deployed functions

You should also set imagePullPolicy to IfNotPresent so that the kubelet only pulls images which are not already available.

httpProbe vs. execProbe

A note on health-checking probes for functions:

  • httpProbe - (default) most efficient. (compatible with Istio >= 1.1.5)
  • execProbe - least efficient option, but compatible with Istio < 1.1.5

Use --set faasnetes.httpProbe=true/false to toggle between http / exec probes.

Verify the installation

Once all the services are up and running, log into your gateway using the OpenFaaS CLI. This will cache your credentials into your ~/.openfaas/config.yml file.

Fetch your public IP or NodePort via kubectl get svc -n openfaas gateway-external -o wide and set it as an environmental variable as below:


If using a remote cluster, you can port-forward the gateway to your local machine:

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

Now log in with the CLI and check connectivity:

echo -n $PASSWORD | faas-cli login -g $OPENFAAS_URL -u admin --password-stdin

faas-cli version

OpenFaaS Operator and Function CRD

If you would like to work with Function CRDs there is an alternative controller to faas-netes named OpenFaaS Operator which can be swapped in at deployment time. The OpenFaaS Operator is suitable for development and testing and may replace the faas-netes controller in the future. The Operator is compatible with Kubernetes 1.9 or later.

To use it, add the flag: --set operator.create=true when installing with Helm.

faas-netes vs OpenFaaS Operator

The faas-netes controller is the most tested, stable and supported version of the OpenFaaS integration with Kubernetes. In contrast the OpenFaaS Operator is based upon the codebase and features from faas-netes, but offers a tighter integration with Kubernetes through CustomResourceDefinitions. This means you can type in kubectl get functions for instance.

See also: Introducing the OpenFaaS Operator

Deployment with helm template

This option is good for those that have issues with installing Tiller, the server/cluster component of helm. Using the helm CLI, we can pre-render and then apply the templates using kubectl.

  1. Clone the faas-netes repository git clone

  2. Render the chart to a Kubernetes manifest called openfaas.yaml

    helm template faas-netes/chart/openfaas \
        --name openfaas \
        --namespace openfaas  \
        --set basic_auth=true \
        --set functionNamespace=openfaas-fn > $HOME/openfaas.yaml

    You can set the values and overrides just as you would in the install/upgrade commands above.

  3. Install the components using kubectl kubectl apply -f faas-netes/namespaces.yml kubectl apply -f $HOME/openfaas.yaml

Now verify your installation.

Test a local helm chart

You can run the following command from within the faas-netes/chart folder in the faas-netes repo.

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

Exposing services


By default a NodePort will be created for the API Gateway.


You temporarily access the Prometheus metrics by ueing port-forward

kubectl --namespace openfaas port-forward deployment/prometheus 31119:9090

Then open http://localhost:31119 to directly query the OpenFaaS metrics scraped by Prometheus.


If you're running on a cloud such as AKS or GKE you will need to pass an additional flag of --set serviceType=LoadBalancer to tell helm to create LoadBalancer objects instead. An alternative to using multiple LoadBalancers is to install an Ingress controller.

Deploy with an IngressController

In order to make use of automatic ingress settings you will need an IngressController in your cluster such as Traefik or Nginx.

Add --set ingress.enabled to enable ingress pass --set ingress.enabled=true when running the installation via helm.

By default services will be exposed with following hostnames (can be changed, see values.yaml for details):

  • gateway.openfaas.local


If you require TLS/SSL then please make use of an IngressController. A full guide is provided to enable TLS for the OpenFaaS Gateway using cert-manager and Let's Encrypt.

Zero scale

Scale-up from zero (on by default)

Scaling up from zero replicas is enabled by default, to turn it off set scaleFromZero to false in the helm chart options for the gateway component.

--set gateway.scaleFromZero=true/false

Scale-down to zero (off by default)

Scaling down to zero replicas can be achieved either through the REST API and your own controller, or by using the faas-idler component.

By default the faas-idler is set to only do a dryRun and to not scale any functions down.

--set faasIdler.dryRun=true/false

The faas-idler will only scale down functions which have marked themselves as eligible for this behaviour through the use of a label:

See also: faas-idler README.


Additional OpenFaaS options in values.yaml.

Parameter Description Default
functionNamespace Functions namespace, preferred openfaas-fn default
async Deploys NATS true
exposeServices Expose NodePorts/LoadBalancer true
serviceType Type of external service to use NodePort/LoadBalancer NodePort
basic_auth Enable basic authentication on the Gateway true
rbac Enable RBAC true
httpProbe Setting to true will use HTTP for readiness and liveness probe on the OpenFaaS system Pods (compatible with Istio >= 1.1.5) true
psp Enable Pod Security Policy for OpenFaaS accounts false
securityContext Deploy with a securityContext set, this can be disabled for use with Istio sidecar injection true
openfaasImagePullPolicy Image pull policy for openfaas components, can change to IfNotPresent in offline env Always
kubernetesDNSDomain Domain name of the Kubernetes cluster cluster.local
operator.create Use the OpenFaaS operator CRD controller, default uses faas-netes as the Kubernetes controller false
operator.createCRD Create the CRD for OpenFaaS Function definition true
ingress.enabled Create ingress resources false
faasnetes.httpProbe Use a httpProbe instead of exec false
faasnetes.readTimeout Queue worker read timeout 60s
faasnetes.writeTimeout Queue worker write timeout 60s
faasnetes.imagePullPolicy Image pull policy for deployed functions Always
faasnetes.setNonRootUser Force all function containers to run with user id 12000 false
gateway.replicas Replicas of the gateway, pick more than 1 for HA 1
gateway.readTimeout Queue worker read timeout 65s
gateway.writeTimeout Queue worker write timeout 65s
gateway.upstreamTimeout Maximum duration of upstream function call, should be lower than readTimeout/writeTimeout 60s
gateway.scaleFromZero Enables an intercepting proxy which will scale any function from 0 replicas to the desired amount true
gateway.maxIdleConns Set max idle connections from gateway to functions 1024
gateway.maxIdleConnsPerHost Set max idle connections from gateway to functions per host 1024
queueWorker.replicas Replicas of the queue-worker, pick more than 1 for HA 1
queueWorker.ackWait Max duration of any async task/request 60s
nats.enableMonitoring Enable the NATS monitoring endpoints on port 8222 false
faasIdler.create Create the faasIdler component true
faasIdler.inactivityDuration Duration after which faas-idler will scale function down to 0 15m
faasIdler.reconcileInterval The time between each of reconciliation 1m
faasIdler.dryRun When set to false the OpenFaaS API will be called to scale down idle functions, by default this is set to only print in the logs. true
prometheus.create Create the Prometheus component true
alertmanager.create Create the AlertManager component true

Specify each parameter using the --set key=value[,key=value] argument to helm install. See values.yaml for detailed configuration.

Removing the OpenFaaS

All control plane components can be cleaned up with helm:

helm delete --purge openfaas

Follow this by the following to remove all other associated objects:

kubectl delete namespace openfaas openfaas-fn

In some cases your additional functions may need to be either deleted before deleting the chart with faas-cli or manually deleted using kubectl delete.

You can’t perform that action at this time.