Сти, гибкости системы администрирования и удобства использования кластера в прикладных расчетах при обеспечении необходимого уровня надёжности и минимуме затрат
Вид материала | Документы |
СодержаниеКонфигурация ядра Initial RAM-диск Preboot eXecution Environment (PXE) Файл linuxrc. Файл mksnapshot. |
- Методы обеспечения надежности задачи обеспечения надежности, 302.01kb.
- «Методы статистической обработки данных», 242.25kb.
- Технологичность изделия, ее показатели и пути обеспечения, 141.6kb.
- Темы для подготовки к Гос экзамену по дисциплине «Бухгалтерский управленческий учет», 14.95kb.
- Исследование возможностей применения методов и средств интегрированных экспертных систем, 28.11kb.
- Предложения в рабочий план кластера «Продукты моря» на 2011 год, 74.3kb.
- 1. Матрица анализа гибкости руководителей и бизнес-процессов верхнего уровня компании, 6.17kb.
- Вопросы для подготовки к экзамену по дисциплине «Теория надежности», 8-й семестр, 2011, 20.46kb.
- Лекции по курсу: «Техническая диагностика сэу», 545.34kb.
- Основы технологии производства электротранспорта, 1174.09kb.
ссылка скрыта
ссылка скрыта
ссылка скрыта
Реализация бездисковых рабочих станций
Введение
В процессе создания кластерных систем необходимо добиться максимума производительности, гибкости системы администрирования и удобства использования кластера в прикладных расчетах при обеспечении необходимого уровня надёжности и минимуме затрат. Одним из вариантов решения поставленной задачи является использование бездисковых рабочих станций (в англоязычной литературе “diskless clients”), т.е. рабочих станций не использующих при работе локальный жёсткий диск. В процессе загрузки ядра системы в оперативной памяти создаётся виртуальный логический диск, на который копируются критически важные для работы операционной системы модули.
Можно добиться бездисковой загрузки используя так называемые live-disk, устройства хранения памяти на сменных носителях (чаще всего компакт-диск). Такой диск содержит минимум стандартных компонентов операционной системы, достаточный для запуска ядра системы и работы определённых приложений, в большинстве случаев специализированных под конкретные задачи. Подход, основанный на использовании сменных носителей, обладает существенными недостатками: во-первых, каждая машина должна обладать устройством чтения и своей копией сменного носителя, что влечёт за собой дополнительные расходы в результате износа носителей и значительных затрат на покупку устройств чтения сменных носителей; во-вторых, такая схема организации работы исключает полноценное администрирование кластера.
Одним из ключевых компонентов кластерных систем является среда передачи данных, в качестве которой чаще всего выступает локальная вычислительная сеть. Поэтому на каждом узле стоит как минимум одно устройство для доступа к сети, поэтому целесообразно производить загрузку ядра операционной системы используя сеть. Подавляющее большинство современных сетевых карт либо поддерживают такую возможность, либо допускают установку дополнительного блока ПЗУ, содержащего набор инструкций, добавляющий поддержку этой полезной возможности.
Список преимуществ загрузки по сети и использования бездисковых рабочих станций приведён ниже.
- Снижение себестоимости каждого узла.
- Снижение числа механических устройств, а именно - жесткого диска, более всего подверженного износу. Исключение жесткого диска существенно повышает надёжность узла кластера, снижает потребление электроэнергии и шум.
- Централизация системы администрирования вычислительного кластера и системы управления задач в прикладных расчетах. Это позволяет упростить действия, необходимые для изменения конфигурации программных средств, используемых всеми узлами, а также в упрощении доступа к данным, необходимых для расчётов. Все данные, используемые пользовательскими программами, в том числе настройки хранятся в одном месте.
- Ускорение доступа к данным. Файловая система, расположенная на удалённом узле (сервере), может, и в среднем при правильной организации вычислительного комплекса, когда не допускается частая перегрузка коммуникационной сети, работает быстрее локальной файловой системы. Перегрузка коммуникационной сети может быть вызвана недостаточно продуманной организацией обменов данных в программах пользователей кластера. На сервере установлены высокопроизводительные дисковые массивы (disk array, RAID-массивы, работающие в режиме 10), которые обеспечивают лучшие скорости записи-чтения, чем локальные жесткие диски. Пропускная способность сети Gigabit Ethernet превышает пиковую скорость обмена данными с накопителями на жестких дисках. Не следует упускать из вида и возможность использования нескольких файл-серверов (или специализированных сетевых хранилищ данных), обеспечивающих доступ к данным.
- Повышение сохранности информации, записанной на жестких дисках. RAID-массив, работающий в режиме 10 объединяет работу 4 жестких дисков. Это не только обеспечивает более высокую скорость доступа к данным, но и реализует параллельную запись информации на двух дисках ("зеркалирование"), что обеспечивает сохранность записанной информации при выходе из строя одного из дисков. Повышение надежности хранения данных особенно важно для вычислительных кластеров, работающих в режиме коллективного доступа. На каждый узел устанавливать RAID-массивы экономически не выгодно.
- Технически просто и быстро осуществляется наращивание вычислительной мощности кластера путем подключения новых дополнительных узлов.
- При необходимости технически просто и быстро подключаются для временного использования в качестве дополнительных узлов кластера полноценные рабочие станции или мощные компьютеры, работающие в другое время автономно. При этом не требуется изменять настройки ОС подключаемых рабочих станций, установленных на локальных накопителях данных.
При выборе метода сетевой загрузки кластера следует учитывать следующие достоинства и недостатки такого подхода:
- Более сложная настройка и отладка. Долгое время бездисковая загрузка не поддерживалась напрямую операционными системами, и до сих пор нет ни одного общего стандарта, хотя де-факто уже выделились основные программные продукты, получившие поддержку в компьютерной индустрии.
- Если будет нарушено функционирование сети и сервер не будет доступен узлам, то будет нарушена и работа всего кластера как целого, и каждого отдельного узла как бездисковой рабочей станции.
- Возникают ограничения на объём доступной памяти. Использование выгружаемой на удалённый компьютер оперативной памяти возможно, однако с практической точки зрения, для достижения максимального быстродействия узла не целесообразно использовать механизм выгружаемой памяти.
- При использовании единственного централизованного хранилища данных и интенсивной одновременной работы узлов с ними возникнет падение скорости доступа к данным. Такие ситуации редки, но могут иметь место в некоторых задачах, где поток данных велик.
Достоинства предложенного способа реализации бездисковых рабочих станций в большинстве случаев превышают его недостатки. Ниже приведён порядок загрузки операционной системы (Linux семейства), а также возникающие на каждом этапе задачи и варианты их решения.
Процесс загрузки бездисковой рабочей станции включает следующие этапы:
- BIOS пытается поместить в память загрузчик, полученный с указанного ему устройства. Для простоты будем считать, что в состав системного блока не входят никакие дополнительные внешние устройства, кроме сетевой карты.
- Загрузчик получает характеристики сети, свой ip-адрес, сервер на котором находится ядро ОС и т.д. Например, устройство может использовать протокол DHCP, с его помощью найти в сети сервер, который выделит ip-адрес этому устройству. Отметим, что в данной работе мы будем рассматривать только сетевые адаптеры, поддерживающие стандарт PXE, который не является единственным возможным. Существуют сетевые адаптеры, например, Etherboot, Netboot, поддерживающие другие стандарты.
- С сервера передается загрузчик ядра, который осуществляет загрузку ядра и сжатого RAM-диска (более точно initial RAM-disk, «диск начальной загрузки»). На диске будет расположена на начальных стадиях загрузки корневая файловая система (root file system), и содержаться компоненты, необходимые для дальнейшей загрузки ОС (в том числе утилиты типа grep, cat, простейший командный интерпретатор, DHCP-клиент и т.д.).
- С RAM-диска запускаются скрипты и программы, организующие следующий этап загрузки, второй сеанс DHCP-запросов, монтирование основной файловой системы (например, удалённой посредством NFS). Затем возможна смена корневой файловой системы (pivot_root) на удалённую, что впрочем, не является обязательным.
- На этом загрузка самой системы закончена, начинается загрузка прикладных программ.
Конфигурация ядра
Первое, с чего надо начать развёртывание бездисковых рабочих станций – это конфигурирование ядра с заданием следующих необходимых параметров.
- Желательно включить поддержку используемого сетевого устройства в ядро, а не использовать загружаемый модуль, хотя можно положить необходимый модуль на initial RAM-диск. В этом случае необходимо организовать загрузку модуля из стартового скрипта ОС.
- Во вкладке «Networking options»: «IP: kernel-level configuration support» можно указать необходимый протокол для авто конфигурирования сетевого интерфейса. Этот протокол надо передать ядру в параметре ip или же указать в том же параметре ip-адрес самостоятельно. Если не планируется проводить конфигурирование на уровне ядра, и тем самым уменьшить объём ядра, необходимо отключить все предложенные варианты, а DHCP клиент запустить со смонтированного RAM-диска.
- Использование RAM-диска требует установки опции «Block devices»: «RAM-disk support», «Initial RAM disk (initrd) support» и указания необходимого размера диска по умолчанию. 10 мегабайт достаточно в большинстве случаев, но если планируется оставить initial RAM-disk основным, то следует подобрать необходимый минимум.
- Использование в качестве удалённой корневой файловой системы NFS требует установки «File Systems»: «Network File Systems»: «Root file system on NFS». Следует заметить, что поддержка такой возможности появилась в ядрах сравнительно недавно и долгое время не рекомендовалась к использованию. Поэтому возможно придётся получить последние стабильные ядра для используемой ОС.
Initial RAM-диск
Этот файл представляет собой сжатую файловую систему (ФС) поддерживаемую ядром (ext2), которую загружает с сервера загрузчик ядра и передаёт ядру. Ядро распаковывает файл в оперативную память (RAM-disk) и монтирует его как корневую ФС. Далее ищется скрипт загрузки модулей ядра. Им чаще всего выступает /linuxrc, более точно это зависит от параметров, переданных ядру (например, утилита redhat-config-netboot прилагающаяся к дистрибутивам от Red Hat конфигурирует систему таким образом, что ядру передаётся параметр disklessrc и соответственно ядро загружает скрипт /disklessrc). Этот скрипт запускается с uid 0.
В последних строках скрипта происходит смена корневой системы (c ФС в памяти на ФС по NFS) и продолжается загрузка операционной системы вызовом скрипта /etc/init. Однако, если указанный скрипт отсутствует или не вызывает pivot_root, смены корневой системы не происходит. В этом случае корневая система остаётся на RAM-диске.
Существует несколько способов получить файл сжатого RAM-диска. Например, можно используя loopback block device. Более подробную информацию можно получить, например, по адресу1.
В качестве пути для корневой файловой системы, с которой собираются все необходимые файлы, можно указать локальную, но чаще поступают следующим образом (в целях безопасности, надёжности и удобства переконфигурирования): получают с эталонной, настроенной и фактически уже являющейся полноценным узлом кластера машины корневую файловую систему.
Эта файловая система будет доступна только для чтения по NFS. Далее необходимо создать так называемые слепки (snapshot), т.е. создать файлы, уникальные для каждой машины (например, файлы fstab, ключи для авторизации, используемые ssh и т.д.), которые доступны клиенту как на чтение, так возможно и на запись. Изменение этих файлов клиентом никак не повлияет на остальные узлы. При загрузке ядру необходимо передать соответствующие параметры для запуска системой стартового скрипта, который выполнит инициализирующие действия. Последняя команда этого скрипта инициализирует «классический» процесс загрузки, однако корневая файловая система узла будет удалённой.
# полагаем, что исполняемый скрипт linuxrc
root=/dev/ram0 init=/linuxrc rw
Preboot eXecution Environment (PXE)
PXE – это результат разработок компании Intel, вылившийся в стандарт для загрузочных ПЗУ (boot ROM). В последние годы этот стандарт находит всё больше и больше поклонников и поддерживается многими производителями комплектующих (включая, конечно же саму Intel, а также 3COM, d-Link и т.д.). Существует также проект NILO (Network Interface Loader, www.nilo.org) для разработки свободно используемой реализации PXE.
Устройство, поддерживающее этот стандарт, будучи выбранным в качестве загрузочного посылает широковещательный DHCP-пакет в сеть и ждёт ответа от сервера, поддерживающего PXE-расширения. В этом ответе содержится имя файла загрузчика ядра (boot loader), который предположительно может быть выполнен на узле, посылавшем запрос. Загрузчик скачивается и запускается на выполнение, используя параметры сети, полученные в DHCP-пакете и сохранённые в памяти. Цель загрузчика, как было уже сказано выше – загрузить ядро операционной системы.
Итак, остался вопрос: а что за загрузчик?
Заслуженной популярностью пользуется загрузчик pxelinux, являющийся частью проекта Syslinux (zytor.com/). Этот загрузчик использует конфигурационные файлы, находящиеся а каталоге /tftpboot/pxelinux.cfg (предполагаем, что TFTP демон запущен с установками по умолчанию, и путь к доступным по TFTP протоколу файлам /tftpboot). Pxelinux запрашивает файл из вышеуказанного каталога по следующему принципу:
Адрес клиента, например 192.168.0.1, записывается в шестнадцатеричной системе счисления: C0A80001. Загрузчик пытается получить файл pxelinux.cfg/C0A80001. Если это невозможно, крайние цифры отбрасываются, и загрузчик пытается получить файл C0A800. Так повторяется, пока подходящий файл не будет найден, либо таких файлов в итоге не окажется. Последние версии pxelinux также пытаются загрузить файл соответствующий MAC-адресу сетевой платы (записанный в виде: 00-07-E9-4A-99-0F)
Файл C0A80001 имеет примерно следующий вид:
DEFAULT linux
APPEND initrd=initrd.gz root=/dev/ram rw
nfsroot=192.168.1.1:/export/root/node1,rw
ip=192.168.1.2:192.168.1.1:192.168.1.1:255.255.255.0:node1:eth0:off
nfsroot – если мы хотим использовать удалённую корневую файловую систему.
ip – параметры в следующем порядке: адрес клиента, адрес сервера, шлюз по умолчанию, маска сети, имя клиента, интерфейс и протокол автоконфигурирования. Также может быть ip=dhcp, если ядро скомпилировано с поддержкой конфигурирования на уровне ядра. Можно пропустить параметр ip если предпочтительнее иное конфигурирование сетевых интерфейсов.
DHCP
Протокол DHCP был создан для динамического получения ip-адреса компьютера, подключающегося к сети. Он пришёл на смену протоколу BOOTP, и не является единственно возможным способом получения ip-адреса: например, всегда остаётся возможность использования RARP протокола (используется, в частности, некоторыми маршрутизаторами для загрузки по сети), однако в наши задачи не входит рассмотрение этих протоколов, поскольку на мой (и не только мой) взгляд DHCP обладает наибольшей гибкостью.
Вкратце этот протокол работает следующим образом:
- Клиент посылает широковещательный пакет DHCPDISCOVER по адресу 255.255.255.255 с маской 0.0.0.0. Этот пакет может содержать некоторую информацию о клиенте, например какова его аппаратная архитектура или какой адрес ему требуется.
- Один или несколько серверов в сети отсылают клиенту пакет DHCPOFFER, содержащий предлагаемый сервером ip-адрес и другие параметры.
- Клиент формирует пакет DHCPREQUEST и отсылает ответ одному из серверов.
- Если сервер согласен с предлагаемыми условиями он возвращает пакет DHCPACK (содержащий назначенный ip-адрес и прочие параметры), иначе он отправляет пакет DHCPNAK и всё повторяется с шага 1.
- После получения ip-адреса клиент использует ARP, чтобы проверить уникальность адреса. Если этот адрес уже занят, клиент отсылает серверу DHCPDECLINE и все начинается сызнова.
Последнюю версию самой распространённой свободной реализации DHCP всегда можно получить на сайте Internet Software Consortium: ссылка скрыта. Большинство дистрибутивов содержат именно эту реализацию.
Достаточно стандартная установка (связка configure – make – make install) пропишет файл /etc/dhcpd.conf который используется демоном dhcpd. Как несложно догадаться, самое важное правильно настроить конфигурационный файл. Пример настройки приводится ниже:
# простейший конфигурационный файл DHCP
ddns-update-style none;
max-lease-time 86400;
default-lease-time 86400;
range 192.168.0.2 192.168.0.254;
### option space PXE;
### option PXE.mtftp-ip code 1 = ip-address;
# далее следует настройки для конкретной подсети
subnet 192.168.0.0 netmask 255.255.255.0 {
class "pxeclients" {
match if substring (option vendor-class-identifier, 0, 9) = "PXEClient";
option vendor-class-identifier "PXEClient";
### vendor-option-space PXE;
### option PXE.mtftp-ip 0.0.0.0;
# имя файла с загрузчиком ядра
filename "pxelinux.0";
# и адрес сервера, на котором этот загрузчик лежит
next-server 192.168.0.1;
}
# «жёсткая» привязка ip по MAC адресу
host node {
hardware ethernet 00:0C:6E:71:B6:55;
fixed-address 192.168.0.2;
}
}
Этот файл использует большинство настроек по умолчанию и в большинстве случаев обеспечивает необходимый результат. В случае, если PXE клиент не распознает сервер как поддерживающий PXE расширения, необходимо убрать комментарии в строках начинающиеся с ###. Это добавит определение пространства PXE и установку одной опции (необходимо установить хотя бы одну).
Жёсткая привязка по MAC-адресу в общем-то не является обязательной и в настроенном кластере не нужна, может применяться при отладке системы.
Заметим, что при загрузке в среде PXE инициируется два сеанса DHCP-запросов: первый проводит PXE-клиент, а второй уже загруженное ядро для получения адреса. При этом в логах можно увидеть нечто вроде:
node33 dhcpd: DHCPDISCOVER from 00:0e:0c:a0:7e:e5 via eth0
node33 dhcpd: DHCPOFFER on 192.168.9.8 to 00:0e:0c:a0:7e:e5 via eth0
node33 dhcpd: DHCPREQUEST for 192.168.9.8 (192.168.9.33) from 00:0e:0c:a0:7e:e5 via eth0
node33 dhcpd: DHCPACK on 192.168.9.8 to 00:0e:0c:a0:7e:e5 via eth0
node33 dhcpd: DHCPDISCOVER from 00:0e:0c:a0:7e:e5 via eth0
node33 dhcpd: DHCPOFFER on 192.168.9.8 to 00:0e:0c:a0:7e:e5 via eth0
node33 dhcpd: DHCPREQUEST for 192.168.9.8 (192.168.9.33) from 00:0e:0c:a0:7e:e5 via eth0
node33 dhcpd: DHCPACK on 192.168.9.8 to 00:0e:0c:a0:7e:e5 via eth0
node33 rpc.mountd: authenticated mount request from node8:677 for /home/netboot/cent/root (/home)
node33 rpc.mountd: authenticated mount request from node8:697 for /home/netboot/cent/snapshot (/home)
TFTP
Trivial FTP (TFTP) расшифровывается как тривиальная версия FTP-протокола. TFTP протокол не поддерживает, например аутентификацию и получение списка файлов, поскольку максимально упрощен, что сделано с целью упростить код, необходимый для загрузки файлов (TFTP часто используется для скачивания различными устройствами загрузочных образов, или же например, обновлений прошивок, по сети)
Установка его также тривиальна и особых пояснений не требует. TFTP запускается как сервис в xinetd и единственное, что следует настроить это путь к файлам, доступным по этому протоколу, а также права доступа к этим файлам. Для запуска демона tftp необходимо добавить в файл /etc/xinetd.d/tftp соответствующие параметры для демона. Если он отсутствует – следует создать его скопировав любой другой и сделав соответствующие изменения.
В последних дистрибутивах протокол классифицируется как legacy software. Но достойной альтернативы ему, поддерживаемому большинством оборудования, пока нет.
NFS
Network File System (NFS), - «сетевая файловая система», была внедрена компанией Sun Microsystems в далёком 1985 году как подобие файловой системы для бездисковых клиентов. Однако предложенный протокол оказался настолько удачным, что подобие со временем стало полноценным и универсальным решением для совместного использования файлов. Мало того, протокол оказался на удивление стабильным: первый выпуск имел версию 2, затем в начале 90-х годов была выпущена версия 3, которая поддерживает и старый протокол. Больше коренных изменений не было.
В данной работе не рассматриваются проблемы блокировки файлов, вопросы безопасности и конфиденциальности. Далее кратко описаны используемые нами настройки NFS.
В Linux имена экспортируемых каталогов хранятся в файле /etc/exports в текстовом виде. Нам необходимо подправить его, добавив следующие строки:
/home 192.168.9.0/24(rw,sync,no_root_squash)
Формат файла достаточно прост: вначале строки стоит путь к экспортируемому каталогу, затем имена клиентов через пробел (в нашем случае всего один), после имени в круглых скобках указываются опции. Наиболее часто используются следующие:
ro экспорт только для чтения
rw экспорт для чтения и записи. Также поддерживается синтаксис rw=список, в котором указываются клиенты, которым доступен экспортируемый каталог на запись, остальным только на чтение
root_squah закрепляет UID 0 и GID 0 за идентификаторами, указываемыми в опциях anonuid и anongid. Опуская подробности, это сделано в целях безопасности. Полностью противоположна no_root_squash, которая разрешает доступ пользователю root.
Необходимо открыть для общего доступа как минимум две папки: предназначенную для использования в качестве удалённой корневой файловой системы и для каталога экспортируемых слепков (одно может лежать в другом). Помимо этого бывает удобно открыть и другие общие каталоги, в которых будут находиться программы и данные, необходимые для решения поставленных задач, а также куда могут помещаться результаты вычислений.
Приложение 1
Процедура создания образа системы, инициализации RAM-диска
Файл mk_net_rd.sh:
#!/bin/bash
PATH=/sbin:$PATH
# путь к корню файловой системы
ROOT="/home/netboot/cent/root"
# версия ядра
VERSION="2.6.12.6-sc-xen0"
#размер образа RAM-диска (если скрипт будет создавать образ и файловую систему сам)
IMAGESIZE=10000
#имя файла образа
IMAGE="initrd-xen.img"
#точка монтирования, для работы с образом
MNTPOINT="/mnt/initrd_image"
#путь к ядру
KERNEL=$ROOT/boot/vmlinuz-$VERSION
#путь к модулям для данного ядра
MODULES=$ROOT/lib/modules/$VERSION
TOP_DIR=`pwd`
# каталог в который произвести копирование готового образа. Должен существовать.
INSTALL_DIR="sc"
# версия CRT библиотеки
CVERS=2.3.4
# выполнение некоторых операций требует привилегий суперпользователя
echo -n "Checking uid.."
if [ $(id -u) != 0 ]; then
echo "mk_net_rd must be run as root"
exit 1
fi
echo "OK"
# далее производится создание файла необходимого размера и создание файловой
#системы в нём
echo -n "Creating image file.."
dd if=/dev/zero of=$IMAGE bs=1k count=$IMAGESIZE || {
echo "FAILED"
exit 1;
}
echo "OK"
echo -n "Creating ext2 filesystem.."
mke2fs -F -m0 -b 1024 $IMAGE || {
echo "FAILED ($?)"
exit 1;
}
echo "OK"
# монтируем полученный образ, затем создаём в нём необходимое дерево каталогов
echo -n "Mounting image.."
mount -t ext2 $IMAGE -o loop $MNTPOINT || {
echo "FAILED"
exit 1
}
echo "OK"
echo "Creating directory structure"
mkdir -p $MNTPOINT
mkdir -p $MNTPOINT/lib
mkdir -p $MNTPOINT/bin
mkdir -p $MNTPOINT/etc
mkdir -p $MNTPOINT/etc/rc.d/init.d/
mkdir -p $MNTPOINT/etc/sysconfig/network-scripts
mkdir -p $MNTPOINT/dev
mkdir -p $MNTPOINT/proc
mkdir -p $MNTPOINT/tmp
mkdir -p $MNTPOINT/var/lib/nfs
mkdir -p $MNTPOINT/var/lib/dhcp
mkdir -p $MNTPOINT/usr/share/hwdata/
mkdir -p $MNTPOINT/mnt
# удаляем созданный mk2fs каталог, который нам абсолютно не нужен
rm -rf $MNTPOINT/lost+found
# создаём специальные файлы, которые должны существовать
# к ним относятся базовые устройства: консольный ввод-вывод и т.д.
echo "Perform mknode..."
mknod $MNTPOINT/dev/console c 5 1
mknod $MNTPOINT/dev/null c 1 3
mknod $MNTPOINT/dev/ram b 1 1
mknod $MNTPOINT/dev/systty c 4 0
for i in 1 2 3 4; do
mknod $MNTPOINT/dev/tty$i c 4 $i
done
# прописываем конфигурационные файла для ethernet интерфейсов.
for ((i=0;i<2;i=i+1)); do
cat << __EOF > $MNTPOINT/etc/sysconfig/network-scripts/ifcfg-eth$i
DEVICE=eth$i
BOOTPROTO=dhcp
ONBOOT=yes
TYPE=Ethernet
__EOF
done
# Копируем стартовую процедуру (скрипт) и прочие файлы,
# в том числе динамические библиотеки, простейшие утилиты и т.п.
echo "Copying rc-scripts"
cp linuxrc2 $MNTPOINT/disklessrc
cp $ROOT/etc/rc.d/init.d/functions $MNTPOINT/etc/rc.d/init.d/
cp $ROOT/etc/sysconfig/network-scripts/network-functions \
$MNTPOINT/etc/sysconfig/network-scripts/
cp $ROOT/bin/bash $MNTPOINT/bin
cp $ROOT/bin/mount $MNTPOINT/bin
cp $ROOT/bin/cat $MNTPOINT/bin
cp $ROOT/bin/grep $MNTPOINT/bin
cp $ROOT/bin/sed $MNTPOINT/bin
cp $ROOT/bin/sleep $MNTPOINT/bin
cp $ROOT/bin/sort $MNTPOINT/bin
cp $ROOT/bin/umount $MNTPOINT/bin
cp $ROOT/sbin/insmod $MNTPOINT/bin/
cp $ROOT/sbin/dhclient $MNTPOINT/bin/
cp $ROOT/sbin/dhclient-script $MNTPOINT/bin/
cp $ROOT/sbin/lspci $MNTPOINT/bin
cp $ROOT/sbin/ifconfig $MNTPOINT/bin
cp $ROOT/sbin/consoletype $MNTPOINT/bin
cp $ROOT/sbin/pivot_root $MNTPOINT/bin
cp $ROOT/sbin/route $MNTPOINT/bin
cp $ROOT/usr/bin/expr $MNTPOINT/bin
cp $ROOT/usr/share/hwdata/pcitable $MNTPOINT/usr/share/hwdata/
cp ./busybox $MNTPOINT/bin/busybox
# делаем ссылки на busybox
cd $MNTPOINT/bin/
ln -sf bin ../sbin
ln -sf insmod modprobe
ln -sf insmod lsmod
ln -sf insmod rmmod
ln -sf busybox awk
ln -sf busybox basename
ln -sf busybox cut
ln -sf busybox df
ln -sf busybox ln
ln -sf busybox ls
ln -sf busybox more
ln -sf busybox rm
ln -sf busybox uname
ln -sf bash ash
# Создаём файл fstab
cd ../etc
touch fstab
# mtab подменяем ссылкой на /proc/mounts
ln -sf /proc/mounts mtab
# Собираем файлы библиотек
cd ../lib
cp $ROOT/lib/ld-${CVERS}.so .
ln -sf ld-${CVERS}.so ld-linux.so.2
cp $ROOT/lib/libc-${CVERS}.so .
ln -sf libc-${CVERS}.so libc.so.6
cp $ROOT/lib/libdl-${CVERS}.so .
ln -sf libdl-${CVERS}.so libdl.so.2
cp $ROOT/lib/libm-${CVERS}.so .
ln -sf libm-${CVERS}.so libm.so.6
cp $ROOT/lib/libtermcap.so.2 .
cp $ROOT/lib/librt-${CVERS}.so .
ln -sf librt.so.1 librt-${CVERS}.so
cp $ROOT/lib/libpcre.so.0.0.1 .
ln -sf libpcre.so.0.0.1 libpcre.so.0
cp $ROOT/lib/libuuid.so.1.2 .
ln -sf libuuid.so.1.2 libuuid.so.1
cd $TOP_DIR
# Создаём каталог для модулей и копируем в него все модули,
# в основном для файловых систем и сетевых адаптеров.
NEWMODDIR=$MNTPOINT/lib/modules/$VERSION
mkdir -p $NEWMODDIR
cp $MODULES/modules.* $NEWMODDIR
mkdir -p $NEWMODDIR/kernel/drivers/
#cp -r $MODULES/kernel/drivers/net $NEWMODDIR/kernel/drivers
#cp -r $MODULES/kernel/drivers/net $NEWMODDIR/kernel/drivers
mkdir -p $NEWMODDIR/kernel/fs/
#cp -r $MODULES/kernel/fs/nfs $NEWMODDIR/kernel/fs/
#cp -r $MODULES/kernel/fs/lockd $NEWMODDIR/kernel/fs/
mkdir -p $NEWMODDIR/kernel/net/
# dummy.ko чаще всего отсутствует
cp -r $MODULES/kernel/drivers/net/dummy.ko $NEWMODDIR/kernel/net/
umount $MNTPOINT
# сжимаем образ и копируем по указанному пути
echo "Compressing initial ram disk image"
gzip -9 $IMAGE
echo "installing kernel image and initrd"
cp -v $KERNEL /tftpboot/linux-install/$INSTALL_DIR/vmlinuz
mv -v $IMAGE.gz /tftpboot/linux-install/$INSTALL_DIR/initrd0
exit $rc
Файл linuxrc.
Загрузочный скрипт, запускаемый ядром.
#!/bin/ash
# Процедура монтирует файлы и каталоги поверх тех, что в root (которая
# должна быть примонтирована как read-only), с целью допустить изменение
# указанных файлов узлами
mountfile () {
snapshotfile=/.snapshot/${2}${1}
dir=`dirname $snapshotfile`
# Проверяем наличие файла в снэпшоте, если да – пропускаем,
# иначе копируем в снэпшот
if [ ! -e $snapshotfile ]; then
mkdir -p $dir
echo "${1} missing from client specific area."
if [ -e ${1} ] ; then
echo "Copying ${1}"
rsync -a ${1} $dir
else
echo "Creating ${1}"
touch $snapshotfile
fi
else
# Если dev в снэпшоте старее аналогичного в корневой папке,
# то использовать последний
if [ ${1} == "/dev" -a ${1} -nt ${dir}/dev ]; then
rsync -a ${1} $dir
fi
fi
mount -n -o bind /.snapshot/${2}${1} ${1}
}
echo "Running /disklessrc"
echo "Mounting /proc"
/bin/mount -n -t proc /proc /proc
if [ -z "${ETHERNET}" ]; then export ETHERNET="eth0"; fi
echo "Mounting /"
/bin/mount -n -o remount,rw /
/bin/mount -n -t tmpfs /dev/shm /tmp
# Конфигурируемый интерфейс для запроса по DHCP необходимых параметров
ifconfig
cat <
interface "$ETHERNET" {
request subnet-mask,
broadcast-address,
routers,
domain-name,
domain-name-servers,
host-name,
root-path;
}
EOF
# Запуск клиента получения параметров по DHCP
echo "Running dhclient"
/bin/dhclient -cf /tmp/dhclient.conf -pf /tmp/dhclient.pid \
$ETHERNET > /tmp/dhclient.out 2>&1
if [ $? -ne 0 ]; then
exec /bin/ash
cat /tmp/dhclient.out
echo "ERROR! dhclient failed!"
exit 1
fi
# Проверяем получение пути к корню с сервера
if [ -z "${NFSROOT}" ]; then
echo "ERROR! No root-path. "
exit 1
fi
# Разделяем полученную строку на ip и путь
NFS_IP=` echo ${NFSROOT} | cut -d : -f 1`
NFS_DIR=`echo ${NFSROOT} | cut -d : -f 2`
echo "Mounting root filesystem: ${NFS_DIR} from: ${NFS_IP}"
mount -n -o nolock,ro ${NFS_IP}:${NFS_DIR}/root /mnt
if [ $? -ne 0 ]; then
echo "ERROR! Failed to mount the root directory."
exit 1
fi
# Меняем корень с помощью системного вызова
umount /proc
echo "Doing the pivot_root"
cd /mnt
/sbin/pivot_root . .oldroot
if [ $? -ne 0 ]; then
echo "ERROR! Failed to do pivot_root."
exit 1
fi
cd /
mount -n -t proc /proc /proc
# Получаем ip
IP=`/sbin/ifconfig $ETHERNET|grep inet|cut -f 2 -d ':'|cut -f 1 -d ' '`
# Задаём имя узла по ip
hostname `host $IP | sed 's/.* \(.*\)./\1/'` 2> /dev/null
if [ -z "${SNAPSHOT}" ]; then
SNAPSHOT=`hostname`
fi
# монтируем каталог со снэпшотами
echo Mounting Snapshot directories
mount $NFS_IP:${NFS_DIR}/snapshot /.snapshot -o nolock &&
{
# Просматриваем два файла и монтируем указанные в них файлы и папки.
# Принципиально можно обойтись и одним
for i in `grep -v "#" /.snapshot/files`; do
mountfile $i ${SNAPSHOT}
done
if [ -e /.snapshot/files.custom ]; then
for i in `grep -v "#" /.snapshot/files.custom`; do
mountfile $i ${SNAPSHOT}
done
fi
RELEASE=`uname -r`
for i in `ls /lib/modules/$RELEASE/modules.*`; do
mountfile $i ${SNAPSHOT}
done
/sbin/ifup lo
}
# Уничтожаем демон клиента DHCP
/bin/kill -TERM `cat /.oldroot/tmp/dhclient.pid`
umount /proc
umount /.oldroot/tmp
# Выводим баннер
echo "--------======== cluster node info ========--------"
echo " Cluster: X"
echo " boot system: diskless, NFS"
echo " NFS server ip : ${NFS_IP}"
echo " NFS root directory : ${NFS_DIR}"
echo " local info:"
echo " local ip (${ETHERNET}) : ${IP}"
echo " using snapshot : ${SNAPSHOT}"
echo " just to know : ${RELEASE}"
echo "--------======== OK ========--------"
/bin/sleep 4s
# Инициируем стандартную загрузку (скрипт init)
echo "Running /sbin/init"
/sbin/init –init
Файл mksnapshot.
Создание слепка для узла.
#!/bin/bash
# Имя снэпшота
snap="cent05"
# файлы которые необходимо скопировать в слепок храним в ./files
files=`cat ./files`
# Путь к корню
files_root="/home/netboot/cent/root"
mkdir $snap
for i in $files ; do
if [ -d $i ]; then
s=${i:0:${#i}-1}
mkdir -pv ./$snap$s
cp -rv $files_root$i ./$snap$i/..;
else
pw=`stat --format=%a $files_root$i`
us=`stat --format=%u $files_root$i`
gr=`stat --format=%g $files_root$i`
install -D -v -m $pw -o $us -g $gr $files_root$i $snap$i;
fi
done
# Формируем файл network
cat <
NETWORKNIG=yes
HOSTNAME=$snap
EOF
# Формируем fstab
cat <
none /dev/pts devpts gid=5,mode=620 0 0
none /dev/shm tmpfs defaults 0 0
none /proc proc defaults 0 0
none /sys sysfs defaults 0 0
EOF
mkdir ./$snap/tmp
Пример файла files, используемого при монтировании слепков
/dev
/etc/resolv.conf
/etc/adjtime
/etc/sysconfig/hwconf
/root
/var/empty
/var/lib/nfs
/var/lib/random-seed
/var/tmp
/var/lock
/var/spool
/var/run
/var/log
/var/lib/logrotate.status
1 io.org/navigator-bin/navigator.cgi?Documentation/initrd.txt