Skip to content

Commit

Permalink
Remove support for Canal and the vxlan Flannel backend for k8s 1.17+
Browse files Browse the repository at this point in the history
  • Loading branch information
johngmyers committed Apr 10, 2020
1 parent d0dea75 commit 2b5e086
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 24 deletions.
3 changes: 3 additions & 0 deletions docs/releases/1.17-NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ the notes prior to the release).
* Since 1.16, a controller is now used to apply labels to nodes. If
you are not using AWS, GCE or OpenStack your (non-master) nodes may
not have labels applied correctly.

* As of Kubernetes 1.17 the Canal CNI and the "vxlan" backend of the Flannel CNI
are no longer supported due to [a bug in Flannel](https://github.com/coreos/flannel/issues/1243).

# Required Actions

Expand Down
1 change: 1 addition & 0 deletions pkg/apis/kops/validation/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ go_test(
deps = [
"//pkg/apis/kops:go_default_library",
"//upup/pkg/fi:go_default_library",
"//vendor/github.com/blang/semver:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
Expand Down
45 changes: 27 additions & 18 deletions pkg/apis/kops/validation/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import (

func newValidateCluster(cluster *kops.Cluster) field.ErrorList {
allErrs := validation.ValidateObjectMeta(&cluster.ObjectMeta, false, validation.NameIsDNSSubdomain, field.NewPath("metadata"))
allErrs = append(allErrs, validateClusterSpec(&cluster.Spec, field.NewPath("spec"))...)
allErrs = append(allErrs, validateClusterSpec(&cluster.Spec, cluster, field.NewPath("spec"))...)

// Additional cloud-specific validation rules
switch kops.CloudProviderID(cluster.Spec.CloudProvider) {
Expand All @@ -48,7 +48,7 @@ func newValidateCluster(cluster *kops.Cluster) field.ErrorList {
return allErrs
}

func validateClusterSpec(spec *kops.ClusterSpec, fieldPath *field.Path) field.ErrorList {
func validateClusterSpec(spec *kops.ClusterSpec, c *kops.Cluster, fieldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}

allErrs = append(allErrs, validateSubnets(spec.Subnets, fieldPath.Child("subnets"))...)
Expand Down Expand Up @@ -89,7 +89,7 @@ func validateClusterSpec(spec *kops.ClusterSpec, fieldPath *field.Path) field.Er
}

if spec.Networking != nil {
allErrs = append(allErrs, validateNetworking(spec, spec.Networking, fieldPath.Child("networking"))...)
allErrs = append(allErrs, validateNetworking(spec.Networking, c, fieldPath.Child("networking"))...)
if spec.Networking.Calico != nil {
allErrs = append(allErrs, validateNetworkingCalico(spec.Networking.Calico, spec.EtcdClusters[0], fieldPath.Child("networking", "calico"))...)
}
Expand Down Expand Up @@ -285,7 +285,7 @@ func validateKubeAPIServer(v *kops.KubeAPIServerConfig, fldPath *field.Path) fie
return allErrs
}

func validateNetworking(c *kops.ClusterSpec, v *kops.NetworkingSpec, fldPath *field.Path) field.ErrorList {
func validateNetworking(v *kops.NetworkingSpec, c *kops.Cluster, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
optionTaken := false

Expand Down Expand Up @@ -331,7 +331,7 @@ func validateNetworking(c *kops.ClusterSpec, v *kops.NetworkingSpec, fldPath *fi
}
optionTaken = true

allErrs = append(allErrs, validateNetworkingFlannel(v.Flannel, fldPath.Child("flannel"))...)
allErrs = append(allErrs, validateNetworkingFlannel(v.Flannel, c, fldPath.Child("flannel"))...)
}

if v.Calico != nil {
Expand All @@ -347,7 +347,7 @@ func validateNetworking(c *kops.ClusterSpec, v *kops.NetworkingSpec, fldPath *fi
}
optionTaken = true

allErrs = append(allErrs, validateNetworkingCanal(v.Canal, fldPath.Child("canal"))...)
allErrs = append(allErrs, validateNetworkingCanal(v.Canal, c, fldPath.Child("canal"))...)
}

if v.Kuberouter != nil {
Expand All @@ -370,7 +370,7 @@ func validateNetworking(c *kops.ClusterSpec, v *kops.NetworkingSpec, fldPath *fi
}
optionTaken = true

if c.CloudProvider != "aws" {
if c.Spec.CloudProvider != "aws" {
allErrs = append(allErrs, field.Forbidden(fldPath.Child("amazonvpc"), "amazon-vpc-routed-eni networking is supported only in AWS"))
}
}
Expand All @@ -381,7 +381,7 @@ func validateNetworking(c *kops.ClusterSpec, v *kops.NetworkingSpec, fldPath *fi
}
optionTaken = true

allErrs = append(allErrs, validateNetworkingCilium(c, v.Cilium, fldPath.Child("cilium"))...)
allErrs = append(allErrs, validateNetworkingCilium(v.Cilium, c, fldPath.Child("cilium"))...)
}

if v.LyftVPC != nil {
Expand All @@ -390,7 +390,7 @@ func validateNetworking(c *kops.ClusterSpec, v *kops.NetworkingSpec, fldPath *fi
}
optionTaken = true

if c.CloudProvider != "aws" {
if c.Spec.CloudProvider != "aws" {
allErrs = append(allErrs, field.Forbidden(fldPath.Child("lyftvpc"), "amazon-vpc-routed-eni networking is supported only in AWS"))
}
}
Expand All @@ -401,27 +401,36 @@ func validateNetworking(c *kops.ClusterSpec, v *kops.NetworkingSpec, fldPath *fi
}
optionTaken = true

allErrs = append(allErrs, validateNetworkingGCE(c, v.GCE, fldPath.Child("gce"))...)
allErrs = append(allErrs, validateNetworkingGCE(v.GCE, c, fldPath.Child("gce"))...)
}

return allErrs
}

func validateNetworkingFlannel(v *kops.FlannelNetworkingSpec, fldPath *field.Path) field.ErrorList {
func validateNetworkingFlannel(v *kops.FlannelNetworkingSpec, c *kops.Cluster, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}

supported := []string{"udp"}
if !c.IsKubernetesGTE("1.17") {
supported = append(supported, "vxlan")
}

if v.Backend == "" {
allErrs = append(allErrs, field.Required(fldPath.Child("backend"), "Flannel backend must be specified"))
} else {
allErrs = append(allErrs, IsValidValue(fldPath.Child("backend"), &v.Backend, []string{"udp", "vxlan"})...)
allErrs = append(allErrs, IsValidValue(fldPath.Child("backend"), &v.Backend, supported)...)
}

return allErrs
}

func validateNetworkingCanal(v *kops.CanalNetworkingSpec, fldPath *field.Path) field.ErrorList {
func validateNetworkingCanal(v *kops.CanalNetworkingSpec, c *kops.Cluster, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}

if c.IsKubernetesGTE("1.17") {
return append(allErrs, field.Forbidden(fldPath.Child("canal"), "Canal CNI is not supported as of Kubernetes 1.17"))
}

if v.DefaultEndpointToHostAction != "" {
valid := []string{"ACCEPT", "DROP", "RETURN"}
allErrs = append(allErrs, IsValidValue(fldPath.Child("defaultEndpointToHostAction"), &v.DefaultEndpointToHostAction, valid)...)
Expand All @@ -445,10 +454,10 @@ func validateNetworkingCanal(v *kops.CanalNetworkingSpec, fldPath *field.Path) f
return allErrs
}

func validateNetworkingCilium(c *kops.ClusterSpec, v *kops.CiliumNetworkingSpec, fldPath *field.Path) field.ErrorList {
func validateNetworkingCilium(v *kops.CiliumNetworkingSpec, c *kops.Cluster, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}

if v.EnableNodePort && c.KubeProxy != nil && (c.KubeProxy.Enabled == nil || *c.KubeProxy.Enabled) {
if v.EnableNodePort && c.Spec.KubeProxy != nil && (c.Spec.KubeProxy.Enabled == nil || *c.Spec.KubeProxy.Enabled) {
allErrs = append(allErrs, field.Forbidden(fldPath.Root().Child("spec", "kubeProxy", "enabled"), "When Cilium NodePort is enabled, kubeProxy must be disabled"))
}

Expand All @@ -473,7 +482,7 @@ func validateNetworkingCilium(c *kops.ClusterSpec, v *kops.CiliumNetworkingSpec,
allErrs = append(allErrs, IsValidValue(fldPath.Child("ipam"), &v.Ipam, []string{"crd", "eni"})...)

if v.Ipam == kops.CiliumIpamEni {
if c.CloudProvider != string(kops.CloudProviderAWS) {
if c.Spec.CloudProvider != string(kops.CloudProviderAWS) {
allErrs = append(allErrs, field.Forbidden(fldPath.Child("ipam"), "Cilum ENI IPAM is supported only in AWS"))
}
if !v.DisableMasquerade {
Expand All @@ -485,10 +494,10 @@ func validateNetworkingCilium(c *kops.ClusterSpec, v *kops.CiliumNetworkingSpec,
return allErrs
}

func validateNetworkingGCE(c *kops.ClusterSpec, v *kops.GCENetworkingSpec, fldPath *field.Path) field.ErrorList {
func validateNetworkingGCE(v *kops.GCENetworkingSpec, c *kops.Cluster, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}

if c.CloudProvider != "gce" {
if c.Spec.CloudProvider != "gce" {
allErrs = append(allErrs, field.Forbidden(fldPath, "gce networking is supported only when on GCP"))
}

Expand Down
16 changes: 10 additions & 6 deletions pkg/apis/kops/validation/validation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -284,9 +284,10 @@ func Test_Validate_Networking_Flannel(t *testing.T) {
networking.Flannel = &g.Input

cluster := &kops.Cluster{}
cluster.Spec.KubernetesVersion = "1.16.0"
cluster.Spec.Networking = networking

errs := validateNetworking(&cluster.Spec, networking, field.NewPath("networking"))
errs := validateNetworking(networking, cluster, field.NewPath("networking"))
testErrors(t, g.Input, errs, g.ExpectedErrors)
}
}
Expand Down Expand Up @@ -330,13 +331,16 @@ func Test_Validate_AdditionalPolicies(t *testing.T) {
},
}
for _, g := range grid {
clusterSpec := &kops.ClusterSpec{
AdditionalPolicies: &g.Input,
Subnets: []kops.ClusterSubnetSpec{
{Name: "subnet1"},
cluster := &kops.Cluster{
Spec: kops.ClusterSpec{
KubernetesVersion: "1.16.0",
AdditionalPolicies: &g.Input,
Subnets: []kops.ClusterSubnetSpec{
{Name: "subnet1"},
},
},
}
errs := validateClusterSpec(clusterSpec, field.NewPath("spec"))
errs := validateClusterSpec(&cluster.Spec, cluster, field.NewPath("spec"))
testErrors(t, g.Input, errs, g.ExpectedErrors)
}
}
Expand Down

0 comments on commit 2b5e086

Please sign in to comment.