Create a different daemonset for gw running on controllers
diff --git a/charts/ovn/templates/bin/_ovn-controller-gw-init.sh.tpl b/charts/ovn/templates/bin/_ovn-controller-gw-init.sh.tpl
new file mode 100644
index 0000000..5528155
--- /dev/null
+++ b/charts/ovn/templates/bin/_ovn-controller-gw-init.sh.tpl
@@ -0,0 +1,142 @@
+#!/bin/bash -xe
+
+# Copyright 2023 VEXXHOST, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+function get_ip_address_from_interface {
+ local interface=$1
+ local ip=$(ip -4 -o addr s "${interface}" | awk '{ print $4; exit }' | awk -F '/' '{print $1}')
+ if [ -z "${ip}" ] ; then
+ exit 1
+ fi
+ echo ${ip}
+}
+
+function get_ip_prefix_from_interface {
+ local interface=$1
+ local prefix=$(ip -4 -o addr s "${interface}" | awk '{ print $4; exit }' | awk -F '/' '{print $2}')
+ if [ -z "${prefix}" ] ; then
+ exit 1
+ fi
+ echo ${prefix}
+}
+
+function migrate_ip_from_nic {
+ src_nic=$1
+ bridge_name=$2
+
+ # Enabling explicit error handling: We must avoid to lose the IP
+ # address in the migration process. Hence, on every error, we
+ # attempt to assign the IP back to the original NIC and exit.
+ set +e
+
+ ip=$(get_ip_address_from_interface ${src_nic})
+ prefix=$(get_ip_prefix_from_interface ${src_nic})
+
+ bridge_ip=$(get_ip_address_from_interface "${bridge_name}")
+ bridge_prefix=$(get_ip_prefix_from_interface "${bridge_name}")
+
+ ip link set ${bridge_name} up
+
+ if [[ -n "${ip}" && -n "${prefix}" ]]; then
+ ip addr flush dev ${src_nic}
+ if [ $? -ne 0 ] ; then
+ ip addr add ${ip}/${prefix} dev ${src_nic}
+ echo "Error while flushing IP from ${src_nic}."
+ exit 1
+ fi
+
+ ip addr add ${ip}/${prefix} dev "${bridge_name}"
+ if [ $? -ne 0 ] ; then
+ echo "Error assigning IP to bridge "${bridge_name}"."
+ ip addr add ${ip}/${prefix} dev ${src_nic}
+ exit 1
+ fi
+ elif [[ -n "${bridge_ip}" && -n "${bridge_prefix}" ]]; then
+ echo "Bridge '${bridge_name}' already has IP assigned. Keeping the same:: IP:[${bridge_ip}]; Prefix:[${bridge_prefix}]..."
+ elif [[ -z "${bridge_ip}" && -z "${ip}" ]]; then
+ echo "Interface and bridge have no ips configured. Leaving as is."
+ else
+ echo "Interface ${name} has invalid IP address. IP:[${ip}]; Prefix:[${prefix}]..."
+ exit 1
+ fi
+
+ set -e
+}
+
+# Detect tunnel interface
+tunnel_interface="{{- .Values.network.interface.tunnel -}}"
+if [ -z "${tunnel_interface}" ] ; then
+ # search for interface with tunnel network routing
+ tunnel_network_cidr="{{- .Values.network.interface.tunnel_network_cidr -}}"
+ if [ -z "${tunnel_network_cidr}" ] ; then
+ tunnel_network_cidr="0/0"
+ fi
+ # If there is not tunnel network gateway, exit
+ tunnel_interface=$(ip -4 route list ${tunnel_network_cidr} | awk -F 'dev' '{ print $2; exit }' \
+ | awk '{ print $1 }') || exit 1
+fi
+ovs-vsctl set open . external_ids:ovn-encap-ip="$(get_ip_address_from_interface ${tunnel_interface})"
+
+# Configure system ID
+set +e
+ovs-vsctl get open . external-ids:system-id
+if [ $? -eq 1 ]; then
+ ovs-vsctl set open . external-ids:system-id="$(uuidgen)"
+fi
+set -e
+
+# Configure OVN remote
+{{- if empty .Values.conf.ovn_remote -}}
+{{- $sb_svc_name := "ovn-ovsdb-sb" -}}
+{{- $sb_svc := (tuple $sb_svc_name "internal" . | include "helm-toolkit.endpoints.hostname_fqdn_endpoint_lookup") -}}
+{{- $sb_port := (tuple "ovn-ovsdb-sb" "internal" "ovsdb" . | include "helm-toolkit.endpoints.endpoint_port_lookup") -}}
+{{- $sb_service_list := list -}}
+{{- range $i := until (.Values.pod.replicas.ovn_ovsdb_sb | int) -}}
+ {{- $sb_service_list = printf "tcp:%s-%d.%s:%s" $sb_svc_name $i $sb_svc $sb_port | append $sb_service_list -}}
+{{- end }}
+
+ovs-vsctl set open . external-ids:ovn-remote="{{ include "helm-toolkit.utils.joinListWithComma" $sb_service_list }}"
+{{- else -}}
+ovs-vsctl set open . external-ids:ovn-remote="{{ .Values.conf.ovn_remote }}"
+{{- end }}
+
+# Configure OVN values
+ovs-vsctl set open . external-ids:rundir="/var/run/openvswitch"
+ovs-vsctl set open . external-ids:ovn-encap-type="{{ .Values.conf.ovn_encap_type }}"
+ovs-vsctl set open . external-ids:ovn-bridge="{{ .Values.conf.ovn_bridge }}"
+ovs-vsctl set open . external-ids:ovn-bridge-mappings="{{ .Values.conf.ovn_bridge_mappings }}"
+ovs-vsctl set open . external-ids:ovn-cms-options="{{ .Values.conf.gw_ovn_cms_options }}"
+
+# Configure hostname
+{{- if .Values.conf.use_fqdn.compute }}
+ ovs-vsctl set open . external-ids:hostname="$(hostname -f)"
+{{- else }}
+ ovs-vsctl set open . external-ids:hostname="$(hostname)"
+{{- end }}
+
+# Create bridges and create ports
+# handle any bridge mappings
+# /tmp/auto_bridge_add is one line json file: {"br-ex1":"eth1","br-ex2":"eth2"}
+for bmap in `sed 's/[{}"]//g' /tmp/auto_bridge_add | tr "," "\n"`
+do
+ bridge=${bmap%:*}
+ iface=${bmap#*:}
+ ovs-vsctl --may-exist add-br $bridge -- set bridge $bridge protocols=OpenFlow13
+ if [ -n "$iface" ] && [ "$iface" != "null" ]
+ then
+ ovs-vsctl --may-exist add-port $bridge $iface
+ migrate_ip_from_nic $iface $bridge
+ fi
+done
diff --git a/charts/ovn/templates/configmap-bin.yaml b/charts/ovn/templates/configmap-bin.yaml
index a849dd8..1beb0d2 100644
--- a/charts/ovn/templates/configmap-bin.yaml
+++ b/charts/ovn/templates/configmap-bin.yaml
@@ -30,6 +30,8 @@
{{ tuple "bin/_ovn-northd.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }}
ovn-controller-init.sh: |
{{ tuple "bin/_ovn-controller-init.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }}
+ ovn-controller-gw-init.sh: |
+{{ tuple "bin/_ovn-controller-gw-init.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }}
ovn-controller.sh: |
{{ tuple "bin/_ovn-controller.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }}
{{- end }}
diff --git a/charts/ovn/templates/daemonset-controller-gw.yaml b/charts/ovn/templates/daemonset-controller-gw.yaml
new file mode 100644
index 0000000..6267970
--- /dev/null
+++ b/charts/ovn/templates/daemonset-controller-gw.yaml
@@ -0,0 +1,101 @@
+{{/*
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/}}
+
+{{- if .Values.manifests.daemonset_controller }}
+{{- $envAll := . }}
+
+{{- $configMapName := "ovn-etc" }}
+{{- $serviceAccountName := "ovn-controller-gw" }}
+{{ tuple $envAll "ovn_controller_gw" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }}
+---
+kind: DaemonSet
+apiVersion: apps/v1
+metadata:
+ name: ovn-controller-gw
+ annotations:
+ {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }}
+ configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }}
+ labels:
+{{ tuple $envAll "ovn" "ovn-controller-gw" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }}
+spec:
+ selector:
+ matchLabels:
+{{ tuple $envAll "ovn" "ovn-controller-gw" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }}
+ template:
+ metadata:
+ labels:
+{{ tuple $envAll "ovn" "ovn-controller-gw" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }}
+ annotations:
+{{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }}
+ configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }}
+ configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }}
+ spec:
+ serviceAccountName: {{ $serviceAccountName }}
+ hostNetwork: true
+ dnsPolicy: {{ .Values.pod.dns_policy }}
+ nodeSelector:
+ {{ .Values.labels.ovn_controller_gw.node_selector_key }}: {{ .Values.labels.ovn_controller_gw.node_selector_value }}
+ initContainers:
+{{- tuple $envAll "ovn_controller_gw" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }}
+ - name: controller-init
+{{ tuple $envAll "ovn_controller_gw" | include "helm-toolkit.snippets.image" | indent 10 }}
+{{ dict "envAll" $envAll "application" "ovn_controller_gw" "container" "controller_init" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }}
+ command:
+ - /tmp/ovn-controller-gw-init.sh
+ volumeMounts:
+ - name: ovn-bin
+ mountPath: /tmp/ovn-controller-gw-init.sh
+ subPath: ovn-controller-gw-init.sh
+ readOnly: true
+ - name: run-openvswitch
+ mountPath: /run/openvswitch
+ - name: ovn-etc
+ mountPath: /tmp/auto_bridge_add
+ subPath: auto_bridge_add
+ readOnly: true
+ containers:
+ - name: controller
+{{ tuple $envAll "ovn_controller_gw" | include "helm-toolkit.snippets.image" | indent 10 }}
+{{ tuple $envAll $envAll.Values.pod.resources.server | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }}
+{{ dict "envAll" $envAll "application" "ovn_controller_gw" "container" "controller" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }}
+ command:
+ - /tmp/ovn-controller.sh
+ - start
+ lifecycle:
+ preStop:
+ exec:
+ command:
+ - /tmp/ovn-controller.sh
+ - stop
+ volumeMounts:
+ - name: ovn-bin
+ mountPath: /tmp/ovn-controller.sh
+ subPath: ovn-controller.sh
+ readOnly: true
+ - name: run-openvswitch
+ mountPath: /run/openvswitch
+ volumes:
+ - name: ovn-bin
+ configMap:
+ name: ovn-bin
+ defaultMode: 0777
+ - name: run-openvswitch
+ hostPath:
+ path: /run/openvswitch
+ type: DirectoryOrCreate
+ - name: ovn-etc
+ secret:
+ secretName: {{ $configMapName }}
+ defaultMode: 0444
+{{- end }}
diff --git a/charts/ovn/values.yaml b/charts/ovn/values.yaml
index 05408fa..41fca3e 100644
--- a/charts/ovn/values.yaml
+++ b/charts/ovn/values.yaml
@@ -24,6 +24,7 @@
ovn_ovsdb_sb: docker.io/openstackhelm/ovn:latest-ubuntu_focal
ovn_northd: docker.io/openstackhelm/ovn:latest-ubuntu_focal
ovn_controller: docker.io/openstackhelm/ovn:latest-ubuntu_focal
+ ovn_controller_gw: docker.io/openstackhelm/ovn:latest-ubuntu_focal
dep_check: quay.io/airshipit/kubernetes-entrypoint:v1.0.0
image_repo_sync: docker.io/library/docker:17.07.0
pull_policy: "IfNotPresent"
@@ -44,7 +45,10 @@
node_selector_key: openstack-network-node
node_selector_value: enabled
ovn_controller:
- node_selector_key: openvswitch
+ node_selector_key: openstack-network-node
+ node_selector_value: enabled
+ ovn_controller_gw:
+ node_selector_key: openstack-control-plane
node_selector_value: enabled
volume:
@@ -66,7 +70,8 @@
tunnel_network_cidr: "0/0"
conf:
- ovn_cms_options: "enable-chassis-as-gw,availability-zones=nova"
+ ovn_cms_options: "availability-zones=nova"
+ gw_ovn_cms_options: "enable-chassis-as-gw,availability-zones=nova"
ovn_encap_type: geneve
ovn_bridge: br-int
ovn_bridge_mappings: external:br-ex
@@ -97,6 +102,15 @@
capabilities:
add:
- SYS_NICE
+ ovn_controller_gw:
+ container:
+ controller_init:
+ privileged: true
+ runAsUser: 0
+ controller:
+ capabilities:
+ add:
+ - SYS_NICE
tolerations:
ovn_ovsdb_nb:
enabled: false
@@ -106,6 +120,8 @@
enabled: false
ovn_controller:
enabled: false
+ ovn_controller_gw:
+ enabled: false
affinity:
anti:
type:
@@ -153,6 +169,10 @@
enabled: true
min_ready_seconds: 0
max_unavailable: 1
+ ovn_controller_gw:
+ enabled: true
+ min_ready_seconds: 0
+ max_unavailable: 1
resources:
enabled: false
ovs:
@@ -184,6 +204,13 @@
limits:
memory: "1024Mi"
cpu: "2000m"
+ ovn_controller_gw:
+ requests:
+ memory: "128Mi"
+ cpu: "100m"
+ limits:
+ memory: "1024Mi"
+ cpu: "2000m"
jobs:
image_repo_sync:
requests:
@@ -199,6 +226,7 @@
ovn_ovsdb_sb: ovn-ovsdb-sb-oci-image-registry-key
ovn_northd: ovn-northd-oci-image-registry-key
ovn_controller: ovn-controller-oci-image-registry-key
+ ovn_controller_gw: ovn-controller-gw-oci-image-registry-key
# TODO: Check these endpoints?!
endpoints:
@@ -274,6 +302,9 @@
ovn_controller:
ingress:
- {}
+ ovn_controller_gw:
+ ingress:
+ - {}
egress:
- {}
@@ -299,6 +330,10 @@
services:
- endpoint: internal
service: ovn-ovsdb-sb
+ ovn_controller_gw:
+ services:
+ - endpoint: internal
+ service: ovn-ovsdb-sb
pod:
- requireSameNode: true
labels:
@@ -320,5 +355,6 @@
statefulset_ovn_ovsdb_sb: true
deployment_ovn_northd: true
daemonset_ovn_controller: true
+ daemonset_ovn_controller_gw: true
job_image_repo_sync: true
...