Feature: pod affinity changes for OVN
Deploy OVN northd using the same pod affinity rules
used with the NB and SB statefulsets. Also change
default anti-affinity for NB and SB statefulsets
to requiredDuringSchedulingIgnoredDuringExecution
over preferredDuringSchedulingIgnoredDuringExecution
Change-Id: I844bbdc53fe10a8b8d9f017b9a3c68d93b695b98
Add unit tests to for OVN Anti-Affinity Rules
These unit tests go over all the statefulset and
deployment pods using the and make sure they are
all using the right anti-affinity rules.
Change-Id: I2c8b5bf7515040e715bdeed4410acf6656578133
diff --git a/charts/ovn/templates/deployment-northd.yaml b/charts/ovn/templates/deployment-northd.yaml
index 2dbbb68..baf5a0c 100644
--- a/charts/ovn/templates/deployment-northd.yaml
+++ b/charts/ovn/templates/deployment-northd.yaml
@@ -49,6 +49,8 @@
configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }}
spec:
serviceAccountName: {{ $serviceAccountName }}
+ affinity:
+{{- tuple $envAll "ovn" "ovn_northd" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }}
nodeSelector:
{{ .Values.labels.ovn_northd.node_selector_key }}: {{ .Values.labels.ovn_northd.node_selector_value }}
initContainers:
diff --git a/charts/patches/ovn/0003-add-ovn-northd-pod-affinity.patch b/charts/patches/ovn/0003-add-ovn-northd-pod-affinity.patch
new file mode 100644
index 0000000..37acdae
--- /dev/null
+++ b/charts/patches/ovn/0003-add-ovn-northd-pod-affinity.patch
@@ -0,0 +1,13 @@
+diff --git a/charts/ovn/templates/deployment-northd.yaml b/charts/ovn/templates/deployment-northd.yaml
+index 2dbbb689..baf5a0c7 100644
+--- a/ovn/templates/deployment-northd.yaml
++++ b/ovn/templates/deployment-northd.yaml
+@@ -49,6 +49,8 @@ spec:
+ configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }}
+ spec:
+ serviceAccountName: {{ $serviceAccountName }}
++ affinity:
++{{- tuple $envAll "ovn" "ovn_northd" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }}
+ nodeSelector:
+ {{ .Values.labels.ovn_northd.node_selector_key }}: {{ .Values.labels.ovn_northd.node_selector_value }}
+ initContainers:
diff --git a/internal/openstack_helm/openstack_helm.go b/internal/openstack_helm/openstack_helm.go
index c8dd65e..e7a509d 100644
--- a/internal/openstack_helm/openstack_helm.go
+++ b/internal/openstack_helm/openstack_helm.go
@@ -20,8 +20,11 @@
PriorityClass PodPriorityClassConfig `yaml:"priorityClassName,omitempty"`
RuntimeClass PodRuntimeClassConfig `yaml:"runtimeClassName,omitempty"`
Mounts map[string]PodMount `yaml:"mounts,omitempty"`
+ AntiAffinityType PodAntiAffinityTypeConfig `yaml:"affinity.anti.type,omitempty"`
}
+type PodAntiAffinityTypeConfig map[string]interface{}
+
type Conf struct {
Barbican *BarbicanConf `yaml:"barbican,omitempty"`
Cinder *CinderConf `yaml:"cinder,omitempty"`
diff --git a/internal/testutils/oslo_db.go b/internal/testutils/oslo_db.go
index 0b02304..3a9159d 100644
--- a/internal/testutils/oslo_db.go
+++ b/internal/testutils/oslo_db.go
@@ -5,6 +5,7 @@
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
"github.com/vexxhost/atmosphere/internal/openstack_helm"
)
@@ -43,3 +44,20 @@
assert.Contains(t, vals.Pod.PriorityClass, podName)
}
}
+
+func TestAllPodsHaveAntiAffinityType(t *testing.T, vals *openstack_helm.HelmValues) {
+ for pod := range vals.Pod.AntiAffinityType {
+ podName := podNameForClass(pod)
+
+ expected := "requiredDuringSchedulingIgnoredDuringExecution"
+
+ defaultRaw, ok := vals.Pod.AntiAffinityType["default"]
+ require.True(t, ok, "default key not found in affinity.anti.type block")
+
+ actual, ok := defaultRaw.(string)
+ require.True(t, ok, "default anti affinity type is not a string")
+
+ assert.Equal(t, expected, actual, "anti affinity type does not match expected value")
+ assert.Contains(t, vals.Pod.AntiAffinityType, podName)
+ }
+}
diff --git a/releasenotes/notes/enable-ovn-affinity-rules-54efa650be79426c.yaml b/releasenotes/notes/enable-ovn-affinity-rules-54efa650be79426c.yaml
new file mode 100644
index 0000000..601f254
--- /dev/null
+++ b/releasenotes/notes/enable-ovn-affinity-rules-54efa650be79426c.yaml
@@ -0,0 +1,6 @@
+---
+features:
+ - |
+ Applied the same pod affinity rules used for OVN NB/SB sts's to northd deployment and
+ changed the default pod affinity rules from preferred during scheduling to required
+ during scheduling.
diff --git a/roles/ovn/vars/main.yml b/roles/ovn/vars/main.yml
index b879919..a24b7e9 100644
--- a/roles/ovn/vars/main.yml
+++ b/roles/ovn/vars/main.yml
@@ -43,6 +43,14 @@
initialDelaySeconds: 30
timeoutSeconds: 30
periodSeconds: 60
+ affinity:
+ anti:
+ type:
+ default: requiredDuringSchedulingIgnoredDuringExecution
+ topologyKey:
+ default: kubernetes.io/hostname
+ weight:
+ default: 10
replicas:
ovn_ovsdb_nb: 3
ovn_ovsdb_sb: 3
diff --git a/roles/ovn/vars_test.go b/roles/ovn/vars_test.go
new file mode 100644
index 0000000..ee4d95b
--- /dev/null
+++ b/roles/ovn/vars_test.go
@@ -0,0 +1,39 @@
+package ovn
+
+import (
+ _ "embed"
+ "os"
+ "testing"
+
+ "github.com/goccy/go-yaml"
+ "github.com/stretchr/testify/require"
+
+ "github.com/vexxhost/atmosphere/internal/openstack_helm"
+ "github.com/vexxhost/atmosphere/internal/testutils"
+)
+
+var (
+ //go:embed vars/main.yml
+ varsFile []byte
+ vars Vars
+)
+
+type Vars struct {
+ openstack_helm.HelmValues `yaml:"_ovn_helm_values"`
+}
+
+func TestMain(m *testing.M) {
+ t := &testing.T{}
+ err := yaml.UnmarshalWithOptions(varsFile, &vars)
+ require.NoError(t, err)
+
+ code := m.Run()
+ os.Exit(code)
+}
+
+func TestHelmValues(t *testing.T) {
+ vals, err := openstack_helm.CoalescedHelmValues("../../charts/ovn", &vars.HelmValues)
+ require.NoError(t, err)
+
+ testutils.TestAllPodsHaveAntiAffinityType(t, vals)
+}