Установка BAYRELL Cloud OS на LXC

Настройка Облачной операционной системы BAYRELL Cloud OS в LXC контейнере.

Инструкция предназначена для Ubuntu 18.04. Для новой версии, не проверял, возможно, не потребуется обновлять ядро.

LXC - это система виртуальных контейнеров для Linux. Отличием от Docker в том, что LXC эмулирует операционную систему в контейнере, и позволяет вносить изменения. При перезапуске LXC контейнера, изменения сохраняться. Docker подходит для распостранения приложения. А LXC удобен для настройки системы, и при необходимости, бэкапе и легком переносе на другой сервер.


Установка и настройка LXC

Для установки Облачной ОС на сервер, воспользуйтесь следующей инструкцией.

1) Осуществите базовую настройку Ubuntu 18.04.

2) Обновите ядро системы до версии 5.3, согласно инструкции.

3) Установите программу LXC

aptitude install lxc

Установите права доступа, чтобы корректно запускались контейнеры:

chown lxc-root:root /var/lib/lxc
chmod 755 /var/lib/lxc

4) Настройте сеть LXC

Рекомендуется использовать сеть 172.30.0.1/24. Более подробный список указан в списке сетей.

В файле /etc/default/lxc-net пропишите

USE_LXC_BRIDGE="true"
LXC_BRIDGE="lxcbr0"
LXC_ADDR="172.30.0.1"
LXC_NETMASK="255.255.255.0"
LXC_NETWORK="172.30.0.0/24"
LXC_DHCP_RANGE="172.30.0.2,172.30.0.254"
LXC_DHCP_MAX="253"
LXC_DHCP_CONFILE=/etc/lxc/dnsmasq.conf
#LXC_DOMAIN="lxc"

Создайте файл /etc/lxc/dnsmasq.conf и пропишите в нем:

port=53
listen-address=172.30.0.1
resolv-file=/etc/resolv.conf
domain-needed

5) Пропишите хосты

В /etc/hosts добавьте строчки

172.30.0.20 docker0
172.30.0.21 docker1

6) Включите драйвера br_netfilter

echo overlay >> /etc/modules-load.d/docker.conf
echo br_netfilter >> /etc/modules-load.d/docker.conf

Установка LXC контейнера

1) В файле /etc/lxc/default.conf проверьте и закоментируйте строчки:

#lxc.idmap = u 0 100000 65536
#lxc.idmap = g 0 100000 65536

2) Установите контейнер docker0

DOWNLOAD_KEYSERVER="hkp://keyserver.ubuntu.com" lxc-create -t download -n docker0 -- --dist ubuntu --release focal --arch amd64

3) Внесите изменения в файл /var/lib/lxc/docker0/config

Раскоментируйте строку

lxc.include = /usr/share/lxc/config/nesting.conf

Это позволит создать Nested контейнер — возможность запустить контейнер в контейнере (вложенные контейнеры).

Добавьте в файл следующие строки

lxc.net.0.ipv4.address = 172.30.0.20/24
lxc.net.0.ipv4.gateway = 172.30.0.1
lxc.mount.auto = cgroup-full:rw
lxc.apparmor.profile = unconfined
lxc.cgroup.devices.allow = a
lxc.cap.drop =

Если вы хотите дать доступ к видеокарте, то нужно также добавить строчки:

# GPU
lxc.cgroup.devices.allow = c 195:* rwm
lxc.cgroup.devices.allow = c 243:* rwm
lxc.cgroup.devices.allow = c 510:* rwm
lxc.cgroup2.devices.allow = c 195:* rwm
lxc.cgroup2.devices.allow = c 243:* rwm
lxc.cgroup2.devices.allow = c 510:* rwm
lxc.mount.entry = /dev/nvidia0 dev/nvidia0 none bind,optional,create=file
lxc.mount.entry = /dev/nvidiactl dev/nvidiactl none bind,optional,create=file
lxc.mount.entry = /dev/nvidia-uvm dev/nvidia-uvm none bind,optional,create=file
lxc.mount.entry = /dev/nvidia-modeset dev/nvidia-modeset none bind,optional,create=file
lxc.mount.entry = /dev/nvidia-uvm-tools dev/nvidia-uvm-tools none bind,optional,create=file

4) В файле /var/lib/lxc/docker0/rootfs/etc/netplan/10-lxc.yaml укажите:

network:
  version: 2
  ethernets:
    eth0:
      dhcp4: no
      dhcp6: no
      addresses: [172.30.0.20/24]
      gateway4: 172.30.0.1
      nameservers:
        addresses: [172.30.0.1]

5) Пересоздайте resolv.conf

rm /var/lib/lxc/docker0/rootfs/etc/resolv.conf
nano /var/lib/lxc/docker0/rootfs/etc/resolv.conf

Укажите в нем новый адреса DNS серверов:

nameserver 172.30.0.1

6) Скопируйте ssh ключ. Вместо /home/user укажите вашу домашнюю папку.

mkdir /var/lib/lxc/docker0/rootfs/root/.ssh
chmod 700 /var/lib/lxc/docker0/rootfs/root/.ssh
cat /home/user/.ssh/id_rsa.pub >> /var/lib/lxc/docker0/rootfs/root/.ssh/authorized_keys
chmod 600 /var/lib/lxc/docker0/rootfs/root/.ssh/authorized_keys

mkdir /var/lib/lxc/docker0/rootfs/home/ubuntu/.ssh
chmod 700 /var/lib/lxc/docker0/rootfs/home/ubuntu/.ssh
cat /home/user/.ssh/id_rsa.pub >> /var/lib/lxc/docker0/rootfs/home/ubuntu/.ssh/authorized_keys
chmod 600 /var/lib/lxc/docker0/rootfs/home/ubuntu/.ssh/authorized_keys
chown -R 1000:1000 /var/lib/lxc/docker0/rootfs/home/ubuntu/.ssh

7) Запустите контейнер и подключитесь к нему:

lxc-start docker0
lxc-attach docker0

8) Установите программы

apt update
apt install nano

9) Установите локаль. Раскоментируйте строки в файле через команду nano /etc/locale.gen

en_US.UTF-8 UTF-8
ru_RU.UTF-8 UTF-8

Пересоздайте локаль:

locale-gen

Пропишите локаль на уровне системы:

nano /etc/profile.d/0.locale.sh

export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/sbin:/bin"
export LANG="en_US.UTF-8"
export LANGUAGE="en_US:en"
export LC_CTYPE="en_US.UTF-8"
export LC_NUMERIC="en_US.UTF-8"
export LC_TIME="en_US.UTF-8"
export LC_COLLATE="en_US.UTF-8"
export LC_MONETARY="en_US.UTF-8"
export LC_MESSAGES="en_US.UTF-8"
export LC_PAPER="en_US.UTF-8"
export LC_NAME="en_US.UTF-8"
export LC_ADDRESS="en_US.UTF-8"
export LC_TELEPHONE="en_US.UTF-8"
export LC_MEASUREMENT="en_US.UTF-8"
export LC_IDENTIFICATION="en_US.UTF-8"
export EDITOR=nano

10) Установите программы:

apt install aptitude mc nano htop iftop bwm-ng iperf iperf3 iotop tmux screen sshfs net-tools dnsutils bind9-utils openssh-server curl
systemctl enable ssh
systemctl start ssh

11) Ограничьте размер логов systemd

Пропишите в /etc/systemd/journald.conf строчку:

SystemMaxUse=1G

Это строчка ограничивает максимальный размер логов в 1 гигабайт. 

Перезагрузите конфигурацию systemd:

systemctl daemon-reload

12) Сделайте sudo без ввода пароля

Добавьте группу wheel

groupadd -r wheel
usermod -a -G wheel ubuntu

в /etc/sudoers добавьте строчку

%wheel ALL=(ALL:ALL) NOPASSWD: ALL

Все пользователи, которые находятся в группе wheel будут иметь возможность выполнять команды рут без пароля

13) Установка dnsmasq

apt install dnsmasq

Скопируйте конфиг dnsmasq:

cp /etc/dnsmasq.conf /etc/dnsmasq.conf.example
echo "" > /etc/dnsmasq.conf

Создайте файл /etc/resolv.dnsmasq

nameserver 8.8.8.8
nameserver 8.8.4.4
nameserver 1.1.1.1

В /etc/dnsmasq.conf пропишите:

port=53
listen-address=0.0.0.0
no-dhcp-interface=
bind-interfaces
expand-hosts
local-ttl=1
no-negcache

# Настройки DNS по умолчанию
resolv-file=/etc/resolv.dnsmasq

conf-dir=/etc/dnsmasq.d
cache-size=150
max-cache-ttl=600
min-cache-ttl=60

# Одновременный запрос ко всем DNS серверам
# all-servers

# Запрещаем резолвить домены без точки (нужно для Docker Swarm)
domain-needed

# Для отладки
#log-queries

Создайте файл /etc/NetworkManager/dispatcher.d/99-dnsmasq

#!/bin/bash

if [[ "$2" = "up" || "$2" = "down" ]]; then
    kill -9 `cat /var/run/dnsmasq/dnsmasq.pid`
    systemctl start dnsmasq
fi

Раскоментируйте строку в файле /etc/default/dnsmasq

IGNORE_RESOLVCONF=yes

Пропишите ip адреса для домена .local в файле /etc/dnsmasq.d/local

address=/.local/127.0.0.1

Выключите резолвер из внешней сети интернет. Создайте файл /etc/dnsmasq.d/disable-external-network

bind-interfaces
except-interface=enp*
except-interface=wlp*
except-interface=wlan*
except-interface=eth*

Удалите файл /etc/resolv.conf и заново его создайте, потому что остается симлинк от днс резолвера systemd, который не дает создать новый файл.

rm -f /etc/resolv.conf
touch /etc/resolv.conf

В /etc/resolv.conf укажите локальный IP адрес

nameserver 127.0.0.1

Отключите резолвер systemd 

systemctl stop systemd-resolved
systemctl disable systemd-resolved

Перезапустите dnsmasq

systemctl restart dnsmasq

14) Отключите apparmor в LXC контейнере

systemctl stop apparmor
systemctl disable apparmor

15) Выйдите из контейнера

exit

16) Перезапустите контейнер

lxc-stop docker0
lxc-start docker0

Установка Docker Swarm

1) Установите Docker

curl -sSL https://get.docker.com | sh
systemctl enable docker
systemctl start docker
apt-get install docker-compose

2) Добавьте в группу docker пользователя ubuntu чтобы он мог управлять docker

usermod -a -G docker ubuntu

3) В файле /etc/docker/daemon.json пропишите:

{
  "log-driver": "journald",
  "log-opts": {
    "labels":"com.docker.swarm.service.name"
  },
  "dns": ["172.17.0.1"]
}

Можно также добавить строчки

"max-concurrent-uploads": 1,
"max-concurrent-downloads": 1,

Они позволяют ограничить количество потоков на загрузку докер образов. По умолчанию 3 потока.

4) Перезапустите Docker:

systemctl restart docker

5) В крон через команду sudo crontab -e пропишите команду, которая будет автоматически очищать контейнеры

0 */2 * * * docker system prune --filter "until=24h" -f > /dev/null

6) Создайте кластер

docker swarm init

Установка NVIDIA драйверов для нейронных сетей

Данную инструкцию нужно выполнять, если вы собираетесь заниматься искусственным интеллектом. На сервере для этого должна быть установлена видеокарта от NVIDIA.

1) Выполните команду ls -l /dev/nvidia* она должна вывести:

crw-rw-rw- 1 root root 195,   0 Oct 19 16:44 /dev/nvidia0
crw-rw-rw- 1 root root 195, 255 Oct 19 16:44 /dev/nvidiactl
crw-rw-rw- 1 root root 195, 254 Oct 19 16:44 /dev/nvidia-modeset
crw-rw-rw- 1 root root 234,   0 Oct 19 16:44 /dev/nvidia-uvm
crw-rw-rw- 1 root root 234,   1 Oct 19 16:44 /dev/nvidia-uvm-tools

2) Установите драйвер на сервер. Драйвер должен быть последней версии.

apt-get update
apt-get install -y nvidia-driver-515-server

3) Установите плагин libnvidia-containuer.

Определите версию Убунту

export distribution=$(. /etc/os-release;echo $ID$VERSION_ID)

Установите ключ nvidia:

curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg

Добавьте репозиторий:

wget https://nvidia.github.io/libnvidia-container/$distribution/libnvidia-container.list -O "/etc/apt/sources.list.d/nvidia-container-toolkit.list"

sed -i 's|deb https://|deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://|g' /etc/apt/sources.list.d/nvidia-container-toolkit.list

Установите Docker плагин:

apt-get update
apt-get install -y nvidia-docker2

4) В файле /etc/docker/daemon.json пропишите:

{
  "log-driver": "journald",
  "log-opts": {
    "labels":"com.docker.swarm.service.name"
  },
  "dns": ["172.17.0.1"],
  "default-runtime": "nvidia",
  "runtimes": {
    "nvidia": {
      "path": "nvidia-container-runtime",
      "runtimeArgs": []
    }
  }
}

5) Перезапустите Docker:

systemctl restart docker

6) Выполните команду:

nvidia-smi

docker run --rm --gpus all nvidia/cuda:11.7.1-base-ubuntu20.04 nvidia-smi

Если обе команды выполнились успешно и правильно определили версию драйвера, значит все установлено корректно.

Установка BAYRELL Cloud OS на сервер

Под пользователем ubuntu выполните:

1) Запустите облачную ОС в домашнюю папку

cd ~
git clone https://github.com/bayrell-os/cloud_os
cd cloud_os

Установите ОС

./cloud_os.sh setup

Подождите пока выполнится скрипт установки. Он также вас попросит ввести логин администратора, и в конце создаст и выведет его на экран.

2) Добавьте в автозапуск облачную ОС

Создайте файл через команду

nano /etc/rc.local

Пропишите в нем команды:

#!/bin/bash

for i in $(seq 0 6); do
	sleep 10
	docker start cloud_os_standard_1
done

Поставьте флаг выполнения для этого файла

chmod +x /etc/rc.local

3) Установка завершена!