-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal: define custom hostname for functions #1082
Comments
The DNS variant is probably the lowest hanging fruit? |
If I understand the suggestion correctly, the core of this implementation is to add a Given the above and reiterating some of what you said, I understand that we need to
Do we want to make this optional via a flag? I am a little worried about adding an additional call to the provider for every function invocation, even with caching. Do we always expect the gateway to always be deployed as single replica? If the replica count is increased, then it is possible that waiting for the cache to populate would really make the initial function invocations slow and if the usage is low enough or TTL long enough, this would then impact all function calls I am also worried about the cache invalidation. What happens when the function is re-deployed? What if someone is using the openfaas-operator? The gateway won't always see the deployment and could miss a cache invalidation event. For example, if the |
If you're worried about this, then I can't be doing a very good job of explaining it. Let me try to introduce a diagram to help. Users are unsure how to map I.e. We can make this easier for them to manage and have them just map it like this: I.e. Then when we detect the Host: header of pay.example.com (already present from the client's request) we can use that to match the correct function and route accordingly. |
Maybe URL is not the best representation of this feature, I would call it custom host name. |
I like the idea of having the ingress handle host name => gateway routing. And the diagram is really clear. My only concern is around the caching you originally mentioned. Would the simplest configuration be to allow the admin to pass a list of allowed host names and then allow matching functions as subdomains of those hosts? E.g. If we want to allow additional host to be added via annotations on functions this could simply be scrapped from the function and added to the list from the flags during gateway startup? You want it during gateway startup to ensure that it is up-to-date after a rolling deployment or if the container is rescheduled. Run it on a schedule in the background of the gateway and it would keep it up-to-date and allow HA deployments of the gateway. |
^ Yes 👍 Changed that to "custom hostname" Here's an example of what some users are doing today:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: api
namespace: openfaas
labels:
app: faas-netes
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /function/$1
nginx.ingress.kubernetes.io/proxy-body-size: "0"
certmanager.k8s.io/issuer: acme-issuer
spec:
tls:
- hosts:
- api.example.com
secretName: api-tls-certificate
rules:
- host: api.example.com
http:
paths:
- path: /(.*)
backend:
serviceName: gateway
servicePort: 8080
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: www-ingress
namespace: openfaas
labels:
app: faas-netes
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /function/www/$1
nginx.ingress.kubernetes.io/proxy-body-size: "0"
certmanager.k8s.io/issuer: acme-issuer
spec:
tls:
- hosts:
- example.com
secretName: www-tls-certificate
rules:
- host: example.com
http:
paths:
- path: /(.*)
backend:
serviceName: gateway
servicePort: 8080 Sample from Brian Woodward on Slack. I don't think this would go away, but it wouldn't have the path mappings anymore. |
This sounds pretty much like what I'm looking for but I'm curious as to why the Ingress points to the gateway service rather than directly at the functions service? My guess is it's something to do with the scale to zero behaviour? The way I had envisioned it was you have a function defined something like this: functions:
giving-page:
image: example/example:0.1
ingress:
host: giving-page.com When this is created in Kubernetes this code (https://github.com/openfaas/faas-netes/blob/master/handlers/deploy.go) would check for the presence of the I would prefer not to have it interpreted from annotations unless a strict schema is used such as |
I would suggest you have a look at how OpenFaaS Cloud works, it may be suitable for your use-case. A single ingress definition is created and points at the edge-router service. A wild-card DNS entry is then used to map and the edge-router creates the appropriate function URLs for invocations.
1-1 mapping between functions and Kubernetes Ingress records would not be practical for a number of reasons.
Typically when people create Ingress records they re-write the host path and point to the gateway. This is something that we are exploring above, but without the automatic creation and management of Ingress records. Ingress does not suit everybody and OpenFaaS does not target only a single platform. Ref: https://blog.alexellis.io/the-power-of-interfaces-openfaas/
|
Ah yes! This is actually all we need. Thanks! |
I've started some work on this and would love feedback: |
@alexellis Do you want feedback here on this issue or should I open issue on that repo? |
Slack would be ideal in the #kubernetes channel. |
The |
I've published a blog / tutorial that walks through this in more detail. https://www.openfaas.com/blog/custom-domains-function-ingress/ Would be good to get feedback from those users who needed this feature. |
What about async though? |
/lock: resolved through https://github.com/openfaas/ingress-operator |
Expected Behaviour
Within the function definition we should provide an alternative configuration for when someone wants to serve a website or api from a function such as:
Imagine a microservice/function named
giving-page
It would be exposed as per:
If a user would like a more user-friendly or custom URL than what they currently have by default
Cookies issued to
gw:port/function/name1
may also be accessible bygw:port/function/name2
, by allowing custom domains we can have more separation at the domain levelUser currently need to do this via an ingress path in Kubernetes or a custom configuration for their reverse proxy of choice.
This proposal would allow a custom domain to be routed such as:
The way we add arbitrary metadata to functions is via annotations, such as how we define topics for the connector SDK / triggers.
The gateway would look for a
Host
header, and if that matched a function queried via the/system/functions/
API (to be cached in-memory) then the traffic would be forwarded to the function using a proxy and any other gateway endpoints would not respond. i.e. you would not be able to callgiving-page.com/system/functions
for instance orgiving-page.com/ui
.A query and cache for
/system/functions
is already being built up and consumed whenscale_from_zero
is enabled on the gateway. It makes available a list of functions and how manyreadyReplicas
they have. This could be extended, or a single mechanism could populate this cache and a second cache.I don't think that multiple URLs (hosts) should be specified at this point, since they will point to the same function.
In production use, the user would still have to manage and configure DNS records and TLS certificates. This change would only be concerned with reverse-proxying requests to functions.
Current Behaviour
The text was updated successfully, but these errors were encountered: