mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-27 13:37:30 +00:00
kube-proxy: fix duplicate port opening
When nodePortAddresses is not specified for kube-proxy, it tried to open the node port for a NodePort service twice, triggered by IPv4ZeroCIDR and IPv6ZeroCIDR separately. The first attempt would succeed and the second one would always generate an error log like below: "listen tcp4 :30522: bind: address already in use" This patch fixes it by ensuring nodeAddresses of a proxier only contain the addresses for its IP family.
This commit is contained in:
parent
475644ccd8
commit
6ce612ef65
@ -975,6 +975,16 @@ func (proxier *Proxier) syncProxyRules() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
klog.ErrorS(err, "Failed to get node ip address matching nodeport cidrs, services with nodeport may not work as intended", "CIDRs", proxier.nodePortAddresses)
|
klog.ErrorS(err, "Failed to get node ip address matching nodeport cidrs, services with nodeport may not work as intended", "CIDRs", proxier.nodePortAddresses)
|
||||||
}
|
}
|
||||||
|
// nodeAddresses may contain dual-stack zero-CIDRs if proxier.nodePortAddresses is empty.
|
||||||
|
// Ensure nodeAddresses only contains the addresses for this proxier's IP family.
|
||||||
|
isIPv6 := proxier.iptables.IsIPv6()
|
||||||
|
for addr := range nodeAddresses {
|
||||||
|
if utilproxy.IsZeroCIDR(addr) && isIPv6 == netutils.IsIPv6CIDRString(addr) {
|
||||||
|
// if any of the addresses is zero cidr of this IP family, non-zero IPs can be excluded.
|
||||||
|
nodeAddresses = sets.NewString(addr)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Build rules for each service.
|
// Build rules for each service.
|
||||||
for svcName, svc := range proxier.serviceMap {
|
for svcName, svc := range proxier.serviceMap {
|
||||||
@ -1438,7 +1448,6 @@ func (proxier *Proxier) syncProxyRules() {
|
|||||||
|
|
||||||
// Finally, tail-call to the nodeports chain. This needs to be after all
|
// Finally, tail-call to the nodeports chain. This needs to be after all
|
||||||
// other service portal rules.
|
// other service portal rules.
|
||||||
isIPv6 := proxier.iptables.IsIPv6()
|
|
||||||
for address := range nodeAddresses {
|
for address := range nodeAddresses {
|
||||||
// TODO(thockin, m1093782566): If/when we have dual-stack support we will want to distinguish v4 from v6 zero-CIDRs.
|
// TODO(thockin, m1093782566): If/when we have dual-stack support we will want to distinguish v4 from v6 zero-CIDRs.
|
||||||
if utilproxy.IsZeroCIDR(address) {
|
if utilproxy.IsZeroCIDR(address) {
|
||||||
|
@ -1587,7 +1587,15 @@ COMMIT
|
|||||||
-A KUBE-SERVICES -m comment --comment "kubernetes service nodeports; NOTE: this must be the last rule in this chain" -m addrtype --dst-type LOCAL -j KUBE-NODEPORTS
|
-A KUBE-SERVICES -m comment --comment "kubernetes service nodeports; NOTE: this must be the last rule in this chain" -m addrtype --dst-type LOCAL -j KUBE-NODEPORTS
|
||||||
COMMIT
|
COMMIT
|
||||||
`
|
`
|
||||||
|
assert.Equal(t, []*netutils.LocalPort{
|
||||||
|
{
|
||||||
|
Description: "nodePort for ns1/svc1:p80",
|
||||||
|
IP: "",
|
||||||
|
IPFamily: netutils.IPv4,
|
||||||
|
Port: svcNodePort,
|
||||||
|
Protocol: netutils.TCP,
|
||||||
|
},
|
||||||
|
}, fp.portMapper.(*fakePortOpener).openPorts)
|
||||||
assertIPTablesRulesEqual(t, expected, fp.iptablesData.String())
|
assertIPTablesRulesEqual(t, expected, fp.iptablesData.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user