Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
linux_faq:setup_lxc_lxd_host_on_ubuntu_1804 [2019/02/11 09:13] – external edit 127.0.0.1linux_faq:setup_lxc_lxd_host_on_ubuntu_1804 [2019/02/13 12:35] (current) – [Миграция LXC-LXD с помощью lxd-tools] admin
Line 1: Line 1:
 +Настраиваем хост контейнеров **LXD** с хранилищем **zfs** и web-интерфейсом.
 +  
 +====== Настройка LXD ======
 +https://habr.com/post/308400/ \\
 +Если мы настраиваем физический хост или виртуальную машину на собственном сервере, то нам нужно удалить пакет **cloud-init**. Он предназначен для автоматического конфигурирования системы в различных облачных окружениях.
 +  sudo apt-get -y purge cloud-init && sudo rm -rf /etc/cloud
 +Теперь ставим **lxd**:
 +  sudo apt-get install lxd zfsutils-linux bridge-utils
 +===== Настраиваем ZFS-pool =====
 +Использование **ZFS** позволяет использовать снепшоты для бекапа, а также дедупликацию и компрессию для экономии места.
 +Если на хосте **LXС/LXD** есть **ZFS volume**, то контейнеры можно создавать как в нем, так и по старому в директории. Просто при создании контейнера нужно указывать имя **zfs pool**, в котором будет создан **dataset**
 +<code>
 +sudo zpool create -f lxd /dev/xvdb
 +sudo zpool status
 +sudo zfs list
 +sudo zfs set dedup=on lxd
 +sudo zfs set compression=on lxd
 +sudo zdb -S lxd
 +</code>
 +
 +===== Настройка network bridge для LXD =====
 +Мне нужно, чтобы контейнеры имели адреса в двух физических **LAN**. Таким образом, в **netplan** мне нужно настроить два **bridge**, в котором указать в качестве **slave**-интерфейсов мои физические интерфейсы.\\
 +Устанавливаем **bridge-utils**:
 +  sudo apt-get install bridge-utils
 +Удаляем все ненужные **yaml**-файлики из **/etc/netplan/** и оставляем единственный с таким вот содержимым:
 +<code>
 +network:
 +  version: 2
 +  renderer: networkd
 +  ethernets:
 +    eth0:
 +      dhcp4: no
 +      dhcp6: no
 +    eth1:
 +      dhcp4: no
 +      dhcp6: no
 +  bridges:
 +    br0:
 +      dhcp4: no
 +      dhcp6: no
 +      interfaces:
 +        - eth0
 +      addresses: [ 192.168.77.13/24 ]
 +      gateway4: 192.168.77.1
 +      nameservers:
 +          addresses:
 +              - 192.168.77.100
 +              - 192.168.77.1
 +          search: [autosys.tk]
 +      parameters:
 +          stp: false
 +          forward-delay: 0
 +    br1:
 +      dhcp4: no
 +      dhcp6: no
 +      interfaces:
 +        - eth1
 +      addresses: [ 192.168.100.113/24 ]
 +      parameters:
 +          stp: false
 +          forward-delay: 0
 +</code>
 +===== Первичная настройка LXD =====
 +Перед созданием или импортом контейнеров необходимо произвести первоначальное конфигурирование LXD. Выполняем команду:
 +  sudo lxd init
 +Вот один из вариантов конфигурирования:
 +<code>
 +Would you like to use LXD clustering? (yes/no) [default=no]: n
 +Do you want to configure a new storage pool? (yes/no) [default=yes]: yes
 +Name of the new storage pool [default=default]: lxd
 +Name of the storage backend to use (btrfs, dir, lvm, zfs) [default=zfs]: zfs
 +Create a new ZFS pool? (yes/no) [default=yes]: n
 +Name of the existing ZFS pool or dataset: lxd
 +Would you like to connect to a MAAS server? (yes/no) [default=no]: n
 +Would you like to create a new local network bridge? (yes/no) [default=yes]: n
 +Would you like to configure LXD to use an existing bridge or host interface? (yes/no) [default=no]: yes
 +Name of the existing bridge or host interface: br0
 +Would you like LXD to be available over the network? (yes/no) [default=no]: n
 +Would you like stale cached images to be updated automatically? (yes/no) [default=yes]
 +Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]: y
 +config: {}
 +cluster: null
 +networks: []
 +storage_pools:
 +- config:
 +    source: lxd
 +  description: ""
 +  name: lxd
 +  driver: zfs
 +profiles:
 +- config: {}
 +  description: ""
 +  devices:
 +    eth0:
 +      name: eth0
 +      nictype: bridged
 +      parent: br0
 +      type: nic
 +    root:
 +      path: /
 +      pool: lxd
 +      type: disk
 +  name: default
 +
 +</code>
 +Повторное конфигурирование можно запустить так:
 +  dpkg-reconfigure -p medium lxd
 +
 +===== Внесение изменений в дефолтный профиль =====
 +Для того, чтобы отредактировать дефолтный профиль, который будет применяться к новым контейнерам.
 +Сохраним его в файл:
 +  sudo lxc profile show default > default_lxd_profile.yaml
 +Отредактируем его, например - заменив **lxdbr0** на имя нашего **bridge** - **br0**. И сохраним его в конфигурации **LXD**:
 +  sudo lxc profile edit default < default_lxd_profile.yaml
 +Удалить дефолтный **lxdbr0** можно командой:
 +  sudo lxc network delete lxdbr0
 +===== Монтируем директорию хоста в контейнер LXD =====
 +  sudo lxc config device add ContainerName DeviceName disk source=/tmp/share_on_host path=/tmp/share_on_guest
 +Тут **ContainerName** - имя контейнера, **DeviceName** - имя устройства (оно может быть произвольным и служит для идентификации этого ресурса в конфигурации).
 +
 +===== Добавление storage pool =====
 +Для добавления хранилища выполняем:
 +  sud mkdir -p /path/to/storage/pool
 +  sudo lxc storage create PoolName dir source=/path/to/storage/pool
 +Данная команда создаст пул в директории.
 +Для того, чтобы его впоследствии использовать нужно создать соответствующий профиль.
 +===== Создаем профиль для нового storage pool =====
 +Создаем пустой профиль:
 +  sudo lxc profile create dir_storage
 +Открываем редактор:
 +  sudo lxc profile edit dir_storage
 +И приводим его к такому виду:
 +<code>
 +config: {}
 +description: "Profile with Directory storage"
 +devices:
 +  eth0:
 +    name: eth0
 +    nictype: bridged
 +    parent: br0
 +    type: nic
 +  root:
 +    path: /
 +    pool: lxd_dir
 +    type: disk
 +name: dir_storage
 +used_by: []
 +</code>
 +===== Добавляем устройство ppp в профиль или контейнер LXD =====
 +Добавление профиля и устройства в него:
 +
 +  sudo lxc profile create device_ppp
 +  sudo lxc profile device add device_ppp dev_ppp unix-char path=/dev/ppp
 +
 +И назначаем профиль контейнеру:
 +
 +  sudo lxc profile assign pptp device_ppp,default
 +
 +Тут важно, что нужно перечислить все профили, назначаемые контейнеру.
 +
 +==== Добавление устройства непосредственно в контейнер ====
 +В этом случае профиль можно не создавать.
 +
 +sudo lxc config device add <ctname> dev_ppp unix-char path=/dev/ppp
 +
 +
 +==== Смена пароля root в контейнере LXD ====
 +Допустим, у нас есть контейнер **test1** и нам надо сменить в нем пароль **root**. Для этого выполняем:
 +  sudo lxc exec test1 -- sh -c passwd
 +  
 +===== Установка web-интерфейса для LXD =====
 +Web-интерфейсов для **LXD** существует несколько. Покопавшись на **github** я выбрал [[https://github.com/AdaptiveScale/lxdui|LXDUI от AdaptiveScale]]. Его преимущества - довольно легкий (написан на **python**), обновляется, по крайней мере пока. \\
 +Устанавливаем запчасти:
 +  sudo apt-get install -y python3 zfsutils-linux bridge-utils unzip python3-pip
 +  sudo rm /usr/bin/python && sudo ln -s /usr/bin/python3.6 /usr/bin/python
 +  sudo pip3 install --upgrade pip
 +Скачиваем:
 +  wget https://github.com/AdaptiveScale/lxdui/archive/master.zip
 +Распаковываем:
 +  unzip ./master.zip
 +Устанавливаем:
 +  cd lxdui-master
 +  sudo pip3 install .
 +Запускаем:
 +  sudo lxdui start
 +==== Создаем файл сервиса systemd ====
 +  sudo nano /lib/systemd/system/lxdui.service
 +Пишем туда вот что:
 +<code>
 +[Unit]
 +Description=LXC/LXD Web User Interface
 +After=network.target
 +
 +[Service]
 +Type=simple
 +ExecStart=/usr/local/bin/lxdui start
 +ExecStop=/usr/local/bin/lxdui stop
 +ExecReload=/usr/local/bin/lxdui reload
 +
 +[Install]
 +WantedBy=multi-user.target
 +</code>
 +Включаем сервис:
 +  sudo systemctl enable lxdui
 +И запускаем его:
 +  sudo service lxdui start
 +  
 +
 +==== Аутентификация локальных и доменных пользователей ====
 +[[https://github.com/AdaptiveScale/lxdui/|LXDUI от AdaptiveScale]] сам по себе прост и неплох, однако в нем нет аутентификации локальных или доменных пользователей. \\
 +Я решил это исправить и добавить аутентификацию пользователей, авторизовавшихся через pam-модули хоста. \\
 +Для этого нужно немного отредактировать файлик **./app/lib/auth.py** \\
 +В моем случае он установился в **/usr/local/lib/python3.6/dist-packages/app/lib/auth.py** \\
 +
 +  sudo pip3 install python-pam
 +В самом конце это файлика есть функция **authenticate**, которую я привел вот к такому виду:
 +<code>    def authenticate(self, username, password):
 +        #try to authenticate using pam
 +        pamobj = pam.pam()
 +        if pamobj.authenticate(username, password) is True:
 +           groups_gids = subprocess.check_output("id -G " + username, shell=True, universal_newlines=True).split()
 +           #for group in  [subprocess.check_output("getent group " + gid, shell=True, universal_newlines=True).split(':',maxsplit = 1)[0] for gid in groups_gids]:
 +           for group in  [grp.getgrgid(gid).gr_name for gid in groups_gids]:
 +                 if group.lower() == 'lxdui':
 +                     return True, 'Authenticated'
 +
 +        #Authebticate using LXDUI database
 +        account, err = self.get(username)
 +
 +        if account is None:
 +            return 'Error', err
 +
 +        if account['password'] == self.sha_password(password):
 +            return True, 'Authenticated'
 +        else:
 +            return False, 'Incorrect password.'
 +</code>
 +Кроме того, в начало файла нужно добавить: 
 +  import pam, grp, subprocess
 +Мой хост присоединен к домену **Active Directory** и теперь пользователи, входящие в доменную или локальную группу **lxdui** будут нормально логиниться. 
 +
 +====== Экспорт/Импорт контейнеров со старого хоста LXC======
 +На новом хосте создаем контейнер с таким же именем как и старый. Останавливаем его. Монтируем.
 +  sudo lxc stop CONTAINERNAME
 +  sudo zfs mount lxd/containers/CONTAINERNAME
 +Удаляем файлы:
 +  sudo rm -Rf /var/lib/lxd/storage-pools/lxd/containers/CONTAINERNAME/rootfs/*
 +И теперь выполняем **rsync**. тут сложность в том, что rsync должен быть выполнен с правами **sudo** на обоих хостах:
 +  sudo rsync -hXAavzP --stats --numeric-ids --rsync-path="echo PASSWORD | sudo -Sv && sudo rsync"  Username@Old_LXC_Host:/var/lib/lxc/CONTAINERNAME/rootfs/ /var/lib/lxd/storage-pools/lxd/containers/CONTAINERNAME/rootfs/
 +Контейнеры импортированные из **LXC** работали в **privileged mode**, поэтому нужно задать такой же режим импортированному контейнеру:
 +  sudo lxc config set CONTAINERNAME security.privileged true
 +Также нужно отключить **apparmor**:
 +  sudo lxc profile set default raw.lxc lxc.apparmor.profile=unconfined
 +В данном случае - отключаем **apparmor** (устанавливаем профиль unconfined) для профиля **default**. \\
 +Или можно отключить **apparmor** для заданного контейнера:
 +  sudo lxc config set CONTAINERNAME raw.lxc lxc.apparmor.profile=unconfined
 +
 +====== Миграция LXC-LXD с помощью lxd-tools ======
 +^При попытке мигрировать с хоста **Ubuntu 16.04.5** у меня толком ничего не вышло. При миграции переезжала файловая система, однако файл с настройками контейнера не создавался.^
 +На хосте **LXC** ставим **lxd-tools**.
 +Добавляем диск и делаем **zfs-пул**.\\
 +Затем настраиваем **lxd** с помощью
 +  lxd init
 +Мигрируем контейнер с помощью
 +  lxc-to-lxd
 +Затем делаем 
 +  export
 +переносим полученный **image** на новый хост и разворачиваем там.
 +
 +===== Установка lxc-to-lxd на Ubuntu 16.04 =====
 +При попытке установить **lxd-tools** из репозитория **Ubuntu 16.04** оказалось, что ставится только версия **lxd-tools (2.0.11-0ubuntu1~16.04.4)**, в которой отсутствует **lxc-to-lxd**. \\
 +Поэтому, ставим из **backports**:
 +  sudo apt install -t xenial-backports lxd-tools  
 +В результате установится версия **3.0.1-0ubuntu1~16.04.4**, в которой **lxc-to-lxd** есть!.
 +===== Конвертация =====
 +  sudo lxc-to-lxd container_to_move
 +===== Миграция =====
 +Если контейнер удачно конвертировался в **LXD**. Экспортируем его в файл:
 +    lxc snapshot container_name backup
 +    lxc publish container_name/backup --alias container_name-backup
 +    lxc image export container_name-backup .
 +    lxc image delete container_name-backup
 +
 +Импортируем на новом хосте:
 +    lxc image import TARBALL-NAME --alias container_name-backup
 +    lxc launch container_name-backup container_name
 +    lxc image delete container_name-backup
  
  • linux_faq/setup_lxc_lxd_host_on_ubuntu_1804.txt
  • Last modified: 2019/02/13 12:35
  • by admin