Skip to content
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

Create NPEP-122 for Tenancy API update. #123

Merged
merged 1 commit into from
Nov 6, 2023

Conversation

npinaeva
Copy link
Member

@npinaeva npinaeva commented Jul 11, 2023

Change Tenancy implementation from SameLabels/NotSameLabels ANP peers to a separate object
that will define Tenancy considering subject and peers are related.

Tracking issue #122

@k8s-ci-robot k8s-ci-robot added the cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. label Jul 11, 2023
@netlify
Copy link

netlify bot commented Jul 11, 2023

Deploy Preview for kubernetes-sigs-network-policy-api ready!

Name Link
🔨 Latest commit 310e46a
🔍 Latest deploy log https://app.netlify.com/sites/kubernetes-sigs-network-policy-api/deploys/654959808c3764000881fb9c
😎 Deploy Preview https://deploy-preview-123--kubernetes-sigs-network-policy-api.netlify.app/npeps/npep-122
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@k8s-ci-robot k8s-ci-robot added the needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. label Jul 11, 2023
@k8s-ci-robot
Copy link
Contributor

Hi @npinaeva. Thanks for your PR.

I'm waiting for a kubernetes-sigs member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@k8s-ci-robot k8s-ci-robot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Jul 11, 2023
@npinaeva
Copy link
Member Author

/ok-to-test

@k8s-ci-robot k8s-ci-robot added ok-to-test Indicates a non-member PR verified by an org member that is safe to test. and removed needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. labels Jul 18, 2023
Copy link
Member

@astoycos astoycos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still working through this but I've got the review mostly done.

npep/npep-122.md Outdated Show resolved Hide resolved
npep/npep-122.md Outdated Show resolved Hide resolved
npep/npep-122.md Outdated Show resolved Hide resolved
npep/npep-122.md Outdated Show resolved Hide resolved
npep/npep-122.md Outdated Show resolved Hide resolved
npep/npep-122.md Outdated Show resolved Hide resolved
npep/npep-122.md Outdated Show resolved Hide resolved
npep/npep-122.md Outdated Show resolved Hide resolved
npep/npep-122.md Outdated Show resolved Hide resolved
npep/npep-122.md Outdated Show resolved Hide resolved
npep/npep-122.md Outdated
> ns5{label1=_, label2=_}
> ns6{label1=A, label2=B}
> ```
> where `_` means the label is not set, and `""` means empty string value.
Copy link
Contributor

@Dyanngg Dyanngg Jul 25, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can touch upon naming later but I just what to point out that, this categorization of tenants is quite different than our original sameLabels proposal, where namespaces who do not have the tenancy label at all (as opposed to have an empty label) are not affected by the policy.
When I read the tenancyLabels field, it is supposed to mean "namespaces that have the exact same values for these labels are considered a single tenant", but it does not and should not IMO imply that, namespaces who are missing this label automatically form a tenant by themselves

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Current design is supposed to be more explicit on which namespaces should be affected, and also allow different configurations. So if you don't want namespace without a "tenancy label" to be affected, you just add
key: <tenancy label>, operator: Exists to the spec.namespaceSelector. But at the same time if you do want to make a separate tenant for all namespaces without that label you leave empty selector.

Also I think tenancyLabels does exactly what you said: "namespaces that have the exact same values for these labels are considered a single tenant", because all namespaces with empty label will be one tenant, and all namespaces without a label (say they all have None value for it) will be one tenant. And you can easily avoid namespaces with unset labels as I pointed above.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could alternatively say that namespaces without all of the tenancyLabels are always excluded from the definition. IOW, namespaceSelector automatically implicitly includes key: X, operator: Exists for every label in tenancyLabels

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can do that, but I see 2 possible disadvantages to this:

  • namespaceSelector doesn't fully define which namespaces will be selected, so we add an implicit label selector key: X, operator: Exists and it makes the API more confusing
  • there is no way to set rules for namespaces with label unset: e.g. if I want to deny-from-not-same-tenant, I may want to deny from not only namespaces with different label value, but also from namespaces without a label, otherwise forgetting to set a label on a namespace may become a security hole, because it won't be affected by tenancy.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO I would like to merge if we agree on the "goals section" the actual API implementation should be hashed out in another PR to this NPEP.

npep/npep-122.md Outdated Show resolved Hide resolved
npep/npep-122.md Outdated Show resolved Hide resolved
npep/npep-122.md Outdated Show resolved Hide resolved
npep/npep-122.md Outdated Show resolved Hide resolved
npep/npep-122.md Outdated
> ns5{label1=_, label2=_}
> ns6{label1=A, label2=B}
> ```
> where `_` means the label is not set, and `""` means empty string value.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could alternatively say that namespaces without all of the tenancyLabels are always excluded from the definition. IOW, namespaceSelector automatically implicitly includes key: X, operator: Exists for every label in tenancyLabels

npep/npep-122.md Outdated Show resolved Hide resolved
npep/npep-122.md Outdated Show resolved Hide resolved
Copy link
Member

@astoycos astoycos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good! I really like the way you explicitly laid out the issues with the existing implementation. I'm planning on lgtm(ing) this KEP without focusing too hard on the actual "API" section as I Think that should be completed in another PR. Let's try to build consensus around the updated user stories and various issues you pointed out in the existing implementation first.

npep/npep-122.md Outdated Show resolved Hide resolved
npep/npep-122.md Outdated Show resolved Hide resolved
npep/npep-122.md Outdated Show resolved Hide resolved
npep/npep-122.md Outdated Show resolved Hide resolved
npep/npep-122.md Outdated Show resolved Hide resolved
npep/npep-122.md Outdated Show resolved Hide resolved
npep/npep-122.md Outdated Show resolved Hide resolved
npep/npep-122.md Outdated
> ns5{label1=_, label2=_}
> ns6{label1=A, label2=B}
> ```
> where `_` means the label is not set, and `""` means empty string value.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO I would like to merge if we agree on the "goals section" the actual API implementation should be hashed out in another PR to this NPEP.

npep/npep-122.md Outdated Show resolved Hide resolved
@npinaeva npinaeva force-pushed the npep-tenancy branch 2 times, most recently from e5c1e3b to 6f99ef0 Compare August 16, 2023 09:24
@npinaeva
Copy link
Member Author

As discussed in the upstream meeting, this version is focused on user stories now, which led me to writing down even more user stories, and also covering existing API fields that I couldn't figure out user stories for.
Since the main problem of the existing API is covering much more configs that we actually have user stories for, we probably shouldn't include fields that we don't have user stories for in the next Tenancy API.

npep/npep-122.md Outdated Show resolved Hide resolved
npep/npep-122.md Outdated Show resolved Hide resolved
npep/npep-122.md Outdated

First, There is no explicit definition of "tenancy" anywhere. The administrator has an idea of
"tenants are defined by the user label", but that's only true because this particular ANP happens to include that
particular rule, and there's no way to find the ANP(s) that defines tenancy if you don't already know what they are.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While this is true, I'm not sure this is a huge problem unique to tenancy. I could make a parallel argument for something like egress rules: There's no way to find the ANP(s) that define egress if you don't already know what they are.

I would argue that this is a problem easily solved by a good naming scheme (e.g. call my ANP "tenant-policy" or "namespace-isolation"). Easy discoverability of a particular type of rule shouldn't be a top-priority for our design, in my opinion.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very valid point, I don't think this is the major problem, but more of an introduction to the following points, just stressing that tenants are different from the other peer types. As you said, if you want to define a tenant, you will probably create a separate ANP with a single tenancy rule and a tenancy-specific name, but that is not dictated by the API, and tenancy may easily be lost in a list of other peers.

npep/npep-122.md Outdated Show resolved Hide resolved
npep/npep-122.md Outdated Show resolved Hide resolved
npep/npep-122.md Outdated Show resolved Hide resolved
npep/npep-122.md Outdated
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.

#### Story 4.3: Allow internal connections for tenants
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hrm this one seems a bit duplicative to the "create and isolate" stories to me...

More specifically...

At the same time I want to setup an overridable deny-all policy to protect namespaces by default.
This policy should make sure internal connectivity for a tenant is always allowed, in case there are
lower-priority deny rules.

In this case (thinking in terms on ANP) you'd use an ANP to setup the tenants... and that ANP would implicity be a "higher-order" policy meaning even with an "overridable deny-all policy" traffic within tenants would always be allowed unless explicitly denied with another ANP or "passed" to namespace owners

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is very similar indeed, but the difference is in the action: "Isolate" user story is focused on the Deny tenancy rules, and "Allow internal connections for tenants" is more about Allow tenancy rules. Maybe they are too similar, lmk if you think I should remove this one

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Isolate" user story is focused on the Deny tenancy rules, and "Allow internal connections for tenants" is more about Allow tenancy rules.

IMO this is somewhat implicit in:

As a cluster admin, I want to build tenants in my cluster that are isolated from each other where this isolation
    can't be overridden by namespace owners.

i.e we're building hard tenants where the definition is tenants can't talk to each other but members of a tenant are of one group, and can communicate.

If you want to augment 4.2 to explicitly mention something like that I think that'd be alright, but I think Dan and I agree here so I'd remove 4.3

   As a cluster admin, I want to build tenants in my cluster that are isolated from each other where this isolation
    can't be overridden by namespace owners. This policy should make every tenant completely independent and isolated 
    from another tenants, while explicitly allowing same tenant members to communicate.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let me try to explain this once again, because I don't think we are talking about the same use case

4.2 story just denies inter-tenant communication, but doesn't say anything about intra-tenant communication, e.g. you could write "deny from the other tenants" ANP, and at the same time define a NP in namespace A saying "deny from namespace B", where namespaces A and B are in the same tenant. That would limit intra-tenant communication, and ANP doesn't say anything about that, so traffic from namespace B will be dropped.

4.3 use case is aimed to prevent namespaces in the same tenant from denying each others connections (e.g. by applying any network policy and by mistake not including your tenant namespaces to the allow list). In that case even if same namespace A applies a "deny from ALL" network policy, namespace B will still be allowed by ANP.

I just want to make sure I've explained the use cases well enough, and then we can surely remove any extra parts or whole user stories.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4.3 use case is aimed to prevent namespaces in the same tenant from denying each others connections

Is that a real use case? Why would an administrator want to enforce that for every tenant at the cluster level?

4.1 is "Engineering vs Marketing" and 4.2 is "Coke vs Pepsi". What is the explanation for this user story?

(Also, you should probably actually put "Engineering vs Marketing" and "Coke vs Pepsi" into the actual user stories. The user story should stand alone to explain the use case. We shouldn't have the user story and also have a separate "here's what this really means". And in this case (4.3), I don't think there is any "here's what this really means".)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think 4.3 is the Engineering vs Engineering, meaning that after you defined Engineering vs Marketing tenants, you still may want to strictly define intra-tenant rules. e.g. you may have a strong policy where every engineering team should be always able to talk to all the other engineering teams. That prevents one engineering team from building its own room and closing the door so that other engineers can't talk to them anymore (also potentially by mistake when defining some deny-all rule).

I am not sure how to say if this is a more or less real use case compared to the previous ones.

npep/npep-122.md Outdated Show resolved Hide resolved
npep/npep-122.md Outdated Show resolved Hide resolved
npep/npep-122.md Outdated Show resolved Hide resolved
@shaneutt
Copy link
Member

/cc

@k8s-ci-robot k8s-ci-robot requested a review from shaneutt August 29, 2023 16:08
npep/npep-122.md Outdated Show resolved Hide resolved
npep/npep-122.md Outdated Show resolved Hide resolved
npep/npep-122.md Outdated Show resolved Hide resolved
npep/npep-122.md Outdated
Comment on lines 80 to 81
As a cluster admin, I want to build tenants in my cluster that are isolated from each other and this can't
be overridden. This policy should make every tenant completely independent and isolated from another tenants.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
As a cluster admin, I want to build tenants in my cluster that are isolated from each other and this can't
be overridden. This policy should make every tenant completely independent and isolated from another tenants.
As a cluster admin, I want to build tenants in my cluster that are isolated from each other where this
isolation can't be overridden by the tenants themselves. This policy should make every tenant completely independent and isolated from another tenants.

(because the admin could still override the isolation with ANPs)

alternatively "where the isolation can't be overridden by NetworkPolicy". Actually, that might be a good way to describe both the previous case and this one; the previous case is where the tenant isolation can be overridden by NetworkPolicy and this case is where it can't be.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point! I made it "namespace owners" just based on the first user story wording, lmk if you prefer some other name for that actor :)

npep/npep-122.md Outdated
As a cluster admin, I want to build tenants in my cluster and always allow connections inside one tenant.
At the same time I want to setup an overridable deny-all policy to protect namespaces by default.
This policy should make sure internal connectivity for a tenant is always allowed, in case there are
lower-priority deny rules.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree with Andrew; I'm not exactly sure what this one is saying. It sounds like you're saying the admin wants to forbid users from using NP within a tenant

npep/npep-122.md Outdated Show resolved Hide resolved
npep/npep-122.md Outdated
#### What I couldn't figure our user stories for

- Skip action
- Ports *[]AdminNetworkPolicyPort
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I don't think there's a good argument for using ports in tenant definitions.

npep/npep-122.md Outdated

- Skip action
- Ports *[]AdminNetworkPolicyPort
- Multiple tenant policies (e.g. based on different labels?)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we want to make this a Non-Goal. The existing KEP allows for having lots of rules with different SameLabels/NotSameLabels doing different things, but the user stories all involve having a single cluster-wide definition of "tenancy".

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if I got that right, but I added "define user stories for multiple tenancy policies in the same cluster" as a non-goal

npep/npep-122.md Outdated Show resolved Hide resolved
npep/npep-122.md Outdated Show resolved Hide resolved
npep/npep-122.md Outdated Show resolved Hide resolved
npep/npep-122.md Outdated Show resolved Hide resolved
Copy link
Member

@astoycos astoycos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/lgtm
/hold

This is ready to go from my side (minus these small nit's and comments) I added /lgtm and I'll let either @danwinship or @Dyanngg Finish this with and approval + removal of the hold. Thanks @npinaeva

npep/npep-122.md Outdated Show resolved Hide resolved
npep/npep-122.md Outdated Show resolved Hide resolved
npep/npep-122.md Outdated Show resolved Hide resolved
npep/npep-122.md Outdated
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.

#### Story 4.3: Allow internal connections for tenants
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Isolate" user story is focused on the Deny tenancy rules, and "Allow internal connections for tenants" is more about Allow tenancy rules.

IMO this is somewhat implicit in:

As a cluster admin, I want to build tenants in my cluster that are isolated from each other where this isolation
    can't be overridden by namespace owners.

i.e we're building hard tenants where the definition is tenants can't talk to each other but members of a tenant are of one group, and can communicate.

If you want to augment 4.2 to explicitly mention something like that I think that'd be alright, but I think Dan and I agree here so I'd remove 4.3

   As a cluster admin, I want to build tenants in my cluster that are isolated from each other where this isolation
    can't be overridden by namespace owners. This policy should make every tenant completely independent and isolated 
    from another tenants, while explicitly allowing same tenant members to communicate.

npep/npep-122.md Outdated Show resolved Hide resolved
@k8s-ci-robot k8s-ci-robot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Oct 13, 2023
@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Oct 13, 2023
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: astoycos, npinaeva

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Oct 13, 2023
@k8s-ci-robot k8s-ci-robot removed the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Oct 16, 2023
npep/npep-122.md Outdated Show resolved Hide resolved
npep/npep-122.md Outdated Show resolved Hide resolved
npep/npep-122.md Outdated
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.

#### Story 4.3: Allow internal connections for tenants
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4.3 use case is aimed to prevent namespaces in the same tenant from denying each others connections

Is that a real use case? Why would an administrator want to enforce that for every tenant at the cluster level?

4.1 is "Engineering vs Marketing" and 4.2 is "Coke vs Pepsi". What is the explanation for this user story?

(Also, you should probably actually put "Engineering vs Marketing" and "Coke vs Pepsi" into the actual user stories. The user story should stand alone to explain the use case. We shouldn't have the user story and also have a separate "here's what this really means". And in this case (4.3), I don't think there is any "here's what this really means".)

npep/npep-122.md Outdated Show resolved Hide resolved
npep/npep-122.md Outdated Show resolved Hide resolved
npep/npep-122.md Outdated Show resolved Hide resolved
@danwinship
Copy link
Contributor

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Nov 6, 2023
@danwinship
Copy link
Contributor

/hold cancel

@k8s-ci-robot k8s-ci-robot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Nov 6, 2023
@k8s-ci-robot k8s-ci-robot removed the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Nov 6, 2023
@astoycos
Copy link
Member

astoycos commented Nov 6, 2023

/lgtm

🍾

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Nov 6, 2023
@k8s-ci-robot k8s-ci-robot merged commit cd92d6e into kubernetes-sigs:main Nov 6, 2023
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. lgtm "Looks good to me", indicates that a PR is ready to be merged. ok-to-test Indicates a non-member PR verified by an org member that is safe to test. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
Development

Successfully merging this pull request may close these issues.

7 participants