From bfa4948bb63274727257944e1d1c21b84f272ce2 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Tue, 29 Nov 2022 09:38:40 -0500 Subject: [PATCH] Don't re-run EnsureChain/EnsureRules on partial syncs We currently invoke /sbin/iptables 24 times on each syncProxyRules before calling iptables-restore. Since even trivial iptables invocations are slow on hosts with lots of iptables rules, this adds a lot of time to each sync. Since these checks are expected to be a no-op 99% of the time, skip them on partial syncs. --- pkg/proxy/iptables/proxier.go | 38 +++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/pkg/proxy/iptables/proxier.go b/pkg/proxy/iptables/proxier.go index e141b6f7082..87cad7c8669 100644 --- a/pkg/proxy/iptables/proxier.go +++ b/pkg/proxy/iptables/proxier.go @@ -863,19 +863,31 @@ func (proxier *Proxier) syncProxyRules() { } }() - // Create and link the kube chains. - for _, jump := range iptablesJumpChains { - if _, err := proxier.iptables.EnsureChain(jump.table, jump.dstChain); err != nil { - klog.ErrorS(err, "Failed to ensure chain exists", "table", jump.table, "chain", jump.dstChain) - return - } - args := append(jump.extraArgs, - "-m", "comment", "--comment", jump.comment, - "-j", string(jump.dstChain), - ) - if _, err := proxier.iptables.EnsureRule(utiliptables.Prepend, jump.table, jump.srcChain, args...); err != nil { - klog.ErrorS(err, "Failed to ensure chain jumps", "table", jump.table, "srcChain", jump.srcChain, "dstChain", jump.dstChain) - return + if !tryPartialSync { + // Ensure that our jump rules (eg from PREROUTING to KUBE-SERVICES) exist. + // We can't do this as part of the iptables-restore because we don't want + // to specify/replace *all* of the rules in PREROUTING, etc. + // + // We need to create these rules when kube-proxy first starts, and we need + // to recreate them if the utiliptables Monitor detects that iptables has + // been flushed. In both of those cases, the code will force a full sync. + // In all other cases, it ought to be safe to assume that the rules + // already exist, so we'll skip this step when doing a partial sync, to + // save us from having to invoke /sbin/iptables 20 times on each sync + // (which will be very slow on hosts with lots of iptables rules). + for _, jump := range iptablesJumpChains { + if _, err := proxier.iptables.EnsureChain(jump.table, jump.dstChain); err != nil { + klog.ErrorS(err, "Failed to ensure chain exists", "table", jump.table, "chain", jump.dstChain) + return + } + args := append(jump.extraArgs, + "-m", "comment", "--comment", jump.comment, + "-j", string(jump.dstChain), + ) + if _, err := proxier.iptables.EnsureRule(utiliptables.Prepend, jump.table, jump.srcChain, args...); err != nil { + klog.ErrorS(err, "Failed to ensure chain jumps", "table", jump.table, "srcChain", jump.srcChain, "dstChain", jump.dstChain) + return + } } }