diff --git a/HACKING.md b/HACKING.md index 7bed3515ad..c1c7da2844 100644 --- a/HACKING.md +++ b/HACKING.md @@ -46,7 +46,7 @@ _output/linux/amd64/cluster-network-renderer --config sample-config.yaml --out o ``` ### Building images -By default, podman is used to build images. +By default, podman is used to build images. ``` ./hack/build-image.sh diff --git a/README.md b/README.md index fa1b51e0d4..71e4282942 100644 --- a/README.md +++ b/README.md @@ -132,8 +132,9 @@ spec: ``` ### Configuring OVNKubernetes -OVNKubernetes supports the following configuration options, all of which are optional: +OVNKubernetes supports the following configuration options, all of which are optional and once set at cluster creation, they can't be changed: * `MTU`: The MTU to use for the geneve overlay. The default is the MTU of the node that the cluster-network-operator is first run on, minus 100 bytes for geneve overhead. If the nodes in your cluster don't all have the same MTU then you may need to set this explicitly. +* `genevePort`: The UDP port to use for the Geneve overlay. The default is 6081. These configuration flags are only in the Operator configuration object. @@ -144,6 +145,7 @@ spec: type: OVNKubernetes ovnKubernetesConfig: mtu: 1400 + genevePort: 6081 ``` Additionally, you can configure per-node verbosity for ovn-kubernetes. This is useful @@ -366,7 +368,7 @@ spec: The operator is expected to run as a pod (via a Deployment) inside a kubernetes cluster. It will retrieve the configuration above and reconcile the desired configuration. A suitable manifest for running the operator is located in `manifests/`. ## Unsafe changes -Most network changes are unsafe to roll out to a production cluster. Therefore, the network operator will stop reconciling if it detects that an unsafe change has been requested. +Most network changes are unsafe to roll out to a production cluster. Therefore, the network operator will stop reconciling if it detects that an unsafe change has been requested. ### Safe changes to apply: It is safe to edit the following fields in the Operator configuration: diff --git a/bindata/network/ovn-kubernetes/004-config.yaml b/bindata/network/ovn-kubernetes/004-config.yaml index cc11560066..30d7a12faa 100644 --- a/bindata/network/ovn-kubernetes/004-config.yaml +++ b/bindata/network/ovn-kubernetes/004-config.yaml @@ -10,6 +10,7 @@ data: [default] mtu="{{.MTU}}" cluster-subnets="{{.OVN_cidr}}" + encap-port="{{.GenevePort}}" [kubernetes] service-cidr="{{.OVN_service_cidr}}" diff --git a/manifests/0000_70_cluster-network-operator_01_crd.yaml b/manifests/0000_70_cluster-network-operator_01_crd.yaml index 97dd62f382..73916310ed 100644 --- a/manifests/0000_70_cluster-network-operator_01_crd.yaml +++ b/manifests/0000_70_cluster-network-operator_01_crd.yaml @@ -278,8 +278,7 @@ spec: format: int32 minimum: 0 ovnKubernetesConfig: - description: oVNKubernetesConfig configures the ovn-kubernetes plugin. - This is currently not implemented. + description: ovnKubernetesConfig configures the ovn-kubernetes plugin. type: object properties: genevePort: diff --git a/pkg/network/ovn_kubernetes.go b/pkg/network/ovn_kubernetes.go index df08d49be4..bac9d95818 100644 --- a/pkg/network/ovn_kubernetes.go +++ b/pkg/network/ovn_kubernetes.go @@ -44,6 +44,7 @@ func renderOVNKubernetes(conf *operv1.NetworkSpec, bootstrapResult *bootstrap.Bo data.Data["KUBERNETES_SERVICE_PORT"] = os.Getenv("KUBERNETES_SERVICE_PORT") data.Data["K8S_APISERVER"] = fmt.Sprintf("https://%s:%s", os.Getenv("KUBERNETES_SERVICE_HOST"), os.Getenv("KUBERNETES_SERVICE_PORT")) data.Data["MTU"] = c.MTU + data.Data["GenevePort"] = c.GenevePort data.Data["CNIConfDir"] = pluginCNIConfDir(conf) data.Data["CNIBinDir"] = CNIBinDir data.Data["OVN_NB_PORT"] = OVN_NB_PORT @@ -108,6 +109,9 @@ func validateOVNKubernetes(conf *operv1.NetworkSpec) []error { if oc.MTU != nil && (*oc.MTU < 576 || *oc.MTU > 65536) { out = append(out, errors.Errorf("invalid MTU %d", *oc.MTU)) } + if oc.GenevePort != nil && (*oc.GenevePort < 1 || *oc.GenevePort > 65535) { + out = append(out, errors.Errorf("invalid GenevePort %d", *oc.GenevePort)) + } } return out @@ -123,11 +127,15 @@ func isOVNKubernetesChangeSafe(prev, next *operv1.NetworkSpec) []error { if !reflect.DeepEqual(pn.MTU, nn.MTU) { errs = append(errs, errors.Errorf("cannot change ovn-kubernetes MTU")) } + if !reflect.DeepEqual(pn.GenevePort, nn.GenevePort) { + errs = append(errs, errors.Errorf("cannot change ovn-kubernetes genevePort")) + } if pn.HybridOverlayConfig != nil { if !reflect.DeepEqual(pn.HybridOverlayConfig, nn.HybridOverlayConfig) { errs = append(errs, errors.Errorf("once set cannot change ovn-kubernetes Hybrid Overlay Config")) } } + return errs } @@ -137,16 +145,22 @@ func fillOVNKubernetesDefaults(conf, previous *operv1.NetworkSpec, hostMTU int) } sc := conf.DefaultNetwork.OVNKubernetesConfig - // MTU is currently the only field we pull from previous. - // If it's not supplied, we infer it from the node on which we're running. + // MTU is currently the only field we pull from previous. + // If MTU is not supplied, we infer it from the host on which CNO is running + // (which may not be a node in the cluster). // However, this can never change, so we always prefer previous. if sc.MTU == nil { var mtu uint32 = uint32(hostMTU) - 100 // 100 byte geneve header - if previous != nil && previous.DefaultNetwork.OVNKubernetesConfig != nil { + if previous != nil && previous.DefaultNetwork.OVNKubernetesConfig != nil && + previous.DefaultNetwork.OVNKubernetesConfig.MTU != nil { mtu = *previous.DefaultNetwork.OVNKubernetesConfig.MTU } sc.MTU = &mtu } + if sc.GenevePort == nil { + var geneve uint32 = uint32(6081) + sc.GenevePort = &geneve + } } func networkPluginName() string { diff --git a/pkg/network/ovn_kubernetes_test.go b/pkg/network/ovn_kubernetes_test.go index d9e7afcfe3..4374bbff09 100644 --- a/pkg/network/ovn_kubernetes_test.go +++ b/pkg/network/ovn_kubernetes_test.go @@ -11,6 +11,8 @@ import ( uns "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) +// vars +var g = uint32(8061) var OVNKubernetesConfig = operv1.Network{ Spec: operv1.NetworkSpec{ ServiceNetwork: []string{"172.30.0.0/16"}, @@ -25,8 +27,10 @@ var OVNKubernetesConfig = operv1.Network{ }, }, DefaultNetwork: operv1.DefaultNetworkDefinition{ - Type: operv1.NetworkTypeOVNKubernetes, - OVNKubernetesConfig: &operv1.OVNKubernetesConfig{}, + Type: operv1.NetworkTypeOVNKubernetes, + OVNKubernetesConfig: &operv1.OVNKubernetesConfig{ + GenevePort: &g, + }, }, }, } @@ -99,6 +103,7 @@ func TestFillOVNKubernetesDefaults(t *testing.T) { // vars m := uint32(8900) + p := uint32(6081) expected := operv1.NetworkSpec{ ServiceNetwork: []string{"172.30.0.0/16"}, @@ -115,7 +120,8 @@ func TestFillOVNKubernetesDefaults(t *testing.T) { DefaultNetwork: operv1.DefaultNetworkDefinition{ Type: operv1.NetworkTypeOVNKubernetes, OVNKubernetesConfig: &operv1.OVNKubernetesConfig{ - MTU: &m, + MTU: &m, + GenevePort: &p, }, }, } @@ -149,6 +155,11 @@ func TestValidateOVNKubernetes(t *testing.T) { ovnConfig.MTU = &mtu errExpect("invalid MTU 70000") + // set geneve port to insanity + geneve := uint32(70001) + ovnConfig.GenevePort = &geneve + errExpect("invalid GenevePort 70001") + config.ClusterNetwork = nil errExpect("ClusterNetworks cannot be empty") } @@ -167,8 +178,12 @@ func TestOVNKubernetesIsSafe(t *testing.T) { // change the mtu mtu := uint32(70000) next.DefaultNetwork.OVNKubernetesConfig.MTU = &mtu - errs = isOVNKubernetesChangeSafe(prev, next) - g.Expect(errs).To(HaveLen(1)) + // change the geneve port + geneve := uint32(34001) + next.DefaultNetwork.OVNKubernetesConfig.GenevePort = &geneve + errs = isOVNKubernetesChangeSafe(prev, next) + g.Expect(errs).To(HaveLen(2)) g.Expect(errs[0]).To(MatchError("cannot change ovn-kubernetes MTU")) + g.Expect(errs[1]).To(MatchError("cannot change ovn-kubernetes genevePort")) }