-
Notifications
You must be signed in to change notification settings - Fork 475
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
Research item: Multiple function namespaces for a single OpenFaaS installation #433
Comments
I like the idea of having this feature. From an operator point of view having to maintain a single OpenFaaS installation and still provide a more isolated environment for different teams/users is better than keeping up with multiple installations. How would this look like from a developer point of view? Will I have to specify the namespace on the yaml of the function, a label maybe? I'm not sure about how to implement this on a more pragmatic way, my knowledge of Kubernetes management is limited. But I will look into alternatives and let you know what I find. As a side note: this also aligns well with OpenFaaS Cloud. We will not only be isolating the routes of each user, but also separating where those functions live. |
As a starting-point we could start with statically provisioned SAs/RBAC and the ability to deploy to different namespaces, then after that look at how to automate it for other downstream projects like OpenFaaS Cloud. You would extend the helm chart with a new parameter like:
For user deployments perhaps using something like an annotation would be sufficient:
|
Matching 1:1 between namespace and stack.yml annotation name may not be ideal for larger systems because we can only support a group of "dev" for the first user that takes it. An alternative could be to use labels on the namespace to lookup a namespace:
|
I really like the idea of using labels on namespaces, but we need to ensure that we handle the case when labels arent unique. Even if it is accidental, surfacing the issue clearly will be important. |
I guess we might also have issues similar to those found with the use of labels before - it's a DNS-only name which is allowed, probably not much more permissive than the plain-old namespace name. |
What if we allow the admin to specify a file with a map of function annotations to namespaces? We could then use a config map to provide this map as via file and build faas-netes to watch if the file changes. This would still allow dynamic configuration and allow the use of any annotation on the function. When the file is loaded, we can validate it and log the errors to stdout and we could also track a metric of config errors, so that admins could alert on configuration errors, if they wanted. The current function namespace flag could be used as a default, when a function has no annotation. In theory, we could even allow a combination of annotations to be specified for a single namespace, e.g. We might consider adding a flag that requires all functions to have a specific annotation or set of annotations. I could even imagine a version of this for the openfaas-operator that is specified via a CRD, similar to how ingress are handled by the nginx-controller to construct a nginx config file. |
If we focus on how the controller would create deployments, there is a question I have. For faas-netes we don't use the watch API, so we have no additional cost of imperatively doing CRUD over N namespaces, even 100. With the Operator we would need all our watches duplicated per namespace - i.e. Pod/Deployment/Service x N namespaces, or would we be able to watch globally and filter down? |
We can use a global watch and filter the events based on a list of namespaces but that means the operator will need a ClusterRole. I think filtering is the easies way of doing this. |
Lister / Informer creation / binding: https://github.com/openfaas-incubator/openfaas-operator/blob/master/pkg/controller/controller.go#L88 Sync for specific namespace: |
From experience talking to OpenShift & enterprise users, I could imagine that a |
Another option would be to deploy one operator per namespace |
In that model I guess it would look a lot like multiple OpenFaaS installations, but we could configure it to share Prometheus/NATS to reduce the footprint. We need to find out how much of a deal-breaker |
To avoid a ClusterRole, couldn't we use a single operator with multiple RoleBindings to access multiple namespaces. The admin could then choose to give openfaas access to the whole cluster or only a subset of namespaces. In the second case, we simply need to make sure we surface the error in a nice way to the user, when the function can not be deployed because a namespace does not exist or is not accessible. |
That would cover the RBAC, but how would the Lister/Informers work? #433 (comment) |
It is possible to create the informers with a namespace, e.g. https://godoc.org/k8s.io/client-go/informers#SharedInformerOption But it isn't clear that it is needed because we don't currently restrict the namespace of the informer. The listener does set a namespace, but this is done on the fly inside |
What if we had Prometheus/NATS and etc in a core/system namespace, and then one operator with a finite scope and |
If the OpenFaaS is meant to be a platform service, I would be inclined to give it a ClusterRole as an operator but from OpenFaaS point of view, I think it should not matter. In the end, if we have the ability to deploy a function in a specific namespace the operator will decide if they want to give a Role or a ClusterRole to the OpenFaaS installation and this is the functionality that I will try to contribute to the chart. So in my opinion the chart might offer three options:
|
Here's me invoking functions in different namespaces Changes I made:
Other limitations:
|
I have drafted a diagram which I also shared on Slack in the #kubernetes channel. There are some comments from the community in the channel which will be lost due to limits of the free tier of Slack. Some people have expressed that they would like to see a new URL scheme to access functions in a non-default namespace such as The I think the change should focus on the smallest possible change domain, but I am open to adding additional vanity URLs if those requesting them are prepared to estimate, carry out and maintain the changes on an ongoing basis. Some concerns I've heard are:
As per my diagram, you can use
This could be covered by an additional vanity URL, however it isn't practical to make huge breaking changes to every component in the stack to work on a new URL scheme. There is a difference between the way internal components interact with the system and how you serve content to your users. Here is where I want to set the scope of the work. This issue is about enabling the multi-namespace use-case, rather than building a multi-tenant system. Multiple namespaces can be used for: projects, environments (staging/e2e/prod), teams, integration testing, and to some extent, tenants. Multiple tenants requires more than a URL scheme, it requires changes for authz deep into the stack. For the work on multi-tenancy see OpenFaaS Cloud comparison grid. |
I am a strong believer in remote development, where each developer has access to its personal namespace. This way, developers can share cluster services like logs aggregators, metrics, service mesh... the OpenFaaS installation would a great example of this scenario. |
@pchico83 I think this is out of scope for the current PR, which is more of a technical discussion on accessing multiple namespaces. OpenFaaS Cloud holds the multi-user story that you're referring to and we've chosen to replace the API with |
I have a question about how the functions in different namespaces are intended to be deployed. Is it possible to either change the name through the cli when deploying from the My main concern is if this is intended to be used for staging deployments, I don't want to edit my To implement that, I would propose adding a The other option is to use multiple Also, in Slack, I liked the idea of having a URI scheme as |
I've opened #511 to track the work required and its progress. |
Tested this, works fine. @alexellis |
In order to support use-cases like the event-connectors, which must traverse all functions to know which expose a topic, and the UI where users may want to get an overview of what is deployed, or the CLI where users need the same, I would suggest the following:
Then "list all" becomes 1 + N API calls:
Even if we don't want to have this kind of a chatty interface, it has to happen somewhere, given the way the Kubernetes clientset works. An alternative is that "list all" becomes the default mode of the @johnmccabe @stefanprodan @LucasRoesler I'd like your input on this please. |
I don't mind having a Not sure if we reached a consensus between the two propositions already? If so, I believe before touching the UI/CLI we need to introduce the endpoints/filter the namespaces, I can try to jump in with that. |
This sounds like a fantastic feature. I see the latest updates to the related feature ticket 511 were in December. Any update on the status of this feature? |
This issue shouldn't be open any more because it has been released. Regarding the update, that's not strictly correct. Checkout the documentation if you'd like to know more https://docs.openfaas.com |
/lock: completed |
For anyone landing here in 2021, there is already a link to the docs. Here's a deep link: https://docs.openfaas.com/reference/namespaces/ |
Description
Multiple function namespaces for a single OpenFaaS installation #433
Expected Behaviour
The behaviour would allow functions to be deployed to N different namespaces, perhaps one per user or team.
Current Behaviour
Either one installation per team or user or use a different mechanism for grouping functions such as prefixes and annotations/labels as in OpenFaaS Cloud.
Possible Solution
The solution would need additional RBAC permissions - potentially to even create new namespaces in the cluster making faas-netes effectively a cluster admin. This is unlikely to be a viable configuration for restrictive environments.
I'm open to suggestions on implementation that are pragmatic when it comes to more restrictive environments.
The text was updated successfully, but these errors were encountered: