// CleanupLeftovers removes all iptables rules and chains created by the Proxier // It returns true if an error was encountered. Errors are logged. func CleanupLeftovers(ipt utiliptables.Interface) (encounteredError bool) { // Unlink the services chain. args := []string{ "-m", "comment", "--comment", "kubernetes service portals", "-j", string(kubeServicesChain), } tableChainsWithJumpServices := []struct { table utiliptables.Table chain utiliptables.Chain }{ {utiliptables.TableFilter, utiliptables.ChainOutput}, {utiliptables.TableNAT, utiliptables.ChainOutput}, {utiliptables.TableNAT, utiliptables.ChainPrerouting}, } for _, tc := range tableChainsWithJumpServices { if err := ipt.DeleteRule(tc.table, tc.chain, args...); err != nil { if !utiliptables.IsNotFoundError(err) { glog.Errorf("Error removing pure-iptables proxy rule: %v", err) encounteredError = true } } } // Unlink the postrouting chain. args = []string{ "-m", "comment", "--comment", "kubernetes postrouting rules", "-j", string(kubePostroutingChain), } if err := ipt.DeleteRule(utiliptables.TableNAT, utiliptables.ChainPostrouting, args...); err != nil { if !utiliptables.IsNotFoundError(err) { glog.Errorf("Error removing pure-iptables proxy rule: %v", err) encounteredError = true } } // Flush and remove all of our chains. if iptablesSaveRaw, err := ipt.Save(utiliptables.TableNAT); err != nil { glog.Errorf("Failed to execute iptables-save for %s: %v", utiliptables.TableNAT, err) encounteredError = true } else { existingNATChains := getChainLines(utiliptables.TableNAT, iptablesSaveRaw) natChains := bytes.NewBuffer(nil) natRules := bytes.NewBuffer(nil) writeLine(natChains, "*nat") // Start with chains we know we need to remove. for _, chain := range []utiliptables.Chain{kubeServicesChain, kubeNodePortsChain, kubePostroutingChain, kubeMarkMasqChain} { if _, found := existingNATChains[chain]; found { chainString := string(chain) writeLine(natChains, existingNATChains[chain]) // flush writeLine(natRules, "-X", chainString) // delete } } // Hunt for service and endpoint chains. for chain := range existingNATChains { chainString := string(chain) if strings.HasPrefix(chainString, "KUBE-SVC-") || strings.HasPrefix(chainString, "KUBE-SEP-") { writeLine(natChains, existingNATChains[chain]) // flush writeLine(natRules, "-X", chainString) // delete } } writeLine(natRules, "COMMIT") natLines := append(natChains.Bytes(), natRules.Bytes()...) // Write it. err = ipt.Restore(utiliptables.TableNAT, natLines, utiliptables.NoFlushTables, utiliptables.RestoreCounters) if err != nil { glog.Errorf("Failed to execute iptables-restore for %s: %v", utiliptables.TableNAT, err) encounteredError = true } } { filterBuf := bytes.NewBuffer(nil) writeLine(filterBuf, "*filter") writeLine(filterBuf, fmt.Sprintf(":%s - [0:0]", kubeServicesChain)) writeLine(filterBuf, fmt.Sprintf("-X %s", kubeServicesChain)) writeLine(filterBuf, "COMMIT") // Write it. if err := ipt.Restore(utiliptables.TableFilter, filterBuf.Bytes(), utiliptables.NoFlushTables, utiliptables.RestoreCounters); err != nil { glog.Errorf("Failed to execute iptables-restore for %s: %v", utiliptables.TableFilter, err) encounteredError = true } } // Clean up the older SNAT rule which was directly in POSTROUTING. // TODO(thockin): Remove this for v1.3 or v1.4. args = []string{ "-m", "comment", "--comment", "kubernetes service traffic requiring SNAT", "-m", "mark", "--mark", oldIptablesMasqueradeMark, "-j", "MASQUERADE", } if err := ipt.DeleteRule(utiliptables.TableNAT, utiliptables.ChainPostrouting, args...); err != nil { if !utiliptables.IsNotFoundError(err) { glog.Errorf("Error removing old-style SNAT rule: %v", err) encounteredError = true } } return encounteredError }