В этой серии статей Олег Филон, ментор Эйч Навыки, рассказывает, как прийти к крутому CI/CD пайплайну. Сегодня разбираемся, как выбрать ВМ и настроить облака с помощью Fedora Core и инструмента mise.
260 открытий530 показов
Дисклеймер! Перед прочтением настоятельно рекомендуем ознакомиться с первой частью статьи.
Если вы знакомы с FreeBSD, вы уже знаете её достоинства и недостатки по сравнению с Linux. Просуммирую некоторые отличия, важные для выбора облачной ВМ.
- FreeBSD не поддерживает контейнеры в привычном понимании — ни docker, ни podman пока не портированы.
- FreeBSD использует свою собственную лицензию The FreeBSD Copyright, позволяющую не раскрывать derivative work. Оценить распространённость FreeBSD иногда затруднительно, возможно, часть её кода используется и в Windows(C), и в MacOS(C). Только иногда разработчики сами признают её использование, например, Евгений Гаврилов, руководитель проекта vStack.
- Метод разработки FreeBSD ближе к академическому стилю. Есть базовый набор пакетов base, включающий не только ядро, но и достаточно инструментов для сборки остальной системы, именуемой ports. Развитие системы управляется elected Core Team — сейчас в команде 9 человек.
- Во FreeBSD давно используется система snapshots/rollback, позволяющая откатить изменения, если что-то сломалось.
Существует дистрибутив Linux, у которого есть некоторые из перечисленных особенностей — это Fedora Core.
Что такое Fedora Core и как с ней работать
Изначально эти идеи возникли в другом дистрибутиве — RedHat CoreOS.
Во-первых, система ориентирована на использование в облаках: в ней предоставляются образы для всех возможных систем виртуализации и форматов дисков. Во-вторых, она разделена на базовую систему, часть из которой монтируется только в режиме чтения (ro:read only), и остальное, доступное через контейнеры.
5 новых ИИ-инструментов в 2025 году: обзорtproger.ru
Обновление системы возможно автоматически, появилась особая утилита rpm-ostree, и можно откатить на предыдущую версию, если что-то не так. Таким образом, CoreOS становится иммутабельной, изменения базовой части системы невозможны в обход коммитов rpm-ostree.
Я как-то провел эксперимент: установил в Yandex Cloud версию FedoraCore 35, выпущенную в конце 2021 года, с включённым по умолчанию сервисом zincati, который автоматически обновляет базовую систему (у него стабильные релизы). Посчитал, сколько коммитов сделано с тех пор: да, как и в git, здесь используется CAS (content-addressable storage), уже привычные нам хэши. ВМ обновилась и рестартанула 8 раз, если я не пропустил какой-либо рестарт:
grep ^Linux uname*|cut -d" " -f1,3,7-|sed 's/Linux//;s/ x86.*//' uname35: 5.15.7-200.fc35.x86_64 Dec 8 19:00:47 UTC 2021 uname36: 5.17.5-300.fc36.x86_64 Thu Apr 28 15:51:30 UTC 2022 uname37: 6.1.18-200.fc37.x86_64 Sat Mar 11 16:09:14 UTC 2023 uname38: 6.5.8-200.fc38.x86_64 Fri Oct 20 15:53:48 UTC 2023 uname39.0: 6.6.8-200.fc39.x86_64 Thu Dec 21 04:01:49 UTC 2023 uname39.1: 6.8.4-200.fc39.x86_64 Thu Apr 4 20:45:21 UTC 2024 uname40.0: 6.8.11-300.fc40.x86_64 Mon May 27 14:53:33 UTC 2024 uname40.1: 6.11.3-200.fc40.x86_64 Thu Oct 10 22:31:19 UTC 2024 uname41: 6.12.7-200.fc41.x86_64 Fri Dec 27 17:05:33 UTC 2024
Теперь можно сравнить с этой же системой, установленной из свежего имиджа — как и ожидалось, системы не отличались, хэши коммитов одинаковы. Это то, что имеется ввиду под иммутабельностью ОС. Кроме иммутабельности и смонтированных только по чтению некоторых каталогов, есть и другие меры безопасности. Используется версия Security-Enhanced Linux, никаких логинов по умолчанию, настройки пользователя либо через утилиту cloud-init, либо специальная утилита butane и так называемый ignition file.
У проекта Fedora есть подробнейшая документация — в ней лежит самое авторитетное руководство по установке. Тем не менее у меня возникла пара вопросов:
- Во-первых, для преобразования .yaml файла в ignition, который по сути обычный .json файл, используется особый инструмент butane, написанный на языке Go. Судя по размеру образа 130M, он довольно увесистый, но никак не упоминаются другие утилиты для конвертациии .yaml в .json.
- Во-вторых, в простейшем случае для первого логина вообще не нужны ни butane, ни .yaml. Вот пример минимального ignition.json файла, который создаётся руками:
cat ignition.json { "ignition": { "version": "3.3.0" }, "passwd": { "users": [ { "name": "core", "sshAuthorizedKeys": [ "<ssh-ed25519 your ssh pub key content>" ] } ] } }
Скопируем этот файл в каталог /tmp, он нужен один раз для первого входа, не содержит секретов, к нему нужно будет указать полный путь. Как и ранее, скачиваем свежий образ для libvirt/qemu: выбираем нужную архитектуру и формат диска, проверяем контрольные суммы и цифровые подписи. Команды для создания ВМ будут немного отличаться от уже опробованных из прошлой статьи — сначала сделаем для нашего ignition.json опцию, которую понимает virt-install:
export IGN=(--qemu-commandline="-fw_cfg name=opt/com.coreos/config,file=/tmp/ignition.json") echo $IGN --qemu-commandline=-fw_cfg name=opt/com.coreos/config,file=/tmp/ignition.json
Затем распаковываем образ в стандартный каталог и создаём ВМ:
xz -cdv fedora-coreos-41.20250215.3.0-qemu.x86_64.qcow2.xz > /var/lib/libvirt/images/fc41stab.qcow2 virt-install --import --memory 4096 --vcpus 1 -w bridge=br0 --os-variant="fedora-coreos-stable" --graphics=none -n fc41stab "${IGN[@]}" --disk /var/lib/libvirt/images/fc41stab.qcow2
Созданная заранее переменная шелл использована как "${IGN[@]}"
. virt-install
выдаст интереснейший лог процесса инсталяции, а в самом конце — перед приглашением — покажет IP-адрес вновь созданной ВМ. Переходим в другую консоль и проверяем наш ssh-ключ: ssh -v core@192.168.100.2
в моём случае. После успешного логина выполняем первоочерёдные проверки и настройки:
$ id uid=1000(core) gid=1000(core) groups=1000(core),4(adm),10(wheel),16(sudo),190(systemd-journal) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 $ sudo -l Matching Defaults entries for core on fc41stab: !visiblepw, always_set_home, match_group_by_gid, always_query_group_plugin, env_reset, env_keep="COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS", env_keep+="MAIL QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE", env_keep+="LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES", env_keep+="LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE", env_keep+="LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY", secure_path=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/var/lib/snapd/snap/bin User core may run the following commands on fc41stab: (ALL) ALL (ALL) NOPASSWD: ALL $ sudo hostnamectl hostname fc41stab $ sudo passwd core
Теперь ВМ можно остановить и сделать финальные настройки нашего персонального облака для этой ВМ. Добавим MAC- и статический IP-адреса в dnsmasq.conf и зададим имя новой ВМ в сети (пример есть в прошлой статье). Откроем в virt-manager окно overview, затем откроем вкладку XML и в самом конце удалим конфиг для qemu — целиком вот этот фрагмент:
<qemu:commandline> <qemu:arg value="-fw_cfg"/> <qemu:arg value="name=opt/com.coreos/config,file=/tmp/ignition.json"/> </qemu:commandline>
Далее кнопка Apply. Возможно, virt-manager попросит сначала установить Edit → Preferences → General → Enable XML editing. То же самое можно сделать из командной строки: sudo virsh edit fc41stab
. Ignition-файл нужен только для установки, далее эту ВМ можно донастраивать, клонировать, копировать её образ куда угодно, в том числе в большие облака.
А мы продолжим знакомство с этой необычной системой, как её рекламирует проект Федора:
Fedora CoreOS — это автоматически обновляемая, минимальная, монолитная, ориентированная на контейнеры операционная система, разработанная для кластеров, работоспособная автономно, оптимизированная для Kubernetes.
Проверим, что dnsmasq обновился, и начнём по порядку.
$ host fc41stab fc41stab.local has address 192.168.100.118 fc41stab.local mail is handled by 1 fc41stab.local. $ ssh -v fc41stab
Далее выполняем команды внутри ВМ. Основное, к чему придётся привыкнуть, — что часть каталогов смонтированы readonly, запись в них в обход утилиты rpm-ostree невозможна даже судоерам:
core@fc41stab:~$ mount|grep ro,|grep ^/dev /dev/vda4 on /sysroot type xfs (ro,relatime,seclabel,attr2,inode64,logbufs=8,logbsize=32k,prjquota) /dev/vda3 on /boot type ext4 (ro,nosuid,nodev,relatime,seclabel) core@fc41stab:~$ mount|grep rw,|grep ^/dev /dev/vda4 on /etc type xfs (rw,relatime,seclabel,attr2,inode64,logbufs=8,logbsize=32k,prjquota) /dev/vda4 on /sysroot/ostree/deploy/fedora-coreos/var type xfs (rw,relatime,seclabel,attr2,inode64,logbufs=8,logbsize=32k,prjquota) /dev/vda4 on /var type xfs (rw,relatime,seclabel,attr2,inode64,logbufs=8,logbsize=32k,prjquota)
Я специально грепнул только реальные устройства, потому что кроме них смонтированы ещё 19 виртуальных — пока углубляться не будем. Как видно, в режиме rw
смонтированы /etc и /var. Даже стандартый home — это линк /home → var/home
.
Корпоративный VPN: что это, для чего необходим бизнесу в 2025 годуtproger.ru
За автоматические обновления отвечает сервис zincati
. Если его отключить, обновления можно запускать вручную: rpm-ostree --bypass-driver upgrade
. После рестарта проверяем новое состояние системы:
core@fc41stab:~$ rpm-ostree status State: idle AutomaticUpdatesDriver: Zincati DriverState: active; periodically polling for updates (last checked Tue 2025-03-18 12:22:26 UTC) Deployments: ● fedora:fedora/x86_64/coreos/stable Version: 41.20250302.3.2 (2025-03-17T22:11:15Z) Commit: aa4d65c700789b34bb953c2ee8250c6643802ed57ab1f4f5dd61e821b2be8709 GPGSignature: Valid signature by 466CF2D8B60BC3057AA9453ED0622462E99D6AD1 fedora:fedora/x86_64/coreos/stable Version: 41.20250215.3.0 (2025-03-04T19:05:12Z) Commit: d0742b8c6b45095a6e4f856d787a65f4d2702316856d78227f0b68f8f85511b5 GPGSignature: Valid signature by 466CF2D8B60BC3057AA9453ED0622462E99D6AD1
rpm-ostree rollback
позволяет откатить обновления к предыдущему комиту. Другие полезные команды:
rpm-ostree db diff
— список обновлённых пакетов между комитамиrpm-ostree db list
— список и версии пакетов в комитах
А как же устанавливать пакеты привычным dnf
? Это своевременный вопрос. Посмотрим сначала что уже стоит:
core@fc41stab:~/temp$ rpm-ostree db list aa4d65> rpm-ostree.db.list.250317 core@fc41stab:~/temp$ head -1 rpm-ostree.db.list.250317 ostree commit: aa4d65 (aa4d65c700789b34bb953c2ee8250c6643802ed57ab1f4f5dd61e821b2be8709) core@fc41stab:~/temp$ wc -l rpm-ostree.db.list.250317 440 rpm-ostree.db.list.250317
Это напоминает FreeBSD base, но важно, что набор включает podman, docker, git — для остального есть утилита toolbox. Она делает доступными все пакеты федоры, упакованные в контейнер. Заглянем в toolbox:
core@fc41stab:~/temp/tbox$ toolbox Error: missing command create Create a new Toolbx container enter Enter an existing Toolbx container list List all existing Toolbx containers and images Run 'toolbox --help' for usage. core@fc41stab:~/temp/tbox$ toolbox create tbox Image required to create Toolbx container. Download registry.fedoraproject.org/fedora-toolbox:41 (384.2MB)? [y/N]: y Created container: tbox Enter with: toolbox enter tbox core@fc41stab:~/temp/tbox$ podman images REPOSITORY TAG IMAGE ID CREATED SIZE registry.fedoraproject.org/fedora-toolbox 41 2288b69816a7 7 hours ago 2.29 GB core@fc41stab:~/temp/tbox$ toolbox enter tbox ⬢ [core@toolbx tbox]$
Мы оказались внутри контейнера — об этом говорит изменившееся приглашение $PS1. Если снова посмотреть mount
, увидим ещё больше хитро подмонтированных каталогов — этакий оверлей из базовой и контейнерной ФС. Но зато работает dnf
, поэтому можно устанавливать любые пакеты. Добавим привычные, без них неуютно в новой системе:
⬢ [core@toolbx tbox]$ sudo dnf update Updating and loading repositories: Fedora 41 openh264 (From Cisco) - x86_64 100% | 7.2 KiB/s | 4.8 KiB | 00m01s Fedora 41 - x86_64 100% | 16.8 MiB/s | 35.2 MiB | 00m02s Fedora 41 - x86_64 - Updates 100% | 5.2 MiB/s | 11.7 MiB | 00m02s Repositories loaded. Nothing to do. ⬢ [core@toolbx tbox]$ sudo dnf install tmux btop
Как видим, пакеты доступны, но желательно иметь их вне контейнера. Нет проблем: скопируем их в свой ~/bin каталог, он одинаков и внутри, и снаружи контейнера:
⬢ [core@toolbx tbox]$ type tmux tmux is /usr/bin/tmux ⬢ [core@toolbx tbox]$ mkdir ~/bin ⬢ [core@toolbx tbox]$ cp /usr/bin/tmux ~/bin ⬢ [core@toolbx tbox]$ type btop btop is /usr/bin/btop ⬢ [core@toolbx tbox]$ cp /usr/bin/btop ~/bin
Выйдем из контейнера и проверим:
⬢ [core@toolbx tbox]$ logout core@fc41stab:~/temp/tbox$ ldd ~/bin/* /var/home/core/bin/btop: linux-vdso.so.1 (0x00007f45e8231000) libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f45e7fc3000) libm.so.6 => /lib64/libm.so.6 (0x00007f45e7edd000) libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f45e7eae000) libc.so.6 => /lib64/libc.so.6 (0x00007f45e7cbb000) /lib64/ld-linux-x86-64.so.2 (0x00007f45e8233000) /var/home/core/bin/tmux: linux-vdso.so.1 (0x00007ff7f2acb000) libsystemd.so.0 => /lib64/libsystemd.so.0 (0x00007ff7f28c8000) libutempter.so.0 => /lib64/libutempter.so.0 (0x00007ff7f28c3000) libtinfo.so.6 => /lib64/libtinfo.so.6 (0x00007ff7f2895000) libevent_core-2.1.so.7 => /lib64/libevent_core-2.1.so.7 (0x00007ff7f285d000) libm.so.6 => /lib64/libm.so.6 (0x00007ff7f2777000) libresolv.so.2 => /lib64/libresolv.so.2 (0x00007ff7f2764000) libc.so.6 => /lib64/libc.so.6 (0x00007ff7f256f000) libcap.so.2 => /lib64/libcap.so.2 (0x00007ff7f2562000) libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007ff7f2533000) /lib64/ld-linux-x86-64.so.2 (0x00007ff7f2acd000)
А теперь серьезно: настраиваем Fedora Core сервер для команды разрабов
Для начала настроим полноценный dev env: репозиторий кода, образы контейнеров, инструменты для сборки и сервер приложений.
Обычно в команде есть один админ или несколько. Уже созданный пользователь core — это админ, у него есть права sudo, плюс ему доступен контейнер tbox. В нашей Федоре каталог с секретами устроен особым образом:
core@fc41stab:~$ tree ~/.ssh/ /var/home/core/.ssh/ └── authorized_keys.d └── ophil 2 directories, 1 file
Первоначально обычный файл authorized_keys назывался ignition и располагался в каталоге ~/.ssh/authorized_keys.d
, что подразумевает, что можно ещё добавить ключей, назвав их никами других админов. Так же можно поступить с разрабами — настроить для всех один dev env.
Создадим нового пользователя без прав sudo:
sudo adduser dev; sudo usermod -aG docker dev sudo passwd dev sudo cp -a ~/.ssh/ ~dev/ sudo chown -R dev:dev ~dev/.ssh
Как мы уже знаем, мелкие утилиты можно просто скопировать из тулбокса в ~/bin или /usr/local/bin. Для языков программирования и прочих инструментов есть замечательная программа mise. Сейчас мы её установим для dev и немного познакомимся. Свой ключ я уже добавил в ~dev/.ssh/authorized_keys.d/
, так что логинимся и настраиваем инструменты для команды разрабов.
ssh -v dev@fc41stab dev@fc41stab:~$ id uid=1001(dev) gid=1001(dev) groups=1001(dev),983(docker) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 dev@fc41stab:~$ curl https://mise.run | sh % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 9557 100 9557 0 0 26211 0 --:--:-- --:--:-- --:--:-- 26255 mise: installing mise... ######################################################################## 100.0% mise: installed successfully to /var/home/dev/.local/bin/mise mise: run the following to activate mise in your shell: echo "eval "$(/var/home/dev/.local/bin/mise activate bash)"" >> ~/.bashrc mise: run `mise doctor` to verify this is setup correctly dev@fc41stab:~$ echo "eval "$(/var/home/dev/.local/bin/mise activate bash)"" >> ~/.bashrc dev@fc41stab:~$ . ~/.bashrc
mise
позволяет устанавливать и использовать различные версии языков программирования, инструментов и библиотек. Другие менеджеры версий, например, aqua, asdf, ubi — собрали репозитории таких инструментов, и mise их использует в качестве бэкендов. Огласим весь список:
dev@fc41stab:~/src$ mise registry > mise.registry dev@fc41stab:~/src$ wc -l mise.registry 883 mise.registry dev@fc41stab:~/src$ mise ls-remote python|tail 3.12.6 3.12.7 3.12.8 3.12.9 3.13.0 3.13-dev 3.13.1 3.13.2 3.14.0a6 3.14-dev dev@fc41stab:~/src$ mise -v use -g python@3.12 dev@fc41stab:~/src$ mise ls Tool Version Source Requested python 3.12.9 ~/.config/mise/config.toml 3.12
Да, список великоват: сохранил в файл — 883 штук, и он постоянно растёт. Это только названия пакетов, поиск версий, а команда mise ls-remote python
выдала 911 вариантов для python.
Зато теперь можно настраивать пайплайны для наших разработчиков. А в следующей статье разберемся, как работать с пайплайнами и хуками в git.