Сохранить изменения resolvectl при перезагрузке.

Вопрос или проблема

Я использую LXC контейнеры и разрешаю CONTAINERNAME.lxd в IP-адрес указанного контейнера, используя:

sudo resolvectl dns lxdbr0 $bridge_ip
sudo resolvectl domain lxdbr0 '~lxd'

Это отлично работает! Но изменения не сохраняются после перезагрузки хоста – как сделать, чтобы они сохранялись?

Я использую Pop!_OS 22.04, основанную на Ubuntu 22.04.

(Я описал “что пробовал” в качестве ответов на этот вопрос, которые имеют различную степень успеха.)

Документация LXD описывает решение:

Поместите это в /etc/systemd/system/lxd-dns-lxdbr0.service:

[Unit]
Description=LXD per-link DNS configuration for lxdbr0
BindsTo=sys-subsystem-net-devices-lxdbr0.device
After=sys-subsystem-net-devices-lxdbr0.device

[Service]
Type=oneshot
ExecStart=/usr/bin/resolvectl dns lxdbr0 BRIDGEIP
ExecStart=/usr/bin/resolvectl domain lxdbr0 '~lxd'
ExecStopPost=/usr/bin/resolvectl revert lxdbr0
RemainAfterExit=yes

[Install]
WantedBy=sys-subsystem-net-devices-lxdbr0.device

(Измените BRIDGEIP на свой, взятый из lxc network show lxdbr0 | grep ipv4.address)

Примените эти настройки без необходимости перезагрузки, используя:

sudo systemctl daemon-reload
sudo systemctl enable --now lxd-dns-lxdbr0

Я создал ужасный обходной путь: создал скрипт lxc-ip, который получает IPv4 контейнера из вывода команды lxc list. Пример использования: ping $(lxc-ip mycontainer).

Скрипт выглядит так:

#!/usr/bin/env bash

prog=$(basename $0)

function usage {
    echo "Usage: $prog CONTAINER" >&2
    echo "Outputs IPv4 address of given CONTAINER." >&2
}

container=""

while [[ $# -gt 0 ]]
do
  case "$1" in
  -h|--help)
    usage
    exit 0
    ;;
  *)
    if [ -z "$container" ]; then
        container=$1
    else
        echo "$prog error: Not multiple CONTAINERs" >&2
        usage
        exit 1
    fi
    ;;
  esac
  shift
done

if [ -z "$container" ]; then
    echo "$prog error: Must pass a CONTAINER" >&2
    usage
    exit 1
fi

table=$(lxc list -c ns4 -f csv)
line=$(echo "$table" | grep "$container")
if [ -z "$line" ]; then
    echo "$prog error: Container '$container' not found. Existing containers are:" >&2
    lxc list -c n -f compact >&2
    exit 2
fi

if ! grep -qs RUNNING <<<"$line" ; then
    echo "$prog error: Container is not running: $line" >&2
    exit 3
fi

ipv4=$(echo "$line" | cut -d',' -f3 | cut -d' ' -f1)
if [ -z "$ipv4" ]; then
    echo "$prog error: Container has no IPv4: $line" >&2
    exit 4
fi

echo "$ipv4"

На случай, если кто-то сможет это уточнить или подтвердить: мой коллега сообщает, что решил это с помощью механизма, в котором используется этот текст в /etc/systemd/network/lxd.network:

[Match]
Name=lxdbr0

[Network]
Address=BRIDGEIP/24
DNS=BRIDGEIP
Domains=lxd

(Измените BRIDGEIP на свой, взятый из lxc network show lxdbr0 | grep ipv4.address)

(Это также может потребовать одновременного запуска systemd-networkd и NetworkManager)

Я вижу похожий вопрос на askubuntu.com, в котором один (-1) ответ советует сохранять другие изменения resolvectl, превращая их в вызовы nmcli (интерфейс командной строки Network Manager). Это, по-видимому, сохраняет информацию где-то в постоянном хранилище, которая используется для наполнения конфигурации ‘resolvectl’ при загрузке.

Если бы я хотел это сделать, я думаю, я могу понять, как я бы конвертировал первый из моих вызовов resolvectl, используя что-то вроде:

sudo nmcli connection modify lxdbr0 ipv4.dns $bridge_ip

Но я не могу преобразовать мой второй вызов resolvectl, устанавливающий `domain=~lxd”, в команды nmcli.

Поэтому этот подход не решает проблему.

Ответ или решение

Для обеспечения постоянства настроек DNS через resolvectl после перезагрузки системы в LXC-контейнерах на ОС Pop!_OS 22.04, есть несколько решений, которые можно использовать. Давайте подробно рассмотрим наиболее надежные и распространенные методы.

Проблема

При использовании команды:

sudo resolvectl dns lxdbr0 $bridge_ip
sudo resolvectl domain lxdbr0 '~lxd'

IP-адрес контейнера может быть успешно назначен, но после перезагрузки все изменения исчезают. Чтобы избежать этого, нужно интегрировать данные изменения в структуру systemd, обеспечив их устойчивость.

Решение с использованием systemd-сервиса

Создание пользовательского systemd-сервиса позволяет автоматически применять DNS-настройки. Вот как это можно реализовать:

  1. Создайте новый сервис:

    Создайте файл /etc/systemd/system/lxd-dns-lxdbr0.service с содержанием:

    [Unit]
    Description=LXD per-link DNS configuration for lxdbr0
    BindsTo=sys-subsystem-net-devices-lxdbr0.device
    After=sys-subsystem-net-devices-lxdbr0.device
    
    [Service]
    Type=oneshot
    ExecStart=/usr/bin/resolvectl dns lxdbr0 BRIDGEIP
    ExecStart=/usr/bin/resolvectl domain lxdbr0 '~lxd'
    ExecStopPost=/usr/bin/resolvectl revert lxdbr0
    RemainAfterExit=yes
    
    [Install]
    WantedBy=sys-subsystem-net-devices-lxdbr0.device

    Замените BRIDGEIP на фактический IP-адрес, который можно получить с помощью команды:

    lxc network show lxdbr0 | grep ipv4.address
  2. Активируйте сервис:

    Выполните следующие команды, чтобы активировать и запустить сервис:

    sudo systemctl daemon-reload
    sudo systemctl enable --now lxd-dns-lxdbr0

Альтернативное решение с использованием systemd-networkd

Для тех, кто предпочитает использовать конфигурации systemd-networkd, можно создать файл /etc/systemd/network/lxd.network со следующим содержанием:

[Match]
Name=lxdbr0

[Network]
Address=BRIDGEIP/24
DNS=BRIDGEIP
Domains=lxd

Этот метод предполагает использование systemd-networkd для управления сетевыми подключениям, что может конфликтовать с некоторыми настройками NetworkManager.

Заключение

Каждое предложенное решение имеет свои преимущества и ограничения, поэтому выбор подходящего метода зависит от конкретной среды и требований. Автоматизированное развертывание через systemd-сервис чаще всего является предпочтительным подходом для автоматизации и удобства поддержки изменений. Убедитесь, что все настройки протестированы в тестовой среде перед применением на продакшене, чтобы убедиться в их корректности и предсказуемости.

Этот подход обеспечит надежное сохранение DNS-настроек для контейнеров LXC, а также упростит управление ими, особенно в масштабируемых средах.

Оцените материал
Добавить комментарий

Капча загружается...