DNS для lxc контейнеров в приватной сети

Контейнерная LXC виртуализация прекрасно работает в Ubuntu 12.04, но у неё есть серьезный недостаток: если контейнеру назначен статический IP адрес, через конфигурационный файл, то по имени данный контейнер не ресолвится в DNS даже в частной сети которая создается по умолчанию. Правка файла /etc/hosts  на основной машине ситуацию не исправляет.

Можно конечно поднять отдельный DNS сервер или использовать имеющийся в настоящей локальной сети, но это может быть не применимым или слишком тяжеловесным решением  в некоторых ситуация, например на девелоперской машине.

К счастью, проблема исправляется посредством правки файла /etc/init/lxc-net.conf. Вот последовательность шагов, который позволят вам настроить корректное разрешение DNS имени:

  1. Создайте файл, по формату аналогичный /etc/hosts и заполните его информацией по IP адресам и доменным именам контейнеров. Далее я буду считать что вы сохранили этот файл как /var/lib/lxc/hosts хотя никто не мешает разместить его в другом месте
  2. От имени root'а откройте на редактирование файл /etc/init/lxc-net.conf и найдите строчку в которой производится старт dnsmasq. Её начало выглядит вот так:
    dnsmasq -u lxc-dnsmasq --strict-order...
  3. В конце этой строчки, прямо перед || cleanup добавьте
    --addn-hosts=/var/lib/lxc/hosts
  4. В результате правки вся строка будет выглядеть вот так:
    dnsmasq -u lxc-dnsmasq --strict-order --bind-interfaces --pid-file=${varrun}/dnsmasq.pid --conf-file= --listen-address ${LXC_ADDR} --dhcp-range ${LXC_DHCP_RANGE} --dhcp-lease-max=${LXC_DHCP_MAX} --dhcp-no-override --except-interface=lo --interface=${LXC_BRIDGE} --dhcp-option=119,${LXC_DOMAIN_SEARCH} --dhcp-option=6,${LXC_DNS_SERVER} --addn-hosts=/var/lib/lxc/hosts|| cleanup
  5. Сохранив изменения произведите остановку и запуск сервиса lxc-net:
    sudo service lxc-net stop; sudo service lxc-net start
После этого сервис dnsmasq, который используется по умолчанию в качестве dhcp/dns сервера для внутренней сети контейнеров будет смотреть в наш файл когда контейнер будет приходить к нему с запросом разрешения доменного имени.

Если часть ваших контейнеров получает IP адрес через dhcp и вы также хотите предоставить им возможность обращаться к контейнерам со статическими адресами по имени, убедитесь что переменная LXC_DNS_SERVER содержит адрес вашей машины с запущенными lxc контейнерами, а не адрес DNS сервера реальной локальной сети. Эту переменную можно исправить непосредственно в /etc/init/lxc-net, но лучше это сделать в /etc/default/lxc

Данной решение имеет один недостаток: здесь мы правим системный init скрипт, который потенциально может быть обновлен при получении в процессе обновления новой версии пакета lxc. В таком случае придется слить наши локальный правки с изменениями файла из пакета.

Managing DNS for lxc containers in private network

LXC containers in ubuntu 12.04 works great, but have serious problem: static ip address, set by lxc config file, and resolvable domain name accross private network does not automatically work together. Editing /etc/hosts on host machine does not make any effect.

Of course we can set up additional dns server or use existing one in our real network, but it can be inapplicable or overkill for small network or developer machine.

This problem can be solved by editing startup script /etc/init/lxc-net.conf. Here are the steps, that allow you to easily setup dns resolving:

  1. Create somewhere in the system file similiar to /etc/hosts and fill it with ip addresses and dns names for your containers. /var/lib/lxc/hosts should be a good a place, and I suppose you select it in further steps
  2. As root, open file /etc/init/lxc-net.conf with your favorite text editor and find line where dnsmasq is started. It is look like this:
    dnsmasq -u lxc-dnsmasq --strict-order...
  3. In the end of this line right before || cleanup add --addn-hosts=/var/lib/lxc/hosts
  4. As a result all line would look like:
    dnsmasq -u lxc-dnsmasq --strict-order --bind-interfaces --pid-file=${varrun}/dnsmasq.pid --conf-file= --listen-address ${LXC_ADDR} --dhcp-range ${LXC_DHCP_RANGE} --dhcp-lease-max=${LXC_DHCP_MAX} --dhcp-no-override --except-interface=lo --interface=${LXC_BRIDGE} --dhcp-option=119,${LXC_DOMAIN_SEARCH} --dhcp-option=6,${LXC_DNS_SERVER} --addn-hosts=/var/lib/lxc/hosts || cleanup
  5. Start and stop service lxc-net
  6. sudo service lxc-net stop; sudo service lxc-net start
After that dnsmasq daemon that is used in default config will lookup in file for dns names when containers will issue to it nslookup request.

If some of your containers get ip address via dhcp and you want them to resolve your static containers too, ensure that your LXC_DNS_SERVER variable point to your machine with lxc, but not to your real network dns server. You can also edit it in /etc/init/lxc-net, but you should better set it in /etc/default/lxc

This solution has one lack: we editing a system file that can be potentially updated during lxc package update, and you'll have to merge your modification with package changes.