Skip to content

Commit 2107534

Browse files
authored
Fixes regression, where adding service VIP to the tunnel interface inside the pods when DSR is used was failing (#462)
1 parent 327a46d commit 2107534

File tree

3 files changed

+44
-18
lines changed

3 files changed

+44
-18
lines changed

pkg/controllers/proxy/network_services_controller.go

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ type ipvsCalls interface {
7474
}
7575

7676
type netlinkCalls interface {
77-
ipAddrAdd(iface netlink.Link, ip string) error
77+
ipAddrAdd(iface netlink.Link, ip string, addRoute bool) error
7878
ipAddrDel(iface netlink.Link, ip string) error
7979
prepareEndpointForDsr(containerId string, endpointIP string, vip string) error
8080
getKubeDummyInterface() (netlink.Link, error)
@@ -104,7 +104,10 @@ func (ln *linuxNetworking) ipAddrDel(iface netlink.Link, ip string) error {
104104
return err
105105
}
106106

107-
func (ln *linuxNetworking) ipAddrAdd(iface netlink.Link, ip string) error {
107+
// utility method to assign an IP to an interface. Mainly used to assign service VIP's
108+
// to kube-dummy-if. Also when DSR is used, used to assign VIP to dummy interface
109+
// inside the container.
110+
func (ln *linuxNetworking) ipAddrAdd(iface netlink.Link, ip string, addRoute bool) error {
108111
naddr := &netlink.Addr{IPNet: &net.IPNet{IP: net.ParseIP(ip), Mask: net.IPv4Mask(255, 255, 255, 255)}, Scope: syscall.RT_SCOPE_LINK}
109112
err := netlink.AddrAdd(iface, naddr)
110113
if err != nil && err.Error() != IFACE_HAS_ADDR {
@@ -113,6 +116,15 @@ func (ln *linuxNetworking) ipAddrAdd(iface netlink.Link, ip string) error {
113116
return err
114117
}
115118

119+
// When a service VIP is assigned to a dummy interface and accessed from host, in some of the
120+
// case Linux source IP selection logix selects VIP itself as source leading to problems
121+
// to avoid this an explicit entry is added to use node IP as source IP when accessing
122+
// VIP from the host. Please see https://github.com/cloudnativelabs/kube-router/issues/376
123+
124+
if !addRoute {
125+
return nil
126+
}
127+
116128
// TODO: netlink.RouteReplace which is replacement for below command is not working as expected. Call succeeds but
117129
// route is not replaced. For now do it with command.
118130
out, err := exec.Command("ip", "route", "replace", "local", ip, "dev", KUBE_DUMMY_IF, "table", "local", "proto", "kernel", "scope", "host", "src",
@@ -122,27 +134,35 @@ func (ln *linuxNetworking) ipAddrAdd(iface netlink.Link, ip string) error {
122134
}
123135
return nil
124136
}
137+
125138
func (ln *linuxNetworking) ipvsGetServices() ([]*ipvs.Service, error) {
126139
return ln.ipvsHandle.GetServices()
127140
}
141+
128142
func (ln *linuxNetworking) ipvsGetDestinations(ipvsSvc *ipvs.Service) ([]*ipvs.Destination, error) {
129143
return ln.ipvsHandle.GetDestinations(ipvsSvc)
130144
}
145+
131146
func (ln *linuxNetworking) ipvsDelDestination(ipvsSvc *ipvs.Service, ipvsDst *ipvs.Destination) error {
132147
return ln.ipvsHandle.DelDestination(ipvsSvc, ipvsDst)
133148
}
149+
134150
func (ln *linuxNetworking) ipvsNewDestination(ipvsSvc *ipvs.Service, ipvsDst *ipvs.Destination) error {
135151
return ln.ipvsHandle.NewDestination(ipvsSvc, ipvsDst)
136152
}
153+
137154
func (ln *linuxNetworking) ipvsUpdateDestination(ipvsSvc *ipvs.Service, ipvsDst *ipvs.Destination) error {
138155
return ln.ipvsHandle.UpdateDestination(ipvsSvc, ipvsDst)
139156
}
157+
140158
func (ln *linuxNetworking) ipvsDelService(ipvsSvc *ipvs.Service) error {
141159
return ln.ipvsHandle.DelService(ipvsSvc)
142160
}
161+
143162
func (ln *linuxNetworking) ipvsUpdateService(ipvsSvc *ipvs.Service) error {
144163
return ln.ipvsHandle.UpdateService(ipvsSvc)
145164
}
165+
146166
func (ln *linuxNetworking) ipvsNewService(ipvsSvc *ipvs.Service) error {
147167
return ln.ipvsHandle.NewService(ipvsSvc)
148168
}
@@ -526,7 +546,7 @@ func (nsc *NetworkServicesController) syncIpvsServices(serviceInfoMap serviceInf
526546
}
527547

528548
// assign cluster IP of the service to the dummy interface so that its routable from the pod's on the node
529-
err := nsc.ln.ipAddrAdd(dummyVipInterface, svc.clusterIP.String())
549+
err := nsc.ln.ipAddrAdd(dummyVipInterface, svc.clusterIP.String(), true)
530550
if err != nil {
531551
continue
532552
}
@@ -636,7 +656,7 @@ func (nsc *NetworkServicesController) syncIpvsServices(serviceInfoMap serviceInf
636656
}
637657
} else {
638658
// ensure director with vip assigned
639-
err := nsc.ln.ipAddrAdd(dummyVipInterface, externalIP)
659+
err := nsc.ln.ipAddrAdd(dummyVipInterface, externalIP, true)
640660
if err != nil && err.Error() != IFACE_HAS_ADDR {
641661
glog.Errorf("Failed to assign external ip %s to dummy interface %s due to %s", externalIP, KUBE_DUMMY_IF, err.Error())
642662
}
@@ -981,7 +1001,7 @@ func (ln *linuxNetworking) prepareEndpointForDsr(containerId string, endpointIP
9811001
}
9821002

9831003
// assign VIP to the KUBE_TUNNEL_IF interface
984-
err = ln.ipAddrAdd(tunIf, vip)
1004+
err = ln.ipAddrAdd(tunIf, vip, false)
9851005
if err != nil && err.Error() != IFACE_HAS_ADDR {
9861006
netns.Set(hostNetworkNamespaceHandle)
9871007
activeNetworkNamespaceHandle, err = netns.Get()

pkg/controllers/proxy/network_services_controller_moq.go

Lines changed: 18 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/controllers/proxy/network_services_controller_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ func (lnm *LinuxNetworkingMockImpl) ipvsGetServices() ([]*ipvs.Service, error) {
4646
copy(svcsCopy, lnm.ipvsSvcs)
4747
return svcsCopy, nil
4848
}
49-
func (lnm *LinuxNetworkingMockImpl) ipAddrAdd(iface netlink.Link, addr string) error {
49+
func (lnm *LinuxNetworkingMockImpl) ipAddrAdd(iface netlink.Link, addr string, addRouter bool) error {
5050
return nil
5151
}
5252
func (lnm *LinuxNetworkingMockImpl) ipvsAddServer(ipvsSvc *ipvs.Service, ipvsDst *ipvs.Destination, local bool, podCidr string) error {

0 commit comments

Comments
 (0)