diff --git a/cmd/kube-proxy/app/server.go b/cmd/kube-proxy/app/server.go index 427aa7f33fd..4eebb611399 100644 --- a/cmd/kube-proxy/app/server.go +++ b/cmd/kube-proxy/app/server.go @@ -190,7 +190,7 @@ func NewProxyServerDefault(config *options.ProxyServerConfig) (*ProxyServer, err proxyMode := getProxyMode(string(config.Mode), client.Nodes(), hostname, iptInterface) if proxyMode == proxyModeIptables { - glog.V(2).Info("Using iptables Proxier.") + glog.V(0).Info("Using iptables Proxier.") proxierIptables, err := iptables.NewProxier(iptInterface, execer, config.IPTablesSyncPeriod.Duration, config.MasqueradeAll) if err != nil { glog.Fatalf("Unable to create proxier: %v", err) @@ -198,10 +198,10 @@ func NewProxyServerDefault(config *options.ProxyServerConfig) (*ProxyServer, err proxier = proxierIptables endpointsHandler = proxierIptables // No turning back. Remove artifacts that might still exist from the userspace Proxier. - glog.V(2).Info("Tearing down userspace rules. Errors here are acceptable.") + glog.V(0).Info("Tearing down userspace rules.") userspace.CleanupLeftovers(iptInterface) } else { - glog.V(2).Info("Using userspace Proxier.") + glog.V(0).Info("Using userspace Proxier.") // This is a proxy.LoadBalancer which NewProxier needs but has methods we don't need for // our config.EndpointsConfigHandler. loadBalancer := userspace.NewLoadBalancerRR() @@ -221,7 +221,7 @@ func NewProxyServerDefault(config *options.ProxyServerConfig) (*ProxyServer, err } proxier = proxierUserspace // Remove artifacts from the pure-iptables Proxier. - glog.V(2).Info("Tearing down pure-iptables proxy rules. Errors here are acceptable.") + glog.V(0).Info("Tearing down pure-iptables proxy rules.") iptables.CleanupLeftovers(iptInterface) } iptInterface.AddReloadFunc(proxier.Sync) diff --git a/pkg/proxy/iptables/proxier.go b/pkg/proxy/iptables/proxier.go index ee0603520d9..71463d2ac69 100644 --- a/pkg/proxy/iptables/proxier.go +++ b/pkg/proxy/iptables/proxier.go @@ -115,8 +115,7 @@ type serviceInfo struct { loadBalancerStatus api.LoadBalancerStatus sessionAffinityType api.ServiceAffinity stickyMaxAgeSeconds int - // Deprecated, but required for back-compat (including e2e) - externalIPs []string + externalIPs []string } // returns a new serviceInfo struct @@ -196,18 +195,24 @@ func CleanupLeftovers(ipt utiliptables.Interface) (encounteredError bool) { //TODO: actually tear down all rules and chains. args := []string{"-m", "comment", "--comment", "kubernetes service portals", "-j", string(iptablesServicesChain)} if err := ipt.DeleteRule(utiliptables.TableNAT, utiliptables.ChainOutput, args...); err != nil { - glog.Errorf("Error removing pure-iptables proxy rule: %v", err) - encounteredError = true + if !utiliptables.IsNotFoundError(err) { + glog.Errorf("Error removing pure-iptables proxy rule: %v", err) + encounteredError = true + } } if err := ipt.DeleteRule(utiliptables.TableNAT, utiliptables.ChainPrerouting, args...); err != nil { - glog.Errorf("Error removing pure-iptables proxy rule: %v", err) - encounteredError = true + if !utiliptables.IsNotFoundError(err) { + glog.Errorf("Error removing pure-iptables proxy rule: %v", err) + encounteredError = true + } } args = []string{"-m", "comment", "--comment", "kubernetes service traffic requiring SNAT", "-m", "mark", "--mark", iptablesMasqueradeMark, "-j", "MASQUERADE"} if err := ipt.DeleteRule(utiliptables.TableNAT, utiliptables.ChainPostrouting, args...); err != nil { - glog.Errorf("Error removing pure-iptables proxy rule: %v", err) - encounteredError = true + if !utiliptables.IsNotFoundError(err) { + glog.Errorf("Error removing pure-iptables proxy rule: %v", err) + encounteredError = true + } } // flush and delete chains. @@ -215,12 +220,16 @@ func CleanupLeftovers(ipt utiliptables.Interface) (encounteredError bool) { for _, c := range chains { // flush chain, then if sucessful delete, delete will fail if flush fails. if err := ipt.FlushChain(utiliptables.TableNAT, c); err != nil { - glog.Errorf("Error flushing pure-iptables proxy chain: %v", err) - encounteredError = true + if !utiliptables.IsNotFoundError(err) { + glog.Errorf("Error flushing pure-iptables proxy chain: %v", err) + encounteredError = true + } } else { if err = ipt.DeleteChain(utiliptables.TableNAT, c); err != nil { - glog.Errorf("Error deleting pure-iptables proxy chain: %v", err) - encounteredError = true + if !utiliptables.IsNotFoundError(err) { + glog.Errorf("Error deleting pure-iptables proxy chain: %v", err) + encounteredError = true + } } } } diff --git a/pkg/proxy/userspace/proxier.go b/pkg/proxy/userspace/proxier.go index 35a6b7585b2..76ba794811d 100644 --- a/pkg/proxy/userspace/proxier.go +++ b/pkg/proxy/userspace/proxier.go @@ -196,27 +196,37 @@ func CleanupLeftovers(ipt iptables.Interface) (encounteredError bool) { // Delete Rules first, then Flush and Delete Chains args := []string{"-m", "comment", "--comment", "handle ClusterIPs; NOTE: this must be before the NodePort rules"} if err := ipt.DeleteRule(iptables.TableNAT, iptables.ChainOutput, append(args, "-j", string(iptablesHostPortalChain))...); err != nil { - glog.Errorf("Error removing userspace rule: %v", err) - encounteredError = true + if !iptables.IsNotFoundError(err) { + glog.Errorf("Error removing userspace rule: %v", err) + encounteredError = true + } } if err := ipt.DeleteRule(iptables.TableNAT, iptables.ChainPrerouting, append(args, "-j", string(iptablesContainerPortalChain))...); err != nil { - glog.Errorf("Error removing userspace rule: %v", err) - encounteredError = true + if !iptables.IsNotFoundError(err) { + glog.Errorf("Error removing userspace rule: %v", err) + encounteredError = true + } } args = []string{"-m", "addrtype", "--dst-type", "LOCAL"} args = append(args, "-m", "comment", "--comment", "handle service NodePorts; NOTE: this must be the last rule in the chain") if err := ipt.DeleteRule(iptables.TableNAT, iptables.ChainOutput, append(args, "-j", string(iptablesHostNodePortChain))...); err != nil { - glog.Errorf("Error removing userspace rule: %v", err) - encounteredError = true + if !iptables.IsNotFoundError(err) { + glog.Errorf("Error removing userspace rule: %v", err) + encounteredError = true + } } if err := ipt.DeleteRule(iptables.TableNAT, iptables.ChainPrerouting, append(args, "-j", string(iptablesContainerNodePortChain))...); err != nil { - glog.Errorf("Error removing userspace rule: %v", err) - encounteredError = true + if !iptables.IsNotFoundError(err) { + glog.Errorf("Error removing userspace rule: %v", err) + encounteredError = true + } } args = []string{"-m", "comment", "--comment", "Ensure that non-local NodePort traffic can flow"} if err := ipt.DeleteRule(iptables.TableFilter, iptables.ChainInput, append(args, "-j", string(iptablesNonLocalNodePortChain))...); err != nil { - glog.Errorf("Error removing userspace rule: %v", err) - encounteredError = true + if !iptables.IsNotFoundError(err) { + glog.Errorf("Error removing userspace rule: %v", err) + encounteredError = true + } } // flush and delete chains. @@ -228,12 +238,16 @@ func CleanupLeftovers(ipt iptables.Interface) (encounteredError bool) { for _, c := range chains { // flush chain, then if successful delete, delete will fail if flush fails. if err := ipt.FlushChain(table, c); err != nil { - glog.Errorf("Error flushing userspace chain: %v", err) - encounteredError = true + if !iptables.IsNotFoundError(err) { + glog.Errorf("Error flushing userspace chain: %v", err) + encounteredError = true + } } else { if err = ipt.DeleteChain(table, c); err != nil { - glog.Errorf("Error deleting userspace chain: %v", err) - encounteredError = true + if !iptables.IsNotFoundError(err) { + glog.Errorf("Error deleting userspace chain: %v", err) + encounteredError = true + } } } } diff --git a/pkg/util/iptables/iptables.go b/pkg/util/iptables/iptables.go index 4329dcc3f5d..1a0f181e946 100644 --- a/pkg/util/iptables/iptables.go +++ b/pkg/util/iptables/iptables.go @@ -576,3 +576,17 @@ func (runner *runner) reload() { f() } } + +// IsNotFoundError returns true if the error indicates "not found". It parses +// the error string looking for known values, which is imperfect but works in +// practice. +func IsNotFoundError(err error) bool { + es := err.Error() + if strings.Contains(es, "No such file or directory") { + return true + } + if strings.Contains(es, "No chain/target/match by that name") { + return true + } + return false +}