Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support configurable network V4 CIDR for Pod traffic across Node (#2473) #2663

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions build/yamls/antrea-aks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3911,9 +3911,20 @@ data:
#tlsMinVersion:

# The name of the interface on Node which is used for tunneling or routing the traffic across Nodes.
# If there are multiple IP addresses configured on the interface, the first one is used.
# The interface configured with Node IP is used if this parameter is not set.
# If there are multiple IP addresses configured on the interface, the first one is used. The order for
# configuring tunneling or routing the traffic across Nodes is (from highest to lowest):
# 1.TransportInterface
# 2.TransportV4CIDR
# 3.The Node IP.
#transportInterface:

# The network V4 CIDR of the interface on Node which is used for tunneling or routing the traffic across
# Nodes. If there are multiple interfaces configured the same network V4 CIDR, the first one is used. The
# order for configuring tunneling or routing the traffic across Nodes is (from highest to lowest):
# 1.TransportInterface
# 2.TransportV4CIDR
# 3.The Node IP
#transportV4CIDR:
antrea-cni.conflist: |
{
"cniVersion":"0.3.0",
Expand Down
15 changes: 13 additions & 2 deletions build/yamls/antrea-eks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3911,9 +3911,20 @@ data:
#tlsMinVersion:

# The name of the interface on Node which is used for tunneling or routing the traffic across Nodes.
# If there are multiple IP addresses configured on the interface, the first one is used.
# The interface configured with Node IP is used if this parameter is not set.
# If there are multiple IP addresses configured on the interface, the first one is used. The order for
# configuring tunneling or routing the traffic across Nodes is (from highest to lowest):
# 1.TransportInterface
# 2.TransportV4CIDR
# 3.The Node IP.
#transportInterface:

# The network V4 CIDR of the interface on Node which is used for tunneling or routing the traffic across
# Nodes. If there are multiple interfaces configured the same network V4 CIDR, the first one is used. The
# order for configuring tunneling or routing the traffic across Nodes is (from highest to lowest):
# 1.TransportInterface
# 2.TransportV4CIDR
# 3.The Node IP
#transportV4CIDR:
antrea-cni.conflist: |
{
"cniVersion":"0.3.0",
Expand Down
15 changes: 13 additions & 2 deletions build/yamls/antrea-gke.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3911,9 +3911,20 @@ data:
#tlsMinVersion:

# The name of the interface on Node which is used for tunneling or routing the traffic across Nodes.
# If there are multiple IP addresses configured on the interface, the first one is used.
# The interface configured with Node IP is used if this parameter is not set.
# If there are multiple IP addresses configured on the interface, the first one is used. The order for
# configuring tunneling or routing the traffic across Nodes is (from highest to lowest):
# 1.TransportInterface
# 2.TransportV4CIDR
# 3.The Node IP.
#transportInterface:

# The network V4 CIDR of the interface on Node which is used for tunneling or routing the traffic across
# Nodes. If there are multiple interfaces configured the same network V4 CIDR, the first one is used. The
# order for configuring tunneling or routing the traffic across Nodes is (from highest to lowest):
# 1.TransportInterface
# 2.TransportV4CIDR
# 3.The Node IP
#transportV4CIDR:
antrea-cni.conflist: |
{
"cniVersion":"0.3.0",
Expand Down
15 changes: 13 additions & 2 deletions build/yamls/antrea-ipsec.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3916,9 +3916,20 @@ data:
#tlsMinVersion:

# The name of the interface on Node which is used for tunneling or routing the traffic across Nodes.
# If there are multiple IP addresses configured on the interface, the first one is used.
# The interface configured with Node IP is used if this parameter is not set.
# If there are multiple IP addresses configured on the interface, the first one is used. The order for
# configuring tunneling or routing the traffic across Nodes is (from highest to lowest):
# 1.TransportInterface
# 2.TransportV4CIDR
# 3.The Node IP.
#transportInterface:

# The network V4 CIDR of the interface on Node which is used for tunneling or routing the traffic across
# Nodes. If there are multiple interfaces configured the same network V4 CIDR, the first one is used. The
# order for configuring tunneling or routing the traffic across Nodes is (from highest to lowest):
# 1.TransportInterface
# 2.TransportV4CIDR
# 3.The Node IP
#transportV4CIDR:
antrea-cni.conflist: |
{
"cniVersion":"0.3.0",
Expand Down
15 changes: 13 additions & 2 deletions build/yamls/antrea-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,20 @@ data:
#trafficEncapMode: encap

# The name of the interface on Node which is used for tunneling or routing the traffic across Nodes.
# If there are multiple IP addresses configured on the interface, the first one is used.
# The interface configured with Node IP is used if this parameter is not set.
# If there are multiple IP addresses configured on the interface, the first one is used. The order for
# configuring tunneling or routing the traffic across Nodes is (from highest to lowest):
# 1.TransportInterface
# 2.TransportV4CIDR
# 3.The Node IP.
#transportInterface:

# The network V4 CIDR of the interface on Node which is used for tunneling or routing the traffic across
# Nodes. If there are multiple interfaces configured the same network V4 CIDR, the first one is used. The
# order for configuring tunneling or routing the traffic across Nodes is (from highest to lowest):
# 1.TransportInterface
# 2.TransportV4CIDR
# 3.The Node IP
#transportV4CIDR:
antrea-cni.conflist: |
{
"cniVersion":"0.3.0",
Expand Down
15 changes: 13 additions & 2 deletions build/yamls/antrea.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3916,9 +3916,20 @@ data:
#tlsMinVersion:

# The name of the interface on Node which is used for tunneling or routing the traffic across Nodes.
# If there are multiple IP addresses configured on the interface, the first one is used.
# The interface configured with Node IP is used if this parameter is not set.
# If there are multiple IP addresses configured on the interface, the first one is used. The order for
# configuring tunneling or routing the traffic across Nodes is (from highest to lowest):
# 1.TransportInterface
# 2.TransportV4CIDR
# 3.The Node IP.
#transportInterface:

# The network V4 CIDR of the interface on Node which is used for tunneling or routing the traffic across
# Nodes. If there are multiple interfaces configured the same network V4 CIDR, the first one is used. The
# order for configuring tunneling or routing the traffic across Nodes is (from highest to lowest):
# 1.TransportInterface
# 2.TransportV4CIDR
# 3.The Node IP
#transportV4CIDR:
antrea-cni.conflist: |
{
"cniVersion":"0.3.0",
Expand Down
15 changes: 13 additions & 2 deletions build/yamls/base/conf/antrea-agent.conf
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,17 @@ wireGuard:
#tlsMinVersion:

# The name of the interface on Node which is used for tunneling or routing the traffic across Nodes.
# If there are multiple IP addresses configured on the interface, the first one is used.
# The interface configured with Node IP is used if this parameter is not set.
# If there are multiple IP addresses configured on the interface, the first one is used. The order for
# configuring tunneling or routing the traffic across Nodes is (from highest to lowest):
# 1.TransportInterface
# 2.TransportV4CIDR
# 3.The Node IP.
#transportInterface:

# The network V4 CIDR of the interface on Node which is used for tunneling or routing the traffic across
# Nodes. If there are multiple interfaces configured the same network V4 CIDR, the first one is used. The
# order for configuring tunneling or routing the traffic across Nodes is (from highest to lowest):
# 1.TransportInterface
# 2.TransportV4CIDR
# 3.The Node IP
#transportV4CIDR:
1 change: 1 addition & 0 deletions cmd/antrea-agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ func run(o *Options) error {
TrafficEncapMode: encapMode,
TrafficEncryptionMode: encryptionMode,
TransportIface: o.config.TransportInterface,
TransportV4CIDR: o.config.TransportV4CIDR,
}

wireguardConfig := &config.WireGuardConfig{
Expand Down
14 changes: 12 additions & 2 deletions cmd/antrea-agent/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,9 +159,19 @@ type AgentConfig struct {
// TLS min version.
TLSMinVersion string `yaml:"tlsMinVersion,omitempty"`
// The name of the interface on Node which is used for tunneling or routing the traffic across Nodes.
// If there are multiple IP addresses configured on the interface, the first one is used.
// The interface configured with Node IP is used if this parameter is not set.
// If there are multiple IP addresses configured on the interface, the first one is used. The order for
// configuring tunneling or routing the traffic across Nodes is (from highest to lowest):
// 1.TransportInterface
// 2.TransportV4CIDR
// 3.The Node IP
TransportInterface string `yaml:"transportInterface,omitempty"`
// The network CIDR of the interface on Node which is used for tunneling or routing the traffic across
// Nodes. If there are multiple interfaces configured the same network CIDR, the first one is used. The
// order for configuring tunneling or routing the traffic across Nodes is (from highest to lowest):
// 1.TransportInterface
// 2.TransportV4CIDR
// 3.The Node IP
TransportV4CIDR string `yaml:"transportV4CIDR,omitempty"`
}

type WireGuardConfig struct {
Expand Down
23 changes: 19 additions & 4 deletions pkg/agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,16 @@ const (
maxRetryForRoundNumSave = 5
)

// getIPNetDeviceFromIP is meant to be overridden for testing.
var getIPNetDeviceFromIP = util.GetIPNetDeviceFromIP
var (
// getIPNetDeviceFromIP is meant to be overridden for testing.
getIPNetDeviceFromIP = util.GetIPNetDeviceFromIP

// getTransportIPNetDeviceByName is meant to be overridden for testing.
var getTransportIPNetDeviceByName = GetTransportIPNetDeviceByName
// getIPNetDeviceByV4CIDR is meant to be overridden for testing.
getIPNetDeviceByV4CIDR = util.GetIPNetDeviceByV4CIDR

// getTransportIPNetDeviceByName is meant to be overridden for testing.
getTransportIPNetDeviceByName = GetTransportIPNetDeviceByName
)

// Initializer knows how to setup host networking, OpenVSwitch, and Openflow.
type Initializer struct {
Expand Down Expand Up @@ -728,6 +733,16 @@ func (i *Initializer) initNodeLocalConfig() error {
if err := i.patchNodeAnnotations(nodeName, types.NodeTransportAddressAnnotationKey, strings.Join(ips, ",")); err != nil {
return err
}
} else if i.networkConfig.TransportV4CIDR != "" {
transportIPv4Addr, localIntf, err = getIPNetDeviceByV4CIDR(i.networkConfig.TransportV4CIDR)
if err != nil {
return fmt.Errorf("failed to get local IPNet device with transport CIDR %s: %v", i.networkConfig.TransportV4CIDR, err)
}
ips := []string{transportIPv4Addr.IP.String()}
klog.InfoS("Updating Node transport addresses annotation")
if err := i.patchNodeAnnotations(nodeName, types.NodeTransportAddressAnnotationKey, strings.Join(ips, ",")); err != nil {
return err
}
} else {
// Remove the existing annotation "transport-address" if transportInterface is not set in the configuration.
if node.Annotations[types.NodeTransportAddressAnnotationKey] != "" {
Expand Down
75 changes: 73 additions & 2 deletions pkg/agent/agent_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,8 @@ func TestInitNodeLocalConfig(t *testing.T) {
}
podCIDRStr := "172.16.10.0/24"
_, podCIDR, _ := net.ParseCIDR(podCIDRStr)
transportIP, transportIPNet, _ := net.ParseCIDR("172.16.100.7/24")
transportV4CIDRStr := "172.16.100.7/24"
transportIP, transportIPNet, _ := net.ParseCIDR(transportV4CIDRStr)
transportIPNet.IP = transportIP
transportIfaceMAC, _ := net.ParseMAC("00:0c:29:f5:e2:ce")
type testTransInterface struct {
Expand All @@ -177,6 +178,8 @@ func TestInitNodeLocalConfig(t *testing.T) {
tests := []struct {
name string
trafficEncapMode config.TrafficEncapModeType
transportIfName string
transportIfV4CIDR string
transportInterface *testTransInterface
tunnelType ovsconfig.TunnelType
mtu int
Expand Down Expand Up @@ -221,6 +224,7 @@ func TestInitNodeLocalConfig(t *testing.T) {
{
name: "noencap mode with transportInterface",
trafficEncapMode: config.TrafficEncapModeNoEncap,
transportIfName: testTransportIface.iface.Name,
transportInterface: testTransportIface,
mtu: 0,
expectedNodeLocalIfaceMTU: 1500,
Expand All @@ -233,6 +237,7 @@ func TestInitNodeLocalConfig(t *testing.T) {
{
name: "hybrid mode with transportInterface",
trafficEncapMode: config.TrafficEncapModeHybrid,
transportIfName: testTransportIface.iface.Name,
transportInterface: testTransportIface,
mtu: 0,
expectedNodeLocalIfaceMTU: 1500,
Expand All @@ -245,6 +250,7 @@ func TestInitNodeLocalConfig(t *testing.T) {
{
name: "encap mode with transportInterface, geneve tunnel",
trafficEncapMode: config.TrafficEncapModeEncap,
transportIfName: testTransportIface.iface.Name,
transportInterface: testTransportIface,
tunnelType: ovsconfig.GeneveTunnel,
mtu: 0,
Expand All @@ -257,6 +263,59 @@ func TestInitNodeLocalConfig(t *testing.T) {
{
name: "encap mode with transportInterface, mtu specified",
trafficEncapMode: config.TrafficEncapModeEncap,
transportIfName: testTransportIface.iface.Name,
transportInterface: testTransportIface,
tunnelType: ovsconfig.GeneveTunnel,
mtu: 1400,
expectedNodeLocalIfaceMTU: 1500,
expectedMTU: 1400,
expectedNodeAnnotation: map[string]string{
types.NodeTransportAddressAnnotationKey: transportIP.String(),
},
},
{
name: "noencap mode with transportV4CIDR",
trafficEncapMode: config.TrafficEncapModeNoEncap,
transportIfV4CIDR: transportV4CIDRStr,
transportInterface: testTransportIface,
mtu: 0,
expectedNodeLocalIfaceMTU: 1500,
expectedMTU: 1500,
expectedNodeAnnotation: map[string]string{
types.NodeMACAddressAnnotationKey: transportIfaceMAC.String(),
types.NodeTransportAddressAnnotationKey: transportIP.String(),
},
},
{
name: "hybrid mode with transportV4CIDR",
trafficEncapMode: config.TrafficEncapModeHybrid,
transportIfV4CIDR: transportV4CIDRStr,
transportInterface: testTransportIface,
mtu: 0,
expectedNodeLocalIfaceMTU: 1500,
expectedMTU: 1500,
expectedNodeAnnotation: map[string]string{
types.NodeMACAddressAnnotationKey: transportIfaceMAC.String(),
types.NodeTransportAddressAnnotationKey: transportIP.String(),
},
},
{
name: "encap mode with transportV4CIDR, geneve tunnel",
trafficEncapMode: config.TrafficEncapModeEncap,
transportIfV4CIDR: transportV4CIDRStr,
transportInterface: testTransportIface,
tunnelType: ovsconfig.GeneveTunnel,
mtu: 0,
expectedNodeLocalIfaceMTU: 1500,
expectedMTU: 1450,
expectedNodeAnnotation: map[string]string{
types.NodeTransportAddressAnnotationKey: transportIP.String(),
},
},
{
name: "encap mode with transportV4CIDR, mtu specified",
trafficEncapMode: config.TrafficEncapModeEncap,
transportIfV4CIDR: transportV4CIDRStr,
transportInterface: testTransportIface,
tunnelType: ovsconfig.GeneveTunnel,
mtu: 1400,
Expand Down Expand Up @@ -309,10 +368,14 @@ func TestInitNodeLocalConfig(t *testing.T) {
TunnelType: tt.tunnelType,
},
}
if tt.transportInterface != nil {
if tt.transportIfName != "" {
initializer.networkConfig.TransportIface = tt.transportInterface.iface.Name
expectedNodeConfig.NodeTransportIPv4Addr = tt.transportInterface.ipNet
defer mockGetTransportIPNetDeviceByName(tt.transportInterface.ipNet, tt.transportInterface.iface)()
} else if tt.transportIfV4CIDR != "" {
initializer.networkConfig.TransportV4CIDR = transportV4CIDRStr
expectedNodeConfig.NodeTransportIPv4Addr = tt.transportInterface.ipNet
defer mockGetIPNetDeviceByV4CIDR(tt.transportInterface.ipNet, tt.transportInterface.iface)()
}
defer mockGetIPNetDeviceFromIP(nodeIPNet, ipDevice)()
defer mockNodeNameEnv(nodeName)()
Expand Down Expand Up @@ -346,3 +409,11 @@ func mockGetTransportIPNetDeviceByName(ipNet *net.IPNet, ipDevice *net.Interface
}
return func() { getTransportIPNetDeviceByName = prevGetIPNetDeviceByName }
}

func mockGetIPNetDeviceByV4CIDR(ipNet *net.IPNet, ipDevice *net.Interface) func() {
prevGetIPNetDeviceByV4CIDR := getIPNetDeviceByV4CIDR
getIPNetDeviceByV4CIDR = func(ifName string) (*net.IPNet, *net.Interface, error) {
return ipNet, ipDevice, nil
}
return func() { getIPNetDeviceByV4CIDR = prevGetIPNetDeviceByV4CIDR }
}
1 change: 1 addition & 0 deletions pkg/agent/config/node_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ type NetworkConfig struct {
TrafficEncryptionMode TrafficEncryptionModeType
IPSecPSK string
TransportIface string
TransportV4CIDR string
}

// IsIPv4Enabled returns true if the cluster network supports IPv4.
Expand Down
4 changes: 2 additions & 2 deletions pkg/agent/controller/noderoute/node_route_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -739,8 +739,8 @@ func getNodeMAC(node *corev1.Node) (net.HardwareAddr, error) {
}

func (c *Controller) getNodeTransportAddrs(node *corev1.Node) (*utilip.DualStackIPs, error) {
var transportAddrs *utilip.DualStackIPs
if c.networkConfig.TransportIface != "" {
transportAddrs := &utilip.DualStackIPs{}
if c.networkConfig.TransportIface != "" || c.networkConfig.TransportV4CIDR != "" {
transportAddrsStr := node.Annotations[types.NodeTransportAddressAnnotationKey]
if transportAddrsStr != "" {
for _, addr := range strings.Split(transportAddrsStr, ",") {
Expand Down
Loading