-
Notifications
You must be signed in to change notification settings - Fork 40k
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
Conversation
@@ -117,7 +117,6 @@ var iptablesChains = []struct { | |||
{utiliptables.TableNAT, KubeNodePortChain}, | |||
{utiliptables.TableNAT, KubeLoadBalancerChain}, | |||
{utiliptables.TableNAT, KubeMarkMasqChain}, | |||
{utiliptables.TableNAT, KubeMarkDropChain}, |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
xref #82125 (comment)
😄
There was a problem hiding this comment.
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:
- Ensure the chain exists but not try any rules to it (Maybe the same with
KUBE-MARK-MASQ
) - 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.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
kubernetes/pkg/proxy/ipvs/proxier.go
Lines 1866 to 1882 in 3fc1bc7
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)) | |
} | |
} |
/assign @andrewsykim @uablrek |
{utiliptables.TableNAT, KubeMarkMasqChain}, | ||
{utiliptables.TableNAT, KubeMarkDropChain}, | ||
{utiliptables.TableFilter, KubeForwardChain}, |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No reason, actually. 😂
pkg/proxy/ipvs/proxier.go
Outdated
@@ -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 { |
There was a problem hiding this comment.
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
.
There was a problem hiding this comment.
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. : )
pkg/proxy/ipvs/proxier.go
Outdated
@@ -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 |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
pkg/proxy/ipvs/proxier.go
Outdated
// value should ever change. | ||
writeLine(proxier.natRules, []string{ | ||
"-A", string(KubeMarkMasqChain), | ||
"-j", "MARK", "--or-mark", proxier.masqueradeMark, |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
pkg/proxy/iptables/proxier.go
Outdated
// 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 |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/priority important-soon |
/test pull-kubernetes-e2e-gci-gce-ipvs I'll fix this flaky case ASAP 😓 |
pkg/proxy/iptables/proxier.go
Outdated
@@ -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 { |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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 : )
There was a problem hiding this 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
pkg/proxy/ipvs/proxier.go
Outdated
@@ -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 |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
/assign @danwinship @thockin |
pkg/proxy/iptables/proxier.go
Outdated
table utiliptables.Table | ||
chain utiliptables.Chain | ||
}{ | ||
{utiliptables.TableNAT, KubeMarkMasqChain}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be KubeMarkDropChain?
pkg/proxy/ipvs/proxier.go
Outdated
table utiliptables.Table | ||
chain utiliptables.Chain | ||
}{ | ||
{utiliptables.TableNAT, KubeMarkMasqChain}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be KubeMarkDropChain?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, sorry
/lgtm |
[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 |
/retest Review the full test history for this PR. Silence the bot with an |
@Lion-Wei: The following test failed, say
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. |
/retest |
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 theKUBE-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?: