Grab free TLS & Custom Domains for your Functions with FunctionIngress
With OpenFaaS, you get a URL for every function by convention which is great and suits many people. This guide shows you how to get a Custom Domain along with a free TLS cert for your functions using the new FunctionIngress concept.
July 29, 2019
Community
End-user
Ingress
Production
Kubernetes
Find out how you can expand beyond the default URL given to each function in OpenFaaS with the new FunctionIngress CRD.
In this tutorial I’ll show you how to use the new FunctionIngress Custom Resource Definition (CRD) along with a new Kubernetes Operator to get Custom Domains for any OpenFaaS function deployed on Kubernetes.
How it works
First of all, we install the new Kubernetes Operator called “IngressOperator”. This Operator is responsible for translating CRD entries called FunctionIngress into two separate resources in the cluster: an Ingress definition and a TLS Certificate. The TLS Certificate is optional, and created by cert-manager by adding special annotations to the generated Ingress definition.
I built the IngressOperator to automate some of the tasks end-users of the project were using to deploy pretty-URLs for their static websites, APIs and functions with OpenFaaS. The first time I wrote about the Operator was in the Insiders Update for 2019-07-05.
Tutorial
To run through the tutorial, you will need to have some software set up already and a Kubernetes cluster with a public LoadBalancer service. If your Kubernetes services does not have a public LoadBalancer, install the IngressController using host ports.
Pre-reqs
Kubernetes
You need to have a Kubernetes cluster. I recommend using DigitalOcean Kubernetes for an easy and cost-efficient set-up.helm
You’ll need helm for most of the components we are using. If you are allergic to helm’s server-side component called “tiller”, then don’t worry. You can simply use the “helm template” command to generate plain YAML files.OpenFaaS via helm
Install OpenFaaS via helmThe IngressController
Nginx, Traefik and Zalando’s Skipper are currently supported, if you have a request for another controller, then raise an issue.
In this tutorial I’ll be using Nginx, install with the following:
helm install stable/nginx-ingress --name nginxingress --set rbac.create=true
- cert-manager (optional)
Using TLS is optional, but highly recommended and I will be setting it up today.
Follow the steps for “Install cert-manager” and “Configure cert-manager” from the OpenFaaS documentation here.
Deploy IngressOperator
We’ll now deploy the IngressOperator.
You’ll need to find your values.yaml file for the OpenFaaS Helm chart, then add:
ingressOperator:
create: true
Then run a helm upgrade --install as per the Helm chart README.
Create a static website
We can use the Nginx static website template to create a function or microservice. Once deployed, we’ll move on to creating its custom domain name entry and then a CRD entry for it.
export OPENFAAS_PREFIX=alexellis2
faas template pull https://github.com/alexellis/static-site-template
faas new --lang static-site-nginx my-homepage --prefix ${OPENFAAS_PREFIX}
Set OPENFAAS_PREFIX with your own Docker Hub username, or private registry address and repo.
Create the homepage:
echo "<html>Hello world</html>" > ./my-homepage/index.html
The following will build a container image, push it to the remote registry and then deploy it to OpenFaaS, resulting in a static website.
faas-cli up -f my-homepage.yml
Your traditional URL will appear on:
faas-cli describe -f my-homepage.yml my-homepage
Name: my-homepage
Status: Ready
Replicas: 1
Available replicas: 0
Invocations: 0
Image: alexellis2/my-homepage:latest
Function process:
URL: http://206.189.242.89:8080/function/my-homepage
Async URL: http://206.189.242.89:8080/async-function/my-homepage
Labels: faas_function : my-homepage
We’ll now create a DNS entry and then the custom hostname mapping and TLS certificate along with that.
Create a DNS A record for your sub-domain
My testing domain is myfaas.club and it cost me a very minimal amount of money from namecheap.com. I can create sub-domains for each function, or for any testing that I do. If you are familiar with DNS-management, then create an A record for the IP address of the LoadBalancer created by Nginx.
kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginxingress-nginx-ingress-controller LoadBalancer 10.245.169.18 178.128.137.209 80:32126/TCP,443:30028/TCP 32d
You can see my external IP listed as 178.128.137.209.
As a DigitalOcean customer, I can now use the DigitalOcean UI or CLI to create a DNS A record for 178.128.137.209. Here is an example using the doctl CLI:
doctl compute domain create my-homepage.myfaas.club --ip-address 178.128.137.209
Domain TTL
my-homepage.myfaas.club 0
Map the Custom Domain with a FunctionIngress
Now we will map the Custom Domain to the function using a FunctionIngress definition.
Save the following in a YAML file my-homepage-fni.yaml:
apiVersion: openfaas.com/v1
kind: FunctionIngress
metadata:
name: my-homepage-tls
namespace: openfaas
spec:
domain: "my-homepage.myfaas.club"
function: "my-homepage"
ingressType: "nginx"
tls:
enabled: true
issuerRef:
name: "letsencrypt-prod"
kind: "Issuer"
- For the
nameI used a convention of the function’s name plus a suffix of-tlsif using TLS. - Edit the
domainto point as your own DNS A record or sub-domain. - For the
issuerRef, you can use the-stagingor-prodissuer which you set up earlier using the OpenFaaS docs.
Now apply the file with kubectl apply -f my-homepage-fni.yaml
Check what happened
We already have a URL to access our static website, but after having created the FunctionIngress, we’ll get a HTTPS URL too.
This is what happens:
- The CRD is detected and an Ingress record is created
- The Ingress record is decorated with information about TLS
- CertManager detects the TLS information using something called IngressShim
- CertManager creates the TLS certificate
Check the ingress:
kubectl get ingress -n openfaas
NAME HOSTS ADDRESS PORTS AGE
my-homepage-tls my-homepage.myfaas.club 167.71.8.102 80, 443 46s
Now check the certificate:
kubectl get cert -n openfaas
NAME READY SECRET AGE
my-homepage-tls-certificate true my-homepage-tls-certificate-secret 2m37s
Note, if it appears as “Not Ready” for a long time, you can debug it with: kubectl describe cert/my-homepage-tls-certificate -n openfaas
The objects above were created automatically, so they will be deleted or edited if you delete or edit the FunctionIngress custom resource.
You can find out what happened inside the Operator by checking its logs:
kubectl logs -n openfaas deploy/ingress-operator
Try out your brand new Custom Domain
Congratulations! You can now create Custom Domains for any of your functions or microservices deployed with OpenFaaS, and add TLS too.
Changing versions
We can now create a dedicated URL for anything we deploy through OpenFaaS. There’s nothing to stop you deploying multiple names for the same function to create an alias or versioned endpoint.
If we were to deploy a new version of our function (my-homepage-v2), we could deploy a new FunctionIngress record, or simply edit the object in Kubernetes via kubectl. The result is that the Ingress record will be edited to point at the new function without deleting or re-issuing a new Certificate.
apiVersion: openfaas.com/v1
kind: FunctionIngress
metadata:
name: my-homepage-tls
namespace: openfaas
spec:
domain: "my-homepage.myfaas.club"
function: "my-homepage-v2"
ingressType: "nginx"
tls:
enabled: true
issuerRef:
name: "letsencrypt-prod"
kind: "Issuer"
Connect & Learn
I hope you enjoyed the tutorial for the IngressOperator and FunctionIngress CRD. In the next post the community will show you how to combine this blog post with OpenFaaS Cloud and a template for Hugo to generate static websites from markdown. This would be great for hosting documentation, blogs and much more.