Mdadm Gpt 3Tb Non-UEFI

Интересная попалась задача – заменить в сервере на Legacy (не UEFI) BIOS пару обычных (до 2 Tb) дисков на два 3 Tb.

Диски работали в софтовом рейде, что, значительно облегчает задачу, вроде как. Вот только непонятно, что делать с тем, что во время последовательной замены дисков необходимо переехать с MBR на GPT. Все получилось, но есть особенности.

Например, не все старые контроллеры и Legacy биосы в принципе видят 2+ Tb диски. Например, в моем случае в LSI 1068 он виделся только как 2 Tb. В набортном обычном SATA виделись почти все 3 Tb. Далее последовательность действий:

  1. Заранее проверяем, что parted, gdisk и прочее установлено
  2. Заменяем второй диск
  3. Подглядываем в http://www.howtoforge.com/replacing_hard_disks_in_a_raid1_array
  4. Временно ставим MBR на второй большой диск
    1. parted /dev/sdX
    2. mklabel msdos
    3. quit
  5. Клонируем разделы с основного диска
    1. sfdisk -d /dev/sdY | sfdisk /dev/sdX
    2. Проверяем в fdisk, что все совпало
  6. Конвертируем в GPT
    1. gdisk /dev/sdX
    2. w
    3. То есть просто выход, никаких особых команд не надо, конвертация происходит автоматически
  7. Создаем еще один раздел в gdisk (не обязательно в начале, мой был под номером 3), ставим ему код EF02 (магия), размер якобы от 1 Мб, я создал 100 Мб на всякий случай 🙂
  8. По инструкции из пункта 3 добавляем разделы со второго диска в MD разделы
  9. Ждем синхронизации, можно ускорить выполнив
    1. echo 500000 > /proc/sys/dev/raid/speed_limit_min
  10. Устанавливаем grub-install /dev/sdX
  11. Выставляем в биосе загрузку с нового диска и отключаем старый
  12. Возможно, пингвиньи боги сжалились и ОС загрузилась
  13. Мне не повезло :), появлется grub rescue, который не видит массива
  14. Грузимся в ubuntu rescue, доходим до выбора корня, автоматом оно его не найдет, открываем по alt-F2 консольку
  15. cat /proc/mdstat показывает, что /dev/mdXXX inactive и вообще все плохо
  16. Пересобираем массив
    1. mdadm –stop /dev/mdXXX
    2. mdadm –assemble –force /dev/md0 /dev/sdaX
    3. Пробуем его примонтировать куда ни будь, посмотреть, что там, если все ОК – umount
  17. exit – возвращаемся в ubuntu rescue, выбираем корнем /dev/md0
  18. Тут же выбираем пункт resintall grub
  19. Запускаем шелл с корнем в md0, я на всякий случай проверил, что mduuid (виден по mdadm –detail) и uuid /dev/md0 (виден по blkid) совпадают с теми, что прописаны в /boot/grub/grub.cfg и /etc/fstab
  20. Выходим из rescue, ребутимся, все хорошо, ОС запускается с первого диска
  21. Клонируем GPT таблицу
    1. sgdisk -R/dev/target /dev/source (главное не перепутать source с destination)
  22. По инструкции из пункта 3 добавляем разделы в md
  23. Скорее всего надо обновить в /etc/fstab uuid для swap разделов
  24. grub-install на новый диск
  25. После окончательного синка перезагружаемся, проверяем, что диски в массиве, свопы на месте, для особо дотошных, можно загрузиться со второго диска для проверки
  26. Осваиваем новое полученное место

Перенос Ubuntu с обычного диска на MD RAID

Несколько раз добавлял зеркало gmirror для единственного диска во FreeBSD. Даже данные не надо мигрировать – все достаточно просто и документировано.

А вот в Ubuntu 9.10 как то не заладилось, убил практически целый день. Из толковых инструкций, что удалось найти, понравилась вот эта. Многа букав! Инструкция в готовом виде, к сожалению, не подошла.

Основные моменты:

  • Я подключал два диска (основной с системой и чистый для зеркала) одновременно и грузился в Rescue Mode с CD.
  • Создавая массив, я указывал sdXY от чистого диска.
  • Данные копировались командой cd target; dump -0 -f – /dev/source| restore rf – (по привычке, но надо поставить пакет dump).
  • Во все конфигурационные файлы вписывалось /dev/mdX вместо /dev/sdXY.
  • Swap я тоже размещаю на зеркале.

В общем то, загрузившись в режим восстановления, создать массивы на чистом диске и скопирнуть туда данные относительно несложно. Далее нужно поправить /etc/fstab, /etc/mdadm/mdadm.conf, запустить grub и просетапиться в MBR.

Как всегда сложности начинаются при попытке загрузиться с этого диска. Меня все время загружало в grub>.

Находясь в grub> можно загрузить систему такими командами:

kernel /boot/vmli<tab-autocomplete> root=/dev/md0
initrd /boot/init<tab-autocomplete>
boot

Механизм работы grub на 9.10+ для меня до сих пор является загадкой. Совершенно не представляю откуда оно берет настройки, в частности имя загрузочного устройства (md0 vs sdb1).

Попав в шелл решил проблему таким способом.

apt-get purge grub-common grub-pc
apt-get install grub-common grub-pc

Оно само раздуплилось какой диск является корнем и правильно прописало его в /boot/grub/grub.cfg (который генерируется автоматически).

После этого старый диск был отключен, а диск с MD был сделан основным, старый же переразбит и добавлен как вторая часть зеркала (это есть в инструкции).

Так же в процессе экспериментов (по-моему в Rescue Mode) запускалась команда

apt-get install mdadm
update-initramfs -u

Без них, скорее всего, в initramfs не были бы добавлены модули поддержки MD RAID. Мрак, но заработало.

Виртуализация в Ubuntu Server

Часто полезно иметь чуть более мощный сервер чем необходимо, что бы иметь возможность запускать в нем виртуальные машины. Когда хост машина – windows, все понятно: VMware Server, Microsoft Virtual Server, Microsoft Hyper-V и тд. Зато под Ubuntu наступил на грабли.

Имеем: десктоп с процессором AMD и установленным Ubuntu Server 10.04 LTS x86_64.

Задача: запустить Windows Server, который бы решал инфраструктурные задачи и запускался автоматически.

Сначала попробовал официально поддерживаемую виртуализацию KVM-Qemu. Несмотря на то, что все тщательно документировано в официальной документации Ubuntu, необходимо сделать кучу шагов, что бы запустить машину. В итоге после прохождения текстовой части инсталляции Windows Server 2003 32 bit (64 bit эмуляция не заработала в силу ограничений процессора) – черное окно. Доступ к виртуалке, кстати, через VNC с пробросом порта через putty. Побороть черное окно не смог.

Затем последовала серия наскоков на Vmware Server 2.0.2 (который бесплатный). Пробовал и i386 и x86_64 и с рекомендованными патчами от Ubuntu и без. И форумы читал – не компилятся модули ядра хоть ты тресни.

Далее пришла очередь VirtualBox. Документации практически нет. Установил virtualbox-ose, virtualbox-ose-dkms, virtualbox-ose-qt, virtualbox-guest-additions. Комманд не много, но vboxmanage испугала огромным количеством своих аргументов. Попробовал просто virtualbox – попросило X-ы. Как оказалось, найти X-ы под Windows достаточно просто – Xming. В ssh клиенте сделан проброс X11 (одна галочка), перелогон, запустилось!

Приятный графический интерфейс:


“Немного” подтормаживает, но все таки это отображение виртуалки хостящейся на удаленном Ubuntu сервере, через виндовый X-сервер поверх ssh соединения.

С позиционированием мышки большие проблемы, но клавиатура работает прогнозируемо (с задержкой в 5-30 секунд). Еще, похоже, пришлось в свойствах виртуалки включить ускорение графики, иначе отображался мусор.

Текстовая часть инсталла прошла гораздо быстрее чем в KVM-Qemu и вообще все работает работает шустро, но

из-за тормозов связки отображения консоли у меня ушло еще около двух часов на то, что бы вызвать свойства удаленных подключений и включить RDP в котором все работает моментально как и обычно. Виртуалка корректно реагирует на перезагрузку или выключение. Все, что осталось, это настроить автоматический запуск виртуалки вместе со стартом Ubuntu сервера. Для этого я добавил vboxmanage startvm infra1 –type headless в /etc/rc.local.

Обратный NAT в ufw (ubuntu)

Для того, что бы добавить правила обратного NAT (DNAT) в Ubuntu используя стандартный для него ufw, достаточно в начало файла /etc/ufw/before.rules добавить такие строки:

*nat
:PREROUTING ACCEPT [0:0]
-A PREROUTING -i ethX -p tcp --dport XXX -j DNAT --to-destination A.B.C.D:YYY
COMMIT

Тем самым для внешнего интерфейса ethX будет прокинут порт XXX внутрь сети на хост A.B.C.D порт YYY.

Postfix Postgrey и очистка очереди

Не дают покоя спаммеры факультетской почте. После настройки Яндекс.Спамооборона 1024 спам в ящики практически перестал приходить, но пошла новая тема – вдувать за день в очередь около миллиона корявых сообщений, которые системе приходится обрабатывать и получается, фактически, отказ в обслуживании.

Пришлось подключить к postfix релею policy server Postgrey. Смысл её работы:

When a request for delivery of a mail is received by Postfix via SMTP, the triplet CLIENT_IP / SENDER / RECIPIENT is built. If it is the first time that this triplet is seen, or if the triplet was first seen, less than 5 minutes ago, then the mail gets rejected with a temporary error. Hopefully spammers or viruses will not try again later, as it is however required per RFC.

Тем самым отсекается основной поток одинаковых писем.

Настроить на Ubuntu очень просто:

apt-get install postgrey

И потом добавить нужную директиву к smtpd_recipient_restrictions, например:

smtpd_recipient_restrictions = permit_mynetworks, reject_unauth_destination, check_policy_service inet:127.0.0.1:10023

И перезапустить postfix:

/etc/init.d/postfix reload

После этого не помешает очистить очередь от скопившихся там баунсов. Что бы найти и удалить все письма в очереди от MAILER-DAEMON, я воспользовался скриптом, найденным тут:

#!/bin/bash
mailq | tail -n +2 | grep -v '^ *(' | awk  'BEGIN { RS = "" }
# $7=sender, $8=recipient1, $9=recipient2
{ if ($7 == "MAILER-DAEMON" )
    print $1 }
' | tr -d '*!' | postsuper -d -

Быстрая настройка офисного роутера на ubuntu

Встала задача максимально быстро и правильно поднять офисный роутер на ubuntu. Почему то мне подумалось, что эту процедуру уже давно должны были упростить и вручную ничего делать не надо. Я оказался практически прав: очень многое упростили и стандартизировали, нужно просто действовать по официальной документации ubuntu (главное найти правильный раздел).

Настройка сетевых интерфейсов описана тут.

На этой страницы на Wiki описана настройка файрвола в общих чертах.

На странице по настройке firewall на ubuntu 9.10 написано как включить ufw и настроить через него же NAT (Masquerading). Единственное, что я сначала сделал

ufw allow 22
а уж только потом
ufw enable
так как настраивал сервер удаленно.

В итоге серверный файрвол настраивается через простенькую команду ufw, а дополнительные правила для NAT вписываются в конфиги ufw вручную, но там нет ничего сложного.

Остается настроить DHCP и насладиться полученным результатом.

Порядок определения дисков в Linux

Стыдно признаться, НЕДЕЛЮ устанавливал Ubuntu на сервер. Проблемы начались после того, как я тестировал сервер под Windows с динамическими GPT дисками. Видать винда что то там сделала с областью загрузчика и после установки Ubuntu загрузка заканчивалась на мигающем курсоре, даже до Grub не доходило. Я долгое время тупил и что то там делал с MD RAID массивом при установке, пока не догадался, что порядок дисков для загрузки в BIOS и Linux отличается, а Ubuntu этого не просек. Windows, кстати, это определил и создавал 100 мегабайтный загрузочный раздел не на первом диске в списке дисков. В результате я не стал вспоминать как инсталлировать GRUB вручную с rescue диска, а просто инсталлировал Ubuntu на все диски поочередно оставляя их единственными в шасси. После этого заработала загрузка в нужной конфигурации software RAID. Вот выдержка по этому поводу из исходников драйвера:

4.4. Controlling Boot order on non SES-2 systems
    Linux discovers drives by walking sequentially through
    each channel/target/lun of the host adapter, mapping the
    drives that it finds sequentially to sda, sdb, sdc, etc.
    SAS, on the other hand, does not guarantee what order
    drives will be discovered, or appear.  Because of this
    "drive drift" (different than migration) a mechanism is
    needed to guarantee that SAS drives will be consistently
    mapped to device names.  The Razor BIOS provides a
    mechanism for determining what order drives have been
    reported to the system BIOS.  Because of the different
    mechanisms that system BIOS vendors use to manage
    devices in BIOS and because of the limited size of the
    Razor OCM structures, the Razor BIOS structures can not
    be use to consistently map all drives to a unique device
    name that persists across boots.
    The only way to solve the problem of "drive drift" is to
    require that users assign a UUID or label to the
    filesystems on their drives.  In addition, because swap
    does not support labels or UUIDs, we should recommend
    that the users use swap files instead of swap
    partitions.

Репликация MySQL на уже работающем сервере

В интернете есть достаточно много хаутушек про настройку репликации. Как подключить slave для уже работающего сервера с данными инструкции тоже есть. Но я не смог найти такую инструкцию, которая бы соответствовала современным особенностям и полностью меня устроила. Пришлось разобраться самому.

При использовании описанного ниже подхода стоит рассчитывать на даунтайм основного сервера на время его перезапуска. В примере использовался сервер под управлением Ubuntu и MySQL 5.0 из основного репозитория с настройками по умолчанию. Я исходил из того, что реплицировать нужно все базы данных, за исключением системных.

На главном сервере.

Надо поправить файл /etc/mysql/my.cnf:

[mysqld]
# Необходимо открыть доступ к серверу по сети,
# что бы slave имел возможность подключиться
# и не забыть закрыть этот доступ, например файрволом, для тех, кому он не нужен
bind-address            = 0.0.0.0
server-id               = 1
log_bin                 = /var/log/mysql/mysql-bin.log
expire_logs_days        = 10
max_binlog_size         = 100M
# Исключим ненужные БД
#binlog_do_db           = include_database_name
binlog_ignore_db        = information_schema
binlog_ignore_db        = mysql
binlog_ignore_db        = test
# Это рекомендуется для более стабильной работы репликации баз на InnoDB
innodb_flush_log_at_trx_commit=1
sync_binlog=1

Перезапускаем mysql:

/etc/init.d/mysql restart

Выдаем slave права на репликацию:

mysql -u root
GRANT REPLICATION SLAVE ON *.* TO 'replication'@'10.0.0.2' IDENTIFIED BY 'slave_password';
FLUSH PRIVILEGES;

Посмотреть статус можно командой:

SHOW MASTER STATUS;
+------------------+----------+--------------+-------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB              |
+------------------+----------+--------------+-------------------------------+
| mysql-bin.000015 |       98 |              | information_schema,mysql,test |
+------------------+----------+--------------+-------------------------------+
1 row in set (0.00 sec)

Далее делаем дамп существующих баз данных. Ключи –single-transaction –master-data –flush-logs должны глобально заблокировать на время дампа базу данных на запись и вписать в дамп номер и позицию лога, с которых надо начать репликацию на slave. Это обеспечит точность совпадения данных на главном и slave серверах, даже если с главным сервером в этот момент идет работа и записываются данные.

mysqldump -u root --single-transaction --master-data --flush-logs --databases db1 db2 db3 > ALL_DB.sql

Если посмотреть внутрь ALL_DB.sql, то там должна присутствовать строка:

CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000015', MASTER_LOG_POS=98;

Далее копируем дамп на slave:

scp ALL_DB.sql 10.0.0.2:

Продолжаем на втором сервере.

Убеждаемся что там нет остатков настроек репликации, в принципе, если на сервере нет нужных данных, не помешает переустановить mysql с очисткой папок БД.

Так как начиная с версии MySQL 5.2 параметры доступа для репликации убираются из my.cnf сразу перейдем на использование такой схемы.

Правим файл /etc/mysql/my.cnf:

[mysqld]
# ID slave должен отличаться от главного сервера
server-id               = 2
replicate-ignore-db     = information_schema
replicate-ignore-db     = mysql
replicate-ignore-db     = test
relay-log               = /var/log/mysql/mysqld-relay-bin.log

Перезапускаем сервер:

/etc/init.d/mysql restart

Поправим файл ALL_DB.sql:

Дописываем к строке

CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000015', MASTER_LOG_POS=98;

параметры доступа:

CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000015', MASTER_LOG_POS=98, MASTER_HOST='10.0.0.1', MASTER_USER='replication',
MASTER_PASSWORD='slave_password', MASTER_CONNECT_RETRY=60;

Загружаем данные:

mysql -u root < ALL_DB.sql

Проверяем состояние репликации, она НЕ должна быть запущена (Slave_IO_Running, Slave_SQL_Running: no, no):

mysql -u root
show slave status;

Запускаем репликацию (теперь должно быть Slave_IO_Running, Slave_SQL_Running: yes, yes):

START SLAVE;
show slave status;

Для проверки можно попробовать перезапустить mysql и проверить состояние репликации еще раз:

/etc/init.d/mysql restart
mysql -u root
show slave status;

Остается по желанию проверить репликацию, создав, например, тестовую таблицу или добавив данные в существующую и убедиться, что изменения отразились на slave.

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

Ubuntu 8.04 LTS Server Edition супротив Microsoft Virtual Server 2005

Мне всегда нравилась виртуализация от Microsoft благодаря её простоте использования и бесплатности. Когда мне нужно запустить на одном сервере несколько разных ОС, я всегда использую MS Virtual Server и совершенно не боюсь этого делать в Production.

А еще мне все больше нравится Ubuntu как ОС, когда мне нужен Unix. Например, я столкнулся с проблемой неправильности обработки русских тегов на моём блоге под FreeBSD-7.0, и решил попробовать поднять WordPress на Ubuntu в виртуальной машине.

Это оказалось совсем не просто. Если FreeBSD-7.0 устанавливалась в виртуальную машину без проблем и, по сравнению с реальным компьютером, надо было только решить проблему четкости работы часов, то с Ubuntu все пошло гораздо тяжелее. Виснет инсталляция, виснет ядро после инсталляции, опять же не работают правильно часы. Не буду вдаваться в подробности, а просто опишу как же все таки установить Ubuntu. Кстати кроме Ubuntu Server Edition существует еще и Ubuntu JeOS – специальная сборка Ubuntu для виртуальных машин. JeOS поставилась в виртуальную машину без особых проблем, но её ядро не увидело сетевой карты. Мне показалось что решить проблему со сменой или перекомпилированием ядра тяжелее чем заставить Server Edition, которая определяла сеть нормально, работать. Итак, последовательность такая:

Создаем виртуальную машину, подключаем образ диска, настраиваем автозапуск виртуальной машины. Запускаем виртуальную машину, в её биосе можно ничего не менять. Запускаемся с CD, выбираем язык:

Нажимаем F6 и добавляем перед двумя тире:
vga=791 noreplace-paravirt

Далее жмем Enter и запускаемся.

Vga=791 переводит экран в расширенный текстовый режим и избавляет от лишних проверок на тип графического адаптера. У меня несколько раз виртуальная машина входила в какой-то непонятный графический режим, а эта опция позволяет этого избежать. К тому же потом удобнее работать с большей в 2 раза консолью.

Дальше проводим инсталляцию как обычно по своим требованиям.

Если мы попытаемся запустить машину сразу после инсталляции, даже добавив vga=791 noreplace-paravirt к параметрам ядра, то мы получим вот такой красивый Stack-Trace и надпись BUG: Int 6: CR2 00000000.

Поэтому опять грузимся с компакт диска.

Выбираем “Rescue a broken system” и, конечно же, добавляем магические vga=791 noreplace-paravirt.

После того, как получаем доступ к командной строке (в окружении виртуального диска а не инсталлятора – первая опция), выполняем:
apt-get update
apt-get remove linux-server
apt-get install linux-386

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

Далее фиксируем параметры запуска ядра:
vim /boot/grub/menu.lst

Убираем две записи с -server ядром, а к -386 ядру добавляем нужные параметры:
vga=791 noreplace-paravirt noapic nolapic clock=pit
Будет выглядеть это вот так:

Кстати курсоры работать не будут, напоминаю, что в ViM можно использовать вместо курсоров клавиши H J K L.

Сохраняемся. Exit из шелла. Перегружаем систему и можно грузиться в установленную ОС! Все должно работать, при чем часы должны идти точно, не опаздывать и не спешить, благодаря noapic nolapic clock=pit.

Из скришота видно, что со временем погрешность не набегает, хотя, конечно же, это не отменяет необходимости запуска ntpd для того, что бы время всегда было актуальным в дальнейшей эксплуатации.

Вот и все – пущай работает!