Skip to content

Commit 27fca55

Browse files
authored
Merge pull request kubernetes#71895 from DataDog/lbernail/svc-graceful-deletion
Support IPVS graceful termination when deleting a service
2 parents d4fe512 + ec598d1 commit 27fca55

File tree

2 files changed

+74
-98
lines changed

2 files changed

+74
-98
lines changed

pkg/proxy/ipvs/proxier.go

Lines changed: 38 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1190,7 +1190,15 @@ func (proxier *Proxier) syncProxyRules() {
11901190
}
11911191
proxier.portsMap = replacementPortsMap
11921192

1193-
// Clean up legacy IPVS services
1193+
// Get legacy bind address
1194+
// currentBindAddrs represents ip addresses bind to DefaultDummyDevice from the system
1195+
currentBindAddrs, err := proxier.netlinkHandle.ListBindAddress(DefaultDummyDevice)
1196+
if err != nil {
1197+
klog.Errorf("Failed to get bind address, err: %v", err)
1198+
}
1199+
legacyBindAddrs := proxier.getLegacyBindAddr(activeBindAddrs, currentBindAddrs)
1200+
1201+
// Clean up legacy IPVS services and unbind addresses
11941202
appliedSvcs, err := proxier.ipvs.GetVirtualServers()
11951203
if err == nil {
11961204
for _, appliedSvc := range appliedSvcs {
@@ -1199,15 +1207,7 @@ func (proxier *Proxier) syncProxyRules() {
11991207
} else {
12001208
klog.Errorf("Failed to get ipvs service, err: %v", err)
12011209
}
1202-
proxier.cleanLegacyService(activeIPVSServices, currentIPVSServices)
1203-
1204-
// Clean up legacy bind address
1205-
// currentBindAddrs represents ip addresses bind to DefaultDummyDevice from the system
1206-
currentBindAddrs, err := proxier.netlinkHandle.ListBindAddress(DefaultDummyDevice)
1207-
if err != nil {
1208-
klog.Errorf("Failed to get bind address, err: %v", err)
1209-
}
1210-
proxier.cleanLegacyBindAddr(activeBindAddrs, currentBindAddrs)
1210+
proxier.cleanLegacyService(activeIPVSServices, currentIPVSServices, legacyBindAddrs)
12111211

12121212
// Update healthz timestamp
12131213
if proxier.healthzServer != nil {
@@ -1605,29 +1605,34 @@ func (proxier *Proxier) syncEndpoint(svcPortName proxy.ServicePortName, onlyNode
16051605
klog.V(5).Infof("Using graceful delete to delete: %v", uniqueRS)
16061606
err = proxier.gracefuldeleteManager.GracefulDeleteRS(appliedVirtualServer, delDest)
16071607
if err != nil {
1608-
klog.Errorf("Failed to delete destination: %v, error: %v", delDest, err)
1608+
klog.Errorf("Failed to delete destination: %v, error: %v", uniqueRS, err)
16091609
continue
16101610
}
16111611
}
16121612
return nil
16131613
}
16141614

1615-
func (proxier *Proxier) cleanLegacyService(activeServices map[string]bool, currentServices map[string]*utilipvs.VirtualServer) {
1615+
func (proxier *Proxier) cleanLegacyService(activeServices map[string]bool, currentServices map[string]*utilipvs.VirtualServer, legacyBindAddrs map[string]bool) {
16161616
for cs := range currentServices {
16171617
svc := currentServices[cs]
16181618
if _, ok := activeServices[cs]; !ok {
16191619
// This service was not processed in the latest sync loop so before deleting it,
1620-
// make sure it does not fall within an excluded CIDR range.
16211620
okayToDelete := true
16221621
rsList, _ := proxier.ipvs.GetRealServers(svc)
1622+
1623+
// If we still have real servers graceful termination is not done
1624+
if len(rsList) > 0 {
1625+
okayToDelete = false
1626+
}
1627+
// Applying graceful termination to all real servers
16231628
for _, rs := range rsList {
16241629
uniqueRS := GetUniqueRSName(svc, rs)
1625-
// if there are in terminating real server in this service, then handle it later
1626-
if proxier.gracefuldeleteManager.InTerminationList(uniqueRS) {
1627-
okayToDelete = false
1628-
break
1630+
klog.V(5).Infof("Using graceful delete to delete: %v", uniqueRS)
1631+
if err := proxier.gracefuldeleteManager.GracefulDeleteRS(svc, rs); err != nil {
1632+
klog.Errorf("Failed to delete destination: %v, error: %v", uniqueRS, err)
16291633
}
16301634
}
1635+
// make sure it does not fall within an excluded CIDR range.
16311636
for _, excludedCIDR := range proxier.excludeCIDRs {
16321637
// Any validation of this CIDR already should have occurred.
16331638
_, n, _ := net.ParseCIDR(excludedCIDR)
@@ -1637,26 +1642,33 @@ func (proxier *Proxier) cleanLegacyService(activeServices map[string]bool, curre
16371642
}
16381643
}
16391644
if okayToDelete {
1645+
klog.V(4).Infof("Delete service %s", svc.String())
16401646
if err := proxier.ipvs.DeleteVirtualServer(svc); err != nil {
1641-
klog.Errorf("Failed to delete service, error: %v", err)
1647+
klog.Errorf("Failed to delete service %s, error: %v", svc.String(), err)
1648+
}
1649+
addr := svc.Address.String()
1650+
if _, ok := legacyBindAddrs[addr]; ok {
1651+
klog.V(4).Infof("Unbinding address %s", addr)
1652+
if err := proxier.netlinkHandle.UnbindAddress(addr, DefaultDummyDevice); err != nil {
1653+
klog.Errorf("Failed to unbind service addr %s from dummy interface %s: %v", addr, DefaultDummyDevice, err)
1654+
} else {
1655+
// In case we delete a multi-port service, avoid trying to unbind multiple times
1656+
delete(legacyBindAddrs, addr)
1657+
}
16421658
}
16431659
}
16441660
}
16451661
}
16461662
}
16471663

1648-
func (proxier *Proxier) cleanLegacyBindAddr(activeBindAddrs map[string]bool, currentBindAddrs []string) {
1664+
func (proxier *Proxier) getLegacyBindAddr(activeBindAddrs map[string]bool, currentBindAddrs []string) map[string]bool {
1665+
legacyAddrs := make(map[string]bool)
16491666
for _, addr := range currentBindAddrs {
16501667
if _, ok := activeBindAddrs[addr]; !ok {
1651-
// This address was not processed in the latest sync loop
1652-
klog.V(4).Infof("Unbind addr %s", addr)
1653-
err := proxier.netlinkHandle.UnbindAddress(addr, DefaultDummyDevice)
1654-
// Ignore no such address error when try to unbind address
1655-
if err != nil {
1656-
klog.Errorf("Failed to unbind service addr %s from dummy interface %s: %v", addr, DefaultDummyDevice, err)
1657-
}
1668+
legacyAddrs[addr] = true
16581669
}
16591670
}
1671+
return legacyAddrs
16601672
}
16611673

16621674
// Join all words with spaces, terminate with newline and write to buff.

0 commit comments

Comments
 (0)