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

Add a RoutingMode option to cniConfig #6766

Merged
merged 3 commits into from
Dec 12, 2023
Merged
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
23 changes: 23 additions & 0 deletions config/crd/bases/anywhere.eks.amazonaws.com_clusters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,34 @@ spec:
network interfaces are used for masquerading. Accepted
values are a valid interface name or interface prefix.
type: string
ipv4NativeRoutingCIDR:
description: IPv4NativeRoutingCIDR specifies the CIDR
to use when RoutingMode is set to direct. When specified,
Cilium assumes networking for this CIDR is preconfigured
and hands traffic destined for that range to the Linux
network stack without applying any SNAT. If this is
not set autoDirectNodeRoutes will be set to true
type: string
ipv6NativeRoutingCIDR:
description: IPv6NativeRoutingCIDR specifies the IPv6
CIDR to use when RoutingMode is set to direct. When
specified, Cilium assumes networking for this CIDR is
preconfigured and hands traffic destined for that range
to the Linux network stack without applying any SNAT.
If this is not set autoDirectNodeRoutes will be set
to true
type: string
policyEnforcementMode:
description: PolicyEnforcementMode determines communication
allowed between pods. Accepted values are default, always,
never.
type: string
routingMode:
description: RoutingMode indicates the routing tunnel
mode to use for Cilium. Accepted values are overlay
(geneve tunnel with overlay) or direct (tunneling disabled
with direct routing) Defaults to overlay.
type: string
skipUpgrade:
description: SkipUpgrade indicicates that Cilium maintenance
chrisdoherty4 marked this conversation as resolved.
Show resolved Hide resolved
should be skipped during upgrades. This can be used
Expand Down
23 changes: 23 additions & 0 deletions docs/content/en/docs/getting-started/optional/cni.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,29 @@ spec:
egressMasqueradeInterfaces: "eth0"
```

### RoutingMode option for Cilium plugin

By default all traffic is sent by Cilium over Geneve tunneling on the network. The `routingMode` option allows users to switch to [native routing](https://docs.cilium.io/en/v1.12/concepts/networking/routing/#native-routing) instead.

This field can be set as follows:
```yaml
apiVersion: anywhere.eks.amazonaws.com/v1alpha1
kind: Cluster
metadata:
name: my-cluster-name
spec:
clusterNetwork:
pods:
cidrBlocks:
- 192.168.0.0/16
services:
cidrBlocks:
- 10.96.0.0/12
cniConfig:
cilium:
routingMode: "direct"
```

### Use a custom CNI

EKS Anywhere can be configured to skip EKS Anywhere's default Cilium CNI upgrades via the `skipUpgrade` field.
Expand Down
10 changes: 10 additions & 0 deletions internal/pkg/api/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,16 @@ func WithCiliumSkipUpgrade() ClusterFiller {
}
}

// WithCiliumRoutingMode sets the tunnel mode with the provided mode option to use.
func WithCiliumRoutingMode(mode anywherev1.CiliumRoutingMode) ClusterFiller {
return func(c *anywherev1.Cluster) {
if c.Spec.ClusterNetwork.CNIConfig == nil {
c.Spec.ClusterNetwork.CNIConfig = &anywherev1.CNIConfig{Cilium: &anywherev1.CiliumConfig{}}
}
c.Spec.ClusterNetwork.CNIConfig.Cilium.RoutingMode = mode
}
}

func WithClusterNamespace(ns string) ClusterFiller {
return func(c *anywherev1.Cluster) {
c.Namespace = ns
Expand Down
46 changes: 44 additions & 2 deletions pkg/api/v1alpha1/cluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,10 @@
return false
}

if n.RoutingMode != o.RoutingMode {
return false
}

Check warning on line 631 in pkg/api/v1alpha1/cluster_types.go

View check run for this annotation

Codecov / codecov/patch

pkg/api/v1alpha1/cluster_types.go#L629-L631

Added lines #L629 - L631 were not covered by tests

oSkipUpgradeIsFalse := o.SkipUpgrade == nil || !*o.SkipUpgrade
nSkipUpgradeIsFalse := n.SkipUpgrade == nil || !*n.SkipUpgrade

Expand Down Expand Up @@ -825,6 +829,8 @@

type CiliumPolicyEnforcementMode string

type CiliumRoutingMode string

type CNIConfig struct {
Cilium *CiliumConfig `json:"cilium,omitempty"`
Kindnetd *KindnetdConfig `json:"kindnetd,omitempty"`
Expand All @@ -835,6 +841,7 @@
return n != nil && (n.Kindnetd != nil || n.Cilium != nil && n.Cilium.IsManaged())
}

// CiliumConfig contains configuration specific to the Cilium CNI.
type CiliumConfig struct {
// PolicyEnforcementMode determines communication allowed between pods. Accepted values are default, always, never.
PolicyEnforcementMode CiliumPolicyEnforcementMode `json:"policyEnforcementMode,omitempty"`
Expand All @@ -847,6 +854,28 @@
// be used when operators wish to self manage the Cilium installation.
// +optional
SkipUpgrade *bool `json:"skipUpgrade,omitempty"`

// RoutingMode indicates the routing tunnel mode to use for Cilium. Accepted values are overlay (geneve tunnel with overlay)
// or direct (tunneling disabled with direct routing)
// Defaults to overlay.
// +optional
RoutingMode CiliumRoutingMode `json:"routingMode,omitempty"`

// IPv4NativeRoutingCIDR specifies the CIDR to use when RoutingMode is set to direct.
// When specified, Cilium assumes networking for this CIDR is preconfigured and
// hands traffic destined for that range to the Linux network stack without
// applying any SNAT.
// If this is not set autoDirectNodeRoutes will be set to true
// +optional
IPv4NativeRoutingCIDR string `json:"ipv4NativeRoutingCIDR,omitempty"`

// IPv6NativeRoutingCIDR specifies the IPv6 CIDR to use when RoutingMode is set to direct.
// When specified, Cilium assumes networking for this CIDR is preconfigured and
// hands traffic destined for that range to the Linux network stack without
// applying any SNAT.
// If this is not set autoDirectNodeRoutes will be set to true
// +optional
IPv6NativeRoutingCIDR string `json:"ipv6NativeRoutingCIDR,omitempty"`
}

// IsManaged returns true if SkipUpgrade is nil or false indicating EKS-A is responsible for
Expand All @@ -855,19 +884,26 @@
return n.SkipUpgrade == nil || !*n.SkipUpgrade
}

// KindnetdConfig contains configuration specific to the Kindnetd CNI.
type KindnetdConfig struct{}

const (
Cilium CNI = "cilium"
// Cilium is the EKS-A Cilium.
Cilium CNI = "cilium"

// CiliumEnterprise is Isovalents Cilium.
CiliumEnterprise CNI = "cilium-enterprise"
Kindnetd CNI = "kindnetd"

// Kindnetd is the CNI shipped with KinD.
Kindnetd CNI = "kindnetd"
)

var validCNIs = map[CNI]struct{}{
Cilium: {},
Kindnetd: {},
}

// Policy enforcement modes for Cilium.
const (
CiliumPolicyModeDefault CiliumPolicyEnforcementMode = "default"
CiliumPolicyModeAlways CiliumPolicyEnforcementMode = "always"
Expand All @@ -880,6 +916,12 @@
CiliumPolicyModeNever: true,
}

// Routing modes for Cilium.
const (
CiliumRoutingModeOverlay CiliumRoutingMode = "overlay"
CiliumRoutingModeDirect CiliumRoutingMode = "direct"
)

// FailureReasonType is a type for defining failure reasons.
type FailureReasonType string

Expand Down
12 changes: 12 additions & 0 deletions pkg/networking/cilium/templater.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,18 @@ func templateValues(spec *cluster.Spec, versionsBundle *cluster.VersionsBundle)
val["egressMasqueradeInterfaces"] = spec.Cluster.Spec.ClusterNetwork.CNIConfig.Cilium.EgressMasqueradeInterfaces
}

if spec.Cluster.Spec.ClusterNetwork.CNIConfig.Cilium.RoutingMode == anywherev1.CiliumRoutingModeDirect {
val["tunnel"] = "disabled"

if spec.Cluster.Spec.ClusterNetwork.CNIConfig.Cilium.IPv4NativeRoutingCIDR == "" &&
spec.Cluster.Spec.ClusterNetwork.CNIConfig.Cilium.IPv6NativeRoutingCIDR == "" {
val["autoDirectNodeRoutes"] = "true"
} else {
val["ipv4NativeRoutingCIDR"] = spec.Cluster.Spec.ClusterNetwork.CNIConfig.Cilium.IPv4NativeRoutingCIDR
val["ipv6NativeRoutingCIDR"] = spec.Cluster.Spec.ClusterNetwork.CNIConfig.Cilium.IPv6NativeRoutingCIDR
}
}

return val
}

Expand Down
79 changes: 79 additions & 0 deletions pkg/networking/cilium/templater_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,85 @@ func TestTemplaterGenerateManifestEgressMasqueradeInterfacesSuccess(t *testing.T
tt.Expect(tt.t.GenerateManifest(tt.ctx, tt.spec)).To(Equal(tt.manifest), "templater.GenerateManifest() should return right manifest")
}

func TestTemplaterGenerateManifestDirectRouteModeSuccess(t *testing.T) {
wantValues := map[string]interface{}{
"cni": map[string]interface{}{
"chainingMode": "portmap",
},
"ipam": map[string]interface{}{
"mode": "kubernetes",
},
"identityAllocationMode": "crd",
"prometheus": map[string]interface{}{
"enabled": true,
},
"rollOutCiliumPods": true,
"tunnel": "disabled",
"autoDirectNodeRoutes": "true",
"image": map[string]interface{}{
"repository": "public.ecr.aws/isovalent/cilium",
"tag": "v1.9.11-eksa.1",
},
"operator": map[string]interface{}{
"image": map[string]interface{}{
"repository": "public.ecr.aws/isovalent/operator",
"tag": "v1.9.11-eksa.1",
},
"prometheus": map[string]interface{}{
"enabled": true,
},
},
}

tt := newtemplaterTest(t)
tt.spec.Cluster.Spec.ManagementCluster.Name = "managed"
tt.spec.Cluster.Spec.ClusterNetwork.CNIConfig.Cilium.RoutingMode = v1alpha1.CiliumRoutingModeDirect
tt.expectHelmTemplateWith(eqMap(wantValues), "1.22").Return(tt.manifest, nil)

tt.Expect(tt.t.GenerateManifest(tt.ctx, tt.spec)).To(Equal(tt.manifest), "templater.GenerateManifest() should return right manifest")
}

func TestTemplaterGenerateManifestDirectModeManualIPCIDRSuccess(t *testing.T) {
wantValues := map[string]interface{}{
"cni": map[string]interface{}{
"chainingMode": "portmap",
},
"ipam": map[string]interface{}{
"mode": "kubernetes",
},
"identityAllocationMode": "crd",
"prometheus": map[string]interface{}{
"enabled": true,
},
"rollOutCiliumPods": true,
"tunnel": "disabled",
"ipv4NativeRoutingCIDR": "192.168.0.0/24",
"ipv6NativeRoutingCIDR": "2001:db8::/32",
"image": map[string]interface{}{
"repository": "public.ecr.aws/isovalent/cilium",
"tag": "v1.9.11-eksa.1",
},
"operator": map[string]interface{}{
"image": map[string]interface{}{
"repository": "public.ecr.aws/isovalent/operator",
"tag": "v1.9.11-eksa.1",
},
"prometheus": map[string]interface{}{
"enabled": true,
},
},
}

tt := newtemplaterTest(t)
tt.spec.Cluster.Spec.ManagementCluster.Name = "managed"
tt.spec.Cluster.Spec.ClusterNetwork.CNIConfig.Cilium.RoutingMode = v1alpha1.CiliumRoutingModeDirect
tt.spec.Cluster.Spec.ClusterNetwork.CNIConfig.Cilium.IPv4NativeRoutingCIDR = "192.168.0.0/24"
tt.spec.Cluster.Spec.ClusterNetwork.CNIConfig.Cilium.IPv6NativeRoutingCIDR = "2001:db8::/32"
tt.expectHelmTemplateWith(eqMap(wantValues), "1.22").Return(tt.manifest, nil)

tt.Expect(tt.t.GenerateManifest(tt.ctx, tt.spec)).To(Equal(tt.manifest), "templater.GenerateManifest() should return right manifest")
}

func TestTemplaterGenerateManifestError(t *testing.T) {
expectedAttempts := 2
tt := newtemplaterTest(t)
Expand Down