Merge pull request #1501 from sanimej/vip
Enable ping for service vip address
This commit is contained in:
commit
b1e753137f
|
@ -1131,3 +1131,20 @@ func (c *controller) cleanupLocalEndpoints() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ep *endpoint) setAliasIP(sb *sandbox, ip net.IP, add bool) error {
|
||||||
|
sb.Lock()
|
||||||
|
sbox := sb.osSbox
|
||||||
|
sb.Unlock()
|
||||||
|
|
||||||
|
for _, i := range sbox.Info().Interfaces() {
|
||||||
|
if ep.hasInterface(i.SrcName()) {
|
||||||
|
ipNet := &net.IPNet{IP: ip, Mask: []byte{255, 255, 255, 255}}
|
||||||
|
if err := i.SetAliasIP(ipNet, add); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -26,7 +26,6 @@ type nwIface struct {
|
||||||
mac net.HardwareAddr
|
mac net.HardwareAddr
|
||||||
address *net.IPNet
|
address *net.IPNet
|
||||||
addressIPv6 *net.IPNet
|
addressIPv6 *net.IPNet
|
||||||
ipAliases []*net.IPNet
|
|
||||||
llAddrs []*net.IPNet
|
llAddrs []*net.IPNet
|
||||||
routes []*net.IPNet
|
routes []*net.IPNet
|
||||||
bridge bool
|
bridge bool
|
||||||
|
@ -97,13 +96,6 @@ func (i *nwIface) LinkLocalAddresses() []*net.IPNet {
|
||||||
return i.llAddrs
|
return i.llAddrs
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *nwIface) IPAliases() []*net.IPNet {
|
|
||||||
i.Lock()
|
|
||||||
defer i.Unlock()
|
|
||||||
|
|
||||||
return i.ipAliases
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i *nwIface) Routes() []*net.IPNet {
|
func (i *nwIface) Routes() []*net.IPNet {
|
||||||
i.Lock()
|
i.Lock()
|
||||||
defer i.Unlock()
|
defer i.Unlock()
|
||||||
|
@ -130,6 +122,28 @@ func (n *networkNamespace) Interfaces() []Interface {
|
||||||
return ifaces
|
return ifaces
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (i *nwIface) SetAliasIP(ip *net.IPNet, add bool) error {
|
||||||
|
i.Lock()
|
||||||
|
n := i.ns
|
||||||
|
i.Unlock()
|
||||||
|
|
||||||
|
n.Lock()
|
||||||
|
nlh := n.nlHandle
|
||||||
|
n.Unlock()
|
||||||
|
|
||||||
|
// Find the network interface identified by the DstName attribute.
|
||||||
|
iface, err := nlh.LinkByName(i.DstName())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
ipAddr := &netlink.Addr{IPNet: ip, Label: ""}
|
||||||
|
if add {
|
||||||
|
return nlh.AddrAdd(iface, ipAddr)
|
||||||
|
}
|
||||||
|
return nlh.AddrDel(iface, ipAddr)
|
||||||
|
}
|
||||||
|
|
||||||
func (i *nwIface) Remove() error {
|
func (i *nwIface) Remove() error {
|
||||||
i.Lock()
|
i.Lock()
|
||||||
n := i.ns
|
n := i.ns
|
||||||
|
@ -333,7 +347,6 @@ func configureInterface(nlh *netlink.Handle, iface netlink.Link, i *nwIface) err
|
||||||
{setInterfaceIPv6, fmt.Sprintf("error setting interface %q IPv6 to %v", ifaceName, i.AddressIPv6())},
|
{setInterfaceIPv6, fmt.Sprintf("error setting interface %q IPv6 to %v", ifaceName, i.AddressIPv6())},
|
||||||
{setInterfaceMaster, fmt.Sprintf("error setting interface %q master to %q", ifaceName, i.DstMaster())},
|
{setInterfaceMaster, fmt.Sprintf("error setting interface %q master to %q", ifaceName, i.DstMaster())},
|
||||||
{setInterfaceLinkLocalIPs, fmt.Sprintf("error setting interface %q link local IPs to %v", ifaceName, i.LinkLocalAddresses())},
|
{setInterfaceLinkLocalIPs, fmt.Sprintf("error setting interface %q link local IPs to %v", ifaceName, i.LinkLocalAddresses())},
|
||||||
{setInterfaceIPAliases, fmt.Sprintf("error setting interface %q IP Aliases to %v", ifaceName, i.IPAliases())},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, config := range ifaceConfigurators {
|
for _, config := range ifaceConfigurators {
|
||||||
|
@ -387,16 +400,6 @@ func setInterfaceLinkLocalIPs(nlh *netlink.Handle, iface netlink.Link, i *nwIfac
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func setInterfaceIPAliases(nlh *netlink.Handle, iface netlink.Link, i *nwIface) error {
|
|
||||||
for _, si := range i.IPAliases() {
|
|
||||||
ipAddr := &netlink.Addr{IPNet: si}
|
|
||||||
if err := nlh.AddrAdd(iface, ipAddr); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func setInterfaceName(nlh *netlink.Handle, iface netlink.Link, i *nwIface) error {
|
func setInterfaceName(nlh *netlink.Handle, iface netlink.Link, i *nwIface) error {
|
||||||
return nlh.LinkSetName(iface, i.DstName())
|
return nlh.LinkSetName(iface, i.DstName())
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,12 +66,6 @@ func (n *networkNamespace) LinkLocalAddresses(list []*net.IPNet) IfaceOption {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *networkNamespace) IPAliases(list []*net.IPNet) IfaceOption {
|
|
||||||
return func(i *nwIface) {
|
|
||||||
i.ipAliases = list
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *networkNamespace) Routes(routes []*net.IPNet) IfaceOption {
|
func (n *networkNamespace) Routes(routes []*net.IPNet) IfaceOption {
|
||||||
return func(i *nwIface) {
|
return func(i *nwIface) {
|
||||||
i.routes = routes
|
i.routes = routes
|
||||||
|
|
|
@ -91,9 +91,6 @@ type IfaceOptionSetter interface {
|
||||||
// LinkLocalAddresses returns an option setter to set the link-local IP addresses.
|
// LinkLocalAddresses returns an option setter to set the link-local IP addresses.
|
||||||
LinkLocalAddresses([]*net.IPNet) IfaceOption
|
LinkLocalAddresses([]*net.IPNet) IfaceOption
|
||||||
|
|
||||||
// IPAliases returns an option setter to set IP address Aliases
|
|
||||||
IPAliases([]*net.IPNet) IfaceOption
|
|
||||||
|
|
||||||
// Master returns an option setter to set the master interface if any for this
|
// Master returns an option setter to set the master interface if any for this
|
||||||
// interface. The master interface name should refer to the srcname of a
|
// interface. The master interface name should refer to the srcname of a
|
||||||
// previously added interface of type bridge.
|
// previously added interface of type bridge.
|
||||||
|
@ -150,9 +147,6 @@ type Interface interface {
|
||||||
// LinkLocalAddresses returns the link-local IP addresses assigned to the interface.
|
// LinkLocalAddresses returns the link-local IP addresses assigned to the interface.
|
||||||
LinkLocalAddresses() []*net.IPNet
|
LinkLocalAddresses() []*net.IPNet
|
||||||
|
|
||||||
// IPAliases returns the IP address aliases assigned to the interface.
|
|
||||||
IPAliases() []*net.IPNet
|
|
||||||
|
|
||||||
// IP routes for the interface.
|
// IP routes for the interface.
|
||||||
Routes() []*net.IPNet
|
Routes() []*net.IPNet
|
||||||
|
|
||||||
|
@ -166,6 +160,10 @@ type Interface interface {
|
||||||
// and moving it out of the sandbox.
|
// and moving it out of the sandbox.
|
||||||
Remove() error
|
Remove() error
|
||||||
|
|
||||||
|
// SetAliasIP adds or deletes the passed IP as an alias on the interface.
|
||||||
|
// ex: set the vip of services in the same network as secondary IP.
|
||||||
|
SetAliasIP(ip *net.IPNet, add bool) error
|
||||||
|
|
||||||
// Statistics returns the statistics for this interface
|
// Statistics returns the statistics for this interface
|
||||||
Statistics() (*types.InterfaceStatistics, error)
|
Statistics() (*types.InterfaceStatistics, error)
|
||||||
}
|
}
|
||||||
|
|
|
@ -725,10 +725,6 @@ func (sb *sandbox) restoreOslSandbox() error {
|
||||||
if len(i.llAddrs) != 0 {
|
if len(i.llAddrs) != 0 {
|
||||||
ifaceOptions = append(ifaceOptions, sb.osSbox.InterfaceOptions().LinkLocalAddresses(i.llAddrs))
|
ifaceOptions = append(ifaceOptions, sb.osSbox.InterfaceOptions().LinkLocalAddresses(i.llAddrs))
|
||||||
}
|
}
|
||||||
if len(ep.virtualIP) != 0 {
|
|
||||||
vipAlias := &net.IPNet{IP: ep.virtualIP, Mask: net.CIDRMask(32, 32)}
|
|
||||||
ifaceOptions = append(ifaceOptions, sb.osSbox.InterfaceOptions().IPAliases([]*net.IPNet{vipAlias}))
|
|
||||||
}
|
|
||||||
Ifaces[fmt.Sprintf("%s+%s", i.srcName, i.dstPrefix)] = ifaceOptions
|
Ifaces[fmt.Sprintf("%s+%s", i.srcName, i.dstPrefix)] = ifaceOptions
|
||||||
if joinInfo != nil {
|
if joinInfo != nil {
|
||||||
for _, r := range joinInfo.StaticRoutes {
|
for _, r := range joinInfo.StaticRoutes {
|
||||||
|
@ -782,10 +778,6 @@ func (sb *sandbox) populateNetworkResources(ep *endpoint) error {
|
||||||
if len(i.llAddrs) != 0 {
|
if len(i.llAddrs) != 0 {
|
||||||
ifaceOptions = append(ifaceOptions, sb.osSbox.InterfaceOptions().LinkLocalAddresses(i.llAddrs))
|
ifaceOptions = append(ifaceOptions, sb.osSbox.InterfaceOptions().LinkLocalAddresses(i.llAddrs))
|
||||||
}
|
}
|
||||||
if len(ep.virtualIP) != 0 {
|
|
||||||
vipAlias := &net.IPNet{IP: ep.virtualIP, Mask: net.CIDRMask(32, 32)}
|
|
||||||
ifaceOptions = append(ifaceOptions, sb.osSbox.InterfaceOptions().IPAliases([]*net.IPNet{vipAlias}))
|
|
||||||
}
|
|
||||||
if i.mac != nil {
|
if i.mac != nil {
|
||||||
ifaceOptions = append(ifaceOptions, sb.osSbox.InterfaceOptions().MacAddress(i.mac))
|
ifaceOptions = append(ifaceOptions, sb.osSbox.InterfaceOptions().MacAddress(i.mac))
|
||||||
}
|
}
|
||||||
|
|
|
@ -317,6 +317,14 @@ func (sb *sandbox) populateLoadbalancers(ep *endpoint) {
|
||||||
for _, ip := range lb.backEnds {
|
for _, ip := range lb.backEnds {
|
||||||
sb.addLBBackend(ip, lb.vip, lb.fwMark, lb.service.ingressPorts,
|
sb.addLBBackend(ip, lb.vip, lb.fwMark, lb.service.ingressPorts,
|
||||||
eIP, gwIP, addService, n.ingress)
|
eIP, gwIP, addService, n.ingress)
|
||||||
|
// For a new service program the vip as an alias on the task's sandbox interface
|
||||||
|
// connected to this network.
|
||||||
|
if !addService {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err := ep.setAliasIP(sb, lb.vip, true); err != nil {
|
||||||
|
logrus.Errorf("Adding Service VIP %v to ep %v(%v) failed: %v", lb.vip, ep.ID(), ep.Name(), err)
|
||||||
|
}
|
||||||
addService = false
|
addService = false
|
||||||
}
|
}
|
||||||
lb.service.Unlock()
|
lb.service.Unlock()
|
||||||
|
@ -340,8 +348,16 @@ func (n *network) addLBBackend(ip, vip net.IP, fwMark uint32, ingressPorts []*Po
|
||||||
}
|
}
|
||||||
|
|
||||||
sb.addLBBackend(ip, vip, fwMark, ingressPorts, ep.Iface().Address(), gwIP, addService, n.ingress)
|
sb.addLBBackend(ip, vip, fwMark, ingressPorts, ep.Iface().Address(), gwIP, addService, n.ingress)
|
||||||
}
|
|
||||||
|
|
||||||
|
// For a new service program the vip as an alias on the task's sandbox interface
|
||||||
|
// connected to this network.
|
||||||
|
if !addService {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if err := ep.setAliasIP(sb, vip, true); err != nil {
|
||||||
|
logrus.Errorf("Adding Service VIP %v to ep %v(%v) failed: %v", vip, ep.ID(), ep.Name(), err)
|
||||||
|
}
|
||||||
|
}
|
||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -363,8 +379,16 @@ func (n *network) rmLBBackend(ip, vip net.IP, fwMark uint32, ingressPorts []*Por
|
||||||
}
|
}
|
||||||
|
|
||||||
sb.rmLBBackend(ip, vip, fwMark, ingressPorts, ep.Iface().Address(), gwIP, rmService, n.ingress)
|
sb.rmLBBackend(ip, vip, fwMark, ingressPorts, ep.Iface().Address(), gwIP, rmService, n.ingress)
|
||||||
}
|
|
||||||
|
|
||||||
|
// If the service is being remove its vip alias on on the task's sandbox interface
|
||||||
|
// has to be removed as well.
|
||||||
|
if !rmService {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if err := ep.setAliasIP(sb, vip, false); err != nil {
|
||||||
|
logrus.Errorf("Removing Service VIP %v from ep %v(%v) failed: %v", vip, ep.ID(), ep.Name(), err)
|
||||||
|
}
|
||||||
|
}
|
||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue