Skip to content
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
2 changes: 1 addition & 1 deletion HACKING.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand All @@ -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
Expand Down Expand Up @@ -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:
Expand Down
1 change: 1 addition & 0 deletions bindata/network/ovn-kubernetes/004-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ data:
[default]
mtu="{{.MTU}}"
cluster-subnets="{{.OVN_cidr}}"
encap-port="{{.GenevePort}}"

[kubernetes]
service-cidr="{{.OVN_service_cidr}}"
Expand Down
3 changes: 1 addition & 2 deletions manifests/0000_70_cluster-network-operator_01_crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
20 changes: 17 additions & 3 deletions pkg/network/ovn_kubernetes.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
}

Expand All @@ -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 {
Expand Down
25 changes: 20 additions & 5 deletions pkg/network/ovn_kubernetes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"},
Expand All @@ -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,
},
},
},
}
Expand Down Expand Up @@ -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"},
Expand All @@ -115,7 +120,8 @@ func TestFillOVNKubernetesDefaults(t *testing.T) {
DefaultNetwork: operv1.DefaultNetworkDefinition{
Type: operv1.NetworkTypeOVNKubernetes,
OVNKubernetesConfig: &operv1.OVNKubernetesConfig{
MTU: &m,
MTU: &m,
GenevePort: &p,
},
},
}
Expand Down Expand Up @@ -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")
}
Expand All @@ -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"))
}