Идея реализации бездисковых станций на базе OverlayFS была не моя, а моих коллег по работе.
Вероятно, уже многие рассматривали варианты как сделать бездисковые станции на базе слоситых файловых систем. Например на базе AuFS.
Но это было не просто - т.к. много работы по установке и настройке модулей ядра, которых нет по умолчанию.
А зачем вообще такие бездисковые станции? спросите вы.
Сразу скажу это решение для Linux систем.
А с другими я особо и не работаю :))
1. Самое понятное - Класс в учебном заведении.
на всех машинах должны стоять одинаковые системы, они должны обновляться одинаково. На них должны стоять одинаковые наборы программ с одинаковыми настройками и связями между собой и с принтерами например.
Ну а наработанные данные пользователя должны тоже сохраниться и они будут лежать в отдельных папках на сервере.
2. Разные операционисты в банках, в торговых заведениях. Если например все они должны работать в общем пространстве программ и все программы должны быть настроены одинаково на всех машинах.
3. Различные пультовые и компьютеры управления какими-нибудь системами.
Суть в том что в разных местах сложных больших по площади установок могут стоять бездисковые машины для контроля и управления этой установкой и при запуске эти машины будут работать совершенно одинаково и показывать одни и теже приложения которые настраиваются один раз для всех машин.
Ну и можно еще много всего перечислять.
Есть один большой и мощный NFS сервер, который для каждого клиента (бездисковой машины) имеет свой ресурс выдачи.
Этот ресурс формируется из двух слоев, можно и больше если в этом есть производственная необходимость (позже расскажу какая может быть потребность).
Нижний или Базовый слой содержит всю основную систему со всеми пакетами программ и настройками драйверов для внешних и устройств. В этом плане все клиентские машины должны быть унифицированы и иметь одинаковые подключенные внешние и внутренние устройства. Ну или придется устанавливать драйвера для всех имеющихся на клиентах устройств.
На верхнем слое будет лежать только то, что наработал пользователь. Здесь имеется ввиду логи его действий, временные и рабочие каталоги или настройки программ для этой машины.
А вот данные пользователя и его домашний каталог можно держать совершенно в отдельном каталоге. Это можно было делать и без использования слоистой файловой системы.
В итоге мы получаем :
1. настроенная система в одном экземпляре
2. пользовательские папки - на каждого пользователя по одной папке, независимо от количества бездисковых машин. На всех них он может работать с одинаковыми программами и со своими данными
3. в верхних слоях для каждой машины лежат временные папки и папки логов. Эти папки кстати можно периодически чистить без особого урона.
За счет этого объединения слоев мы получаем значительную экономию места на nfs сервере
и унификацию всех настроек программ на всех машинах. Скорость внесения изменений в базовый слой - мгновенно!
В общем то все зависит как будут организованы слои.
Самый простой способ использования это два слоя базовый и верхний слой где лежат только пользовательские настройки. Пользователь не может устанавливать в этом случае программы и добавлять устройства в машину.
Можно организовать трехслойную структуру, в этом случае у администора конкретной машины будет возможность устанавливать пакеты в средний слой, который базируется на общий для всех машин. А пользователи по-прежнему будут сохранять свои настройки в верхний слой.
Но в любом случае нельзя исправлять или добавлять файлы в верхние слои если слои не смонтированы в overlayfs. Дело в том что если слои размонтировать , то в папках слоев будут лежать файлы, которые привязаны к файлам более нижнего слоя и поэтому если файл более верхнего слоя изменился а система overlayfs об этом не знает , это может привести к не предсказуемым результатам.
Также есть особенность в пересборке ядра. Ядро нужно будет пересобирать только в базовом слое, то есть нужно загрузить машину с этим слоем, собрать ядро с указанием аргументов с тем что при загрузке ядро подмонтирует рутовую директорию коорая находится на nfs ресурсе. Затем нужно пересобрать iniramfs и скопировать ядро и initramfs на tftp сервер, для того чтобы следующая загрузка машины произошла уже с новым ядром.
Итак рассмотрим реализация системы с двумя слоями.
В качестве сервера будет выступать система Centos 7.4
Поддержка модуля overlayfs в ядре появилась только с версии 4.16. Поэтому обновляем ядро до 4.16 или выше.
Устанавливаем пакет с репозиторием elrepo:
# rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
# rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm
Оставляем только ядерные ветки репозитория:
# yum --disablerepo="*" --enablerepo="elrepo-kernel" list available
Устанавливаем последнее ядро:
# yum --enablerepo=elrepo-kernel install kernel-ml
После этого перегружаем машину и смотрим какое ядро появилось в папке /boot
После этого нужно убедиться что в grub.conf - е указана правильная строка загрузки по умолчанию.
То есть смотрим файл /etc/default/grub и убеждаемся что там написано:
GRUB_DEFAULT=0
Обычно после установки нового ядра оно прописывается в самый первый (нулевой) уровень загрузки. Но если оно установилось в другой уровень то пропишите этот уровень в GRUB_DEFAULT
Создадим структуру папок для слоистой файловой системы:
Давайте подключим отдельный диск или раздел диска и подмонтируем его в папку /DATA
В ней создадим базовый слой:
# mkdir /DATA/base/centos7.4
можно в дальнейшем и базовые слои других операционных систем создать.
Создаем место для верхних слоев :
# mkdir /DATA/hosts/host1
# mkdir /DATA/hosts/host2
# mkdir /DATA/hosts/host3
И еще нужно создать папки для временных рабочих файлов слоистой файловой системы:
# mkdir /DATA/works/host1
# mkdir /DATA/works/host2
# mkdir /DATA/works/host3
Устанавливаем систему в базовый слой :
# yum groups -y install "Server with GUI" --releasever=7 --installroot=/DATA/base/centos7.4
Здесь мы ставим например сервер с GUI.
Теперь устанавливаем nfs сервер:
# yum install nfs-utils
Создаем папки для выдачи соединенных слоев (соединять будем позже):
# mkdir /export/hosts/host1
# mkdir /export/hosts/host2
# mkdir /export/hosts/host3
устанавливаем права на папки:
# chmod -R 755 /export/hosts/host1
# chown nfsnobody:nfsnobody /export/hosts/host1
все то же самое для остальных папок.
Настраиваем файерволл:
firewall-cmd --permanent --zone=public --add-service=nfs
firewall-cmd --permanent --zone=public --add-service=mountd
firewall-cmd --permanent --zone=public --add-service=rpc-bind
firewall-cmd --reload
Запускаем все сервисы:
systemctl enable rpcbind
systemctl enable nfs-server
systemctl enable nfs-lock
systemctl enable nfs-idmap
systemctl start rpcbind
systemctl start nfs-server
systemctl start nfs-lock
systemctl start nfs-idmap
создаем файл /etc/exports и пишем туда примерно следующее:
/export/hosts/host1 192.168.0.1(rw,sync,no_root_squash,no_all_squash)
/export/hosts/host2 192.168.0.2(rw,sync,no_root_squash,no_all_squash)
/export/hosts/host3 192.168.0.3(rw,sync,no_root_squash,no_all_squash)
Теперь настроим монтирование слоев в overlayfs:
Во первых нужно настроить модуль ядра overlayfs, включаем возможность експортировать слои через NFS:
В файле /sys/module/overlay/parameters/nfs_export пишем YВ /sys/module/overlay/parameters/redirect_always_follow тоже пишем Y
Теперь подготовим файл /etc/fstab. Пишем для каждой машины:
overlay /exports/hosts/host1 overlay noauto,x-systemd.requires=/DATA,x-systemd.automount,lowerdir=/DATA/base/centos7.4/,upperdir=/DATA/hosts/host1/,workdir=/DATA/works/host1/,index=on 0 0
Здесь нужно отметить, что используется опция ядра index=on это важно для работы overlayfs через nfs. Иначе смонтированные по nfs верхние слои не будут видны на клиенте nfs.
А так же тут указаны важные опции noauto, x-systemd.requires и x-systemd.automount .
Это нужно для того чтобы монтирование папок происходило последовательно друг за другом.
То есть сначала монтируется диск с данными nfs ресурсов /DATA, а затем монтируются слои overlayfs. Чтобы такое произошло, нужно отключить автомонтирование слоев overlayfs. Кроме того монтирование будет производиться спомощью системы systemd.automount.
После перезагрузки сервера слои смонтируются и будут доступны по nfs.
Теперь нужно настроить выдачу загрузочного образа ядра для хостов через tftp сервер:
# yum install tftp-server
Меняем настройки по-умолчанию:
в файле /etc/xinetd.d/tftp меняем параметр disable на 'no'
перегружаем xinetd:
# service xinetd restart
Устанавливаем основные загрузочные образы:
# yum install syslinux
Копируем нужные файлы в корень (/var/lib/tftpboot/) tftp сервера:
# cp /usr/lib/syslinux/pxelinux.0 /var/lib/tftpboot
# cp /usr/lib/syslinux/menu.c32 /var/lib/tftpboot
# cp /usr/lib/syslinux/memdisk /var/lib/tftpboot
# cp /usr/lib/syslinux/mboot.c32 /var/lib/tftpboot
# cp /usr/lib/syslinux/chain.c32 /var/lib/tftpboot
Создаем директорию для загрузочного меню:
# mkdir /var/lib/tftpboot/pxelinux.cfg
Тут же создаем директорию для загрузочного образа базовой системы бездисковых станций:
# mkdir /var/lib/tftpboot/base-centos7.4
Туда же копируем vmlinuz и initrd.img.
в файле /var/lib/tftpboot/pxelinux.cfg/default пишем примерно следующее:
default vesamenu.c32
prompt 0
timeout 300
ONTIMEOUT local
MENU TITLE PXE Menu
Local HHD0 Boot
LABEL Centos
MENU LABEL Centos Install
KERNEL base-centos7.4/vmlinuz
APPEND initrd=base-centos7.4/initrd.img root=/dev/nfs rw nfsroot=nfs-server:/DATA/base/centos7.4 ip=eth0:dhcp selinux=0 ipv6.disable=1 console=tty0 plymouth.enable=0
Это настройки загрузки любой машины которую DHCP сервер перенаправил для загрузки ядра по сети на этот сервер. В данном случае загрузится базовый слой.
Для каждого хоста определяем IP адрес, который будет выдавать DHCP сервер, переводим этот адрес в hex представлении и создаем файл с таким именем и в нем прописываем загрузочное меню для этого хоста. tftp сервер будет выдавать это меню загрузки только для машин с IP для которого был сделан файл.
Вот пример файла:
default vesamenu.c32
prompt 0
timeout 60
ONTIMEOUT Main
MENU TITLE PXE Boot Host1
LABEL Main
MENU LABEL host1
KERNEL base-centos7.4/vmlinus
APPEND initrd=base-centos7.4/initrd.img root=/dev/nfs rw nfsroot=nfs-server:/exports/hosts/host1 ip=eth0:dhcp selinux=0 ipv6.disable=1 console=tty0 plymouth.enable=0
LABEL base-pult
MENU LABEL base-centos7.4
KERNEL base-centos7.4/vmlinuz
APPEND initrd=base-centos7.4/initrd.img root=/dev/nfs rw nfsroot=nfs-server:/DATA/base/centos7.4 ip=eth0:dhcp ipv6.disable=1 console=tty0 plymouth.enable=0
Теперь перегружаем сервисы :
# service xinetd restart
# service tftpbootd restart
В настройках dhcp сервера, который выдает адреса машинам в этом сегменте сети нужно прописать опцию для перенаправления машины, которая получила IP адрес, на tftp сервер для получения загрузочного образа ядра.
Прописываем в /etc/dhcp/dhcpd.conf
next-server nfs-server;
filename "pxelinux.0";
в секции описывающей сеть или сегмент сети.
После этого загружаем бездисковую станцию и смотрим как она получает адрес и затем получает загрузочное меню.
В меню два пункта. Первый пункт это загрузка машины именно в слоистой файловой системе.
Второй пункт это загрузка базового слоя в корневую директорию.
Второй пункт нужен чтобы вносить изменения на базовый слой.
Про особенности работы в слоистой файловой системе было написано выше.
Добавление нового хоста в слоистую файловую систему
Как можно понять из описанного выше добавление нового бездискового хоста потребует внести изменения как минимм в трех местах на nfs сервере:
1. Cоздаем структуру в /DATA/hosts/newhost и /DATA/works/newhost
2. Делаем соответствующие записи в /etc/fstab
3. Создаем файл соответствующий IP адресу новой машины в /var/lib/tft[pboot/pxelinux.cfg/
4. Перегружаем все нужные сервисы.
Ну конечно же можно просто написать скрипт для автоматизации всего этого дела:
#!/usr/bin/python
import os, sys
import socket
ROOT_PATH = '/DATA'
EXPORT_PATH = '/exports'
BASE = 'base-centos7.4'
WORK_NET = '192.168.0.0/24'
EXPORT_CONF_FILE = '/etc/exports'
ROOT_TFTP = '/var/lib/tftpboot/pxelinux.cfg/'
IP_NFS_SERVER = '192.168.0.254'
LOWER_DIR = os.path.join(ROOT_PATH,'base',BASE)
BASE_WORK_DIR = os.path.join(ROOT_PATH,'works')
def ip_to_hex(ip):
out = ''
hex_symbol = ''
for i in ip.split('.'):
hex_symbol = hex(int(i)).replace('0x','').upper()
if len(hex_symbol) == 1:
hex_symbol = '0'+hex_symbol
out += hex_symbol
return out
def make_export_conf(EXPORT_CONF_FILE, export_row):
with open(EXPORT_CONF_FILE,'r') as expfile:
text_file = expfile.read()
if text_file.find(export_row) == -1:
with open(EXPORT_CONF_FILE,'a') as expfile:
expfile.write(export_row)
return
def make_tftp_file(hex_name,EXPORT_DIR,ROOT_TFTP,if_name):
conf_file_text = ''
dict_replace = {'hostname':hostname,
'export_dir':EXPORT_DIR,
'ip_nfs_server':IP_NFS_SERVER,
'if_name':if_name}
text_tpl = open('tftpboot.tpl','r').read()
text_next = text_tpl
for k in dict_replace.keys():
conf_file_text = text_next.replace('{'+k+'}',dict_replace[k])
text_next = conf_file_text
print conf_file_text
conf_file = open(ROOT_TFTP+'/'+hex_name,'w')
conf_file.write(conf_file_text)
return
def make_fstab(mount_row):
with open('/etc/fstab','r') as expfile:
text_file = expfile.read()
if text_file.find(mount_row) == -1:
with open('/etc/fstab','a') as expfile:
expfile.write(mount_row)
os.system('umount '+EXPORT_DIR)
print 'mount -t overlay overlay -o lowerdir='+LOWER_DIR\
+'/,upperdir='+UPPER_DIR+'/,workdir='+WORK_HOST_DIR+'/,index=on '+EXPORT_DIR
os.system('mount -t overlay overlay -o lowerdir='+LOWER_DIR\
+'/,upperdir='+UPPER_DIR+'/,workdir='+WORK_HOST_DIR+'/,index=on '+EXPORT_DIR)
return
count_args = len(sys.argv)
name_interface = 'eth0'
ip = None
print count_args
if count_args < 2:
print "hostname is needed. python create_layer.py {hostname} "
sys.exit(1)
# get name of network interface of machine
if count_args >= 2:
hostname = sys.argv[1] #get hostname
if count_args >= 3:
ip = sys.argv[2] #get ip address
if count_args == 4:
name_interface = sys.argv[3] #get name ethernet
if not ip:
IPHOLDER = socket.gethostbyname(hostname)
else:
IPHOLDER = ip
hex_name = ip_to_hex(IPHOLDER)
print hostname
print ip
print name_interface
print hex_name
Ну и вызов этого скрипта: python create_layer.py {hostname}
Необходим хотябы один аргумент для этого скрипта - это имя бездисковой станции который прописан в ДНС сервере и для которого IP адрес соответствует выдамаемомы dhcp сервером.
Можно так же указать еще два аргумента это ip адрес (на случай если нет записи в ДНС) и имя интерфейса, если хочется указать какой именно интерфейс будет подключаться к сети и к nfs серверу.
Вот так можно все это создавать и автоматизировать.
Все успехов и удачи!
Вероятно, уже многие рассматривали варианты как сделать бездисковые станции на базе слоситых файловых систем. Например на базе AuFS.
Но это было не просто - т.к. много работы по установке и настройке модулей ядра, которых нет по умолчанию.
А зачем вообще такие бездисковые станции? спросите вы.
Область применения:
Сразу скажу это решение для Linux систем.
А с другими я особо и не работаю :))
1. Самое понятное - Класс в учебном заведении.
на всех машинах должны стоять одинаковые системы, они должны обновляться одинаково. На них должны стоять одинаковые наборы программ с одинаковыми настройками и связями между собой и с принтерами например.
Ну а наработанные данные пользователя должны тоже сохраниться и они будут лежать в отдельных папках на сервере.
2. Разные операционисты в банках, в торговых заведениях. Если например все они должны работать в общем пространстве программ и все программы должны быть настроены одинаково на всех машинах.
3. Различные пультовые и компьютеры управления какими-нибудь системами.
Суть в том что в разных местах сложных больших по площади установок могут стоять бездисковые машины для контроля и управления этой установкой и при запуске эти машины будут работать совершенно одинаково и показывать одни и теже приложения которые настраиваются один раз для всех машин.
Ну и можно еще много всего перечислять.
Идея:
Есть один большой и мощный NFS сервер, который для каждого клиента (бездисковой машины) имеет свой ресурс выдачи.
Этот ресурс формируется из двух слоев, можно и больше если в этом есть производственная необходимость (позже расскажу какая может быть потребность).
Нижний или Базовый слой содержит всю основную систему со всеми пакетами программ и настройками драйверов для внешних и устройств. В этом плане все клиентские машины должны быть унифицированы и иметь одинаковые подключенные внешние и внутренние устройства. Ну или придется устанавливать драйвера для всех имеющихся на клиентах устройств.
На верхнем слое будет лежать только то, что наработал пользователь. Здесь имеется ввиду логи его действий, временные и рабочие каталоги или настройки программ для этой машины.
А вот данные пользователя и его домашний каталог можно держать совершенно в отдельном каталоге. Это можно было делать и без использования слоистой файловой системы.
В итоге мы получаем :
1. настроенная система в одном экземпляре
2. пользовательские папки - на каждого пользователя по одной папке, независимо от количества бездисковых машин. На всех них он может работать с одинаковыми программами и со своими данными
3. в верхних слоях для каждой машины лежат временные папки и папки логов. Эти папки кстати можно периодически чистить без особого урона.
За счет этого объединения слоев мы получаем значительную экономию места на nfs сервере
и унификацию всех настроек программ на всех машинах. Скорость внесения изменений в базовый слой - мгновенно!
Особенности:
В общем то все зависит как будут организованы слои.
Самый простой способ использования это два слоя базовый и верхний слой где лежат только пользовательские настройки. Пользователь не может устанавливать в этом случае программы и добавлять устройства в машину.
Можно организовать трехслойную структуру, в этом случае у администора конкретной машины будет возможность устанавливать пакеты в средний слой, который базируется на общий для всех машин. А пользователи по-прежнему будут сохранять свои настройки в верхний слой.
Но в любом случае нельзя исправлять или добавлять файлы в верхние слои если слои не смонтированы в overlayfs. Дело в том что если слои размонтировать , то в папках слоев будут лежать файлы, которые привязаны к файлам более нижнего слоя и поэтому если файл более верхнего слоя изменился а система overlayfs об этом не знает , это может привести к не предсказуемым результатам.
Также есть особенность в пересборке ядра. Ядро нужно будет пересобирать только в базовом слое, то есть нужно загрузить машину с этим слоем, собрать ядро с указанием аргументов с тем что при загрузке ядро подмонтирует рутовую директорию коорая находится на nfs ресурсе. Затем нужно пересобрать iniramfs и скопировать ядро и initramfs на tftp сервер, для того чтобы следующая загрузка машины произошла уже с новым ядром.
Реализация:
Итак рассмотрим реализация системы с двумя слоями.
В качестве сервера будет выступать система Centos 7.4
Поддержка модуля overlayfs в ядре появилась только с версии 4.16. Поэтому обновляем ядро до 4.16 или выше.
Устанавливаем пакет с репозиторием elrepo:
# rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
# rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm
Оставляем только ядерные ветки репозитория:
# yum --disablerepo="*" --enablerepo="elrepo-kernel" list available
Устанавливаем последнее ядро:
# yum --enablerepo=elrepo-kernel install kernel-ml
После этого перегружаем машину и смотрим какое ядро появилось в папке /boot
После этого нужно убедиться что в grub.conf - е указана правильная строка загрузки по умолчанию.
То есть смотрим файл /etc/default/grub и убеждаемся что там написано:
GRUB_DEFAULT=0
Обычно после установки нового ядра оно прописывается в самый первый (нулевой) уровень загрузки. Но если оно установилось в другой уровень то пропишите этот уровень в GRUB_DEFAULT
Создадим структуру папок для слоистой файловой системы:
Давайте подключим отдельный диск или раздел диска и подмонтируем его в папку /DATA
В ней создадим базовый слой:
# mkdir /DATA/base/centos7.4
можно в дальнейшем и базовые слои других операционных систем создать.
Создаем место для верхних слоев :
# mkdir /DATA/hosts/host1
# mkdir /DATA/hosts/host2
# mkdir /DATA/hosts/host3
И еще нужно создать папки для временных рабочих файлов слоистой файловой системы:
# mkdir /DATA/works/host1
# mkdir /DATA/works/host2
# mkdir /DATA/works/host3
Устанавливаем систему в базовый слой :
# yum groups -y install "Server with GUI" --releasever=7 --installroot=/DATA/base/centos7.4
Здесь мы ставим например сервер с GUI.
Теперь устанавливаем nfs сервер:
# yum install nfs-utils
Создаем папки для выдачи соединенных слоев (соединять будем позже):
# mkdir /export/hosts/host1
# mkdir /export/hosts/host2
# mkdir /export/hosts/host3
устанавливаем права на папки:
# chmod -R 755 /export/hosts/host1
# chown nfsnobody:nfsnobody /export/hosts/host1
все то же самое для остальных папок.
Настраиваем файерволл:
firewall-cmd --permanent --zone=public --add-service=nfs
firewall-cmd --permanent --zone=public --add-service=mountd
firewall-cmd --permanent --zone=public --add-service=rpc-bind
firewall-cmd --reload
Запускаем все сервисы:
systemctl enable rpcbind
systemctl enable nfs-server
systemctl enable nfs-lock
systemctl enable nfs-idmap
systemctl start rpcbind
systemctl start nfs-server
systemctl start nfs-lock
systemctl start nfs-idmap
создаем файл /etc/exports и пишем туда примерно следующее:
/export/hosts/host1 192.168.0.1(rw,sync,no_root_squash,no_all_squash)
/export/hosts/host2 192.168.0.2(rw,sync,no_root_squash,no_all_squash)
/export/hosts/host3 192.168.0.3(rw,sync,no_root_squash,no_all_squash)
Теперь настроим монтирование слоев в overlayfs:
Во первых нужно настроить модуль ядра overlayfs, включаем возможность експортировать слои через NFS:
В файле /sys/module/overlay/parameters/nfs_export пишем YВ /sys/module/overlay/parameters/redirect_always_follow тоже пишем Y
Теперь подготовим файл /etc/fstab. Пишем для каждой машины:
overlay /exports/hosts/host1 overlay noauto,x-systemd.requires=/DATA,x-systemd.automount,lowerdir=/DATA/base/centos7.4/,upperdir=/DATA/hosts/host1/,workdir=/DATA/works/host1/,index=on 0 0
Здесь нужно отметить, что используется опция ядра index=on это важно для работы overlayfs через nfs. Иначе смонтированные по nfs верхние слои не будут видны на клиенте nfs.
А так же тут указаны важные опции noauto, x-systemd.requires и x-systemd.automount .
Это нужно для того чтобы монтирование папок происходило последовательно друг за другом.
То есть сначала монтируется диск с данными nfs ресурсов /DATA, а затем монтируются слои overlayfs. Чтобы такое произошло, нужно отключить автомонтирование слоев overlayfs. Кроме того монтирование будет производиться спомощью системы systemd.automount.
После перезагрузки сервера слои смонтируются и будут доступны по nfs.
Теперь нужно настроить выдачу загрузочного образа ядра для хостов через tftp сервер:
# yum install tftp-server
Меняем настройки по-умолчанию:
в файле /etc/xinetd.d/tftp меняем параметр disable на 'no'
перегружаем xinetd:
# service xinetd restart
Устанавливаем основные загрузочные образы:
# yum install syslinux
Копируем нужные файлы в корень (/var/lib/tftpboot/) tftp сервера:
# cp /usr/lib/syslinux/pxelinux.0 /var/lib/tftpboot
# cp /usr/lib/syslinux/menu.c32 /var/lib/tftpboot
# cp /usr/lib/syslinux/memdisk /var/lib/tftpboot
# cp /usr/lib/syslinux/mboot.c32 /var/lib/tftpboot
# cp /usr/lib/syslinux/chain.c32 /var/lib/tftpboot
# mkdir /var/lib/tftpboot/pxelinux.cfg
Тут же создаем директорию для загрузочного образа базовой системы бездисковых станций:
# mkdir /var/lib/tftpboot/base-centos7.4
Туда же копируем vmlinuz и initrd.img.
в файле /var/lib/tftpboot/pxelinux.cfg/default пишем примерно следующее:
default vesamenu.c32
prompt 0
timeout 300
ONTIMEOUT local
MENU TITLE PXE Menu
Local HHD0 Boot
LABEL Centos
MENU LABEL Centos Install
KERNEL base-centos7.4/vmlinuz
APPEND initrd=base-centos7.4/initrd.img root=/dev/nfs rw nfsroot=nfs-server:/DATA/base/centos7.4 ip=eth0:dhcp selinux=0 ipv6.disable=1 console=tty0 plymouth.enable=0
Это настройки загрузки любой машины которую DHCP сервер перенаправил для загрузки ядра по сети на этот сервер. В данном случае загрузится базовый слой.
Для каждого хоста определяем IP адрес, который будет выдавать DHCP сервер, переводим этот адрес в hex представлении и создаем файл с таким именем и в нем прописываем загрузочное меню для этого хоста. tftp сервер будет выдавать это меню загрузки только для машин с IP для которого был сделан файл.
Вот пример файла:
default vesamenu.c32
prompt 0
timeout 60
ONTIMEOUT Main
MENU TITLE PXE Boot Host1
LABEL Main
MENU LABEL host1
KERNEL base-centos7.4/vmlinus
APPEND initrd=base-centos7.4/initrd.img root=/dev/nfs rw nfsroot=nfs-server:/exports/hosts/host1 ip=eth0:dhcp selinux=0 ipv6.disable=1 console=tty0 plymouth.enable=0
LABEL base-pult
MENU LABEL base-centos7.4
KERNEL base-centos7.4/vmlinuz
APPEND initrd=base-centos7.4/initrd.img root=/dev/nfs rw nfsroot=nfs-server:/DATA/base/centos7.4 ip=eth0:dhcp ipv6.disable=1 console=tty0 plymouth.enable=0
Теперь перегружаем сервисы :
# service xinetd restart
# service tftpbootd restart
В настройках dhcp сервера, который выдает адреса машинам в этом сегменте сети нужно прописать опцию для перенаправления машины, которая получила IP адрес, на tftp сервер для получения загрузочного образа ядра.
Прописываем в /etc/dhcp/dhcpd.conf
next-server nfs-server;
filename "pxelinux.0";
в секции описывающей сеть или сегмент сети.
После этого загружаем бездисковую станцию и смотрим как она получает адрес и затем получает загрузочное меню.
В меню два пункта. Первый пункт это загрузка машины именно в слоистой файловой системе.
Второй пункт это загрузка базового слоя в корневую директорию.
Второй пункт нужен чтобы вносить изменения на базовый слой.
Про особенности работы в слоистой файловой системе было написано выше.
Добавление нового хоста в слоистую файловую систему
Как можно понять из описанного выше добавление нового бездискового хоста потребует внести изменения как минимм в трех местах на nfs сервере:
1. Cоздаем структуру в /DATA/hosts/newhost и /DATA/works/newhost
2. Делаем соответствующие записи в /etc/fstab
3. Создаем файл соответствующий IP адресу новой машины в /var/lib/tft[pboot/pxelinux.cfg/
4. Перегружаем все нужные сервисы.
Ну конечно же можно просто написать скрипт для автоматизации всего этого дела:
#!/usr/bin/python
import os, sys
import socket
ROOT_PATH = '/DATA'
EXPORT_PATH = '/exports'
BASE = 'base-centos7.4'
WORK_NET = '192.168.0.0/24'
EXPORT_CONF_FILE = '/etc/exports'
ROOT_TFTP = '/var/lib/tftpboot/pxelinux.cfg/'
IP_NFS_SERVER = '192.168.0.254'
LOWER_DIR = os.path.join(ROOT_PATH,'base',BASE)
BASE_WORK_DIR = os.path.join(ROOT_PATH,'works')
def ip_to_hex(ip):
out = ''
hex_symbol = ''
for i in ip.split('.'):
hex_symbol = hex(int(i)).replace('0x','').upper()
if len(hex_symbol) == 1:
hex_symbol = '0'+hex_symbol
out += hex_symbol
return out
def make_export_conf(EXPORT_CONF_FILE, export_row):
with open(EXPORT_CONF_FILE,'r') as expfile:
text_file = expfile.read()
if text_file.find(export_row) == -1:
with open(EXPORT_CONF_FILE,'a') as expfile:
expfile.write(export_row)
return
def make_tftp_file(hex_name,EXPORT_DIR,ROOT_TFTP,if_name):
conf_file_text = ''
dict_replace = {'hostname':hostname,
'export_dir':EXPORT_DIR,
'ip_nfs_server':IP_NFS_SERVER,
'if_name':if_name}
text_tpl = open('tftpboot.tpl','r').read()
text_next = text_tpl
for k in dict_replace.keys():
conf_file_text = text_next.replace('{'+k+'}',dict_replace[k])
text_next = conf_file_text
print conf_file_text
conf_file = open(ROOT_TFTP+'/'+hex_name,'w')
conf_file.write(conf_file_text)
return
def make_fstab(mount_row):
with open('/etc/fstab','r') as expfile:
text_file = expfile.read()
if text_file.find(mount_row) == -1:
with open('/etc/fstab','a') as expfile:
expfile.write(mount_row)
os.system('umount '+EXPORT_DIR)
print 'mount -t overlay overlay -o lowerdir='+LOWER_DIR\
+'/,upperdir='+UPPER_DIR+'/,workdir='+WORK_HOST_DIR+'/,index=on '+EXPORT_DIR
os.system('mount -t overlay overlay -o lowerdir='+LOWER_DIR\
+'/,upperdir='+UPPER_DIR+'/,workdir='+WORK_HOST_DIR+'/,index=on '+EXPORT_DIR)
return
count_args = len(sys.argv)
name_interface = 'eth0'
ip = None
print count_args
if count_args < 2:
print "hostname is needed. python create_layer.py {hostname} "
sys.exit(1)
# get name of network interface of machine
if count_args >= 2:
hostname = sys.argv[1] #get hostname
if count_args >= 3:
ip = sys.argv[2] #get ip address
if count_args == 4:
name_interface = sys.argv[3] #get name ethernet
if not ip:
IPHOLDER = socket.gethostbyname(hostname)
else:
IPHOLDER = ip
hex_name = ip_to_hex(IPHOLDER)
print hostname
print ip
print name_interface
print hex_name
Ну и вызов этого скрипта: python create_layer.py {hostname}
Необходим хотябы один аргумент для этого скрипта - это имя бездисковой станции который прописан в ДНС сервере и для которого IP адрес соответствует выдамаемомы dhcp сервером.
Можно так же указать еще два аргумента это ip адрес (на случай если нет записи в ДНС) и имя интерфейса, если хочется указать какой именно интерфейс будет подключаться к сети и к nfs серверу.
Вот так можно все это создавать и автоматизировать.
Все успехов и удачи!
