|
1 | 1 | # Using virtual switches with Hotstack |
2 | 2 |
|
| 3 | +## Creating a switch image |
| 4 | + |
3 | 5 | ```bash |
4 | 6 | openstack image create hotstack-switch \ |
5 | 7 | --disk-format qcow2 \ |
6 | 8 | --file <switch-image-file> \ |
7 | 9 | --property hw_firmware_type=uefi \ |
8 | 10 | --property hw_machine_type=q35 --public |
9 | 11 | ``` |
| 12 | + |
| 13 | +## Network wiring: OpenStack networks as bridges |
| 14 | + |
| 15 | +Hotstack uses a special network architecture to connect VMs (like baremetal |
| 16 | +nodes managed by Ironic) to ports on the virtual switch. This approach uses |
| 17 | +**OpenStack Neutron networks as L2 bridges** between VMs and switch ports. |
| 18 | + |
| 19 | +### Architecture overview |
| 20 | + |
| 21 | +The architecture consists of three key components: |
| 22 | + |
| 23 | +1. **Trunk port on the switch**: A Neutron trunk port that carries multiple |
| 24 | + VLANs to the switch |
| 25 | +2. **Bridge networks**: Small point-to-point Neutron networks connecting each |
| 26 | + VM to the switch |
| 27 | +3. **VLAN configuration inside the switch**: The switch's internal |
| 28 | + configuration determines which VLAN each port belongs to |
| 29 | + |
| 30 | +### How it works |
| 31 | + |
| 32 | +The key insight is that **the switch's internal configuration determines |
| 33 | +VLAN membership**, not OpenStack: |
| 34 | + |
| 35 | +- The bridge network (e.g. `ironic0-br-net`) provides L2 connectivity |
| 36 | + between the VM and the switch |
| 37 | +- Inside the switch, you configure which VLAN the port (connected to the |
| 38 | + bridge network) belongs to |
| 39 | +- When you change the VLAN configuration of the switch port, the VM |
| 40 | + effectively "moves" to a different VLAN |
| 41 | + |
| 42 | +**Example flow:** |
| 43 | + |
| 44 | +1. VM `ironic0` is connected to `ironic0-br-net` |
| 45 | +2. The switch port `ethernet1/2` is also connected to `ironic0-br-net` |
| 46 | +3. Inside the switch, configure `ethernet1/2` to be an access port on |
| 47 | + VLAN 101 |
| 48 | +4. Traffic from `ironic0` now flows through the bridge network to the |
| 49 | + switch, where it enters VLAN 101 |
| 50 | +5. VLAN 101 traffic exits the switch through the trunk port (tagged with |
| 51 | + VLAN 101) |
| 52 | +6. OpenStack Neutron receives this as traffic on the `ironic-net` network |
| 53 | + (which is VLAN 101 on the trunk) |
| 54 | + |
| 55 | +**To move the VM to a different VLAN:** |
| 56 | + |
| 57 | +1. Reconfigure switch port `ethernet1/2` to be on VLAN 103 instead |
| 58 | +2. Now traffic from `ironic0` enters VLAN 103 and exits as traffic on the |
| 59 | + `tenant-vlan103` network |
| 60 | +3. **No changes needed in OpenStack** - the bridge network stays the same |
| 61 | + |
| 62 | +### Benefits of this approach |
| 63 | + |
| 64 | +- **Flexibility**: VMs can be moved between VLANs by reconfiguring the |
| 65 | + switch, not by reconfiguring OpenStack |
| 66 | +- **Realistic testing**: Mimics how physical networks work with switches |
| 67 | + controlling VLAN membership |
| 68 | +- **Simplified OpenStack config**: Each VM just needs one static connection |
| 69 | + (the bridge network) |
| 70 | +- **Switch-driven networking**: The switch becomes the central point of |
| 71 | + control for network topology, just like in a physical datacenter |
| 72 | + |
| 73 | +### Implementation in Heat templates |
| 74 | + |
| 75 | +#### 1. Switch trunk port setup |
| 76 | + |
| 77 | +The switch has a trunk port that connects to multiple VLAN networks as |
| 78 | +subports: |
| 79 | + |
| 80 | +```yaml |
| 81 | +switch-trunk-parent-port: |
| 82 | + type: OS::Neutron::Port |
| 83 | + properties: |
| 84 | + network: {get_resource: trunk-net} |
| 85 | + port_security_enabled: false |
| 86 | + |
| 87 | +switch-trunk-ironic-port: |
| 88 | + type: OS::Neutron::Port |
| 89 | + properties: |
| 90 | + network: {get_resource: ironic-net} |
| 91 | + port_security_enabled: false |
| 92 | + |
| 93 | +switch-trunk-tenant-vlan103-port: |
| 94 | + type: OS::Neutron::Port |
| 95 | + properties: |
| 96 | + network: {get_resource: tenant-vlan103} |
| 97 | + port_security_enabled: false |
| 98 | + |
| 99 | +switch-trunk-tenant-vlan104-port: |
| 100 | + type: OS::Neutron::Port |
| 101 | + properties: |
| 102 | + network: {get_resource: tenant-vlan104} |
| 103 | + port_security_enabled: false |
| 104 | + |
| 105 | +switch-trunk-tenant-vlan105-port: |
| 106 | + type: OS::Neutron::Port |
| 107 | + properties: |
| 108 | + network: {get_resource: tenant-vlan105} |
| 109 | + port_security_enabled: false |
| 110 | + |
| 111 | +switch-trunk: |
| 112 | + type: OS::Neutron::Trunk |
| 113 | + properties: |
| 114 | + port: {get_resource: switch-trunk-parent-port} |
| 115 | + sub_ports: |
| 116 | + # Ironic VLAN |
| 117 | + - port: {get_resource: switch-trunk-ironic-port} |
| 118 | + segmentation_id: 101 |
| 119 | + segmentation_type: vlan |
| 120 | + # Tenant VLANs |
| 121 | + - port: {get_resource: switch-trunk-tenant-vlan103-port} |
| 122 | + segmentation_id: 103 |
| 123 | + segmentation_type: vlan |
| 124 | + - port: {get_resource: switch-trunk-tenant-vlan104-port} |
| 125 | + segmentation_id: 104 |
| 126 | + segmentation_type: vlan |
| 127 | + - port: {get_resource: switch-trunk-tenant-vlan105-port} |
| 128 | + segmentation_id: 105 |
| 129 | + segmentation_type: vlan |
| 130 | +``` |
| 131 | +
|
| 132 | +This trunk port presents multiple VLANs to the switch VM, just like a |
| 133 | +physical trunk port would. |
| 134 | +
|
| 135 | +#### 2. Bridge networks connecting VMs to the switch |
| 136 | +
|
| 137 | +Each VM that needs to connect to the switch gets a dedicated "bridge |
| 138 | +network" - a small Neutron network that acts as a point-to-point L2 |
| 139 | +connection: |
| 140 | +
|
| 141 | +```yaml |
| 142 | +ironic0-br-net: |
| 143 | + type: OS::Neutron::Net |
| 144 | + properties: |
| 145 | + port_security_enabled: false |
| 146 | + |
| 147 | +ironic1-br-net: |
| 148 | + type: OS::Neutron::Net |
| 149 | + properties: |
| 150 | + port_security_enabled: false |
| 151 | +``` |
| 152 | +
|
| 153 | +Both the VM and the switch get a port on this bridge network: |
| 154 | +
|
| 155 | +```yaml |
| 156 | +switch-ironic0-br-port: |
| 157 | + type: OS::Neutron::Port |
| 158 | + properties: |
| 159 | + network: {get_resource: ironic0-br-net} |
| 160 | + port_security_enabled: false |
| 161 | + |
| 162 | +switch-ironic1-br-port: |
| 163 | + type: OS::Neutron::Port |
| 164 | + properties: |
| 165 | + network: {get_resource: ironic1-br-net} |
| 166 | + port_security_enabled: false |
| 167 | + |
| 168 | +switch: |
| 169 | + type: OS::Nova::Server |
| 170 | + properties: |
| 171 | + # ... image, flavor, and disk configuration ... |
| 172 | + networks: |
| 173 | + - port: {get_resource: switch-machine-port} |
| 174 | + - port: {get_attr: [switch-trunk, port_id]} |
| 175 | + - port: {get_resource: switch-ironic0-br-port} |
| 176 | + - port: {get_resource: switch-ironic1-br-port} |
| 177 | +``` |
| 178 | +
|
| 179 | +The VMs also connect to their respective bridge networks: |
| 180 | +
|
| 181 | +```yaml |
| 182 | +ironic0-port: |
| 183 | + type: OS::Neutron::Port |
| 184 | + properties: |
| 185 | + network: {get_resource: ironic0-br-net} |
| 186 | + port_security_enabled: false |
| 187 | + |
| 188 | +ironic0: |
| 189 | + type: OS::Nova::Server |
| 190 | + properties: |
| 191 | + # ... image, flavor, and disk configuration ... |
| 192 | + networks: |
| 193 | + - port: {get_resource: ironic0-port} |
| 194 | + |
| 195 | +ironic1-port: |
| 196 | + type: OS::Neutron::Port |
| 197 | + properties: |
| 198 | + network: {get_resource: ironic1-br-net} |
| 199 | + port_security_enabled: false |
| 200 | + |
| 201 | +ironic1: |
| 202 | + type: OS::Nova::Server |
| 203 | + properties: |
| 204 | + # ... image, flavor, and disk configuration ... |
| 205 | + networks: |
| 206 | + - port: {get_resource: ironic1-port} |
| 207 | +``` |
0 commit comments