четверг, 15 августа 2013 г.

Коробочный мини-сервер, оптимизация Debian (initrd rc инициализация)

Началось всё с того, что я решил выпилить из системы всё лишние и так сказать немного сделать ее ближе ко всяким openwrt, у меня есть nettop на атоме, который не блещет производительностью и я на нем решил сделать специфическую систему, которая будет работать только в качестве веб-сервера.



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

План таков:

1. Ставим Debian 7 в минимальной конфигурации без всяких там иксов
2. Если не установлен, то ставим initramfs-tools
3. По желанию можно поставить утилитки hddtemp, smartmontool, lm-sensors, hdparm, только я их все выпилил из сервисов.
4. Выпиливаем "лишние" сервисы из автозапуска
5. Выпиливаем лишние модули из initrd
6. Убиваем лишние операции в инициализации на стадии init.rd

Теперь немного про инициализацию, она состоит из нескольких этапов

1. Загружается GRUB
2. Грузится ядро
3. Загружается initrd, в котором стартовый набор модулей (в дебиане все модули там лежат), потом на этой же стадии происходит подгрузка всех модулей, монтирование дисков, запуск udev и определение оборудования.
4. Переход на уровень rcS и выполнение скриптов из /etc/rcS.d
5. Загружается всё, что находится в /etc/rc2.d/ там у нас всякие веб-сервера, ssh демоны и т.д.
6. Выводится приглашение и предложение залогиниться!


Облегчение автозапуска
автозапуск/завершение/перезагрузка прописаны в /etc/rc*.d/ директориях в виде символических ссылок (ярлыков) на папку /etc/init.d/ если символическая ссылка начинается на S то выполняется запуск, если K то завершение.
Выключение это /etc/rc0.d/, включение /etc/rc2.d/, перезагрузка /etc/rc6.d/.

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

Сделайте резеврную копию /etc, а то вдруг что то удалите лишнее или напортачите
tar -zcf etc.tgz /etc

Главный контролирующий скрипт это /etc/inittab в нем запускаются стадии, в нем же и запускаются терминалы (getty), если вы обладаете небольшими навыками в BASH, то можете перепилить все скрипты инициализации на свой лад, всё зависит от вас.


Займемся initrd

Но на этапе rc2 выполняется порой лишь самая малая часть действий, например у меня стартуется crontab, nginx, mysql, postfix - это занимает меньше времени чем первый этап, на котором происходит подготовка системы, монтирование дисков, опрос железа и многое другое, но если мы поставили задачу сделать систему для неттопа, конфигурация которого не будет изменяться, а весь udev можно заменить на несколько строчек modprobe, еще в дебиане на всякий случай в initrd помещаются абсолютно все модули из системы.

Прежде чем приступать к манипуляциям.
После любого изменения конфигурации initrd нужно обновлять файл образа командой
update-initramfs -u

При любом критичном эксперименте желательно иметь резервную копию образа, создать его можно командой
cp /boot/initrd.img-3.2.0-4-amd64 /boot/initrd.img

и при невозможности запуститься - можно в GRUP нажать кнопку e  и отредактировать путь до initrd и нажав ctrl+x

Так же сделайте на всякий случай резервную копию /etc и /usr/share/initramfs-tools/ мы там можем удалить много лишнего, а достать это будет негде.

1. Облегчение initrd
сперва получим список всех загруженных сейчас модулей (которые нужны) и закинем этот список в конфиг
lsmod | tail -n +2 | sort | awk '{print $1;}' > /etc/initramfs-tools/modules

А потом откроем файлик /etc/initramfs-tools/initramfs.conf
и параметр
MODULES=most
приведем к виду
MODULES=list

Смысл этой модификации в том, что в initrd будут запаковываться только модули из списка /etc/initramfs-tools/modules

2. Init-скрипты
Все скрипты находятся в директории /usr/share/initramfs-tools/
В этой директории есть основной контролирующий скрипт init, есть директория scripts в которой скрипты инициализации, есть еще всякие хуки и др.

Спасибо за информацию этому блогу http://www.ylsoftware.com/news/469 там же вы можете прочитать некоторые другие подробности про initrd.

Я решил выпилить всё лишнее вплоть до udev из своего сервера "типа коробочный роутер".

Без udev не работают uuid дисков и поэтому нужно сперва в файле /etc/default/grub раскомментировать строку:
GRUB_DISABLE_LINUX_UUID=true
далее выполнить команду update-grub2

а далее модифицировать /etc/fstab изменив там все UUID на названия дисков типа /dev/sda1 /dev/sda2 ....

после этого наша система готова работать без udev, но тут нужно обратить внимание что без udev подгрузку модулей вы должны делать сами командой modprobe, определить что вам нужно грузить а что нет можно по выводу lsmod с еще включенным udev

Создадим скрипт загрузки модулей
echo '#!/bin/sh' > /usr/share/initramfs-tools/scripts/modprobe

Добавим в него все загруженные на данный момент модули
lsmod | tail -n +2 | sort | awk '{print "modprobe "$1;}'>> /usr/share/initramfs-tools/scripts/modprobe

И сделаем этот скрипт исполняемым
chmod +x /usr/share/initramfs-tools/scripts/modprobe

А теперь самое интересное, я решил снести всё из  /usr/share/initramfs-tools/init
и вписать туда следующий код
#!/bin/sh
mkdir -p /sys /proc /tmp /var/lock
mount -t sysfs -o nodev,noexec,nosuid sysfs /sys
mount -t proc -o nodev,noexec,nosuid proc /proc
mount -t devtmpfs -o size=10M,mode=0755 none /dev
mkdir /dev/pts
mount -t devpts -o noexec,nosuid,gid=5,mode=0620 devpts /dev/pts || true
mount -t tmpfs -o "nosuid,size=20%,mode=0755" tmpfs /run
mkdir -m 0755 /run/initramfs
export ROOT=



# Parse command line options
for x in $(cat /proc/cmdline); do
        case $x in
        root=*)
                ROOT=${x#root=}
                        ;;
        esac
done

./scripts/modprobe


mount $ROOT /root
mount -n -o move /run /root/run
mount -n -o move /sys /root/sys
mount -n -o move /proc /root/proc
mount -n -o move /dev /root/dev

exec switch_root /root /sbin/init "$@" </root/dev/console >/root/dev/console 




После этого можно выпилить udev из автозапуска, удалив из /etc/rcS.d/ симлинк на udev

Теперь обновляем initrd и перезагружаемся
update-initramfs -u && reboot

После данных модификаций у нас система работает без udev и всё оборудование работает, а так как у нас "вещь в себе", то больше ни чего не нужно, сервак работает, сервисы запущены, лишние мы повыпиливали и еще повыпиливаем и еще ядро обязательно пересоберем и пропатчим всяко-разно.

Далее нам предстоит оптимизировать /etc/rcS.d/ там у нас есть всякие монтирования nfs сетевых хранилищ и много чего другого.

Apache и PHP нам тоже придется немного оптимизировать выпилив лишние модули, если интересны дальнейшие опыты в данной теме - пишите комментарии и я продолжу, а пока я тестирую полученную систему на продакшн-системе








2 комментария:

Unknown комментирует...

Ты мне скажи чего ты добился этим, сперва :)

Павел комментирует...

Теперь, чтобы добавить какое то приложение в автозапуск - я не стану его прописывать внутрь кронтаба, а добился я максимального облегчения, сервер стартуется в 3 раза быстрее, служб гораздо меньше висит, это больше для самообразования.

Отправить комментарий