LXD containers and networking with static IP

6

2

I have done some Docker testing over the years, but for a specific kind of testing, I need a little more then just application containers. So I turned to LXC/LXD containers, which is great. After installing LXD I created my own container:

>> willem@ubuntu:/$ lxc launch images:centos/7/amd64 thing Creating thing
Starting thing 
>> willem@ubuntu:/$ lxc list
+-------+---------+------------------+------+------------+-----------+ 
| NAME  |  STATE  |       IPV4       | IPV6 |    TYPE    | SNAPSHOTS |
+-------+---------+------------------+------+------------+-----------+ 
| thing | RUNNING | 10.0.3.30 (eth0) |      | PERSISTENT |         0 |
+-------+---------+------------------+------+------------+-----------+

Great. Only I don't seem to have any control over the IP address here. I found (with help of Google and locate) a control file:

>> root@ubuntu:/# locate lxc.conf 
/etc/init/lxc.conf 
..
/var/log/lxd/thing/lxc.conf

in which you can put a (what looks like) static IP4-address. Only upon rebooting the container, the host seem to have forgotten my static IP, and takes the one from DHCP. Questions:

  • What is the right way of doing this (I mean, the latest Docker has an --ip switch in docker run which sets the IP address) ?

Willem

Posted 2016-03-02T22:02:40.033

Reputation: 379

You might want to remove your last 2 bullet points. Requests for tutorials and books are off-topic. – DavidPostill – 2016-03-02T22:12:00.433

Answers

2

These configurations are to be placed in the file /var/lib/lxc/ContainerName/config. The possible values of the parameters are specified in the Manual. They pertain to different areas, hostname, network, console, ttys, mount point, cgroups, capabilities,...

Under network, you will find all you need. Sensible values are automatically produced for unspecified variables. The part most relevant to your question is the following:

lxc.network.name

the interface name is dynamically allocated, but if another name is needed because the configuration files being used by the container use a generic name, eg. eth0, this option will rename the interface in the container.

lxc.network.hwaddr

the interface mac address is dynamically allocated by default to the virtual interface, but in some cases, this is needed to resolve a mac address conflict or to always have the same link-local ipv6 address

lxc.network.ipv4

specify the ipv4 address to assign to the virtualized interface. Several lines specify several ipv4 addresses. The address is in format x.y.z.t/m, eg. 192.168.1.123/24. The broadcast address should be specified on the same line, right after the ipv4 address.

lxc.network.ipv4.gateway

specify the ipv4 address to use as the gateway inside the container. The address is in format x.y.z.t, eg. 192.168.1.123. Can also have the special value auto, which means to take the primary address from the bridge interface (as specified by the lxc.network.link option) and use that as the gateway. auto is only available when using the veth and macvlan network types.

MariusMatutiae

Posted 2016-03-02T22:02:40.033

Reputation: 41 321

1Is this answer pertinent to LXD-managed containers as well? I don't have /var/lib/lxc, and all I have in /var/lib/lxd/<ContainerName> is metadata.yaml, templates and rootfs. (I'm on Ubuntu Xenial, LXD version 2.0.0.) – Jonathan Y. – 2016-05-15T21:43:03.743

I haven't tried it, but probably you can give these flags via the --config option to lxc launch. I haven't figured out how to create custom profiles yet. – Per Johansson – 2016-06-01T14:13:03.517

this answer is not relevant to lxd – exebook – 2019-05-15T05:22:14.060

5

If you want to specify ip addresses for containers in LXD, look at the /etc/default/lxd-bridge file. There you will find a spot to include an external dnsmasq configuration file.

Assuming you are on Ubuntu 16.04,

Open up /etc/default/lxd-bridge in your favorite editor. You will need to use sudo.

At around line 16,

LXD_CONFILE=""

Add an entry that points to a dnsmasq configuration file. You are going to have to create this file. So name it whatever you wish. Something like lxd_bridge.conf.

Then create and edit the file that you have named above.

Add a line for each container that you want to assign a specific ip address to.

Like this:

dhcp-host=containername,ipaddress

Then you will need to restart lxd-bridge and then restart the containers.

Here's a detailed article about this:

LXD Static IPs

Note that if you are running Alpine linux in your containers, additional steps need to be taken to make this work. alpine

Jason Trickett

Posted 2016-03-02T22:02:40.033

Reputation: 71

Welcome to Super User! Can you paraphrase the instructions for that link? This is just to prevent any adverse effects for link rot, in accordance with our policy. Thank you! – oldmud0 – 2016-08-03T19:25:02.933

there is no /etc/defaults/lxd-bridge for me. – exebook – 2019-05-15T05:21:52.707

4

System info: lxc-3.0.1 on Ubuntu Server 18.04.1.

After a lot of searching, I found this simple command to assign a static ip to a container:

lxc config set [container] raw.lxc 'lxc.net.[i].ipv4.address = [ip]/[subnet-mask]'

where [container], [i], [ip] and [subnet-mask] are the container name, network interface number, desired static ip address, and the CIDR for the desired subnet mask, respectively.

For instance, if you want to assign 240.10.0.20 with subnet mask 255.255.255.0 to the 0'th network interface of the container named hello, you can use:

lxc config set hello raw.lxc 'lxc.net.0.ipv4.address = 240.10.0.20/24'

You will probably need to restart the container after executing the command.

Note that this will probably not change the current IP address of the container (in my setup anyway); the container should be reachable at both its original IP and the newly assigned IP. As a result, the container entry in lxc list might contain several IP addresses.

Take a look here for the acceptable configuration keys appendable to lxc.net.[i]. This webpage contains information on the CIDR notation.

Unfortunately, I cannot remember where I first found this solution. Here is a relevant GitHub issue that might contain useful information.

Mohamed Laradji

Posted 2016-03-02T22:02:40.033

Reputation: 83

1does the specified address have to be in the same subnet as the lxdbr0 (which defautls to 10.4.50.XXX I believe)? – exebook – 2019-05-15T05:24:45.037

Must this be an accepted answer? – exebook – 2019-05-15T05:41:30.437

@exebook Good question. I do not think the specified address has to be in the same subnet as lxdbr0. I had two containers A and B in lxdbr0 in subnet 10.11.30.0/24. I assigned them 240.10.0.20 and 240.10.0.21, respectively. I tested and these containers can reach each other through the new IPs without problem on the same interface (lxdbr0). – Mohamed Laradji – 2019-05-16T23:09:01.843

2

I found a solution here

Thanks to Stéphane Graber.

Quote:

"If running a modern LXD with an LXD managed bridge, then you can just set the ipv4.address property on the network interface of the container.

  • lxc stop c1
  • lxc network attach lxdbr0 c1 eth0 eth0
  • lxc config device set c1 eth0 ipv4.address 10.99.10.42
  • lxc start c1

"

Dmitry Somov

Posted 2016-03-02T22:02:40.033

Reputation: 71

how is this different from lxc config set ... raw.lxc ... answer? – exebook – 2019-05-15T05:29:26.947

This is what I've got at the last step: lxc twoupdev 20190515053158.157 ERROR network - network.c:lxc_setup_netdev_in_child_namespaces:2883 - Operation not permitted - Failed to rename network device "vethC92YTT" to "eth0" – exebook – 2019-05-15T05:32:59.183

1

For anybody who is still struggling how to assign static ip adresses to the lxd containers.

My first attempt was to do it over dnsmasq so i added the ip adresses of the containers in /var/lib/lxd/networks/lxdbr0/dnsmasq.hosts/<container> and reloaded dnsmasq service. It did really work but did not persist after restarting the Host.

I thought it should be possible to achieve that with lxd tool. In fact it was mentioned in the lcd-doc. I didn't really know how to configure the key user.network-config using the command lxc config set <container> user.network-config <value>. Since i couldn't inject multiple key:values in the value argument.

  1. check the container subnet

    lxc network show lxdbr0
    
  2. fist create a yml (network.yml) file with the following value

    version: 1
    config:
      - type: physical
        name: eth1
        subnets:
          - type: static
            ipv4: true
            address: <ip>
            netmask: 255.255.255.0
            gateway: <gateway> // ends often with .1
            control: auto
      - type: nameserver
        address: 8.8.8.8       // for example
    
  3. create a container with this network configurations

    lxc launch ubuntu:18.04 test --config=user.network-config="$(cat network.yml)"    
    

voalá :)

I tried to change the ip address after creating the container

   lxc config set <container> user.network-config "$(cat network.yml)"

i restarted the container but the ip didn't update. If any body knows how to get it work after creating the container i will very grateful.

lxd version 3.0.1

alixander

Posted 2016-03-02T22:02:40.033

Reputation: 49