Add an option to generate fixed MAC addresses

This change resolves a long standing issue where a container's mac
address regenerates when it was restarted. In most cases when a
container is restarted and it's mac address is rotated and nothing bad
happens; mac learning will resolve itself given enough time in just
about all situations. However services like neutron-agents are long
lived and are highly sensitive to network changes. These types of
services expect consistent hardware addressing and when mac
addresses rotate may become confused.

To limit the possibility of prolonged downtime caused by mac address
rotation on network sensitive containers an option has been created to
allow a container to have a fixed mac address. If this option is enabled
the container will generate fixed addresses for all networks assosiated
with the specific container. The option is `lxc_container_fixed_mac` and
it has a default value of "false".

Change-Id: Ie1a8dc172c45fc2b4cfa724a2bafa67cb481ba73
Signed-off-by: Kevin Carter <kevin.carter@rackspace.com>
This commit is contained in:
Kevin Carter 2016-10-13 02:06:12 -05:00 committed by Kevin Carter (cloudnull)
parent d2c79015d3
commit f924bfb418
5 changed files with 91 additions and 0 deletions

View File

@ -104,3 +104,7 @@ lxc_container_download_template_options: >
lxc_container_allow_restarts: yes
lxc_container_network_veth_pair: "{{ inventory_hostname[-8:].replace('-', '').replace('_', '') }}_{{ item.value.interface }}"
# Enable fixed mac address generation for an lxc container
lxc_container_fixed_mac: false

View File

@ -0,0 +1,15 @@
---
features:
- LXC containers will now generate a fixed mac address on all
network interfaces when the option `lxc_container_fixed_mac`
is set to **true**. This feature was implemented to resolve
issues with dynamic mac addresses in containers generally
experienced at scale with network intensive services.
fixes:
- LXC containers will now have the ability to use a fixed mac
address on all network interfaces when the option
`lxc_container_fixed_mac` is set **true**. This change will
assist in resolving a long standing issue where network intensive
services, such as neutron and rabbitmq, can enter a confused state
for long periods of time and require rolling restarts or internal
system resets to recover.

View File

@ -172,6 +172,72 @@
tags:
- lxc-container-config
# NOTE(cloudnull): Should a container already be up and running with a defined container interface
# the shell command will use the MAC address already set within the container as
# it's value. This allows the tasks to remain idempotent while ensuring that a
# container restart isn't required to set a static mac.
- name: Set define static mac address from an existing interface
shell: |
if lxc-attach -n {{ inventory_hostname }} -- cat /sys/class/net/{{ item.value.interface }}/address; then
lxc-attach -n {{ inventory_hostname }} -- cat /sys/class/net/{{ item.value.interface }}/address > /var/lib/lxc/{{ inventory_hostname }}/{{ item.value.interface }}.hwaddr
fi
args:
executable: /bin/bash
creates: "/var/lib/lxc/{{ inventory_hostname }}/{{ item.value.interface }}.hwaddr"
with_dict: "{{ container_networks | default({}) }}"
delegate_to: "{{ physical_host }}"
failed_when: false
when:
- lxc_container_fixed_mac | bool
tags:
- lxc-container-networks
# NOTE(cloudnull): This task is being done to allow a container to have a static mac address.
# before this task a container had a dynamic mac address which would
# change when a container was restarted. This restart process causes terrible
# issues in several network intensive systems (RabbitMQ, Neutron, etc). To
# resolve the rotating mac address issue this task is setting the mac in a hwaddr
# file and a lookup is being used in the container-interface.ini template to render
# the static hardware address as expected.
- name: Set unique interface mac address
shell: |
hexchars="0123456789abcdef"
echo "00:16:3e$(
for i in {1..6}; do
echo -n ${hexchars:$(( $RANDOM % 16 )):1}
done | sed -e 's/\(..\)/:\1/g'
)" > /var/lib/lxc/{{ inventory_hostname }}/{{ item.value.interface }}.hwaddr
args:
executable: /bin/bash
creates: "/var/lib/lxc/{{ inventory_hostname }}/{{ item.value.interface }}.hwaddr"
with_dict: "{{ container_networks | default({}) }}"
delegate_to: "{{ physical_host }}"
when:
- lxc_container_fixed_mac | bool
tags:
- lxc-container-networks
- name: Gather hardware addresses to be used as facts
command: cat /var/lib/lxc/{{ inventory_hostname }}/{{ item.value.interface }}.hwaddr
changed_when: false
register: macs
with_dict: "{{ container_networks | default({}) }}"
delegate_to: "{{ physical_host }}"
when:
- lxc_container_fixed_mac | bool
tags:
- lxc-container-networks
# NOTE(cloudnull): To dynamically set the the mac address "facts" Ansible line format is being used
- name: Set fixed hardware address fact
set_fact: "{{item.item.value.interface }}_mac_address={{ item.stdout }}"
with_items:
- "{{ macs.results }}"
when:
- lxc_container_fixed_mac | bool
tags:
- lxc-container-networks
- name: LXC host config for container networks
template:
src: "container-interface.ini.j2"

View File

@ -13,7 +13,11 @@ lxc.network.veth.pair = {{ lxc_container_network_veth_pair[-15:] }}
# Host link to attach to, this should be a bridge if lxc.network.type = veth
lxc.network.link = {{ item.value.bridge }}
# Hardware Address
{% if lxc_container_fixed_mac | bool %}
lxc.network.hwaddr = {{ hostvars[inventory_hostname][item.value.interface + '_mac_address'] }}
{% else %}
lxc.network.hwaddr = 00:16:3e:xx:xx:xx
{% endif %}
# enable the device on boot
lxc.network.flags = up
# Set the container network MTU

View File

@ -6,3 +6,5 @@ lxc_container_bind_mounts:
- host_directory: "/openstack/{{ inventory_hostname }}/test2"
container_directory: "/opt/test2"
# TEST FOR FIXED MAC ADDRESS
lxc_container_fixed_mac: true