Booting an instance with multiple fixed addresses
This article expands on my answer to Add multiple specific IPs to instance, a question posted to ask.openstack.org.
In order to serve out SSL services from an OpenStack instance, you will generally want one local ip address for each SSL virtual host you support. It is possible to create an instance with multiple fixed addresses, but there are a few complications to watch out for.
Assumptions⌗
This article assumes that the following resources exist:
- a private network
net0
. - a private network
net0-subnet0
, associated withnet0
, assigned the range10.0.0.0/24
. - a public network
external
assigned the range192.168.200.0/24
. - an image named
fedora-20-x86_64
, with hopefully self-evident contents.
Creating a port⌗
Start by creating a port in Neutron:
$ neutron port-create net0 \
--fixed-ip subnet_id=net0-subnet0 \
--fixed-ip subnet_id=net0-subnet0
This will create a neutron port to which have been allocated to fixed
ip addresses from net0-subnet0
:
+-----------------------+----------------------------------------------------------------------------------+
| Field | Value |
+-----------------------+----------------------------------------------------------------------------------+
| admin_state_up | True |
| allowed_address_pairs | |
| binding:vnic_type | normal |
| device_id | |
| device_owner | |
| fixed_ips | {"subnet_id": "f8ca90fd-cb82-4218-9627-6fa66e4c9c3c", "ip_address": "10.0.0.18"} |
| | {"subnet_id": "f8ca90fd-cb82-4218-9627-6fa66e4c9c3c", "ip_address": "10.0.0.19"} |
| id | 3c564dd5-fd45-4f61-88df-715f71667b3b |
| mac_address | fa:16:3e:e1:15:7f |
| name | |
| network_id | bb4e5e37-74e1-41bd-880e-b59e94236c5e |
| security_groups | 52f7a87c-380f-4a07-a6ff-d64be495f25b |
| status | DOWN |
| tenant_id | 4dfe8e38f68449b6a0c9cd73037726f7 |
+-----------------------+----------------------------------------------------------------------------------+
If you want, you can specify an explicit set of addresses rather than having neutron allocate them for you:
$ neutron port-create net0 \
--fixed-ip subnet_id=net0-subnet0,ip_address=10.0.0.18 \
--fixed-ip subnet_id=net0-subnet0,ip_address=10.0.0.19
Boot an instance⌗
You can boot an instance using this port using the port-id=...
parameter to the --nic
option:
$ nova boot \
--nic port-id=3c564dd5-fd45-4f61-88df-715f71667b3b \
--flavor m1.tiny \
--image fedora-20-x86_64 \
--key-name lars test0
This is where the first complication arises: the instance will boot and receive a DHCP lease for one of the fixed addresses you created, but you don’t know which one. This isn’t an insurmountable problem; you can assign floating ips to each one and then try logging in to both and see which works.
Rather than playing network roulette, you can pass in a script via the
--user-data
option that will take care of configuring the network
correctly. For example, something like this:
#!/bin/sh
cat > /etc/sysconfig/network-scripts/ifcfg-eth0 <<EOF
DEVICE=eth0
BOOTPROTO=none
IPADDR=10.0.0.18
NETMASK=255.255.255.0
GATEWAY=10.0.0.1
ONBOOT=yes
EOF
cat > /etc/sysconfig/network-scripts/ifcfg-eth0:0 <<EOF
DEVICE=eth0:0
BOOTPROTO=none
IPADDR=10.0.0.19
NETMASK=255.255.255.0
GATEWAY=10.0.0.1
ONBOOT=yes
EOF
ifdown eth0
ifup eth0
ifup eth0:0
And boot the instance like this:
$ nova boot --nic port-id=3c564dd5-fd45-4f61-88df-715f71667b3b \
--flavor m1.tiny --image fedora-20-x86_64 --key-name lars \
--user-data userdata.txt test0
Assuming that your image uses cloud-init or something similar, it
should execute the user-data
script at boot and set up the
persistent network configuration.
At this stage, you can verify that both addresses have been assigned
by using the ip netns
command to run ping
inside an appropriate
namespace. Something like:
$ sudo ip netns exec qdhcp-bb4e5e37-74e1-41bd-880e-b59e94236c5e ping -c1 10.0.0.18
PING 10.0.0.18 (10.0.0.18) 56(84) bytes of data.
64 bytes from 10.0.0.18: icmp_seq=1 ttl=64 time=1.60 ms
--- 10.0.0.18 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.606/1.606/1.606/0.000 ms
$ sudo ip netns exec qdhcp-bb4e5e37-74e1-41bd-880e-b59e94236c5e ping -c1 10.0.0.19
PING 10.0.0.19 (10.0.0.19) 56(84) bytes of data.
64 bytes from 10.0.0.19: icmp_seq=1 ttl=64 time=1.60 ms
--- 10.0.0.19 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.701/1.701/1.701/0.000 ms
This assumes that the UUID of the net0
network is bb4e5e37-74e1-41bd-880e-b59e94236c5e
. On your system, the namespace will be something different.
Assign floating ips⌗
Assign a floating ip address to each of the fixed addresses. You will
need to use the --fixed-address
option to nova add-floating-ip
:
$ nova add-floating-ip --fixed-address 10.0.0.19 test0 192.168.200.6
$ nova add-floating-ip --fixed-address 10.0.0.18 test0 192.168.200.4
With these changes in place, the system is accessible via either address:
$ ssh fedora@192.168.200.4 uptime
14:51:52 up 4 min, 0 users, load average: 0.00, 0.02, 0.02
$ ssh fedora@192.168.200.6 uptime
14:51:54 up 4 min, 0 users, load average: 0.00, 0.02, 0.02
And looking at the network configuration on the system, we can see
that both addresses have been assigned to eth0
as expected:
$ ssh fedora@192.168.200.4 /sbin/ip a
[...]
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether fa:16:3e:bf:f9:6a brd ff:ff:ff:ff:ff:ff
inet 10.0.0.18/24 brd 10.0.0.255 scope global eth0
valid_lft forever preferred_lft forever
inet 10.0.0.19/24 brd 10.0.0.255 scope global secondary eth0:0
valid_lft forever ...