Skip to content
Create Ingress records and TLS certificates for your OpenFaaS Functions
Go Shell Dockerfile Makefile
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.github
artifacts
hack
pkg
vendor
.DEREK.yml
.gitignore
.travis.yml
CONTRIBUTING.md
Dockerfile
Gopkg.lock
Gopkg.toml
LICENSE
Makefile
README.md
main.go

README.md

OpenFaaS controller for FunctionIngress

Why is this needed?

OpenFaaS functions are created as pairs with Deployment and Service objects, which eventually go on to create a Pod.

Deployments should not be exposed directly, but accessed via the OpenFaaS Gateway service.

The gateway has a number of rules including:

  • providing HA through N replicas
  • adding tracing IDs
  • adding authz
  • collecting metrics
  • scaling endpoints from zero

Users started to create Ingress records pointing at the gateway for each public endpoint they wanted to host with a specific website address. This Operator automates that.

This project addresses the following Proposal for Kubernetes: Proposal: define custom hostname for functions #1082

Looking for a tutorial? See the OpenFaaS documentation

Schema

This is an Operator / controller to build Kubernetes Ingress and JetStack Certificate objects for functions.

The following example would expose the nodeinfo function from the store as a URL: nodeinfo.myfaas.club.

apiVersion: openfaas.com/v1alpha2
kind: FunctionIngress
metadata:
  name: nodeinfo
  namespace: openfaas
spec:
  domain: "nodeinfo.myfaas.club"
  function: "nodeinfo"
  ingressType: "nginx"
  # tls:
  #   enabled: true
  #   issuerRef:
  #     name: "letsencrypt-staging"
  #     kind: "Issuer"

Exploring the schema:

  • The domain field corresponds to a DNS entry which points at your IngressController's public IP, or the IP of one of the hosts if using HostPort.

  • function refers to the function you want to expose on the domain.

  • tls whether to provision a TLS certificate using JetStack's cert-manager

  • issuerRef which issuer to use, this may be a staging or production issuer.

  • issuerRef.kind Issuer or ClusterIssuer, This depends on whats available in your cluster

Status

This is work-in-progress prototype and only suitable for development and testing. Contributions and suggestions are welcome.

Todo:

  • Create Ingress records for HTTP
  • Create Ingress records for HTTPS
  • Create cert-manager Certificate records
  • Support Nginx
  • Support Zoolando's Skipper
  • Support Traefik
  • Support armhf / Raspberry Pi
  • Add .travis.yml for CI

Deployment

Pre-reqs

There are several pre-reqs for a working installation, but some of these components are installed with OpenFaaS and can also be found in the docs.

Install: tiller

curl https://raw.githubusercontent.com/kubernetes/helm/master/scripts/get | bash

kubectl -n kube-system create sa tiller \
  && kubectl create clusterrolebinding tiller \
  --clusterrole cluster-admin \
  --serviceaccount=kube-system:tiller

## Wait for tiller
helm init --skip-refresh --upgrade --service-account tiller --wait

IngressController: nginx

nginx IngressController is recommended. Use a HostPort if testing against a local cluster where LoadBalancer is unavailable.

Make sure you have helm and Tiller.

Install nginx with LoadBalancer:

helm install stable/nginx-ingress --name nginxingress --set rbac.create=true

Install nginx with host-port:

export ADDITIONAL_SET=",controller.hostNetwork=true,controller.daemonset.useHostPort=true,dnsPolicy=ClusterFirstWithHostNet,controller.kind=DaemonSet"
helm install stable/nginx-ingress --name nginxingress --set rbac.create=true${ADDITIONAL_SET}

OpenFaaS

OpenFaaS is also required:

git clone https://github.com/openfaas/faas-netes
cd faas-netes

kubectl apply -f namespaces.yml
# 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 \
--from-literal=basic-auth-password="$PASSWORD"

echo $PASSWORD > ../password.txt

kubectl apply -f ./yaml

kubectl port-forward -n openfaas deploy/gateway 31112:8080 &
echo -n ${PASSWORD} | faas-cli login --username admin --password-stdin -g 127.0.0.1:31112
faas-cli store deploy nodeinfo -g 127.0.0.1:31112

Configure DNS records

Find your public IP

Find the LB for Nginx:

kubectl get svc -n default

Or find the NodeIP:

kubectl get node -o wide
Create DNS A records

You should now configure your DNS A records:

For example, nodeinfo function in the myfaas.club domain and IP 178.128.137.209:

nodeinfo.myfaas.club  178.128.137.209

Note: with DigitalOcean's CLI you could run: doctl compute domain create nodeinfo.myfaas.club --ip-address 178.128.137.209.

TLS: Configure cert-manager

If using TLS, then install cert-manager.

Now create an issuer:

---
apiVersion: certmanager.k8s.io/v1alpha1
kind: Issuer
metadata:
  name: letsencrypt-staging
  namespace: openfaas
spec:
  acme:
    server: https://acme-staging.api.letsencrypt.org/directory
    # Email address used for ACME registration
    email: <your-email-here>
    # Name of a secret used to store the ACME account private key
    privateKeySecretRef:
      name: letsencrypt-staging
    http01: {}

or ClusterIssuer

apiVersion: certmanager.k8s.io/v1alpha1
kind: ClusterIssuer
metadata:
  name: letsencrypt-staging
spec:
  acme:
    server: https://acme-staging.api.letsencrypt.org/directory
    # Email address used for ACME registration
    email: <your-email-here>
    # Name of a secret used to store the ACME account private key
    privateKeySecretRef:
      name: letsencrypt-staging
    http01: {}

Save as letsencrypt-issuer.yaml then run kubectl apply -f letsencrypt-issuer.yaml.

Run or deploy the IngressOperator

In-cluster:

kubectl apply -f ./artifacts/

kubectl logs -n openfaas deploy/ingress-operator

Local testing:

rm ./artifacts/operator-amd64.yaml
kubectl apply -f ./artifacts/

go build && ./ingress-operator -kubeconfig=./config

Create your own FunctionIngress

With TLS

apiVersion: openfaas.com/v1alpha2
kind: FunctionIngress
metadata:
  name: nodeinfo-tls
  namespace: openfaas
spec:
  domain: "nodeinfo-tls.myfaas.club"
  function: "nodeinfo"
  ingressType: "nginx"
  tls:
    enabled: true
    issuerRef:
      name: "letsencrypt-staging"
      # Change to ClusterIssuer if required
      # https://docs.cert-manager.io/en/latest/reference/clusterissuers.html
      # https://docs.cert-manager.io/en/latest/reference/issuers.html
      kind: "Issuer"

nodeinfo.yaml

Without TLS

apiVersion: openfaas.com/v1alpha2
kind: FunctionIngress
metadata:
  name: nodeinfo
  namespace: openfaas
spec:
  domain: "nodeinfo.myfaas.club"
  function: "nodeinfo"
  ingressType: "nginx"

nodeinfo.yaml

Apply

kubectl apply -f nodeinfo.yaml

Test:

# Find the ingress record
kubectl get ingress -n openfaas

# Find the cert record
kubectl get cert -n openfaas

# Find the FunctionIngress
kubectl get FunctionIngress -n openfaas

Remember to configure DNS for nodeinfo.myfaas.club or edit /etc/hosts and point to your IngressController's IP or LoadBalancer.

Contributing

This project follows the OpenFaaS contributing guide

Configuration via Environment Variable

Option Usage
openfaas_gateway_namespace Namespace for the OpenFaaS gateway, default: openfaas

LICENSE

MIT

You can’t perform that action at this time.