Overview

Highly available VIPs on OpenStack VMs with VRRP

No Comments

Introduction

Virtual IPs (VIPs) are widely used to enable high availabilty for IT infrastructure services. Although the use case is very common, it is surprisingly tricky to set up in an OpenStack environment without a deeper knowledge about neutron and its port security mechanisms. In this blog post I will walk you through the creation of a pair of VMs that share a VIP via the Virtual Router Redundancy Protocol (VRRP) on an OpenStack cloud.

Neutron setup

My OpenStack project has an internal network (192.168.0.0/24) and a router connecting it to an external network (10.98.208.0/24). To setup a HA VIP I need 3 ports that I named vip-port, vm1-port and vm2-port. The VM ports will connect my virtual machines to the internal network, the VIP port actually is just a dummy port that allocates an internal IP address. Neutron will not instantiate this port, it s just a database entry that “blocks” an IP address that will later be used on the VM ports. I want both VMs to be able to communicate via their own IP and the VIP, but the neutron port security mechanisms will drop all traffic not coming from the IP and MAC address pair owned by the VM. Therefore I need to explicitly tell neutron to also allow the IP address of the VIP on the VM ports. This can be done with the --allowed-address-pair parameter on the neutron port-create command:

$ neutron port-create --name vip-port demo-net
Created a new port:
+-----------------------+-------------------------------------------------------------------------------------+
| Field                 | Value                                                                               |
+-----------------------+-------------------------------------------------------------------------------------+
| admin_state_up        | True                                                                                |
| allowed_address_pairs |                                                                                     |
| binding:host_id       |                                                                                     |
| binding:profile       | {}                                                                                  |
| binding:vif_details   | {}                                                                                  |
| binding:vif_type      | unbound                                                                             |
| binding:vnic_type     | normal                                                                              |
| device_id             |                                                                                     |
| device_owner          |                                                                                     |
| fixed_ips             | {"subnet_id": "9bc8ad9b-fa50-41c3-8381-7b86e8fd554b", "ip_address": "192.168.0.14"} |
| id                    | ae020587-e870-4e38-b72a-6c8980bb92f6                                                |
| mac_address           | fa:16:3e:03:84:81                                                                   |
| name                  | vip-port                                                                            |
| network_id            | f2592a01-e31d-4bdc-8aa7-ca66f938eb83                                                |
| security_groups       | da933f24-4b8f-4478-909a-ca19aece379d                                                |
| status                | DOWN                                                                                |
| tenant_id             | 619a60d46b1349f7998116abec50b088                                                    |
+-----------------------+-------------------------------------------------------------------------------------+
$ neutron port-create --name vm1-port --allowed-address-pair ip_address=192.168.0.14 demo-net
Created a new port:
+-----------------------+-------------------------------------------------------------------------------------+
| Field                 | Value                                                                               |
+-----------------------+-------------------------------------------------------------------------------------+
| admin_state_up        | True                                                                                |
| allowed_address_pairs | {"ip_address": "192.168.0.14", "mac_address": "fa:16:3e:69:b2:d2"}                  |
| binding:host_id       |                                                                                     |
| binding:profile       | {}                                                                                  |
| binding:vif_details   | {}                                                                                  |
| binding:vif_type      | unbound                                                                             |
| binding:vnic_type     | normal                                                                              |
| device_id             |                                                                                     |
| device_owner          |                                                                                     |
| fixed_ips             | {"subnet_id": "9bc8ad9b-fa50-41c3-8381-7b86e8fd554b", "ip_address": "192.168.0.15"} |
| id                    | 9ef8a695-0409-43db-9878-bf6b555dcfee                                                |
| mac_address           | fa:16:3e:69:b2:d2                                                                   |
| name                  | vm1-port                                                                            |
| network_id            | f2592a01-e31d-4bdc-8aa7-ca66f938eb83                                                |
| security_groups       | da933f24-4b8f-4478-909a-ca19aece379d                                                |
| status                | DOWN                                                                                |
| tenant_id             | 619a60d46b1349f7998116abec50b088                                                    |
+-----------------------+-------------------------------------------------------------------------------------+
$ neutron port-create --name vm2-port --allowed-address-pair ip_address=192.168.0.14 demo-net
Created a new port:
+-----------------------+-------------------------------------------------------------------------------------+
| Field                 | Value                                                                               |
+-----------------------+-------------------------------------------------------------------------------------+
| admin_state_up        | True                                                                                |
| allowed_address_pairs | {"ip_address": "192.168.0.14", "mac_address": "fa:16:3e:9e:8c:66"}                  |
| binding:host_id       |                                                                                     |
| binding:profile       | {}                                                                                  |
| binding:vif_details   | {}                                                                                  |
| binding:vif_type      | unbound                                                                             |
| binding:vnic_type     | normal                                                                              |
| device_id             |                                                                                     |
| device_owner          |                                                                                     |
| fixed_ips             | {"subnet_id": "9bc8ad9b-fa50-41c3-8381-7b86e8fd554b", "ip_address": "192.168.0.16"} |
| id                    | 928c8761-b98b-4c2f-be41-e4ab5ee82eab                                                |
| mac_address           | fa:16:3e:9e:8c:66                                                                   |
| name                  | vm2-port                                                                            |
| network_id            | f2592a01-e31d-4bdc-8aa7-ca66f938eb83                                                |
| security_groups       | da933f24-4b8f-4478-909a-ca19aece379d                                                |
| status                | DOWN                                                                                |
| tenant_id             | 619a60d46b1349f7998116abec50b088                                                    |
+-----------------------+-------------------------------------------------------------------------------------+

To allow VRRP traffic between the VMs I will now create a security group and assign it to the VM ports we created. Just for convenience reasons I will also add rules for allowing incoming SSH (for login) and ICMP (for ping) traffic.

 $ neutron security-group-rule-create --protocol 112 vrrp
Created a new security_group_rule:
+-------------------+--------------------------------------+
| Field | Value |
+-------------------+--------------------------------------+
| direction | ingress |
| ethertype | IPv4 |
| id | a6602f3b-9c5b-427d-a2b1-fa589e4cabd5 |
| port_range_max | |
| port_range_min | |
| protocol | 112 |
| remote_group_id | |
| remote_ip_prefix | |
| security_group_id | 171563a6-25ce-43dd-8b4f-4fbc5109330e |
| tenant_id | 619a60d46b1349f7998116abec50b088 |
+-------------------+--------------------------------------+
$ neutron security-group-rule-create --protocol tcp --port-range-min 22 --port-range-max 22 vrrp
Created a new security_group_rule:
+-------------------+--------------------------------------+
| Field | Value |
+-------------------+--------------------------------------+
| direction | ingress |
| ethertype | IPv4 |
| id | 717af275-c4bf-41de-9494-2942fa0eae2a |
| port_range_max | 22 |
| port_range_min | 22 |
| protocol | tcp |
| remote_group_id | |
| remote_ip_prefix | |
| security_group_id | 171563a6-25ce-43dd-8b4f-4fbc5109330e |
| tenant_id | 619a60d46b1349f7998116abec50b088 |
+-------------------+--------------------------------------+
$ neutron security-group-rule-create --protocol icmp vrrp
Created a new security_group_rule:
+-------------------+--------------------------------------+
| Field | Value |
+-------------------+--------------------------------------+
| direction | ingress |
| ethertype | IPv4 |
| id | 1bd25b24-33a1-4f13-be8a-361a9c3bff21 |
| port_range_max | |
| port_range_min | |
| protocol | icmp |
| remote_group_id | |
| remote_ip_prefix | |
| security_group_id | 171563a6-25ce-43dd-8b4f-4fbc5109330e |
| tenant_id | 619a60d46b1349f7998116abec50b088 |
+-------------------+--------------------------------------+
$ neutron port-update --security-group vrrp vm1-port
Updated port: vm1-port
$ neutron port-update --security-group vrrp vm2-port
Updated port: vm2-port

  • Page
  • 1
  • 2

Daniel Marks is creating and operating complex distributed software systems and infrastructures. In his current role as a Senior Cloud Engineer he builds OpenStack based clouds for codecentric and its customers.

Share on FacebookGoogle+Share on LinkedInTweet about this on TwitterShare on RedditDigg thisShare on StumbleUpon

Comment

Your email address will not be published. Required fields are marked *