diff --git a/ansible/group_vars/all.yml b/ansible/group_vars/all.yml index 65c1f8c860..6dd64234b6 100644 --- a/ansible/group_vars/all.yml +++ b/ansible/group_vars/all.yml @@ -1018,6 +1018,9 @@ neutron_enable_tls_backend: "{{ kolla_enable_tls_backend }}" # Set OVN network availability zones neutron_ovn_availability_zones: [] +# Enable OVN agent +neutron_enable_ovn_agent: "no" + ####################### # Nova options ####################### diff --git a/ansible/inventory/all-in-one b/ansible/inventory/all-in-one index 31fa79695b..7f49624116 100644 --- a/ansible/inventory/all-in-one +++ b/ansible/inventory/all-in-one @@ -283,6 +283,9 @@ neutron compute network +[neutron-ovn-agent:children] +compute + [neutron-bgp-dragent:children] neutron diff --git a/ansible/inventory/multinode b/ansible/inventory/multinode index 684907258d..929519b721 100644 --- a/ansible/inventory/multinode +++ b/ansible/inventory/multinode @@ -313,6 +313,10 @@ neutron [ironic-neutron-agent:children] neutron +[neutron-ovn-agent:children] +compute +network + # Cinder [cinder-api:children] cinder diff --git a/ansible/roles/neutron/defaults/main.yml b/ansible/roles/neutron/defaults/main.yml index 1dc174ae3e..3b0ea2d389 100644 --- a/ansible/roles/neutron/defaults/main.yml +++ b/ansible/roles/neutron/defaults/main.yml @@ -197,6 +197,15 @@ neutron_services: port: "{{ neutron_server_port }}" listen_port: "{{ neutron_server_listen_port }}" tls_backend: "yes" + neutron-ovn-agent: + container_name: neutron_ovn_agent + group: neutron-ovn-agent + host_in_groups: "{{ inventory_hostname in groups['neutron-ovn-agent'] }}" + enabled: "{{ neutron_enable_ovn_agent | bool }}" + image: "{{ neutron_ovn_agent_image_full }}" + volumes: "{{ neutron_ovn_agent_default_volumes + neutron_ovn_agent_extra_volumes }}" + dimensions: "{{ neutron_ovn_agent_dimensions }}" + healthcheck: "{{ neutron_ovn_agent_healthcheck }}" #################### # Config Validate @@ -312,6 +321,10 @@ neutron_tls_proxy_image: "{{ docker_registry ~ '/' if docker_registry else '' }} neutron_tls_proxy_tag: "{{ haproxy_tag }}" neutron_tls_proxy_image_full: "{{ neutron_tls_proxy_image }}:{{ neutron_tls_proxy_tag }}" +neutron_ovn_agent_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/neutron-ovn-agent" +neutron_ovn_agent_tag: "{{ neutron_tag }}" +neutron_ovn_agent_image_full: "{{ neutron_ovn_agent_image }}:{{ neutron_ovn_agent_tag }}" + neutron_agent_dimensions: "{{ default_container_dimensions }}" neutron_dhcp_agent_dimensions: "{{ neutron_agent_dimensions }}" @@ -329,6 +342,7 @@ neutron_infoblox_ipam_agent_dimensions: "{{ default_container_dimensions }}" neutron_metering_agent_dimensions: "{{ neutron_agent_dimensions }}" ironic_neutron_agent_dimensions: "{{ default_container_dimensions }}" neutron_tls_proxy_dimensions: "{{ default_container_dimensions }}" +neutron_ovn_agent_dimensions: "{{ neutron_agent_dimensions }}" neutron_dhcp_agent_enable_healthchecks: "{{ enable_container_healthchecks }}" neutron_dhcp_agent_healthcheck_interval: "{{ default_container_healthcheck_interval }}" @@ -460,6 +474,19 @@ neutron_sriov_agent_healthcheck: test: "{% if neutron_sriov_agent_enable_healthchecks | bool %}{{ neutron_sriov_agent_healthcheck_test }}{% else %}NONE{% endif %}" timeout: "{{ neutron_sriov_agent_healthcheck_timeout }}" +neutron_ovn_agent_enable_healthchecks: "{{ enable_container_healthchecks }}" +neutron_ovn_agent_healthcheck_interval: "{{ default_container_healthcheck_interval }}" +neutron_ovn_agent_healthcheck_retries: "{{ default_container_healthcheck_retries }}" +neutron_ovn_agent_healthcheck_start_period: "{{ default_container_healthcheck_start_period }}" +neutron_ovn_agent_healthcheck_test: ["CMD-SHELL", "healthcheck_port python {{ ovn_sb_db_port }}"] +neutron_ovn_agent_healthcheck_timeout: "{{ default_container_healthcheck_timeout }}" +neutron_ovn_agent_healthcheck: + interval: "{{ neutron_ovn_agent_healthcheck_interval }}" + retries: "{{ neutron_ovn_agent_healthcheck_retries }}" + start_period: "{{ neutron_ovn_agent_healthcheck_start_period }}" + test: "{% if neutron_ovn_agent_enable_healthchecks | bool %}{{ neutron_ovn_agent_healthcheck_test }}{% else %}NONE{% endif %}" + timeout: "{{ neutron_ovn_agent_healthcheck_timeout }}" + ironic_neutron_agent_enable_healthchecks: "{{ enable_container_healthchecks }}" ironic_neutron_agent_healthcheck_interval: "{{ default_container_healthcheck_interval }}" ironic_neutron_agent_healthcheck_retries: "{{ default_container_healthcheck_retries }}" @@ -571,6 +598,11 @@ neutron_tls_proxy_default_volumes: - "/etc/localtime:/etc/localtime:ro" - "{{ '/etc/timezone:/etc/timezone:ro' if ansible_facts.os_family == 'Debian' else '' }}" - "kolla_logs:/var/log/kolla/" +neutron_ovn_agent_default_volumes: + - "{{ node_config_directory }}/neutron-ovn-agent/:{{ container_config_directory }}/:ro" + - "/etc/localtime:/etc/localtime:ro" + - "{{ '/etc/timezone:/etc/timezone:ro' if ansible_facts.os_family == 'Debian' else '' }}" + - "kolla_logs:/var/log/kolla/" neutron_extra_volumes: "{{ default_extra_volumes }}" neutron_dhcp_agent_extra_volumes: "{{ neutron_extra_volumes }}" @@ -588,6 +620,7 @@ neutron_infoblox_ipam_agent_extra_volumes: "{{ neutron_extra_volumes }}" neutron_metering_agent_extra_volumes: "{{ neutron_extra_volumes }}" ironic_neutron_agent_extra_volumes: "{{ neutron_extra_volumes }}" neutron_tls_proxy_extra_volumes: "{{ neutron_extra_volumes }}" +neutron_ovn_agent_extra_volumes: "{{ neutron_extra_volumes }}" #################### # OpenStack diff --git a/ansible/roles/neutron/handlers/main.yml b/ansible/roles/neutron/handlers/main.yml index 5a3609eb16..f348639349 100644 --- a/ansible/roles/neutron/handlers/main.yml +++ b/ansible/roles/neutron/handlers/main.yml @@ -322,3 +322,20 @@ healthcheck: "{{ service.healthcheck | default(omit) }}" when: - kolla_action != "config" + +- name: Restart neutron-ovn-agent container + vars: + service_name: "neutron-ovn-agent" + service: "{{ neutron_services[service_name] }}" + become: true + kolla_docker: + action: "recreate_or_restart_container" + common_options: "{{ docker_common_options }}" + name: "{{ service.container_name }}" + image: "{{ service.image }}" + volumes: "{{ service.volumes }}" + dimensions: "{{ service.dimensions }}" + privileged: "{{ service.privileged | default(False) }}" + healthcheck: "{{ service.healthcheck | default(omit) }}" + when: + - kolla_action != "config" diff --git a/ansible/roles/neutron/tasks/config.yml b/ansible/roles/neutron/tasks/config.yml index 07de73cf18..dfbf70384c 100644 --- a/ansible/roles/neutron/tasks/config.yml +++ b/ansible/roles/neutron/tasks/config.yml @@ -103,6 +103,7 @@ - "neutron-sriov-agent" - "neutron-mlnx-agent" - "neutron-eswitchd" + - "neutron-ovn-agent" merge_configs: sources: - "{{ role_path }}/templates/neutron.conf.j2" @@ -407,6 +408,23 @@ notify: - "Restart {{ service_name }} container" +- name: Copying over ovn_agent.ini + become: true + vars: + service_name: "neutron-ovn-agent" + neutron_ovn_agent: "{{ neutron_services[service_name] }}" + merge_configs: + sources: + - "{{ role_path }}/templates/ovn_agent.ini.j2" + - "{{ node_custom_config }}/neutron/ovn_agent.ini" + dest: "{{ node_config_directory }}/{{ service_name }}/ovn_agent.ini" + mode: "0660" + when: + - neutron_ovn_agent.enabled | bool + - neutron_ovn_agent.host_in_groups | bool + notify: + - "Restart {{ service_name }} container" + - name: Copying over nsx.ini become: true vars: diff --git a/ansible/roles/neutron/templates/neutron-ovn-agent.json.j2 b/ansible/roles/neutron/templates/neutron-ovn-agent.json.j2 new file mode 100644 index 0000000000..4c10604fb1 --- /dev/null +++ b/ansible/roles/neutron/templates/neutron-ovn-agent.json.j2 @@ -0,0 +1,35 @@ +{ + "command": "neutron-ovn-agent --config-file /etc/neutron/neutron.conf --config-file /etc/neutron/plugins/ml2/ovn_agent.ini", + "config_files": [ + { + "source": "{{ container_config_directory }}/neutron.conf", + "dest": "/etc/neutron/neutron.conf", + "owner": "neutron", + "perm": "0600" + }, + { + "source": "{{ container_config_directory }}/ovn_agent.ini", + "dest": "/etc/neutron/plugins/ml2/ovn_agent.ini", + "owner": "neutron", + "perm": "0600" + } + {% if neutron_policy_file is defined %},{ + "source": "{{ container_config_directory }}/{{ neutron_policy_file }}", + "dest": "/etc/neutron/{{ neutron_policy_file }}", + "owner": "neutron", + "perm": "0600" + }{% endif %} + ], + "permissions": [ + { + "path": "/var/log/kolla/neutron", + "owner": "neutron:neutron", + "recurse": true + }, + { + "path": "/var/lib/neutron/kolla", + "owner": "neutron:neutron", + "recurse": true + } + ] +} diff --git a/ansible/roles/neutron/templates/ovn_agent.ini.j2 b/ansible/roles/neutron/templates/ovn_agent.ini.j2 new file mode 100644 index 0000000000..bf5761353e --- /dev/null +++ b/ansible/roles/neutron/templates/ovn_agent.ini.j2 @@ -0,0 +1,7 @@ +[ovn] +ovn_nb_connection = {{ ovn_nb_connection }} +ovn_sb_connection = {{ ovn_sb_connection }} + +[ovs] +ovsdb_connection = tcp:127.0.0.1:{{ ovsdb_port }} +ovsdb_timeout = {{ ovsdb_timeout }} diff --git a/doc/source/reference/networking/neutron.rst b/doc/source/reference/networking/neutron.rst index cac383bf92..1f7f75326c 100644 --- a/doc/source/reference/networking/neutron.rst +++ b/doc/source/reference/networking/neutron.rst @@ -171,6 +171,15 @@ This might be desired for example when Ironic bare metal nodes are used as a compute service. Currently OVN is not able to answer DHCP queries on port type external, this is where Neutron agent helps. +In order to deploy Neutron OVN Agent you need to set the following: + +.. path /etc/kolla/globals.yml +.. code-block:: yaml + + neutron_enable_ovn_agent: "yes" + +Currently the agent is only needed for QoS for hardware offloaded ports. + Mellanox Infiniband (ml2/mlnx) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/releasenotes/notes/neutron-ovn-agent-d66236e44bde2c29.yaml b/releasenotes/notes/neutron-ovn-agent-d66236e44bde2c29.yaml new file mode 100644 index 0000000000..6d0cf45de8 --- /dev/null +++ b/releasenotes/notes/neutron-ovn-agent-d66236e44bde2c29.yaml @@ -0,0 +1,10 @@ +--- +features: + - | + Adds support for deploying ``neutron-ovn-agent``. The agent is disabled + by default and can be enabled using ``neutron_enable_ovn_agent``. + This new agent will run on a compute node using OVN as + network backend, similar to other ML2 mechanism drivers as ML2/OVS or + ML2/SRIOV. This new agent will perform those actions that the + ovn-controller service cannot execute. + More details in `RFE __` diff --git a/tests/templates/globals-default.j2 b/tests/templates/globals-default.j2 index f57f625a57..58456a4a9e 100644 --- a/tests/templates/globals-default.j2 +++ b/tests/templates/globals-default.j2 @@ -165,6 +165,7 @@ libvirt_tls: "yes" {% if scenario == "ovn" %} neutron_plugin_agent: "ovn" neutron_ovn_distributed_fip: "yes" +neutron_enable_ovn_agent: "yes" enable_octavia: "yes" octavia_provider_drivers: "ovn:OVN provider" octavia_provider_agents: "ovn" diff --git a/tests/templates/inventory.j2 b/tests/templates/inventory.j2 index ae8c54993d..43d83666ad 100644 --- a/tests/templates/inventory.j2 +++ b/tests/templates/inventory.j2 @@ -346,6 +346,10 @@ neutron [ironic-neutron-agent:children] neutron +[neutron-ovn-agent:children] +compute +network + # Cinder [cinder-api:children] cinder