diff --git a/ansible/group_vars/all.yml b/ansible/group_vars/all.yml index b1a84f7e10..30f90a459c 100644 --- a/ansible/group_vars/all.yml +++ b/ansible/group_vars/all.yml @@ -167,6 +167,9 @@ enable_magnum: "no" ironic_keystone_user: "ironic" +# Nova fake driver and the number of fake driver per compute node +enable_nova_fake: "no" +num_nova_fake_per_node: 5 #################### # RabbitMQ options diff --git a/ansible/roles/neutron/tasks/config-neutron-fake.yml b/ansible/roles/neutron/tasks/config-neutron-fake.yml new file mode 100644 index 0000000000..c04420cb0e --- /dev/null +++ b/ansible/roles/neutron/tasks/config-neutron-fake.yml @@ -0,0 +1,47 @@ +--- +- name: Ensuring config directories exist + file: + path: "{{ node_config_directory }}/neutron-openvswitch-agent-fake-{{ item }}" + state: "directory" + recurse: yes + with_sequence: start=1 end={{ num_nova_fake_per_node }} + when: inventory_hostname in groups['compute'] + +- name: Copying over config.json files for services + template: + src: "roles/neutron/templates/neutron-openvswitch-agent.json.j2" + dest: "{{ node_config_directory }}/neutron-openvswitch-agent-fake-{{ item }}/config.json" + with_sequence: start=1 end={{ num_nova_fake_per_node }} + when: + - inventory_hostname in groups['compute'] + - enable_nova_fake | bool + - neutron_plugin_agent == "openvswitch" + +- name: Copying over neutron.conf + merge_configs: + sources: + - "{{ role_path }}/templates/neutron.conf.j2" + - "/etc/kolla/config/global.conf" + - "/etc/kolla/config/database.conf" + - "/etc/kolla/config/messaging.conf" + - "/etc/kolla/config/neutron.conf" + - "/etc/kolla/config/neutron/{{ item }}.conf" + dest: "{{ node_config_directory }}/neutron-openvswitch-agent-fake-{{ item }}/neutron.conf" + with_sequence: start=1 end={{ num_nova_fake_per_node }} + when: + - inventory_hostname in groups['compute'] + - neutron_plugin_agent == "openvswitch" + - enable_nova_fake | bool + +- name: Copying over ml2_conf.ini + merge_configs: + sources: + - "{{ role_path }}/templates/ml2_conf.ini.j2" + - "/etc/kolla/config/neutron/ml2_conf.ini" + dest: "{{ node_config_directory }}/neutron-openvswitch-agent-fake-{{ item }}/ml2_conf.ini" + with_sequence: start=1 end={{ num_nova_fake_per_node }} + when: + - inventory_hostname in groups['compute'] + - neutron_plugin_agent == "openvswitch" + - enable_nova_fake | bool + diff --git a/ansible/roles/neutron/tasks/main.yml b/ansible/roles/neutron/tasks/main.yml index 82132ce494..19bf5d384e 100644 --- a/ansible/roles/neutron/tasks/main.yml +++ b/ansible/roles/neutron/tasks/main.yml @@ -10,6 +10,11 @@ inventory_hostname in groups['neutron-agents'] or inventory_hostname in groups['neutron-server'] +- include: config-neutron-fake.yml + when: + - inventory_hostname in groups['compute'] + - enable_nova_fake | bool + - include: bootstrap.yml when: inventory_hostname in groups['neutron-server'] diff --git a/ansible/roles/neutron/tasks/start.yml b/ansible/roles/neutron/tasks/start.yml index 5d8d3eaf32..76a19d305f 100644 --- a/ansible/roles/neutron/tasks/start.yml +++ b/ansible/roles/neutron/tasks/start.yml @@ -113,8 +113,38 @@ - "/var/lib/kolla/dev/log:/dev/log" env: KOLLA_CONFIG_STRATEGY: "{{ config_strategy }}" - when: (inventory_hostname in groups['compute'] or inventory_hostname in groups['neutron-agents']) - and neutron_plugin_agent == "openvswitch" + when: + - neutron_plugin_agent == "openvswitch" + - ((inventory_hostname in groups['compute'] or inventory_hostname in groups['neutron-agents']) and not (enable_nova_fake | bool)) or + ((inventory_hostname in groups['neutron-agents']) and (enable_nova_fake | bool)) + +- name: Starting Neutron-openvswitch-agent container for fake nova compute + docker: + tty: True + net: host + pull: "{{ docker_pull_policy }}" + restart_policy: "{{ docker_restart_policy }}" + restart_policy_retry: "{{ docker_restart_policy_retry }}" + state: reloaded + registry: "{{ docker_registry }}" + username: "{{ docker_registry_username }}" + password: "{{ docker_registry_password }}" + insecure_registry: "{{ docker_insecure_registry }}" + privileged: True + name: neutron_openvswitch_agent_fake_{{ item }} + image: "{{ neutron_openvswitch_agent_image_full }}" + volumes: + - "/run:/run" + - "/lib/modules:/lib/modules:ro" + - "{{ node_config_directory }}/neutron-openvswitch-agent-fake-{{ item }}/:{{ container_config_directory }}/:ro" + - "/var/lib/kolla/dev/log:/dev/log" + env: + KOLLA_CONFIG_STRATEGY: "{{ config_strategy }}" + with_sequence: start=1 end={{ num_nova_fake_per_node }} + when: + - inventory_hostname in groups['compute'] + - neutron_plugin_agent == "openvswitch" + - enable_nova_fake | bool - name: Starting Neutron-linuxbridge-agent container docker: diff --git a/ansible/roles/neutron/templates/ml2_conf.ini.j2 b/ansible/roles/neutron/templates/ml2_conf.ini.j2 index 061d4d52c9..90049c8b17 100644 --- a/ansible/roles/neutron/templates/ml2_conf.ini.j2 +++ b/ansible/roles/neutron/templates/ml2_conf.ini.j2 @@ -48,10 +48,14 @@ arp_responder = true [ovs] bridge_mappings = physnet1:{{ neutron_bridge_name }} +{% if enable_nova_fake | bool %} +ovs_integration_bridge = br-int-{{ item }} +{% endif %} {% elif neutron_plugin_agent == "linuxbridge" %} [linux_bridge] physical_interface_mappings = physnet1:{{ neutron_external_interface }} + [vxlan] l2_population = true {% endif %} diff --git a/ansible/roles/neutron/templates/neutron.conf.j2 b/ansible/roles/neutron/templates/neutron.conf.j2 index a80349cc52..91e93cca63 100644 --- a/ansible/roles/neutron/templates/neutron.conf.j2 +++ b/ansible/roles/neutron/templates/neutron.conf.j2 @@ -20,6 +20,11 @@ interface_driver = neutron.agent.linux.interface.OVSInterfaceDriver interface_driver = neutron.agent.linux.interface.BridgeInterfaceDriver {% endif %} +{% if enable_nova_fake | bool %} +ovs_integration_bridge = br-int-{{ item }} +host = {{ ansible_hostname }}_{{ item }} +{% endif %} + allow_overlapping_ips = true core_plugin = ml2 service_plugins = router diff --git a/ansible/roles/nova/tasks/config-nova-fake.yml b/ansible/roles/nova/tasks/config-nova-fake.yml new file mode 100644 index 0000000000..9992932ac4 --- /dev/null +++ b/ansible/roles/nova/tasks/config-nova-fake.yml @@ -0,0 +1,27 @@ +--- +- name: Ensuring config directories exist + file: + path: "{{ node_config_directory }}/nova-compute-fake-{{ item }}" + state: "directory" + recurse: yes + with_sequence: start=1 end={{ num_nova_fake_per_node }} + +- name: Copying over config.json files for services + template: + src: "roles/nova/templates/nova-compute.json.j2" + dest: "{{ node_config_directory }}/nova-compute-fake-{{ item }}/config.json" + with_sequence: start=1 end={{ num_nova_fake_per_node }} + +- name: Copying over nova.conf + merge_configs: + vars: + service_name: "{{ item }}" + sources: + - "{{ role_path }}/templates/nova.conf.j2" + - "/etc/kolla/config/global.conf" + - "/etc/kolla/config/database.conf" + - "/etc/kolla/config/messaging.conf" + - "/etc/kolla/config/nova.conf" + - "/etc/kolla/config/nova/{{ item }}.conf" + dest: "{{ node_config_directory }}/nova-compute-fake-{{ item }}/nova.conf" + with_sequence: start=1 end={{ num_nova_fake_per_node }} diff --git a/ansible/roles/nova/tasks/main.yml b/ansible/roles/nova/tasks/main.yml index 748a19f843..f72e6e2193 100644 --- a/ansible/roles/nova/tasks/main.yml +++ b/ansible/roles/nova/tasks/main.yml @@ -21,6 +21,11 @@ inventory_hostname in groups['nova-novncproxy'] or inventory_hostname in groups['nova-scheduler'] +- include: config-nova-fake.yml + when: + - enable_nova_fake | bool + - inventory_hostname in groups['compute'] + - include: bootstrap.yml when: inventory_hostname in groups['nova-api'] diff --git a/ansible/roles/nova/tasks/start.yml b/ansible/roles/nova/tasks/start.yml index 277b0309ec..cc0a6632e1 100644 --- a/ansible/roles/nova/tasks/start.yml +++ b/ansible/roles/nova/tasks/start.yml @@ -201,7 +201,9 @@ - nova_data env: KOLLA_CONFIG_STRATEGY: "{{ config_strategy }}" - when: inventory_hostname in groups['compute'] + when: + - inventory_hostname in groups['compute'] + - not enable_nova_fake | bool - name: Starting Nova-compute-ironic container docker: @@ -226,3 +228,30 @@ when: - inventory_hostname in groups['nova-compute-ironic'] - enable_ironic | bool + +- name: Starting fake Nova-compute containers + docker: + tty: True + net: host + pull: "{{ docker_pull_policy }}" + restart_policy: "{{ docker_restart_policy }}" + restart_policy_retry: "{{ docker_restart_policy_retry }}" + state: reloaded + registry: "{{ docker_registry }}" + username: "{{ docker_registry_username }}" + password: "{{ docker_registry_password }}" + insecure_registry: "{{ docker_insecure_registry }}" + privileged: True + name: nova_compute_fake_{{ item }} + image: "{{ nova_compute_image_full }}" + volumes: + - "{{ node_config_directory }}/nova-compute-fake-{{ item }}/:{{ container_config_directory }}/:ro" + - "/lib/modules:/lib/modules:ro" + - "/run:/run" + - "/var/lib/kolla/dev/log:/dev/log" + env: + KOLLA_CONFIG_STRATEGY: "{{ config_strategy }}" + with_sequence: start=1 end={{ num_nova_fake_per_node }} + when: + - inventory_hostname in groups['compute'] + - enable_nova_fake | bool diff --git a/ansible/roles/nova/templates/nova.conf.j2 b/ansible/roles/nova/templates/nova.conf.j2 index 1d7e95772f..e9b60eb4d7 100644 --- a/ansible/roles/nova/templates/nova.conf.j2 +++ b/ansible/roles/nova/templates/nova.conf.j2 @@ -41,6 +41,10 @@ compute_driver = nova.virt.ironic.IronicDriver vnc_enabled = False ram_allocation_ratio = 1.0 reserved_host_memory_mb = 0 +{% elif enable_nova_fake | bool %} +scheduler_default_filters = RetryFilter,AvailabilityZoneFilter,ComputeFilter,ComputeCapabilitiesFilter,ImagePropertiesFilter +host = {{ ansible_hostname }}_{{ item }} +compute_driver = fake.FakeDriver {% else %} compute_driver = libvirt.LibvirtDriver {% endif %} diff --git a/doc/nova-fake-driver.rst b/doc/nova-fake-driver.rst new file mode 100644 index 0000000000..33f46bead5 --- /dev/null +++ b/doc/nova-fake-driver.rst @@ -0,0 +1,34 @@ +Nova Fake Driver +================ + +One common question from OpenStack operators is that "how does the control plane +(e.g., database, messaging queue, nova-scheduler ) scales?". To answer this +question, operators setup Rally to drive workload to the OpenStack cloud. +However, without a large number of nova-compute nodes, it becomes difficult to +exercise the control performance. + +Given the built-in feature of Docker container, Kolla enables standing up many +many of nova-compute nodes with nova fake driver on a single host. For example, +we can create 100 nova-compute containers on a real host to simulate the +100-hypervisor workload to the nova-conductor and the messaging queue. + +Use nova-fake driver +--------------------- + +Nova fake driver can not work with all-in-one deployment. This is because the +fake neutron-openvswitch-agent for the fake nova-compute container conflicts +with neutron-openvswitch-agent on the compute nodes. Therefore, in the inventory +the network node must be different than the compute node. + +By default, Kolla uses libvirt driver on the compute node. To use nova-fake +driver, edit the following parameters in ansible/group_vars or in the +command line options. + +:: + + enable_nova_fake: "yes" + num_nova_fake_per_node: 5 + +Each compute nodes will run 5 nova-compute containers and 5 +neutron-plugin-agent containers. When booting instance, there will be no +real instances created. But "nova list" shows the fake instances.