generated from kubernetes/kubernetes-template-project
-
Notifications
You must be signed in to change notification settings - Fork 34
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Create NPEP-122 for Tenancy API update.
Signed-off-by: Nadia Pinaeva <[email protected]>
- Loading branch information
Showing
1 changed file
with
174 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,174 @@ | ||
# NPEP-122: NPEP template | ||
|
||
* Issue: [#122](https://github.com/kubernetes-sigs/network-policy-api/issues/122) | ||
* Status: Implementable | ||
|
||
## TLDR | ||
|
||
Change Tenancy implementation from SameLabels/NotSameLabels ANP peers to a separate object | ||
that will define Tenancy considering subject and peers are related. | ||
|
||
## Goals | ||
|
||
- Clarify tenancy use cases | ||
- Define what a Tenant is | ||
- Separate ANP subject from Tenancy subject/peer | ||
|
||
## Non-Goals | ||
|
||
- extend Tenancy API | ||
|
||
## Introduction | ||
|
||
The KEP doesn’t say a whole lot about tenants… | ||
|
||
From the Goals: | ||
|
||
As a cluster administrator, I want to have the option to enforce in-cluster network level access controls that | ||
facilitate network multi-tenancy and strict network level isolation between multiple teams and tenants sharing | ||
a cluster via use of namespaces or groupings of namespaces per tenant. | ||
|
||
Example: I would like to define two tenants in my cluster, one composed of the pods in foo-ns-1 and foo-ns-2 | ||
and the other with pods in bar-ns-1, where inter-tenant traffic is denied. | ||
|
||
From the User Stories: | ||
|
||
Story 4: Create and Isolate multiple tenants in a cluster | ||
|
||
As a cluster admin, I want to build tenants in my cluster that are isolated from each other by default. | ||
Tenancy may be modeled as 1:1, where 1 tenant is mapped to a single Namespace, or 1:n, where a single tenant | ||
may own more than 1 Namespace. | ||
|
||
Elsewhere: | ||
|
||
AdminNetworkPolicy Pass rules allows an admin to delegate security posture for certain traffic to the Namespace | ||
owners by overriding any lower precedence Allow or Deny rules. For example, intra-tenant traffic management can be | ||
delegated to tenant admins explicitly with the use of Pass rules. | ||
|
||
So really, the only solidly-agreed-upon use case is that either you should be able to create enforced isolation | ||
between particular sets of namespaces. | ||
|
||
### What we currently have | ||
|
||
AdminNetworkPolicy has the “SameLabels” and “NotSameLabels” fields to support the use cases involving tenancy. For example: | ||
|
||
**User story** | ||
|
||
Traffic should be disallowed by default between user namespaces owned by different users. | ||
|
||
**Policy** | ||
``` | ||
kind: BaselineAdminNetworkPolicy | ||
apiVersion: policy.networking.k8s.io/v1alpha1 | ||
metadata: | ||
name: user-based-tenancy | ||
spec: | ||
subject: | ||
namespaces: | ||
matchExpressions: | ||
- key: user | ||
operator: Exists | ||
ingress: | ||
- action: Deny | ||
from: | ||
- namespaces: | ||
notSameLabels: | ||
- user | ||
``` | ||
|
||
**Meaning** | ||
|
||
In namespaces that have a “user” label, by default, deny ingress from namespaces that have a different “user” label. | ||
|
||
There are two problems with this implementation of tenancy, relative to the user stories that it exists to support | ||
|
||
First, it never explicitly defines what a tenant is. Although the object correctly implements the desired tenancy | ||
policy, it doesn’t really make it obvious that that’s what it’s doing. | ||
|
||
Second, the syntax is very general purpose / powerful. ANP has subjects and peers, which are different, | ||
and currently Tenancy is defined on the peers side. Tenancy by itself has the same subject and peer, | ||
at least for the existing use cases, and having separate selectors for subject and peer allows for more | ||
configurations than needed. | ||
|
||
## API | ||
|
||
We suggest to define a separate API for tenancy, as in the following example: | ||
|
||
``` | ||
kind: AdminNetworkPolicyTenancy | ||
apiVersion: policy.networking.k8s.io/v1alpha1 | ||
metadata: | ||
name: user-based | ||
spec: | ||
namespaceSelector: | ||
matchExpression: | ||
- key: system-namespace | ||
operator: DoesNotExist | ||
- key: user | ||
operator: Exists | ||
tenancyLabels: | ||
- user | ||
priority: 99 | ||
ingress: | ||
- action: Deny | ||
from: | ||
- NotSameTenant | ||
``` | ||
|
||
that will define a tenant as follows: | ||
- first, select namespaces that will be split into tenants, and have the defined policy applied. `spec.namespaceSelector` | ||
is used for this purpose. This also solves the problem we had for empty or unset labels: if tenancy is defined based on label `user`, | ||
and namespaces without this label should not be affected, `key: user, operator: Exists` selector can be used. | ||
- second, selected namespaces are split into tenants based on label values, `spec.tenancyLabels` field is used for that purpose. | ||
Tenants with the same listed label values will form a tenant. Unset label and empty string label are also values, therefore | ||
in case namespaces with these label values are selected, they will be split into a separate tenant. | ||
|
||
> Example: say we define a tenancy based on `label1` and `label2`, and the following namespaces are selected by `spec.namespaceSelector` | ||
> ``` | ||
> ns1{label1=A, label2=B, label3=C} | ||
> ns2{label1=A, label2=B, label4=D} | ||
> ns3{label1=_, label2=B} | ||
> ns4{label1=_, label2=""} | ||
> ns5{label1=_, label2=_} | ||
> ns6{label1=A, label2=B} | ||
> ``` | ||
> where `_` means the label is not set, and `""` means empty string value. | ||
> | ||
> The following tenants will be created for `tenancyLabels: [label1, label2]` | ||
> ``` | ||
> tenant{label1=A, label2=B} = [ns1, ns2, ns6] | ||
> tenant{label1=_, label2=B} = [ns3] | ||
> tenant{label1=_, label2=""} = [ns4] | ||
> tenant{label1=_, label2=_} = [ns5] | ||
> ``` | ||
|
||
- third, define policy rules. This includes setting ports, action, and peer tenants. | ||
For now, we only have `SameTenant` and `NotSameTenant` as a peer option. | ||
|
||
**Note** with the new tenancy definition there is no need to have `sameLabels` and `notSameLabels`, because | ||
these selectors will define the same tenants, but it is replaces with `SameTenant` and `NotSameTenant` for similar use cases. | ||
|
||
Existing API allows defining tenancy for BANP, we need to decide if the tenancy actually makes sense for that priority. | ||
BANP is overridable by the namespace owners, so the question is if there is a use case for a tenancy policy that can be | ||
overridden? | ||
|
||
## Conformance Details | ||
|
||
TBD | ||
<!--- | ||
(This section describes the names to be used for the feature or | ||
features in conformance tests and profiles. | ||
These should be `CamelCase` names that specify the feature as | ||
precisely as possible, and are particularly important for | ||
Extended features, since they may be surfaced to users.) | ||
--> | ||
|
||
## Alternatives | ||
|
||
Other alternatives were mentioned https://docs.google.com/document/d/113xBe7VMK7hMYdIdB9gobp7JwVkWQLnqdMPNkamfaK8/edit, | ||
but none of them covers all the Goals defined in this NPEP. | ||
|
||
## References | ||
|
||
- https://docs.google.com/document/d/113xBe7VMK7hMYdIdB9gobp7JwVkWQLnqdMPNkamfaK8 |