Fix kubelet iptables startup, clarify semantics of utiliptables calls.

This commit is contained in:
Dan Winship
2025-06-07 10:17:44 -04:00
parent 43bb11b5c1
commit 97ec8618d3
3 changed files with 28 additions and 9 deletions

View File

@@ -37,12 +37,13 @@ const (
)
func (kl *Kubelet) initNetworkUtil() {
iptClients, err := utiliptables.NewDualStack()
if err != nil {
klog.ErrorS(err, "Failed to initialize iptables")
}
if err != nil || len(iptClients) == 0 {
iptClients := utiliptables.NewBestEffort()
if len(iptClients) == 0 {
// We don't log this as an error because kubelet itself doesn't need any
// of this (it sets up these rules for the benefit of *other* components),
// and because we *expect* this to fail on hosts where only nftables is
// supported (in which case there can't be any other components using
// iptables that would need these rules anyway).
klog.InfoS("No iptables support on this system; not creating the KUBE-IPTABLES-HINT chain")
return
}

View File

@@ -275,12 +275,24 @@ func newDualStackInternal(exec utilexec.Interface) (map[v1.IPFamily]Interface, e
}
// NewDualStack returns a map containing an IPv4 Interface (if IPv4 iptables is supported)
// and an IPv6 Interface (if IPv6 iptables is supported). If either family is not
// supported, no Interface will be returned for that family.
// and an IPv6 Interface (if IPv6 iptables is supported). If only one family is supported,
// it will return a map with one Interface *and* an error (indicating the problem with the
// other family). If neither family is supported, it will return an empty map and an
// error.
func NewDualStack() (map[v1.IPFamily]Interface, error) {
return newDualStackInternal(utilexec.New())
}
// NewBestEffort returns a map containing an IPv4 Interface (if IPv4 iptables is
// supported) and an IPv6 Interface (if IPv6 iptables is supported). If iptables is not
// supported, then it just returns an empty map. This function is intended to make things
// simple for callers that just want "best-effort" iptables support, where neither partial
// nor complete lack of iptables support is considered an error.
func NewBestEffort() map[v1.IPFamily]Interface {
ipts, _ := newDualStackInternal(utilexec.New())
return ipts
}
// EnsureChain is part of Interface.
func (runner *runner) EnsureChain(table Table, chain Chain) (bool, error) {
fullArgs := makeFullArgs(table, chain)

View File

@@ -329,7 +329,7 @@ func TestNewDualStack(t *testing.T) {
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
fexec := fakeExecForCommands(tc.commands)
runners, _ := newDualStackInternal(fexec)
runners, err := newDualStackInternal(fexec)
if tc.ipv4 && runners[v1.IPv4Protocol] == nil {
t.Errorf("Expected ipv4 runner, got nil")
@@ -341,6 +341,12 @@ func TestNewDualStack(t *testing.T) {
} else if !tc.ipv6 && runners[v1.IPv6Protocol] != nil {
t.Errorf("Expected no ipv6 runner, got one")
}
if len(runners) == 2 && err != nil {
t.Errorf("Got 2 runners but also an error (%v)", err)
} else if len(runners) != 2 && err == nil {
t.Errorf("Got %d runners but no error", len(runners))
}
})
}
}