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

Support for loading all rules in one command #7

Merged

Conversation

caseydavenport
Copy link
Contributor

@caseydavenport caseydavenport commented May 6, 2024

I've been working with knftables for prototyping Calico's nftables network policy implementation and have found it innefficient to list rules from each chain individually, where Calico usually wants to cache the full set of rules to more effeciently calculate diffs in future updates.

This change allows calls to ListRules without specifying a chain name to return the full set of rules in the table in a single call.

@k8s-ci-robot k8s-ci-robot added the cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. label May 6, 2024
@k8s-ci-robot k8s-ci-robot requested review from aojea and danwinship May 6, 2024 17:43
@k8s-ci-robot k8s-ci-robot added the size/S Denotes a PR that changes 10-29 lines, ignoring generated files. label May 6, 2024
@k8s-ci-robot k8s-ci-robot added size/M Denotes a PR that changes 30-99 lines, ignoring generated files. and removed size/S Denotes a PR that changes 10-29 lines, ignoring generated files. labels May 6, 2024
@caseydavenport
Copy link
Contributor Author

@danwinship @aojea hoping to get your thoughts on this one. I could also reasonably see this functionality being exposed through a different function on the interface (e.g., ListTable) if that's more appealing.

Comment on lines +304 to +308
if chain == "" {
cmd = exec.CommandContext(ctx, nft.path, "--json", "list", "table", string(nft.family), nft.table)
} else {
cmd = exec.CommandContext(ctx, nft.path, "--json", "list", "chain", string(nft.family), nft.table, chain)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

this seems a bit of a stretch for an API, since now it list chains and rules based on a special input

I'm not quite familiar with the implementation, @danwinship should know better, but does the other generic methods in this file List(ctx context.Context, objectType string) ([]string, error) or ListElements do not solve the problem?
If not, should we add a new method?

@danwinship
Copy link
Collaborator

this seems a bit of a stretch for an API

The List APIs are all kind of a mess anyway and at some point I want to redo all of them.

Though part of the reason I haven't yet is because I keep ending up not actually needing to use ListRules anyway, and feel like maybe it's an antipattern for nftables usage? (At least sometimes... it's generally better in nftables is to have mostly-static rules and dynamic sets/maps, and in that case, there's no need to do partial updates to the rules because there aren't many of them; if you think they're wrong, just overwrite all of them. Of course, kube-proxy doesn't currently live up to this ideal; it has static rules for the top-level services chain, but still has dynamic rules per-endpoint.)

But anyway, I don't object to this patch

Calico usually wants to cache the full set of rules to more effeciently calculate diffs in future updates.

Right. IPTables kube-proxy sort of does this too (nftables kube-proxy doesn't yet), but it doesn't bother with actually looking at the rules, it just computes diffs between "what I assume the rules must look like based on my previous state" and "what I want the rules to look like based on my current state", and does a partial update based on that, and if it fails, it just overwrites everything, ensuring the expected state will be correct next time. I'm expecting to do it the same way in the nftables backend.

(Of course, part of the reason iptables does it that way is because iptables-save is almost as slow as iptables-restore, so rewriting all of the rules from scratch isn't really any slower than doing a list followed by a small incremental update. I'm not sure how the timing works out in the nftables case.)

The other reason for not listing the rules is because it's sometimes hard to match up the rules as returned from nft list with the rules you actually created, whether due to version skew, canonical representation, nft optimizing your rules for you, etc. Though given how ListRules currently works in knftables I guess you're not looking at the actual rule text at all? (Though, on that note, would this be useful to you?)

@danwinship
Copy link
Collaborator

/approve
/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label May 7, 2024
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: caseydavenport, danwinship

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 May 7, 2024
@k8s-ci-robot k8s-ci-robot merged commit a1caefd into kubernetes-sigs:master May 7, 2024
5 checks passed
@caseydavenport
Copy link
Contributor Author

@danwinship thanks!

Though given how ListRules currently works in knftables I guess you're not looking at the actual rule text at all?

Yeah, that's right - Calico hashes its own "canonical" representation of the rule and stores that in a comment, so it can read back the comments and compare hashes to determine if a rule matches what it expects without caring that the actual rule text returned may not match.

and feel like maybe it's an antipattern for nftables usage

Yep, one of the things on my roadmap is to leverage maps more but for now I've largely been porting existing iptables patterns in order to get an MVP working quicker.

(Though, on that note, would this be useful to you?)

I am not immediately aware of a reason Calico would need that, but will let you know if that changes :)

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. size/M Denotes a PR that changes 30-99 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants