LINUX.ORG.RU
ФорумAdmin

Руководство - Как запустить firecracker под CentOS 7.

 , ,


0

2

Оригинал статьи здесь

Настройка Firecracker на CentOS 7

В этой статье хочу рассказать вам настроить Firecracker на CentOS 7.

Firecracker - это технология виртуализации с открытым исходным кодом, предназначенная для создания и управления защищенными, мультитенантными контейнерными и функциональными сервисами, обеспечивающими бессерверные операционные модели. Firecracker запускает рабочие нагрузки в облегченных виртуальных машинах, называемых microVMs, которые сочетают свойства безопасности и изоляции, предоставляемые технологией аппаратной виртуализации, со скоростью и гибкостью контейнеров.

План работ

  • Вступительное слово;
  • Обсуждение архитекутуры;
  • Сборка пакета;
  • Сборка ядра;
  • Сборка корневой системы;
    • Сборка CentOS;
    • Сборка Debian;
    • Сборка Ubuntu;
  • Создание параметризированной службы systemd;
  • Шаблон виртуальной машины;
  • Настройка сети;
  • Настройка firewalld;
  • Запуск виртуальной машины;
  • Автоматизация действий;
  • Примеры:
    • CentOS;
    • Debian;
    • Ubuntu;
  • Дальнейшие действия.

Вступительное слово

АВТОР ПРЕДОСТАВЛЯЕТ СТАТЬЮ “КАК ЕСТЬ” БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, ЯВНЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ, ПОДРАЗУМЕВАЕМЫМИ ГАРАНТИЯМИ ТОВАРНОЙ ПРИГОДНОСТИ И ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННОЙ ЦЕЛИ. ВЕСЬ РИСК, СВЯЗАННЫЙ С КАЧЕСТВОМ И ЭФФЕКТИВНОСТЬЮ СТАТЬИ, ЛЕЖИТ НА ВАС. ЕСЛИ СОДЕРЖАНИЕ СТАТЬИ ОКАЖЕТСЯ НЕВЕРНЫМ, ВЫ БЕРЕТЕ НА СЕБЯ РАСХОДЫ НА ВСЕ НЕОБХОДИМОЕ ОБСЛУЖИВАНИЕ, РЕМОНТ ИЛИ ИСПРАВЛЕНИЕ.

Обсуждение архитекутуры

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

  • Бинарный файл firecracker;
  • Специально собранное ядро Linux;
  • Сборка корневой системы.

Данная статья описывает как «правильно приготовить» firecracker для ОС RHEL/CentOS, в частности для 7 версии. Будут использоваться только стандартные пакеты и утилиты, не будет никаких «костылей».

Для firecracker будет собран пакет RPM, с соблюдением требований, пакет не должен влиять на другие пакеты, затирать / изменять файлы.

TODO - Планируется внедрение политик Selinux для более безопасной эксплуатации.

Наше дерево файлов и каталогов:

ПутьОписаниеTODO
/usr/lib/systemd/system/firecracker@.serviceПараметризированная служба systemdСделано
/etc/firecrackerКаталог для хранения конфигурации виртуальных машинСделано
/usr/sbin/firecrackerБинарный файлСделано
/usr/sbin/jailerБинарный файлСделано
/usr/share/firecracker/scriptsКаталог для хранения дополнительных скриптовСделано
/var/lib/firecrackerКаталог для хранения данныхСделано
/var/lib/firecracker/kernelsКаталог для хранения ядер LinuxСделано
/var/lib/firecracker/rootfsКаталог для хранения корневых системСделано
/var/lib/firecracker/microvmКаталог для хранения виртуальных машинСделано
/var/lib/firecracker/metricsКаталог для хранения метрик виртуальных машинНе сделано
/var/run/firecrackerКаталог для socket-файловСделано
/var/log/firecracker/Каталог для логовСделано
/etc/selinuxКаталог для файлов SelinuxНе сделано
/etc/firewalldКаталог для файлов FirewalldНе сделано

Запуск виртуальных машин будет происходить через параметризированную службу firecracker@.service. Рассмотрим пример, если нам нужно запустить виртуальную машину с именем testcentos, то нам нужны будут:

ТипСодержание
Служба systemdfirecracker@testcentos.service
Файл конфигурации/etc/firecracker/testcentos.json
ROOTFS/var/lib/firecracker/microvm/testcentos.ext4

Сборка пакета

Предполагаю, что у вас уже настроено рабочее окружение для сборки пакетов. Если нет, то вы можете ознакомится здесь, здесь и здесь. Также предполагаю, что у вас уже есть опыт работы с RHEL и работа с пакетами у вас не вызывает трудностей.

Для сборки пакета нам нужно скачать бинарные файлы с github - firecracker, jailer

wget https://github.com/firecracker-microvm/firecracker/releases/download/v0.21.1/firecracker-v0.21.1-x86_64

mv ./firecracker-v0.21.1-x86_64 ~/rpmbuild/SOURCES/firecracker
chmod a+x ~/rpmbuild/SOURCES/firecracker

wget https://github.com/firecracker-microvm/firecracker/releases/download/v0.21.1/jailer-v0.21.1-x86_64
mv jailer-v0.21.1-x86_64 rpmbuild/SOURCES/jailer
chmod a+x ~/rpmbuild/SOURCES/jailer

Создадим параметризированную службу systemd

cat<<EOF | tee rpmbuild/SOURCES/firecracker@.service
[Unit]
Description=Firecracker starting microvm %I
After=network.target

[Service]
PrivateTmp=true
Type=simple
PIDFile=/var/run/firecracker/%i.pid
ExecStartPre=-/bin/rm /var/run/firecracker/%I.socket
ExecStart=/usr/sbin/firecracker --api-sock /var/run/firecracker/%I.socket --config-file /etc/firecracker/%I.json

[Install]
WantedBy=multi-user.target
EOF

Создадим шаблон spec-файл для сборки пакета

rpmdev-newspec rpmbuild/SPECS/firecracker.spec

Шаблон Spec-файла выглядит так:

Name:           firecracker
Version:
Release:        1%{?dist}
Summary:

License:
URL:
Source0:

BuildRequires:
Requires:

%description


%prep
%setup -q


%build
%configure
make %{?_smp_mflags}


%install
rm -rf $RPM_BUILD_ROOT
%make_install


%files
%doc



%changelog

Теперь файл нужно привести к следующему виду:

Name:           firecracker
Version:        v0.21.1
Release:        1%{?dist}
Summary:        Open source virtualization technology

License:        Apache License 2.0
URL:            https://github.com/firecracker-microvm/firecracker
Source0:        https://github.com/firecracker-microvm/firecracker/releases/download/v0.21.1/firecracker-v0.21.1-x86_64
Source1:        https://github.com/firecracker-microvm/firecracker/releases/download/v0.21.1/jailer-v0.21.1-x86_64
Source2:        firecracker@.service
BuildArch:      x86_64

BuildRequires:  systemd

Requires(post): systemd systemd-sysv chkconfig
Requires(preun): systemd
Requires(postun): systemd

%description
Firecracker is an open source virtualization technology that is purpose-built for creating and managing secure, multi-tenant container and function-based services that provide serverless operational models. Firecracker runs workloads in lightweight virtual machines, called microVMs, which combine the security and isolation properties provided by hardware virtualization technology with the speed and flexibility of containers.

%build

%install

rm -rf %{buildroot}

mkdir -p %{buildroot}%{_sbindir} \
        %{buildroot}%{_var}/lib/firecracker/{kernels,rootfs,microvm,metrics} \
        %{buildroot}%{_var}/run/firecracker \
        %{buildroot}%{_var}/log/firecracker \
        %{buildroot}%{_sysconfdir}/firecracker \
        %{buildroot}%/usr/share/firecracker/scripts

install -d -m 0755 %{buildroot}/etc/firecracker
install -d -m 0755 %{buildroot}/usr/share/firecracker
install -d -m 0755 %{buildroot}/usr/share/firecracker/scripts
install -d -m 0755 %{buildroot}/var/lib/firecracker
install -d -m 0755 %{buildroot}/var/lib/firecracker/kernels
install -d -m 0755 %{buildroot}/var/lib/firecracker/rootfs
install -d -m 0755 %{buildroot}/var/lib/firecracker/microvm
install -d -m 0755 %{buildroot}/var/lib/firecracker/metrics
install -d -m 0755 %{buildroot}/var/run/firecracker
install -d -m 0755 %{buildroot}/var/log/firecracker

install -m 0755 %{SOURCE0} %{buildroot}/%{_sbindir}/firecracker
install -m 0755 %{SOURCE1} %{buildroot}/%{_sbindir}/jailer

mkdir -p %{buildroot}%{_unitdir}
install -m644 %{SOURCE2} %{buildroot}%{_unitdir}

%clean
rm -rf %{buildroot}

%post
%systemd_post firecracker@.service

%preun
%systemd_preun firecracker@.service

%postun
%systemd_postun_with_restart firecracker@.service

%files
%defattr(-,root,root,-)
%dir /etc/firecracker
%dir /usr/share/firecracker
%dir /usr/share/firecracker/scripts
%dir /var/lib/firecracker
%dir /var/lib/firecracker/kernels
%dir /var/lib/firecracker/rootfs
%dir /var/lib/firecracker/microvm
%dir /var/lib/firecracker/metrics
%dir /var/run/firecracker
%dir /var/log/firecracker
%{_sbindir}/firecracker
%{_sbindir}/jailer
%{_unitdir}/firecracker@.service
%doc



%changelog
* Mon May 18 2020 Nurmukhamed Artykaly <nurmukhamed.artykaly@hdfilm.kz> v0.21.1-1
- Initial spec file

Собираем RPM-пакет

spectool -g -R ~/rpmbuild/SPECS/firecracker.spec
rpmbuild -bs ~/rpmbuild/SPECS/firecracker.spec
sudo mock ~/rpmbuild/SRPMS/firecracker-v0.21.1-1.el7.src.rpm

Готовый пакет будет здесь

ll /var/lib/mock/epel-7-x86_64/result/
total 2800
-rw-rw-r-- 1 root mock    9792 May 18 16:03 build.log
-rw-r--r-- 1 root mock 1850581 May 18 16:03 firecracker-v0.21.1-1.el7.src.rpm
-rw-r--r-- 1 root mock  914196 May 18 16:03 firecracker-v0.21.1-1.el7.x86_64.rpm
-rw-rw-r-- 1 root mock    1568 May 18 16:03 hw_info.log
-rw-rw-r-- 1 root mock   16450 May 18 16:03 installed_pkgs.log
-rw-rw-r-- 1 root mock   56517 May 18 16:03 root.log
-rw-rw-r-- 1 root mock     847 May 18 16:03 state.log

Можем установить пакет

sudo yum localinstall /var/lib/mock/epel-7-x86_64/result/firecracker-v0.21.1-1.el7.x86_64.rpm

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

Сборка ядра

Нам понадобится ядро Linux. Варианты:

Разберем второй вариант.

По данной ссылке подготовим рабочее окружение и загрузим последнею версию ядра.

sudo yum install flex flex-devel bison bison-devel ncurses-devel make gcc bc openssl-devel elfutils-libelf-devel rpm-build

wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.6.13.tar.xz
tar xvf linux-5.6.13.tar.xz

cd linux-5.6.13
curl https://raw.githubusercontent.com/firecracker-microvm/firecracker/master/resources/microvm-kernel-x86_64.config -o .config

make menuconfig

Ничего не выбираем, просто сохраняем конфиг как .config

make vmlinux

Скопируем полученный файл в каталог /var/lib/firecracker/kernels/

sudo cp ./vmlinux /var/lib/firecracker/kernels/vmlinux-5.6.13

Теперь мы можем организовать целый каталог ядер, который может быть использован под различные задачи с различными требованиями.

Сборка корневой системы

Нам понадобится корневая система. Варианты:

Разберем второй вариант.

Сборка корневой системы CentOS

В данной сборке будет минимальная система CentOS, включая systemd-networkd и openssh-server. Эти пакеты необходимы, чтобы виртуальная машина запускалась с настроенной сетью и серверов openssh для удаленного доступа.

Подготовим рабочее окружение

cd
mkdir myrootfs
cat<<EOF | tee chroot-centos7.repo
[centos7-chroot-base]
name=CentOS-7-Base
baseurl=http://mirror.centos.org/centos/7/os/x86_64
gpgcheck=0
[centos7-chroot-epel]
name=Extra Packages for Enterprise Linux 7
baseurl=http://dl.fedoraproject.org/pub/epel/7/x86_64
gpgcheck=0
EOF

Установим минимальный набор пакетов

sudo yum -y -c chroot-centos7.repo --disablerepo=* --enablerepo=centos7-chroot-base --enablerepo=centos7-chroot-epel --disableplugin=* --installroot=/home/nurmukhamed/myrootfs install \
	bash \
	bash-completion \
	vim-minimal \
	yum \
	iproute \
	iputils \
	rootfiles \
	sudo \
    systemd-networkd \
    openssh-server \
    openssh

Подготовка к chroot

sudo mount --bind /dev ~/myrootfs/dev
sudo mount --bind /dev/pts ~/myrootfs/dev/pts
sudo mount --bind /sys ~/myrootfs/sys
sudo mount --bind /proc ~/myrootfs/proc
sudo cp /etc/resolv.conf ~/myrootfs/etc/

Chroot

sudo bash
cd ~/myrootfs
chroot ~/myrootfs

Внутри chroot

echo "7" > /etc/yum/vars/releasever
echo "x86_64" > /etc/yum/vars/basearch

yum update -y 

yum clean all
rm -rf /boot /var/cache/yum/*

systemd-tmpfiles --create --boot
rm -f /var/run/nologin

echo 'firecracker' > /etc/yum/vars/infra

awk '(NF==0&&!done){print "override_install_langs='$LANG'\ntsflags=nodocs";done=1}{print}' \
    < /etc/yum.conf > /etc/yum.conf.new
mv /etc/yum.conf.new /etc/yum.conf

rm -f /usr/lib/locale/locale-archive

#Setup locale properly
localedef -v -c -i en_US -f UTF-8 en_US.UTF-8
/bin/date +%Y%m%d_%H%M > /etc/BUILDTIME

# Create folder for systemd-networkd service
mkdir /etc/systemd/network

:> /etc/machine-id

exit

Отключаем разделы

sudo rm ~/myrootfs/etc/resolv.conf
sudo umount ~/myrootfs/dev/pts
sudo umount ~/myrootfs/dev
sudo umount ~/myrootfs/sys
sudo umount ~/myrootfs/proc

Чистка

sudo rm -rf ~/myrootfs/boot
sudo rm -rf ~/myrootfs/var/cache/yum/*
sudo rm -f ~/myrootfs/tmp/ks-script*
sudo rm -rf ~/myrootfs/var/log/*
sudo rm -rf ~/myrootfs/tmp/*
sudo rm -rf ~/myrootfs/etc/sysconfig/network-scripts/ifcfg-*

Произведем упаковку образа

sudo -Jcvf /var/lib/firecracker/rootfs/centos7-$(/bin/date +%Y%m%d).tar.xz -C /home/nurmukhamed/myrootfs .

Теперь у нас имеется образ ОС CentOS, который мы можем развернуть в любой момент.

TODO - Сборка корневой системы Debian

TODO - Сборка корневой системы Ubuntu

Создание параметризированной службы systemd

На данный момент у нас имеются:

  • Пакет firecracker;
  • Собранное ядро linux 5.6.13;
  • Собранная корневая система ОС CentOS 7.

Теперь мы можем приступить к запуску первой виртуальной машины в firecracker.

Имя виртуальной машины: testcentos

sudo systemctl enable firecracker@testcentos.service

Наша параметризированная служба теперь будет искать файл /etc/firecracker/testcentos.json. В этом файле будут описаны параметры виртуальной машины

Шаблон виртуальной машины

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

ПараметрЗначение
CPU2
RAM1024MB
Hyper-Threadfalse
Kernel Path/var/lib/firecracker/kernels/vmlinux-5.6.13
RootFS Image/var/lib/firecracker/rootfs/centos7-20200518.tar.xz
RootFS Path/var/lib/firecracker/microvm/testcentos.ext4
RootFS Size8GB
NICeth0
IP-address172.16.0.2

Для запуска виртуальной машины нам необходимо развернуть образ ОС CentOS.

sudo dd if=/dev/zero of=/var/lib/firecracker/microvm/testcentos.ext4 bs=1M count=8192
sudo mkfs.ext4 /var/lib/firecracker/microvm/testcentos.ext4
sudo mkdir /tmp/testcentos
sudo mount -o loop /var/lib/firecracker/microvm/testcentos.ext4 /tmp/testcentos
sudo tar -Jxvf /var/lib/firecracker/rootfs/centos7-20200518.tar.xz -C /tmp/testcentos

Нужно сгенерировать пароль пользователя root. Установим пароль как «MySecretPassword».

sudo rm /tmp/testcentos/etc/shadow*

password=$(python -c "import random,string,crypt;
randomsalt = ''.join(random.sample(string.ascii_letters,8));
print crypt.crypt('MySecretPassword', '\$6\$%s\$' % randomsalt)")

cat<<EOF| sudo tee /tmp/testcentos/etc/shadow
root:${password}:18353:0:99999:7:::
bin:*:18353:0:99999:7:::
daemon:*:18353:0:99999:7:::
adm:*:18353:0:99999:7:::
lp:*:18353:0:99999:7:::
sync:*:18353:0:99999:7:::
shutdown:*:18353:0:99999:7:::
halt:*:18353:0:99999:7:::
mail:*:18353:0:99999:7:::
operator:*:18353:0:99999:7:::
games:*:18353:0:99999:7:::
ftp:*:18353:0:99999:7:::
nobody:*:18353:0:99999:7:::
systemd-network:!!:18400::::::
dbus:!!:18400::::::
EOF

cat<<EOF| sudo tee /tmp/testcentos/etc/shadow-
root:${password}:18353:0:99999:7:::
bin:*:18353:0:99999:7:::
daemon:*:18353:0:99999:7:::
adm:*:18353:0:99999:7:::
lp:*:18353:0:99999:7:::
sync:*:18353:0:99999:7:::
shutdown:*:18353:0:99999:7:::
halt:*:18353:0:99999:7:::
mail:*:18353:0:99999:7:::
operator:*:18353:0:99999:7:::
games:*:18353:0:99999:7:::
ftp:*:18353:0:99999:7:::
nobody:*:18353:0:99999:7:::
systemd-network:!!:18400::::::
dbus:!!:18400::::::
EOF

sudo chown root:root /tmp/testcentos/etc/shadow*
sudo chmod 0000 /tmp/testcentos/etc/shadow*

Настройки сетевой карты

cat<<EOF | sudo tee /tmp/testcentos/etc/systemd/network/20-wired.network
[Match]
Name=eth0

[Network]
Address=172.16.0.2/24
Gateway=172.16.0.1
DNS=8.8.8.8
EOF
sudo umount /tmp/testcentos
sudo rmdir /tmp/testcentos

Образ развернут, теперь нужна конфигурация виртуальной машины. Наша тестовая конфигурация будет выглядет так:

macaddress=$(echo 00:60:2F:$[RANDOM%10]$[RANDOM%10]:$[RANDOM%10]$[RANDOM%10]:$[RANDOM%10]$[RANDOM%10])
cat<<EOF | sudo tee /etc/firecracker/testcentos.json
{
  "boot-source": {
    "kernel_image_path": "/var/lib/firecracker/kernels/vmlinux-5.6.13",
    "boot_args": "console=ttyS0 reboot=k panic=1 pci=off"
  },
  "drives": [
    {
      "drive_id": "rootfs",
      "path_on_host": "/var/lib/firecracker/microvm/testcentos.ext4",
      "is_root_device": true,
      "is_read_only": false
    }
  ],
  "machine-config": {
    "vcpu_count": 2,
    "mem_size_mib": 1024,
    "ht_enabled": false
  },
  "network-interfaces": [ 
      {
      "iface_id": "eth0",
      "guest_mac": "${macaddress}",
      "host_dev_name": "testcentos"
    }
  ],
  "actions": {
      "action_type": "InstanceStart"
  }
}
EOF

Также нам понадобится генератор MAC-адресов для генерации случайных MAC-адресов. В данной статье я не буду проверять на уникальность полученные адреса. А вы должны!

Конфигурация сетевой карты будет далее.

Настройка сети

Более подробно настройка сети для firecracker приведена здесь.

sudo ip tuntap add testcentos mode tap
sudo ip addr add 172.16.0.1/24 dev testcentos
sudo ip link set testcentos up

Настройка firewalld

Используйте firewalld, забудьте про iptables править вручную.

sudo firewall-cmd --new-zone=testcentos --permanent
sudo firewall-cmd --reload
sudo firewall-cmd --zone=testcentos --change-interface=testcentos
sudo firewall-cmd --zone=testcentos --add-service=ssh
sudo firewall-cmd --zone=public --add-masquerade

В данной конфигурации, настройки firewalld будут работать до перегрузки системы.

Запуск виртуальной машины

sudo systemctl start firecracker@testcentos.service

В случае ошибки, можно посмотреть логи системы

sudo journalctl -u firecracker@testcentos.service

TODO Автоматизация действий

Теперь у нас появилась возможность для автоматизации наших действий и программно запускать виртуальные машины в firecracker.

Представим, что у нас имеется рабочий CI/CD, например, Gitlab. Тогда мы можем добавить в него еще 3 pipeline:

  • Сборка ядер, по мере выхода новых ядер или исправления критических уязвимостей;
  • Сборка образов корневых систем;
  • Создание виртуальной машины с заданными параметрами.

TODO Примеры:

TODO CentOS

TODO Debian

TODO Ubuntu

TODO Дальнейшие действия.