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

Fix failing test "Services should only allow access from service loadbalancer source ranges" #94591

Merged
merged 1 commit into from
Oct 16, 2020

Conversation

Lion-Wei
Copy link

@Lion-Wei Lion-Wei commented Sep 7, 2020

What type of PR is this?

/kind bug
/kind failing-test

What this PR does / why we need it:

kube-proxy IPVS mode will check KUBE-MARK-DROP chain in each sync, which will result in kube-proxy cleanup rules associated to the KUBE-MARK-DROP chain, and this will break firewall logic.

And this result in "Services should only allow access from service loadbalancer source ranges" case keep failing.

This pr removed check KUBE-MARK-DROP in ipvs mode, to make sure kubelet and kube-proxy handle their own rules.

Which issue(s) this PR fixes:
Fixes #94356

Special notes for your reviewer:

Does this PR introduce a user-facing change?:

NONE

@k8s-ci-robot k8s-ci-robot added release-note-none Denotes a PR that doesn't merit a release note. kind/bug Categorizes issue or PR as related to a bug. size/XS Denotes a PR that changes 0-9 lines, ignoring generated files. kind/failing-test Categorizes issue or PR as related to a consistently or frequently failing test. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. needs-sig Indicates an issue or PR lacks a `sig/foo` label and requires one. needs-priority Indicates a PR lacks a `priority/foo` label and requires one. labels Sep 7, 2020
@k8s-ci-robot k8s-ci-robot added area/ipvs sig/network Categorizes an issue or PR as relevant to SIG Network. and removed needs-sig Indicates an issue or PR lacks a `sig/foo` label and requires one. labels Sep 7, 2020
@@ -117,7 +117,6 @@ var iptablesChains = []struct {
{utiliptables.TableNAT, KubeNodePortChain},
{utiliptables.TableNAT, KubeLoadBalancerChain},
{utiliptables.TableNAT, KubeMarkMasqChain},
{utiliptables.TableNAT, KubeMarkDropChain},
Copy link
Member

Choose a reason for hiding this comment

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

If I recall correctly, this is only ensuring the drop chain doesn't exist but I don't think we're writing any rules here that would conflict with kubelet. Can you point me to where we're doing this?

Copy link
Member

@aojea aojea Sep 7, 2020

Choose a reason for hiding this comment

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

lol, I've introduced the same bug in kube-proxy iptables some time ago :) #85527

9e6a687

Copy link
Member

Choose a reason for hiding this comment

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

Ah I see -- so as part of the save/restore it is also clearing out rules that kubelet created.

The issue that @uablrek mentioned in #82214 still seems valid though? Can we ensure the chain exists but not try any rules to it?

Copy link
Contributor

Choose a reason for hiding this comment

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

How is the dual-stack situation handled for proxy-mode=iptables? I use a work-around by creating the chain in a script before K8s is started;

/etc/init.d/30kube-prep.rc:   ip6tables -t nat -N KUBE-MARK-DROP

Copy link
Contributor

@uablrek uablrek Sep 7, 2020

Choose a reason for hiding this comment

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

Since I start kubelet and kube-proxy from scripts I also get the race. kube-proxy crashes and re-starts a couple of times until the chain is created by kubelet. Not a big deal, but not the most elegant solotion either.

Copy link
Member

Choose a reason for hiding this comment

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

xref #82125 (comment)
😄

Copy link
Author

Choose a reason for hiding this comment

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

Thanks for reviewing 😄

As what we did in #81517 , we chosed to belived nobody change or delete iptables chains created by kubernetes, except system firewall be reloaded.

But we do have race issues like kube-proxy up before kubelet, maybe ensures the chain before is tries to use it is a better way, but not try to change any rule.

After all, this is because KUBE-MARK-DROP chain created by kubelet and used by kube-proxy, as @aojea metioned, kube-proxy is the only consumer, maybe moving KUBE-MARK-DROP to the kube-proxies is another solution.

Overall, I think we have two potential solutions to solve this problem:

  1. Ensure the chain exists but not try any rules to it (Maybe the same with KUBE-MARK-MASQ)
  2. Moving KUBE-MARK-DROP to the kube-proxies.

I think the first one is a better way to solve current failing test, the second way would need further discussion.

Copy link
Contributor

Choose a reason for hiding this comment

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

The issue that @uablrek mentioned in #82214 still seems valid though? Can we ensure the chain exists but not try any rules to it?

As Antonio said, the problem there is mostly that kube-proxy supports dual-stack and kubelet does not currently, and that should be fixed by #94474. Given #94474, the fix here is probably safe, although yes, I agree it would be better if ipvs could ensure that the chain exists but not delete it.

And then longer-term, #82125

Copy link
Member

Choose a reason for hiding this comment

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

I agree it would be better if ipvs could ensure that the chain exists but not delete it.

Can we do this now for both ipvs and iptables? Seems like the fix is to run EnsureChain for KUBE-MARK-DROP but not add anything to the nat chain buffer.

Copy link
Member

Choose a reason for hiding this comment

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

if _, err := proxier.iptables.EnsureChain(ch.table, ch.chain); err != nil {
klog.Errorf("Failed to ensure that %s chain %s exists: %v", ch.table, ch.chain, err)
return
}
if ch.table == utiliptables.TableNAT {
if chain, ok := existingNATChains[ch.chain]; ok {
writeBytesLine(proxier.natChains, chain)
} else {
writeLine(proxier.natChains, utiliptables.MakeChainLine(kubePostroutingChain))
}
} else {
if chain, ok := existingFilterChains[KubeForwardChain]; ok {
writeBytesLine(proxier.filterChains, chain)
} else {
writeLine(proxier.filterChains, utiliptables.MakeChainLine(KubeForwardChain))
}
}

@aojea
Copy link
Member

aojea commented Sep 7, 2020

/assign @andrewsykim @uablrek
xref #85527

@k8s-ci-robot k8s-ci-robot added size/S Denotes a PR that changes 10-29 lines, ignoring generated files. and removed size/XS Denotes a PR that changes 0-9 lines, ignoring generated files. labels Sep 10, 2020
{utiliptables.TableNAT, KubeMarkMasqChain},
{utiliptables.TableNAT, KubeMarkDropChain},
{utiliptables.TableFilter, KubeForwardChain},
Copy link
Member

Choose a reason for hiding this comment

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

What's the reason for changing the order here?

Copy link
Author

Choose a reason for hiding this comment

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

No reason, actually. 😂

@@ -1867,6 +1859,11 @@ func (proxier *Proxier) createAndLinkeKubeChain() {
klog.Errorf("Failed to ensure that %s chain %s exists: %v", ch.table, ch.chain, err)
return
}
// KUBE-MARK-MASQ and KUBE-MARK-DROP is created in kubelet
// kube-proxy only ensure it exist but not do anything to those chains
if ch.chain == KubeMarkDropChain || ch.chain == KubeMarkMasqChain {
Copy link
Member

Choose a reason for hiding this comment

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

Instead of checking specifically for KubeMarkDropChain and KubeMarkMasqChain here and skipping, I would prefer a separate list of chains containing KubeMarkDropChain and KubeMarkMasqChain only (similar to iptablesChains) where we only run proxier.iptables.EnsureChain.

Copy link
Author

Choose a reason for hiding this comment

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

Sure, that might be better. Addressed. : )

@@ -1862,6 +1852,12 @@ func (proxier *Proxier) createAndLinkeKubeChain() {
existingNATChains := proxier.getExistingChains(proxier.iptablesData, utiliptables.TableNAT)

// Make sure we keep stats for the top-level chains
Copy link
Member

Choose a reason for hiding this comment

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

This comment still belongs below I think.

Copy link
Author

Choose a reason for hiding this comment

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

I think KubeMarkDropChain and KubeMarkMasqChain also chains that we should keep stat?

// value should ever change.
writeLine(proxier.natRules, []string{
"-A", string(KubeMarkMasqChain),
"-j", "MARK", "--or-mark", proxier.masqueradeMark,
Copy link
Member

Choose a reason for hiding this comment

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

I don't think it's safe to delete this yet?

Copy link
Author

Choose a reason for hiding this comment

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

Is that so? IMO, KUBE-MARK-MASQ and KUBE-MARK-DROP are similar.

Copy link
Member

Choose a reason for hiding this comment

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

They are similar, but kube-proxy relies on kubelet to apply the drop rules in KUBE-MARK-DROP, where-as kube-proxy adds rules to KUBE-MARK-MASQ like here, which may overlap with kubelet.

@k8s-ci-robot k8s-ci-robot added size/XS Denotes a PR that changes 0-9 lines, ignoring generated files. and removed size/S Denotes a PR that changes 10-29 lines, ignoring generated files. labels Sep 11, 2020
@k8s-ci-robot k8s-ci-robot added size/S Denotes a PR that changes 10-29 lines, ignoring generated files. and removed size/XS Denotes a PR that changes 0-9 lines, ignoring generated files. labels Sep 11, 2020
// ensure KUBE-MARK-DROP chain exist but not do any change
if _, err := proxier.iptables.EnsureChain(utiliptables.TableNAT, KubeMarkDropChain); err != nil {
klog.Errorf("Failed to ensure that %s chain %s exists: %v", utiliptables.TableNAT, KubeMarkDropChain, err)
return
Copy link
Member

Choose a reason for hiding this comment

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

in a dual stack cluster, that we know this rule does not exist in one of the ip families,
kube-proxy will stop to work in a one family or will stop to work at all?

Copy link
Author

Choose a reason for hiding this comment

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

Sorry I didn't notice this before. Then both ipvs and iptbales mode have this issue, I think one of the ip familier don't have this rule is a bug, maybe we can wait #94474 to be merged.

Copy link
Member

Choose a reason for hiding this comment

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

Are we still waiting on #94474 for this?

It seems like there are two separate issues here. For IPVS specifically, we are doing what iptables used to do before #85527. Sounds like we should fix that first independent of the dual-stack PR? Am I missing something there?

@aojea
Copy link
Member

aojea commented Oct 1, 2020

@Lion-Wei I think that this is not the problem, the test is failing with the same error in other jobs with iptables instead of ipvs

#95225

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Oct 15, 2020
@aojea
Copy link
Member

aojea commented Oct 15, 2020

/priority important-soon

@k8s-ci-robot k8s-ci-robot added priority/important-soon Must be staffed and worked on either currently, or very soon, ideally in time for the next release. and removed needs-priority Indicates a PR lacks a `priority/foo` label and requires one. labels Oct 15, 2020
@Lion-Wei
Copy link
Author

Lion-Wei commented Oct 15, 2020

/test pull-kubernetes-e2e-gci-gce-ipvs

I'll fix this flaky case ASAP 😓

@@ -868,6 +868,12 @@ func (proxier *Proxier) syncProxyRules() {
}
}

// ensure KUBE-MARK-DROP chain exist but not do any change
if _, err := proxier.iptables.EnsureChain(utiliptables.TableNAT, KubeMarkDropChain); err != nil {
Copy link
Member

Choose a reason for hiding this comment

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

Similar to iptablesJumpChains can we have a variable like iptablesEnsureChain containing only KubeMarkDropChain?

Copy link
Author

Choose a reason for hiding this comment

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

That will be more readable. Addressed : )

Copy link
Member

@andrewsykim andrewsykim left a comment

Choose a reason for hiding this comment

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

Left some minor comments but overall I think this looks okay -- someone else with more context on kubelet / kube-proxy iptables ownership (#82125) should probably be the approver

@@ -1858,6 +1857,12 @@ func (proxier *Proxier) createAndLinkeKubeChain() {
existingFilterChains := proxier.getExistingChains(proxier.filterChainsData, utiliptables.TableFilter)
existingNATChains := proxier.getExistingChains(proxier.iptablesData, utiliptables.TableNAT)

// ensure KUBE-MARK-DROP chain exist but not do any change
Copy link
Member

Choose a reason for hiding this comment

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

// ensure KUBE-MARK-DROP chain exist but not do any change any rules

Copy link
Author

Choose a reason for hiding this comment

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

Done

@aojea
Copy link
Member

aojea commented Oct 15, 2020

kubelet / kube-proxy iptables ownership (#82125) should probably be the approver
:)

/assign @danwinship @thockin

@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, 2020
@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 Oct 16, 2020
table utiliptables.Table
chain utiliptables.Chain
}{
{utiliptables.TableNAT, KubeMarkMasqChain},
Copy link
Member

Choose a reason for hiding this comment

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

This should be KubeMarkDropChain?

table utiliptables.Table
chain utiliptables.Chain
}{
{utiliptables.TableNAT, KubeMarkMasqChain},
Copy link
Member

Choose a reason for hiding this comment

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

This should be KubeMarkDropChain?

Copy link
Author

Choose a reason for hiding this comment

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

Oops, sorry

@danwinship
Copy link
Contributor

/lgtm
/approve

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

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: danwinship, Lion-Wei

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 16, 2020
@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to fejta).

Review the full test history for this PR.

Silence the bot with an /lgtm cancel or /hold comment for consistent failures.

@k8s-ci-robot
Copy link
Contributor

@Lion-Wei: The following test failed, say /retest to rerun all failed tests:

Test name Commit Details Rerun command
pull-kubernetes-integration 1f7ea16 link /test pull-kubernetes-integration

Full PR test history. Your PR dashboard. Please help us cut down on flakes by linking to an open issue when you hit one in your PR.

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. I understand the commands that are listed here.

@cmluciano
Copy link

/retest

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. area/ipvs cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. kind/bug Categorizes issue or PR as related to a bug. kind/failing-test Categorizes issue or PR as related to a consistently or frequently failing test. lgtm "Looks good to me", indicates that a PR is ready to be merged. priority/important-soon Must be staffed and worked on either currently, or very soon, ideally in time for the next release. release-note-none Denotes a PR that doesn't merit a release note. sig/network Categorizes an issue or PR as relevant to SIG Network. 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.

[failing test][ipvs] Services should only allow access from service loadbalancer source ranges
9 participants