You have a cloud server and you got more than one public IP addresses. How do you get those additional IP addresses to associate to specific LXD containers? That is, how do you get your LXD container to use a public IP address?
This post has been tested with a packet.net baremetal server.
Prerequisites
You have configured a cloud server and you arranged to have at least one additional public IP address.
In the following, we assume that
- the gateway of your cloud server is 100.100.100.97
- the unused public IP address is 100.100.100.98
- the network is 100.100.100.96/29
- the default network interface on the host is enp0s100 (if you have a bonded interface, the name would be something like bond0)
Creating a macvlan LXD profile
Create a new LXD profile and set up a macvlan interface. The name of the interface in the container will be eth0, the nictype is macvlan and the parent points to the default network interface on the host.
$ lxc profile create macvlan $ lxc profile device add macvlan eth0 nic nictype=macvlan parent=enp0s100
Here is how the profile macvlan looks like.
ubuntu@myserver:~$ lxc profile show macvlan config: {} description: "" devices: eth0: nictype: macvlan parent: enp0s100 type: nic name: macvlan used_by:
Launching the container
Launch the container by specifying the macvlan profile on top (stacked) of the default profile. The container is called c1public.
$ lxc launch --profile default --profile macvlan ubuntu:18.04 c1public
Get a shell into the container and view the network interfaces
ubuntu@myserver:~$ lxc exec c1public bash root@c1public:~# ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet6 fe80::216:3eff:fe55:1930 prefixlen 64 scopeid 0x20<link> ether 00:16:3e:55:19:30 txqueuelen 1000 (Ethernet) RX packets 82 bytes 5200 (5.2 KB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 16 bytes 2788 (2.7 KB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 .... root@c1public:~# ip link 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 8: eth0@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000 link/ether 00:16:3e:55:19:30 brd ff:ff:ff:ff:ff:ff link-netnsid 0
At this stage, we can configure manually the appropriate public IP address for the network interface eth0 of the container and it will work. If you are familiar with /etc/network/interfaces, you can go ahead and make the static network configuration. In the next section we are going to see how to use netplan to configure the network.
Configuring the public IP with netplan
In the container, create a file /etc/netplan/50-static-public-ip.yaml so that it as follows. There are two options for the renderer, networkd (systemd-networkd which is available on Ubuntu 18.04) and NetworkManager. We then specify the public IP address, the gateway and finally the DNS server IP addresses. You may want to replace the DNS server with that of your cloud provider.
root@c1public:~# cat /etc/netplan/50-static-public-ip.yaml network: version: 2 renderer: networkd ethernets: eth0: dhcp4: no dhcp6: no addresses: - 100.100.100.98/29 gateway4: 100.100.100.97 nameservers: addresses: - 8.8.8.8
Applying the netplan network configuration
Run the following command to apply the netplan network configuration. Alternatively, you can restart the container.
root@c1public:~# netplan --debug apply ** (generate:294): DEBUG: 15:46:19.174: Processing input file //etc/netplan/50-cloud-init.yaml.. ** (generate:294): DEBUG: 15:46:19.174: starting new processing pass ** (generate:294): DEBUG: 15:46:19.174: Processing input file //etc/netplan/50-static-public-ip.yaml.. ** (generate:294): DEBUG: 15:46:19.174: starting new processing pass ** (generate:294): DEBUG: 15:46:19.174: eth0: setting default backend to 1 ** (generate:294): DEBUG: 15:46:19.175: Generating output files.. ** (generate:294): DEBUG: 15:46:19.175: NetworkManager: definition eth0 is not for us (backend 1) DEBUG:netplan generated networkd configuration exists, restarting networkd DEBUG:no netplan generated NM configuration exists DEBUG:device lo operstate is unknown, not replugging DEBUG:netplan triggering .link rules for lo DEBUG:device eth0 operstate is up, not replugging DEBUG:netplan triggering .link rules for eth0 root@c1public:~#
Here is the network interface with the new IP address,
root@c1public:~# ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 100.100.100.98 netmask 255.255.255.255 broadcast 0.0.0.0 inet6 fe80::216:3eff:fe55:1930 prefixlen 64 scopeid 0x20<link> ether 00:16:3e:55:19:30 txqueuelen 1000 (Ethernet) RX packets 489 bytes 30168 (30.1 KB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 18 bytes 1356 (1.3 KB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 ... root@c1public:~# route Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface default _gateway 0.0.0.0 UG 0 0 0 eth0 100.100.100.97 0.0.0.0 255.255.255.240 U 0 0 0 eth0 root@c1public:~# ping -c 3 www.ubuntu.com PING www.ubuntu.com (91.189.89.118) 56(84) bytes of data. 64 bytes from www-ubuntu-com.nuno.canonical.com (91.189.89.118): icmp_seq=1 ttl=53 time=8.10 ms 64 bytes from www-ubuntu-com.nuno.canonical.com (91.189.89.118): icmp_seq=2 ttl=53 time=8.77 ms 64 bytes from www-ubuntu-com.nuno.canonical.com (91.189.89.118): icmp_seq=3 ttl=53 time=9.81 ms --- www.ubuntu.com ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2003ms rtt min/avg/max/mdev = 8.106/8.896/9.810/0.701 ms root@c1public:~#
Testing the public IP address
Let’s test that the public IP address of the LXD container works. We install nginx and modify a bit the default HTML page.
ubuntu@c1public:~$ sudo apt update ... ubuntu@c1public:~$ sudo apt install nginx ... ubuntu@c1public:~$ cat /var/www/html/index.nginx-debian.html <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html> ubuntu@c1public:~$ sudo sed -i 's/to nginx/to nginx running in a LXD container with public IP address/g' /var/www/html/index.nginx-debian.html ubuntu@c1public:~$
Let’s visit the public IP address with our browser!
It worked!
Troubleshooting
Help! I can see the IP address but there is no route?!?
Most likely you misconfigured the network prefix in the netplan configuration file. Find the details at
ubuntu@myserver:~$ sudo apt install ipcalc ubuntu@myserver:~$ ipcalc 100.100.100.96/29 Address: 100.100.100.96 01100100.01100100.01100100.01100 000 Netmask: 255.255.255.248 = 29 11111111.11111111.11111111.11111 000 Wildcard: 0.0.0.7 00000000.00000000.00000000.00000 111 => Network: 100.100.100.96/29 01100100.01100100.01100100.01100 000 HostMin: 100.100.100.97 01100100.01100100.01100100.01100 001 HostMax: 100.100.100.102 01100100.01100100.01100100.01100 110 Broadcast: 100.100.100.103 01100100.01100100.01100100.01100 111 Hosts/Net: 6 Class A
The public IP addresses have the range 100.100.100.[97-102]. Both the gateway (100.100.100.97) and the LXD container public IP address (100.100.100.98) are in this range, therefore all are fine.
Recent Comments