kube-proxy: log ipt errors during platformCheckSupported

Signed-off-by: Daman Arora <aroradaman@gmail.com>
This commit is contained in:
Daman Arora 2025-04-29 22:37:02 +05:30
parent 57218ac969
commit 858b88bcee
7 changed files with 44 additions and 25 deletions

View file

@ -112,16 +112,18 @@ func (s *ProxyServer) platformCheckSupported(ctx context.Context) (ipv4Supported
if isIPTablesBased(s.Config.Mode) {
// Check for the iptables and ip6tables binaries.
ipts := utiliptables.NewDualStack()
var ipts map[v1.IPFamily]utiliptables.Interface
ipts, err = utiliptables.NewDualStack()
ipv4Supported = ipts[v1.IPv4Protocol] != nil
ipv6Supported = ipts[v1.IPv6Protocol] != nil
if !ipv4Supported && !ipv6Supported {
err = fmt.Errorf("iptables is not available on this host")
err = fmt.Errorf("iptables is not available on this host : %w", err)
} else if !ipv4Supported {
logger.Info("No iptables support for family", "ipFamily", v1.IPv4Protocol)
logger.Info("No iptables support for family", "ipFamily", v1.IPv4Protocol, "error", err)
} else if !ipv6Supported {
logger.Info("No iptables support for family", "ipFamily", v1.IPv6Protocol)
logger.Info("No iptables support for family", "ipFamily", v1.IPv6Protocol, "error", err)
}
} else {
// The nft CLI always supports both families.
@ -151,7 +153,7 @@ func (s *ProxyServer) createProxier(ctx context.Context, config *proxyconfigapi.
if config.Mode == proxyconfigapi.ProxyModeIPTables {
logger.Info("Using iptables Proxier")
ipts := utiliptables.NewDualStack()
ipts, _ := utiliptables.NewDualStack()
if dualStack {
// TODO this has side effects that should only happen when Run() is invoked.
@ -205,7 +207,7 @@ func (s *ProxyServer) createProxier(ctx context.Context, config *proxyconfigapi.
if err := ipvs.CanUseIPVSProxier(ctx, ipvsInterface, ipsetInterface, config.IPVS.Scheduler); err != nil {
return nil, fmt.Errorf("can't use the IPVS proxier: %v", err)
}
ipts := utiliptables.NewDualStack()
ipts, _ := utiliptables.NewDualStack()
logger.Info("Using ipvs Proxier")
if dualStack {

View file

@ -37,8 +37,12 @@ const (
)
func (kl *Kubelet) initNetworkUtil() {
iptClients := utiliptables.NewDualStack()
if len(iptClients) == 0 {
iptClients, err := utiliptables.NewDualStack()
if err != nil {
klog.ErrorS(err, "Failed to initialize iptables")
}
if err != nil || len(iptClients) == 0 {
klog.InfoS("No iptables support on this system; not creating the KUBE-IPTABLES-HINT chain")
return
}

View file

@ -406,7 +406,7 @@ var iptablesCleanupOnlyChains = []iptablesJumpChain{}
// CleanupLeftovers removes all iptables rules and chains created by the Proxier
// It returns true if an error was encountered. Errors are logged.
func CleanupLeftovers(ctx context.Context) (encounteredError bool) {
ipts := utiliptables.NewDualStack()
ipts, _ := utiliptables.NewDualStack()
for _, ipt := range ipts {
encounteredError = cleanupLeftoversForFamily(ctx, ipt) || encounteredError
}

View file

@ -706,7 +706,7 @@ func CleanupLeftovers(ctx context.Context) (encounteredError bool) {
return false
}
ipts := utiliptables.NewDualStack()
ipts, _ := utiliptables.NewDualStack()
ipsetInterface := utilipset.New()
ipvsInterface := utilipvs.New()

View file

@ -97,7 +97,7 @@ type Interface interface {
HasRandomFully() bool
// Present checks if the kernel supports the iptable interface
Present() bool
Present() error
}
// Protocol defines the ip protocol either ipv4 or ipv6
@ -250,29 +250,40 @@ func newInternal(exec utilexec.Interface, protocol Protocol, lockfilePath14x, lo
}
// New returns a new Interface which will exec iptables.
// Note that this function will return a single iptables Interface *and* an error, if only
// a single family is supported.
func New(protocol Protocol) Interface {
return newInternal(utilexec.New(), protocol, "", "")
}
func newDualStackInternal(exec utilexec.Interface) map[v1.IPFamily]Interface {
func newDualStackInternal(exec utilexec.Interface) (map[v1.IPFamily]Interface, error) {
var err error
interfaces := map[v1.IPFamily]Interface{}
iptv4 := newInternal(exec, ProtocolIPv4, "", "")
if iptv4.Present() {
if presentErr := iptv4.Present(); presentErr != nil {
err = presentErr
} else {
interfaces[v1.IPv4Protocol] = iptv4
}
iptv6 := newInternal(exec, ProtocolIPv6, "", "")
if iptv6.Present() {
if presentErr := iptv6.Present(); presentErr != nil {
// If we get an error for both IPv4 and IPv6 Present() calls, it's virtually guaranteed that
// they're going to be the same error. We ignore the error for IPv6 if IPv4 has already failed.
if err == nil {
err = presentErr
}
} else {
interfaces[v1.IPv6Protocol] = iptv6
}
return interfaces
return interfaces, err
}
// 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.
func NewDualStack() map[v1.IPFamily]Interface {
func NewDualStack() (map[v1.IPFamily]Interface, error) {
return newDualStackInternal(utilexec.New())
}
@ -654,8 +665,11 @@ func (runner *runner) ChainExists(table Table, chain Chain) (bool, error) {
trace := utiltrace.New("iptables ChainExists")
defer trace.LogIfLong(2 * time.Second)
_, err := runner.run(opListChain, fullArgs)
return err == nil, err
out, err := runner.run(opListChain, fullArgs)
if err != nil {
return false, fmt.Errorf("error listing chain %q in table %q: %w: %s", chain, table, err, out)
}
return true, nil
}
type operation string
@ -759,12 +773,11 @@ func (runner *runner) HasRandomFully() bool {
// Present tests if iptable is supported on current kernel by checking the existence
// of default table and chain
func (runner *runner) Present() bool {
func (runner *runner) Present() error {
if _, err := runner.ChainExists(TableNAT, ChainPostrouting); err != nil {
return false
return err
}
return true
return nil
}
var iptablesNotFoundStrings = []string{

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, _ := newDualStackInternal(fexec)
if tc.ipv4 && runners[v1.IPv4Protocol] == nil {
t.Errorf("Expected ipv4 runner, got nil")

View file

@ -327,8 +327,8 @@ func (f *FakeIPTables) HasRandomFully() bool {
return f.hasRandomFully
}
func (f *FakeIPTables) Present() bool {
return true
func (f *FakeIPTables) Present() error {
return nil
}
var _ = iptables.Interface(&FakeIPTables{})