Skip to content

Commit

Permalink
[IPv6] Add support for dual-stack when using kube-proxy for Service (#…
Browse files Browse the repository at this point in the history
…1200)

1. Add a config item for IPv6 Serivce CIDR if using kube-proxy to
   provide Service functions.
2. Output IPv6 traffic from host gateway if its destination is a
   Service address.
3. Use ct_mark to identify Service traffic and output the reply
   packet to the host gateway to ensure the DNAT processing in iptables.
  • Loading branch information
wenyingd authored and lzhecheng committed Nov 11, 2020
1 parent 23accf0 commit 60a247b
Show file tree
Hide file tree
Showing 20 changed files with 347 additions and 179 deletions.
9 changes: 8 additions & 1 deletion build/yamls/antrea-aks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1056,7 +1056,8 @@ data:
featureGates:
# Enable AntreaProxy which provides ServiceLB for in-cluster Services in antrea-agent.
# It should be enabled on Windows, otherwise NetworkPolicy will not take effect on
# Service traffic.
# Service traffic. Antrea proxy doesn't support an IPv6 only cluster or a Dual-Stack cluster
# before PR #1102[https://github.com/vmware-tanzu/antrea/pull/1102] is merged.
AntreaProxy: true
# Enable traceflow which provides packet tracing feature to diagnose network issue.
Expand Down Expand Up @@ -1124,6 +1125,12 @@ data:
# for the GRE tunnel type.
#enableIPSecTunnel: false
# ClusterIP CIDR range for IPv6 Services. It's required when using kube-proxy to provide IPv6 Service in a Dual-Stack
# cluster or an IPv6 only cluster. The value should be the same as the configuration for kube-apiserver specified by
# --service-cluster-ip-range. When AntreaProxy is enabled, this parameter is not needed.
# No default value for this field.
#serviceCIDRv6:
# The port for the antrea-agent APIServer to serve on.
# Note that if it's set to another value, the `containerPort` of the `api` port of the
# `antrea-agent` container must be set to the same value.
Expand Down
9 changes: 8 additions & 1 deletion build/yamls/antrea-eks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1056,7 +1056,8 @@ data:
featureGates:
# Enable AntreaProxy which provides ServiceLB for in-cluster Services in antrea-agent.
# It should be enabled on Windows, otherwise NetworkPolicy will not take effect on
# Service traffic.
# Service traffic. Antrea proxy doesn't support an IPv6 only cluster or a Dual-Stack cluster
# before PR #1102[https://github.com/vmware-tanzu/antrea/pull/1102] is merged.
AntreaProxy: true
# Enable traceflow which provides packet tracing feature to diagnose network issue.
Expand Down Expand Up @@ -1124,6 +1125,12 @@ data:
# for the GRE tunnel type.
#enableIPSecTunnel: false
# ClusterIP CIDR range for IPv6 Services. It's required when using kube-proxy to provide IPv6 Service in a Dual-Stack
# cluster or an IPv6 only cluster. The value should be the same as the configuration for kube-apiserver specified by
# --service-cluster-ip-range. When AntreaProxy is enabled, this parameter is not needed.
# No default value for this field.
#serviceCIDRv6:
# The port for the antrea-agent APIServer to serve on.
# Note that if it's set to another value, the `containerPort` of the `api` port of the
# `antrea-agent` container must be set to the same value.
Expand Down
9 changes: 8 additions & 1 deletion build/yamls/antrea-gke.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1056,7 +1056,8 @@ data:
featureGates:
# Enable AntreaProxy which provides ServiceLB for in-cluster Services in antrea-agent.
# It should be enabled on Windows, otherwise NetworkPolicy will not take effect on
# Service traffic.
# Service traffic. Antrea proxy doesn't support an IPv6 only cluster or a Dual-Stack cluster
# before PR #1102[https://github.com/vmware-tanzu/antrea/pull/1102] is merged.
AntreaProxy: true
# Enable traceflow which provides packet tracing feature to diagnose network issue.
Expand Down Expand Up @@ -1124,6 +1125,12 @@ data:
# for the GRE tunnel type.
#enableIPSecTunnel: false
# ClusterIP CIDR range for IPv6 Services. It's required when using kube-proxy to provide IPv6 Service in a Dual-Stack
# cluster or an IPv6 only cluster. The value should be the same as the configuration for kube-apiserver specified by
# --service-cluster-ip-range. When AntreaProxy is enabled, this parameter is not needed.
# No default value for this field.
#serviceCIDRv6:
# The port for the antrea-agent APIServer to serve on.
# Note that if it's set to another value, the `containerPort` of the `api` port of the
# `antrea-agent` container must be set to the same value.
Expand Down
9 changes: 8 additions & 1 deletion build/yamls/antrea-ipsec.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1056,7 +1056,8 @@ data:
featureGates:
# Enable AntreaProxy which provides ServiceLB for in-cluster Services in antrea-agent.
# It should be enabled on Windows, otherwise NetworkPolicy will not take effect on
# Service traffic.
# Service traffic. Antrea proxy doesn't support an IPv6 only cluster or a Dual-Stack cluster
# before PR #1102[https://github.com/vmware-tanzu/antrea/pull/1102] is merged.
# AntreaProxy: false
# Enable traceflow which provides packet tracing feature to diagnose network issue.
Expand Down Expand Up @@ -1129,6 +1130,12 @@ data:
# AntreaProxy is enabled, this parameter is not needed and will be ignored if provided.
#serviceCIDR: 10.96.0.0/12
# ClusterIP CIDR range for IPv6 Services. It's required when using kube-proxy to provide IPv6 Service in a Dual-Stack
# cluster or an IPv6 only cluster. The value should be the same as the configuration for kube-apiserver specified by
# --service-cluster-ip-range. When AntreaProxy is enabled, this parameter is not needed.
# No default value for this field.
#serviceCIDRv6:
# The port for the antrea-agent APIServer to serve on.
# Note that if it's set to another value, the `containerPort` of the `api` port of the
# `antrea-agent` container must be set to the same value.
Expand Down
9 changes: 8 additions & 1 deletion build/yamls/antrea.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1056,7 +1056,8 @@ data:
featureGates:
# Enable AntreaProxy which provides ServiceLB for in-cluster Services in antrea-agent.
# It should be enabled on Windows, otherwise NetworkPolicy will not take effect on
# Service traffic.
# Service traffic. Antrea proxy doesn't support an IPv6 only cluster or a Dual-Stack cluster
# before PR #1102[https://github.com/vmware-tanzu/antrea/pull/1102] is merged.
# AntreaProxy: false
# Enable traceflow which provides packet tracing feature to diagnose network issue.
Expand Down Expand Up @@ -1129,6 +1130,12 @@ data:
# AntreaProxy is enabled, this parameter is not needed and will be ignored if provided.
#serviceCIDR: 10.96.0.0/12
# ClusterIP CIDR range for IPv6 Services. It's required when using kube-proxy to provide IPv6 Service in a Dual-Stack
# cluster or an IPv6 only cluster. The value should be the same as the configuration for kube-apiserver specified by
# --service-cluster-ip-range. When AntreaProxy is enabled, this parameter is not needed.
# No default value for this field.
#serviceCIDRv6:
# The port for the antrea-agent APIServer to serve on.
# Note that if it's set to another value, the `containerPort` of the `api` port of the
# `antrea-agent` container must be set to the same value.
Expand Down
9 changes: 8 additions & 1 deletion build/yamls/base/conf/antrea-agent.conf
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
featureGates:
# Enable AntreaProxy which provides ServiceLB for in-cluster Services in antrea-agent.
# It should be enabled on Windows, otherwise NetworkPolicy will not take effect on
# Service traffic.
# Service traffic. Antrea proxy doesn't support an IPv6 only cluster or a Dual-Stack cluster
# before PR #1102[https://github.com/vmware-tanzu/antrea/pull/1102] is merged.
# AntreaProxy: false

# Enable traceflow which provides packet tracing feature to diagnose network issue.
Expand Down Expand Up @@ -75,6 +76,12 @@ featureGates:
# AntreaProxy is enabled, this parameter is not needed and will be ignored if provided.
#serviceCIDR: 10.96.0.0/12

# ClusterIP CIDR range for IPv6 Services. It's required when using kube-proxy to provide IPv6 Service in a Dual-Stack
# cluster or an IPv6 only cluster. The value should be the same as the configuration for kube-apiserver specified by
# --service-cluster-ip-range. When AntreaProxy is enabled, this parameter is not needed.
# No default value for this field.
#serviceCIDRv6:

# The port for the antrea-agent APIServer to serve on.
# Note that if it's set to another value, the `containerPort` of the `api` port of the
# `antrea-agent` container must be set to the same value.
Expand Down
7 changes: 7 additions & 0 deletions cmd/antrea-agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,12 @@ func run(o *Options) error {
features.DefaultFeatureGate.Enabled(features.AntreaPolicy))

_, serviceCIDRNet, _ := net.ParseCIDR(o.config.ServiceCIDR)
var serviceCIDRNetv6 *net.IPNet
// Todo: use FeatureGate to check if IPv6 is enabled and then read configuration item "ServiceCIDRv6".
if o.config.ServiceCIDRv6 != "" {
_, serviceCIDRNetv6, _ = net.ParseCIDR(o.config.ServiceCIDRv6)
}

_, encapMode := config.GetTrafficEncapModeFromStr(o.config.TrafficEncapMode)
networkConfig := &config.NetworkConfig{
TunnelType: ovsconfig.TunnelType(o.config.TunnelType),
Expand Down Expand Up @@ -122,6 +128,7 @@ func run(o *Options) error {
o.config.HostGateway,
o.config.DefaultMTU,
serviceCIDRNet,
serviceCIDRNetv6,
networkConfig,
networkReadyCh,
features.DefaultFeatureGate.Enabled(features.AntreaProxy))
Expand Down
5 changes: 5 additions & 0 deletions cmd/antrea-agent/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ type AgentConfig struct {
// AntreaProxy is enabled, this parameter is not needed and will be ignored if provided.
// Default is 10.96.0.0/12
ServiceCIDR string `yaml:"serviceCIDR,omitempty"`
// ClusterIP CIDR range for IPv6 Services. It's required when using kube-proxy to provide IPv6 Service in a Dual-Stack
// cluster or an IPv6 only cluster. The value should be the same as the configuration for kube-apiserver specified by
// --service-cluster-ip-range. When AntreaProxy is enabled, this parameter is not needed.
// No default value for this field.
ServiceCIDRv6 string `yaml:"serviceCIDRv6,omitempty"`
// Whether or not to enable IPSec (ESP) encryption for Pod traffic across Nodes. IPSec encryption
// is supported only for the GRE tunnel type. Antrea uses Preshared Key (PSK) for IKE
// authentication. When IPSec tunnel is enabled, the PSK value must be passed to Antrea Agent
Expand Down
8 changes: 7 additions & 1 deletion cmd/antrea-agent/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,13 @@ func (o *Options) validate(args []string) error {
// Validate service CIDR configuration
_, _, err := net.ParseCIDR(o.config.ServiceCIDR)
if err != nil {
return fmt.Errorf("service CIDR %s is invalid", o.config.ServiceCIDR)
return fmt.Errorf("Service CIDR %s is invalid", o.config.ServiceCIDR)
}
if o.config.ServiceCIDRv6 != "" {
_, _, err := net.ParseCIDR(o.config.ServiceCIDRv6)
if err != nil {
return fmt.Errorf("Service CIDR v6 %s is invalid", o.config.ServiceCIDRv6)
}
}
if o.config.TunnelType != ovsconfig.VXLANTunnel && o.config.TunnelType != ovsconfig.GeneveTunnel &&
o.config.TunnelType != ovsconfig.GRETunnel && o.config.TunnelType != ovsconfig.STTTunnel {
Expand Down
7 changes: 5 additions & 2 deletions pkg/agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ type Initializer struct {
hostGateway string // name of gateway port on the OVS bridge
mtu int
serviceCIDR *net.IPNet // K8s Service ClusterIP CIDR
serviceCIDRv6 *net.IPNet // K8s Service ClusterIP CIDR in IPv6
networkConfig *config.NetworkConfig
nodeConfig *config.NodeConfig
enableProxy bool
Expand All @@ -82,6 +83,7 @@ func NewInitializer(
hostGateway string,
mtu int,
serviceCIDR *net.IPNet,
serviceCIDRv6 *net.IPNet,
networkConfig *config.NetworkConfig,
networkReadyCh chan<- struct{},
enableProxy bool) *Initializer {
Expand All @@ -95,6 +97,7 @@ func NewInitializer(
hostGateway: hostGateway,
mtu: mtu,
serviceCIDR: serviceCIDR,
serviceCIDRv6: serviceCIDRv6,
networkConfig: networkConfig,
networkReadyCh: networkReadyCh,
enableProxy: enableProxy,
Expand Down Expand Up @@ -318,8 +321,8 @@ func (i *Initializer) initOpenFlowPipeline() error {
// from local Pods to any Service address can be forwarded to the host gateway interface
// correctly. Otherwise packets might be dropped by egress rules before they are DNATed to
// backend Pods.
if err := i.ofClient.InstallClusterServiceCIDRFlows(i.serviceCIDR, gatewayOFPort); err != nil {
klog.Errorf("Failed to setup openflow entries for Cluster Service CIDR %s: %v", i.serviceCIDR, err)
if err := i.ofClient.InstallClusterServiceCIDRFlows([]*net.IPNet{i.serviceCIDR, i.serviceCIDRv6}, gatewayOFPort); err != nil {
klog.Errorf("Failed to setup OpenFlow entries for Service CIDRs: %v", err)
return err
}
} else {
Expand Down
17 changes: 8 additions & 9 deletions pkg/agent/openflow/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ type Client interface {
// InstallClusterServiceCIDRFlows sets up the appropriate flows so that traffic can reach
// the different Services running in the Cluster. This method needs to be invoked once with
// the Cluster Service CIDR as a parameter.
InstallClusterServiceCIDRFlows(serviceNet *net.IPNet, gatewayOFPort uint32) error
InstallClusterServiceCIDRFlows(serviceNets []*net.IPNet, gatewayOFPort uint32) error

// InstallClusterServiceFlows sets up the appropriate flows so that traffic can reach
// the different Services running in the Cluster. This method needs to be invoked once.
Expand Down Expand Up @@ -470,23 +470,22 @@ func (c *client) InstallClusterServiceFlows() error {
return nil
}

func (c *client) InstallClusterServiceCIDRFlows(serviceNet *net.IPNet, gatewayOFPort uint32) error {
flow := c.serviceCIDRDNATFlow(serviceNet, gatewayOFPort)
if err := c.ofEntryOperations.Add(flow); err != nil {
func (c *client) InstallClusterServiceCIDRFlows(serviceNets []*net.IPNet, gatewayOFPort uint32) error {
flows := c.serviceCIDRDNATFlows(serviceNets, gatewayOFPort)
if err := c.ofEntryOperations.AddAll(flows); err != nil {
return err
}
c.defaultServiceFlows = []binding.Flow{flow}
c.defaultServiceFlows = flows
return nil
}

func (c *client) InstallGatewayFlows(gatewayAddrs []net.IP, gatewayMAC net.HardwareAddr, gatewayOFPort uint32) error {
flows := []binding.Flow{
c.gatewayClassifierFlow(gatewayOFPort, cookie.Default),
c.ctRewriteDstMACFlow(gatewayMAC, cookie.Default),
c.l2ForwardCalcFlow(gatewayMAC, gatewayOFPort, cookie.Default),
}
hasIPv6Addr := util.ContainIPv6Addr(gatewayAddrs)
flows = append(flows, c.gatewayIPSpoofGuardFlows(gatewayOFPort, hasIPv6Addr, cookie.Default)...)
hasV4, hasV6 := util.CheckAddressFamilies(gatewayAddrs)
flows = append(flows, c.gatewayIPSpoofGuardFlows(gatewayOFPort, hasV4, hasV6, cookie.Default)...)

// Add ARP SpoofGuard flow for local gateway interface.
gwIPv4 := util.GetIPv4Addr(gatewayAddrs)
Expand All @@ -495,7 +494,7 @@ func (c *client) InstallGatewayFlows(gatewayAddrs []net.IP, gatewayMAC net.Hardw
}
// Add flow to ensure the liveness check packet could be forwarded correctly.
flows = append(flows, c.localProbeFlow(gatewayAddrs, cookie.Default)...)

flows = append(flows, c.ctRewriteDstMACFlow(gatewayMAC, hasV4, hasV6, cookie.Default)...)
// In NoEncap , no traffic from tunnel port
if c.encapMode.SupportsEncap() {
flows = append(flows, c.l3ToGatewayFlow(gatewayAddrs, gatewayMAC, cookie.Default)...)
Expand Down
Loading

0 comments on commit 60a247b

Please sign in to comment.