Service subnets¶
Service subnets enable operators to define valid port types for each subnet on a network without limiting networks to one subnet or manually creating ports with a specific subnet ID. Using this feature, operators can ensure that ports for instances and router interfaces, for example, always use different subnets.
Operation¶
Define one or more service types for one or more subnets on a particular network. Each service type must correspond to a valid device owner within the port model in order for it to be used.
During IP allocation, the IPAM driver returns an address from a subnet with a service type matching the port device owner. If no subnets match, or all matching subnets lack available IP addresses, the IPAM driver attempts to use a subnet without any service types to preserve compatibility. If all subnets on a network have a service type, the IPAM driver cannot preserve compatibility. However, this feature enables strict IP allocation from subnets with a matching device owner. If multiple subnets contain the same service type, or a subnet without a service type exists, the IPAM driver selects the first subnet with a matching service type. For example, a floating IP agent gateway port uses the following selection process:
network:floatingip_agent_gateway
None
Note
Ports with the device owner network:dhcp
are exempt from the above IPAM
logic for subnets with dhcp_enabled
set to True
. This preserves the
existing automatic DHCP port creation behaviour for DHCP-enabled subnets.
Creating or updating a port with a specific subnet skips this selection process and explicitly uses the given subnet.
Usage¶
Note
Creating a subnet with a service type requires administrative privileges.
Example 1 - Proof-of-concept¶
This following example is not typical of an actual deployment. It is shown to allow users to experiment with configuring service subnets.
Create a network.
$ openstack network create demo-net1 +---------------------------+--------------------------------------+ | Field | Value | +---------------------------+--------------------------------------+ | admin_state_up | UP | | availability_zone_hints | | | availability_zones | | | description | | | headers | | | id | b5b729d8-31cc-4d2c-8284-72b3291fec02 | | ipv4_address_scope | None | | ipv6_address_scope | None | | mtu | 1450 | | name | demo-net1 | | port_security_enabled | True | | project_id | a3db43cd0f224242a847ab84d091217d | | provider:network_type | vxlan | | provider:physical_network | None | | provider:segmentation_id | 110 | | revision_number | 1 | | router:external | Internal | | shared | False | | status | ACTIVE | | subnets | | | tags | [] | +---------------------------+--------------------------------------+
Create a subnet on the network with one or more service types. For example, the
compute:nova
service type enables instances to use this subnet.$ openstack subnet create demo-subnet1 --subnet-range 192.0.2.0/24 \ --service-type 'compute:nova' --network demo-net1 +-------------------+--------------------------------------+ | Field | Value | +-------------------+--------------------------------------+ | id | 6e38b23f-0b27-4e3c-8e69-fd23a3df1935 | | ip_version | 4 | | cidr | 192.0.2.0/24 | | name | demo-subnet1 | | network_id | b5b729d8-31cc-4d2c-8284-72b3291fec02 | | revision_number | 1 | | service_types | ['compute:nova'] | | tags | [] | | tenant_id | a8b3054cc1214f18b1186b291525650f | +-------------------+--------------------------------------+
Optionally, create another subnet on the network with a different service type. For example, the
compute:foo
arbitrary service type.$ openstack subnet create demo-subnet2 --subnet-range 198.51.100.0/24 \ --service-type 'compute:foo' --network demo-net1 +-------------------+--------------------------------------+ | Field | Value | +-------------------+--------------------------------------+ | id | ea139dcd-17a3-4f0a-8cca-dff8b4e03f8a | | ip_version | 4 | | cidr | 198.51.100.0/24 | | name | demo-subnet2 | | network_id | b5b729d8-31cc-4d2c-8284-72b3291fec02 | | revision_number | 1 | | service_types | ['compute:foo'] | | tags | [] | | tenant_id | a8b3054cc1214f18b1186b291525650f | +-------------------+--------------------------------------+
Launch an instance using the network. For example, using the
cirros
image andm1.tiny
flavor.$ openstack server create demo-instance1 --flavor m1.tiny \ --image cirros --nic net-id=b5b729d8-31cc-4d2c-8284-72b3291fec02 +--------------------------------------+-----------------------------------------------+ | Field | Value | +--------------------------------------+-----------------------------------------------+ | OS-DCF:diskConfig | MANUAL | | OS-EXT-AZ:availability_zone | | | OS-EXT-SRV-ATTR:host | None | | OS-EXT-SRV-ATTR:hypervisor_hostname | None | | OS-EXT-SRV-ATTR:instance_name | instance-00000009 | | OS-EXT-STS:power_state | 0 | | OS-EXT-STS:task_state | scheduling | | OS-EXT-STS:vm_state | building | | OS-SRV-USG:launched_at | None | | OS-SRV-USG:terminated_at | None | | accessIPv4 | | | accessIPv6 | | | addresses | | | adminPass | Fn85skabdxBL | | config_drive | | | created | 2016-09-19T15:07:42Z | | flavor | m1.tiny (1) | | hostId | | | id | 04222b73-1a6e-4c2a-9af4-ef3d17d521ff | | image | cirros (4aaec87d-c655-4856-8618-b2dada3a2b11) | | key_name | None | | name | demo-instance1 | | os-extended-volumes:volumes_attached | [] | | progress | 0 | | project_id | d44c19e056674381b86430575184b167 | | properties | | | security_groups | [{u'name': u'default'}] | | status | BUILD | | updated | 2016-09-19T15:07:42Z | | user_id | 331afbeb322d4c559a181e19051ae362 | +--------------------------------------+-----------------------------------------------+
Check the instance status. The
Networks
field contains an IP address from the subnet having thecompute:nova
service type.$ openstack server list +--------------------------------------+-----------------+---------+---------------------+--------+---------+ | ID | Name | Status | Networks | Image | Flavor | +--------------------------------------+-----------------+---------+---------------------+--------+---------+ | 20181f46-5cd2-4af8-9af0-f4cf5c983008 | demo-instance1 | ACTIVE | demo-net1=192.0.2.3 | cirros | m1.tiny | +--------------------------------------+-----------------+---------+---------------------+--------+---------+
Example 2 - DVR configuration¶
The following example outlines how you can configure service subnets in a DVR-enabled deployment, with the goal of minimizing public IP address consumption. This example uses three subnets on the same external network:
192.0.2.0/24 for instance floating IP addresses
198.51.100.0/24 for floating IP agent gateway IPs configured on compute nodes
203.0.113.0/25 for all other IP allocations on the external network
This example uses again the private network, demo-net1
(b5b729d8-31cc-4d2c-8284-72b3291fec02) which was created in
Example 1 - Proof-of-concept.
Create an external network:
$ openstack network create --external demo-ext-net
Create a subnet on the external network for the instance floating IP addresses. This uses the
network:floatingip
service type.$ openstack subnet create demo-floating-ip-subnet \ --subnet-range 192.0.2.0/24 --no-dhcp \ --service-type 'network:floatingip' --network demo-ext-net
Create a subnet on the external network for the floating IP agent gateway IP addresses, which are configured by DVR on compute nodes. This will use the
network:floatingip_agent_gateway
service type.$ openstack subnet create demo-floating-ip-agent-gateway-subnet \ --subnet-range 198.51.100.0/24 --no-dhcp \ --service-type 'network:floatingip_agent_gateway' \ --network demo-ext-net
Create a subnet on the external network for all other IP addresses allocated on the external network. This will not use any service type. It acts as a fall back for allocations that do not match either of the above two service subnets.
$ openstack subnet create demo-other-subnet \ --subnet-range 203.0.113.0/25 --no-dhcp \ --network demo-ext-net
Create a router:
$ openstack router create demo-router
Add an interface to the router on demo-subnet1:
$ openstack router add subnet demo-router demo-subnet1
Set the external gateway for the router, which will create an interface and allocate an IP address on demo-ext-net:
$ openstack router set --external-gateway demo-ext-net demo-router
Launch an instance on a private network and retrieve the neutron port ID that was allocated. As above, use the
cirros
image andm1.tiny
flavor:$ openstack server create demo-instance1 --flavor m1.tiny \ --image cirros --nic net-id=b5b729d8-31cc-4d2c-8284-72b3291fec02 $ openstack port list --server demo-instance1 +--------------------------------------+------+-------------------+--------------------------------------------------+--------+ | ID | Name | MAC Address | Fixed IP Addresses | Status | +--------------------------------------+------+-------------------+--------------------------------------------------+--------+ | a752bb24-9bf2-4d37-b9d6-07da69c86f19 | | fa:16:3e:99:54:32 | ip_address='203.0.113.130', | ACTIVE | | | | | subnet_id='6e38b23f-0b27-4e3c-8e69-fd23a3df1935' | | +--------------------------------------+------+-------------------+--------------------------------------------------+--------+
Associate a floating IP with the instance port and verify it was allocated an IP address from the correct subnet:
$ openstack floating ip create --port \ a752bb24-9bf2-4d37-b9d6-07da69c86f19 demo-ext-net +---------------------+--------------------------------------+ | Field | Value | +---------------------+--------------------------------------+ | fixed_ip_address | 203.0.113.130 | | floating_ip_address | 192.0.2.12 | | floating_network_id | 02d236d5-dad9-4082-bb6b-5245f9f84d13 | | id | f15cae7f-5e05-4b19-bd25-4bb71edcf3de | | port_id | a752bb24-9bf2-4d37-b9d6-07da69c86f19 | | project_id | d44c19e056674381b86430575184b167 | | revision_number | 1 | | router_id | 5a8ca19f-3703-4f81-bc29-db6bc2f528d6 | | status | ACTIVE | | tags | [] | +---------------------+--------------------------------------+
As the admin user, verify the neutron routers are allocated IP addresses from their correct subnets. Use
openstack port list
to find ports associated with the routers.First, the router gateway external port:
$ openstack port show f148ffeb-3c26-4067-bc5f-5c3dfddae2f5 +-----------------------+--------------------------------------------------------------------------+ | Field | Value | +-----------------------+--------------------------------------------------------------------------+ | admin_state_up | UP | | device_id | 5a8ca19f-3703-4f81-bc29-db6bc2f528d6 | | device_owner | network:router_gateway | | extra_dhcp_opts | | | fixed_ips | ip_address='203.0.113.11', | | | subnet_id='67c251d9-2b7a-4200-99f6-e13785b0334d' | | id | f148ffeb-3c26-4067-bc5f-5c3dfddae2f5 | | mac_address | fa:16:3e:2c:0f:69 | | network_id | 02d236d5-dad9-4082-bb6b-5245f9f84d13 | | revision_number | 1 | | project_id | | | status | ACTIVE | | tags | [] | +-----------------------+--------------------------------------------------------------------------+
Second, the router floating IP agent gateway external port:
$ openstack port show a2d1e756-8ae1-4f96-9aa1-e7ea16a6a68a +-----------------------+--------------------------------------------------------------------------+ | Field | Value | +-----------------------+--------------------------------------------------------------------------+ | admin_state_up | UP | | device_id | 3d0c98eb-bca3-45cc-8aa4-90ae3deb0844 | | device_owner | network:floatingip_agent_gateway | | extra_dhcp_opts | | | fixed_ips | ip_address='198.51.100.10', | | | subnet_id='67c251d9-2b7a-4200-99f6-e13785b0334d' | | id | a2d1e756-8ae1-4f96-9aa1-e7ea16a6a68a | | mac_address | fa:16:3e:f4:5d:fa | | network_id | 02d236d5-dad9-4082-bb6b-5245f9f84d13 | | project_id | | | revision_number | 1 | | status | ACTIVE | | tags | [] | +-----------------------+--------------------------------------------------------------------------+