How to provide an access from an OpenStack instance to LXD container running on Neutron Gateway

Intro


I have recently been tasked with an interesting problem. Let's assume we have an OpenStack cloud based on Open vSwitch which uses VXLAN tunneling. How would you provide an access from tenant instance to the LXD container running on Neutron Gateway node? The answer seems to be obvious - you assign floating IP to the instance and route the traffic through your networking infrastructure using OpenStack external network. But seriously? What is the point of the whole network virtualization concept then? Wouldn't it be just possible to somehow connect the tenant network with the LXD bridge on the Neutron Gateway node? The answer is "yes" and the following guide will walk you through necessary steps in order to configure it.

Design


The tenant network terminates on OpenStack router which is implemented as Linux namespace on Neutron Gateway node. You can list all OpenStack routers by executing the following command:

# ip netns | grep qrouter
qrouter-3960f517-e2e9-4bca-900e-3681db5fe5ec

On the other side LXD containers are attached to a lxdbr0 bridge by default. You can display it by running the following command:

# brctl show lxdbr0
lxdbr0 8000.000000000000 no eth0

Let's assume that the bridge resides on 10.0.0.0/24 subnet and the container has the IP address of 10.0.0.1. In order to create a connection between the tenant subnet and the container we create a veth pair and assign its ends to the LXD bridge and OpenStack router.

Configuration


Let's start with logging to the Neutron Gateway node as the root user.

1) We start with creation of the veth pair which will connect the LXD bridge with the OpenStack router:

# ip link add veth-qrouter type veth peer name veth-lxdbr

You can check whether the veth pair has actually been created by executing the following command:

# ip link | grep veth
2831: veth-lxdbr@veth-qrouter: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
2832: veth-qrouter@veth-lxdbr: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000

2) Next we attach the veth-lxdbr interface to the LXD bridge and bring it up:

# brctl addif lxdbr0 veth-qrouter
# ip link set dev veth-qrouter up

You can check whether it has been attached by executing the following command:

# brctl show lxdbr0

lxdbr0 8000.000000000000 no eth0
veth-qrouter

3) Then we attach the veth-qrouter interface to the OpenStack rotuer - Linux namespace:

# ip link set veth-lxdbr netns qrouter-3960f517-e2e9-4bca-900e-3681db5fe5ec

Let's check whether it has successfully been attached:

# ip netns exec qrouter-3960f517-e2e9-4bca-900e-3681db5fe5ec ip link 
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: qr-c4ff6972-03@if2829: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether fa:16:3e:37:89:65 brd ff:ff:ff:ff:ff:ff
3: qg-55cb180e-67@if2830: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether fa:16:3e:be:7d:2d brd ff:ff:ff:ff:ff:ff
2831: veth-lxdbr@if2832: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether a2:71:8b:21:42:d8 brd ff:ff:ff:ff:ff:ff

It is there! But wait ... it has now disappeared from the default space:

# ip link | grep veth
2832: veth-qrouter@veth-lxdbr: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000

Of course it did - you have just assigned it to a different space :).

4) The interface withing the space is down. We have to bring it up and configure:

# ip netns exec qrouter-3960f517-e2e9-4bca-900e-3681db5fe5ec ip addr add 10.0.0.2/24 dev veth-lxdbr
# ip netns exec qrouter-3960f517-e2e9-4bca-900e-3681db5fe5ec ip link set dev veth-lxdbr up

Finally, we have to configure SNAT for the traffic coming from the tenant network:

# ip netns exec qrouter-3960f517-e2e9-4bca-900e-3681db5fe5ec iptables -t nat -I POSTROUTING -o veth-lxdbr -j MASQUERADE 

At this point tenant instances should be able to access the LXD container.

No comments:

Post a Comment