Ставим Ubuntu из другого Linux/LiveCD
Речь в статье пойдёт об установке Ubuntu из другого Linux без использования ISO-образа. Нужно это прежде всего для создания кастомизированных тестовых окружений. Информации о такой процедуре в интернете достаточно, она легко гуглится, но, как выяснилось, в некоторых моментах существующие инструкции устарели, да, и все они обладают известным фатальным недостатком.
Итак, постановка задачи: есть голая виртуальная машина с выходом в интернет и EFI BIOS, есть некий линукс (в нашем случае это SystemRescue LiveCD), нужно получить установленную Ubuntu. И все действия должны быть легко автоматизированы, что их можно оформить в виде скрипта.
Прежде всего загружаемся в наш SysRCD. Работать мы будем по SSH, и чтобы он заработал, нужно установить пароль root и разрешить SSH в iptables (изначально в SysRCD запрещены любые входящие соединения):
И подключаемся по SSH:
Теперь нужно подготовить разделы на жёстком диске. Так как система у нас EFI, то таблица разделов будет GPT, нужен EFI FAT-раздел, а сама система будет находится на ext4-разделе. EFI-раздел может очень небольшим — буквально 10 МБ, но для стабильной работы обновлений системы лучше делать его хотя бы 32 МБ. И важное замечание! Во всех инструкциях написано, что раздел должен быть в формате FAT32, но на практике VirtualBox отказывается работать с маленьким EFI-разделом в таком формате (ну, или mkfs.vfat неправильно форматирует маленькие FAT32 разделы — тут нужны эксперименты)! Плюс, есть нюансы с размером диска, размером кластера и совместимостью с EFI биосами. Поэтому форматировать будем в FAT16. Разбивать будем при помощи parted.
Для того, чтобы пометить раздел как служебный EFI в parted ему нужно выставить флаг «esp».
Теперь форматируем вновь созданные разделы. Ещё раз обращаю внимание, что EFI-раздел форматируем в FAT16, иначе могут проблемы с VirtualBox.
Разворачивать базовую систему будет при помощи debootstrap. Но у нас не DEB-система и эта утилита отсутствует. Скачаем её из репозитория Debian и распакуем содержимое DEB-файла прямо в корень нашей системы. У нас LiveCD и такой грязный хак вполне приемлем. DEB-файлы это архивы типа AR, содержащие архивы типа «tar.gz».
Ставить будем Ubuntu 20.04 «Focal» — имя релиза указывается при вызове deboostrap. там же указывается репозиторий, откуда будут скачаны файлы.
Для разворачивания системы, нам естественно, нужно сначала примонтировать её корень в какую-то папку. Не мудрствуя лукаво используем для этого папку «/tmp/».
Теперь нам нужно настроить список репозиториев, откуда будут браться устанавливаемые и обновляемые пакеты. Список находится в файле /etc/apt/sources.list
Теперь настраиваем chroot-окружение и входим в нашу новую систему:
Первым делом настраиваем поддерживаемые локали. Обратите внимание, что добавляется CP866 (на самом деле она «IBM866»), которая до сих пор бывает актуальной при работе со windows-legacy данными.
Список поддерживаемых кодировок хранится в /etc/locale.gen Ещё раз обращаю внимание, что CP866/IBM866 по умолчанию там по какой-то причине нет, хотя в системе она есть.
Обновляем список пакетов и сразу ставим mc, aptitude, чтобы жить стало легче.
EFI раздел будет примонтирован в /boot/efi. Монтируем и настраиваем /etc/fstab.
Настраиваем часовой пояс. То же самое можно выполнить вызовом «dpkg-reconfigure tzdata«. Но нам же нужно, чтобы это можно было заскриптовать. Просмотреть список часовых поясов можно вызовом «timedatectl list-timezones».
Указываем, что аппаратные часы у нас хранят время в UTC. Обратите внимание, что «0» означает время в UTC.
Ставим ядро, дополнительные модули и заголовки ядра. Ядро ставим самое свежее из доступных и заточенное под виртуализацию:
Ставим поддержку консоли, сети, GRUB, SSH и всякие мелкие утилиты:
Это так же можно сделать в интерактивном режиме выполнив:
dpkg-reconfigure console-common
dpkg-reconfigure console-data
dpkg-reconfigure keyboard-configuration
Ставим GRUB на EFI-раздел:
Если нужно, то правим настройки GRUB в файле /etc/default/grub и обновляем конфигурацию GRUB вызовом:
Обновляем образ ядра, чтобы подхватились настройки консоли:
Задаём пароль root и разрешаем авторизацию root в SSH по паролю. Это нужно для того, чтобы можно было подключиться первый раз и залить SSH-ключи.
Для этого в файле настроек SSH-сервера /etc/ssh/sshd_config нужно добавить строку:
PermitRootLogin yes
Позже авторизацию root по паролю нужно не забыть запретить.
Задаём настройки сетевых подключений. У нас netplan и networkd. Не забываем прописывать актуальные значения MAC-адресов адаптеров. На первом адаптере ставим статический адрес, а на второй работает DHCP (это NET-подключение к интернет). Обратите внимание, что IPv6 отключается указанием «link-local: [ ]» в настройках подключения.
Создаём пользователя и добавляем его в административные группы:
Всё! Можно перегружаться и при загрузке с жёсткого диска загрузится уже наша свежеустановленная система.
Если это виртуальная машина VirtualBox, то после перезагрузки нужно ещё желательно поставить дополнения, подключаем «Guest Additions CD Image» и выполняем из-под нашей новой системы:
На этом всё. Дальше нужно подключиться по SSH и залить SSH ключи пользователей. После чего удалить настройку «PermitRootLogin yes» из /etc/ssh/sshd_config.
Если кому-то интересно, то вот такой образ Ubuntu 20.04 занимает 2.2 ГБ дискового пространства.
Источник
Docker — установка и использование
Docker — это оболочка для LXC, предоставляющая удобный интерфейс для работы с контейнерами в среде Linux.
Контейнер в свою очередь это процесс, чем-то похожий на виртуальную машину, который выполняется в изолированном пространстве. При этом используется один экземпляр ядра (kernel) операционной системы, что позволяет экономить ресурсы.
Принцип работы предельно прост. На компьютер с Linux (здесь будет описана установка Docker на ubuntu 16.04) устанавливается сам Docker и дальше можно скачивать готовые образы, либо создавать свои, и запускать их в Docker.
К примеру есть образы с различными CMS, настроенным сервером и базой данных. Допилив такой образ под себя (или создав образ «с нуля») , его можно сохранить в укромном местечке и в любой момент развернуть где угодно.
Преимущество Docker состоит в том, что в случае с виртуальной машиной, приходится эмулировать работу целой операционной системы, тогда как Docker позволяет просто изолировать один процесс.
Контейнеры запускаются и останавливаются практически моментально, так как не требуется загрузка отдельной ОС. Можно запускать несколько контейнеров одновременно, а благодаря использованию файловой системы AuFS, контейнеры используют одно и то же дисковое пространство, доступное только для чтения.
Образы и контейнеры
Образ — это некий шаблон, из которого создаётся контейнер, после чего этот контейнер можно запускать.
Из одного и того же образа можно создавать сколько угодно новых контейнеров, вносить в эти контейнеры изменения и создавать из них новые образы. То есть, например, скачали базовый образ (см. ниже), создали из него контейнер, поделали в этом контейнере что-то, создали из этого контейнера образ и положили его на полку. Теперь для каких-то определённых делишек у Вас есть готовый, настроенный образ.
Образы будут сохраняться в /var/lib/docker.
Установка Docker
Устанавливаем доп. пакеты:
Установка будет производится из официального репозитория разработчика.
Добавляем ключ репозитория:
После успешной установки добавляем себя в группу docker:
Здесь нужно перелогиниться или перезагрузиться.
Если зелёненькое , то всё ОК.
Работа с Docker
… можно посмотреть список всех аргументов и команд.
container
image
network
node
plugin
secret
service
stack
swarm
system
volume
attach — подключиться к запущенному контейнеру.
build — собрать образ из инструкций dockerfile.
commit — создать новый образ из существующего.
cp — копировать файлы между контейнером и физическим компом.
create — создать новый контейнер.
diff — проверить файловую систему контейнера.
events — посмотреть события контейнера.
exec — выполнить команду в контейнере.
export — экспортировать содержимое контейнера в архив.
history — посмотреть историю изменений.
images — список установленных образов.
import — создать контейнер из архива tar.
info — информация о системе.
inspect — информация о контейнере.
kill — остановить запущенный контейнер.
load — загрузить образ из архива.
login — авторизация в официальном репозитории Docker.
logout — выйти из репозитория Docker.
logs — логи контейнера.
pause — приостановить все процессы контейнера.
port — проброс портов для контейнера.
ps — список запущенных контейнеров.
pull — скачать образ контейнера из репозитория.
push — отправить образ в репозиторий.
rename — переименовать контейнер.
restart — перезапустить контейнер.
rm — удалить контейнер.
rmi — удалить образ.
run — запустить новый контейнер.
save — сохранить образ в архив tar.
search — поиск образов в репозитории Docker Hub.
start — запустить контейнер.
stats — статистика использования ресурсов контейнером.
stop — остановить контейнер.
top — посмотреть запущенные процессы в контейнере.
unpause — проложить выполнение процессов в контейнере.
update — обновить конфигурацию контейнера.
version — версия Docker.
Первый запуск
Теперь пришло время что-нибудь запустить. Для этого существует тестовый образ — hello-world
Docker сообщит что такого образа нет на локальной машине, установит его из репозитория и запустит.
Сообщение Hello from Docker! свидетельствует о правильной работе системы.
Далее перечислены 4 шага, которые выполнил Docker. Следом предлагается попробовать запустить образ ubuntu командой docker run -it ubuntu bash, сделаем это чуть позже, а сейчас посмотрим в репозитории все пакеты содержащие слово ubuntu:
Как видно из списка, в наличии имеются образы с разным набором предустановленных программ. Колонка STARS показывает рейтинг.
Так же можно посмотреть какие-нибудь другие образы, например nginx:
Теперь установим образ ubuntu, который в списке значится первым, это базовый вариант, то есть с минимальным набором программ.
Команда «run» скачивает образ из репозитория (либо берет из локального), создаёт из него контейнер и запускает.
Здесь мы видим, что контейнер запустился и работает от пользователя root. Имя хоста (5c87883a3af5) это ID контейнера.
Чтобы посмотреть CONTAINER ID, нужно открыть ещё один терминал и дать команду для просмотра запущенных контейнеров:
Если дать ту же команду с ключём -a, то увидим все контейнеры (запущенные и не запущенные):
CONTAINER ID — ID контейнера, с помощью которого можно оперировать контейнером.
IMAGE — название образа.
Чтобы посмотреть список установленных образов, надо дать команду…
REPOSITORY — название репозитория.
TAG — обычно это версия продукта. Если тега нет, то автоматически используется слово latest.
ImageID — локально генерируемый ID образа, по которому этим образом можно оперировать.
Ну вот, контейнер работает и можно поиграться делая то же самое, что и с обычной ОС, обновляться, устанавливать программы, создавать пользователя и т.д.
Свой образ
Сейчас Docker сделал всё за нас — установил образ и запустил контейнер, а теперь научимся делать всё вручную, это в любом случае понадобится для создания своих образов.
Удалим существующие контейнеры и образы (чтоб глаза не мозолили) , скачаем образ, создадим из него контейнер, запустим его, установим какие-нибудь программы и наконец создадим из него свой образ.
Сначала остановим работающий контейнер. Сделать это можно по разному, прямо в контейнере дать команду exit, либо в соседнем терминале скомандовать…
… либо более жёсткая команда…
Последний аргумент — это ID контейнера (docker ps -a) .
Далее нужно удалить контейнер и образ. Делать это нужно именно в таком порядке, иначе получите ошибку.
Смотрим ID контейнеров (CONTAINER ID):
Удаляем контейнер ubuntu:
Удаляем контейнер hello-world:
Смотрим ID образов (IMAGE ID):
Удаляем образ ubuntu:
Удаляем образ hello-world:
Смотрим ID образа:
Создаём контейнер из скаченного образа и запускаем:
Контейнер запущен, теперь остановим его командой exit. Так как контейнер у нас уже создан, то и запускать его нужно другой командой.
Сначала смотрим ID контейнера:
Контейнер запустился, но мы к нему не подсоединены. Подсоединиться к контейнеру, нужно с помощью команды…
Если всё работает, то можно что-нибудь поделать в контейнере. Давайте обновимся и установим mc и openssh-server, в дальнейшем это нам пригодится:
Теперь можно создать новый образ. В соседнем терминале даём команду…
commit — создать образ.
77d9bfa3c4b4 — ID запущеного контейнера.
myrepo — произвольное название репозитория, который будет создан на вашей машине.
Смотрим список образов:
Чтоб отличать образы друг от друга можно менять название репы, или добавить TAG:
Теперь можно остановить запущенный контейнер (exit) и создать новый контейнер из нашего образа…
Смотрим список контейнеров:
Новый контейнер готов.
Переименовать контейнер
К контейнерам можно обращаться по имени, а для удобства переименовать:
Либо присвоить имя при создании:
Архивация образа
Чтобы переносить образ с компьютера на компьютер его нужно упаковать в архив.
Смотрим ID образа:
Архив образа будет сохранён на компьютере в домашней папке в файл myimage.tar.
После переноса на другой компьютер (с установленным Docker), архив нужно распаковать и создать из него контейнер.
Не очень то красиво.
Зададим название репы и тег:
Так гораздо лучше.
Создаём и запускаем контейнер, заодно присваиваем ему имя mynewcontainer:
Далее из этого контейнера можно создать образ, а из него контейнер и т.д. Только сильно не увлекайтесь, а то будет очень много слоёв.
Вы наверно обратили внимание на многочисленные надписи в терминале — Loading layer и Deleted…
Это создание/удаление тех самых слоёв, про которые говорится в начале статьи по ссылке Подробная инфа.
По умолчанию контейнер видит внешнюю сеть, проверить это можно командой ping ya.ru, предварительно установив пакет iputils-ping:
Однако попасть во внутрь контейнера по сети (например ssh) нельзя, нужно сначала пробросить порт.
IP-адреса у контейнеров будут — 172.17.0.0/16. Проверить можно командой…
Чтобы пробросить порты, нужно создать новый контейнер с необходимыми параметрами.
Смотрим ID образа:
Создаём новый контейнер с именем mysshcont и параметрами -p 2222:22:
2222-ой порт основной машины пробрасываем на порт ssh контейнера.
Далее нужно установить ssh-сервер (apt install openssh-server) и либо разрешить вход по паролю, либо создать ключи.
Заходить в контейнер с основного компьютера так…
То же самое нужно сделать, если вы хотите разместить к контейнере какой-нибудь сервер и сайт. Тогда проброс портов будет выглядеть так…
Естественно на основной машине не должны быть заняты эти порты. И обратите внимание на изменение имени контейнера.
Устанавливаем Apache и стартуем:
В браузере на основной машине пишем…
После этого контейнер можно остановить и запустить обычным способом (настройки портов сохранятся в контейнере):
Однако есть одна сложность, у контейнера нет системы автозапуска приложений, это значит что после остановки и последующего запуска, ни ssh ни сайт работать не будут, нужно вручную стартовать демонов…
О том, как реализуется автозапуск, и о других вещах я планирую написать в следующей части.
В статье затронуты лишь азы использования Docker.
Источник