вторник, 25 декабря 2012 г.

PXE + TFTP + DHCP + ANAKONDA + KVM = Virutal AutoBoot and AutoInstall

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

Все описанное ниже верно для CentOS 6.3, для других дистрибутивов возможны различия, поэтому аккуратнее с sed'ами и прочими скриптами "автоматической настройки".

Цель: добиться следующей схемы - запускаем виртуальную машину и/или стационарный компьютер, она находит dhcp грузит по pxe: ядро и initrd, получается установочный "пакетник" anacond'ы, стартует инсталляция с локального репозитория, организованного на основе iso-образа minimal инсталляции через nginx, автоматически разбивается, ставит нужные настройки безопасности, пароли, устанавливает нужные программы, настраивает их нужным образом, генерирует ssh ключ и высылает на почту сообщение что инсталляция завершена, ip-адрес машины и ключ, под которым можно подключиться помимо парольной аутентификации.



Данная схема позволяет организовать многообразие и вариативность результата. Это всего лишь пример, "как" _можно_ "это" использовать.

Инсталляция TFTP:


# директория с файлами для загрузки по pxe
TFTP_DIR=/var/tftpboot
yum install tftp-server syslinux -y
# правка конфига /etc/xinetd.d/tftp выставление disable=no и смена директории sed s/"disable.*= yes"/"disable                 = no"/g -i /etc/xinetd.d/tftp sed "s|/var/lib/tftpboot|$TFTP_DIR|" -i /etc/xinetd.d/tftp # запуск и автозапуск сервиса xinetd service xinetd restart chkconfig xinetd on # проверить работает ли сервис можно # командой netstat -alpn|grep 69  # правила для фаервола в /etc/sysconfig/iptables: -A INPUT -m state --state NEW -m tcp -p tcp --dport 69 -j ACCEPT -A INPUT -m state --state NEW -m udp -p udp --dport 69 -j ACCEPT  # создание директорий и копирование файлов из пакета syslinux mkdir -p $TFTP_DIR # обычно расположение syslinux в /usr/share/syslinux или /usr/lib/syslinux SYSLNX_DIR=`rpm -ql syslinux|grep '\/pxelinux.0'` SYSLNX_DIR=`dirname $SYSLNX_DIR` cp $SYSLNX_DIR/pxelinux.0 $TFTP_DIR cp $SYSLNX_DIR/menu.c32 $TFTP_DIR cp $SYSLNX_DIR/memdisk $TFTP_DIR cp $SYSLNX_DIR/mboot.c32 $TFTP_DIR cp $SYSLNX_DIR/chain.c32 $TFTP_DIR # создание директории где будут хранится конфиги #(.cfg не опечатка, это именно директория) mkdir $TFTP_DIR/pxelinux.cfg # рандомное место, главное чтобы начиналось от $TFTP_DIR # для размещения образа ядра и initrd mkdir -p $TFTP_DIR/images/centos/x86_64/6.3 # копирование ядра и initrd из инсталяционного диска mount -o loop /home/fura/CentOS-6.3-x86_64-minimal.iso /mnt/tmp/ cp /mnt/tmp/isolinux/initrd.img $TFTP_DIR/images/centos/x86_64/6.3/ cp /mnt/tmp/isolinux/vmlinuz $TFTP_DIR/images/centos/x86_64/6.3/  # меню загрузки при pxe cat >> $TFTP_DIR/pxelinux.cfg/default << EOF default menu.c32 timeout 30 menu title >>> PXE Boot Menu <<< label 1         menu label ^1) CentOS_6.3_x64         kernel images/centos/x86_64/6.3/vmlinuz         append initrd=images/centos/x86_64/6.3/initrd.img ks=http://192.168.0.1/centos6.ks label 2         menu label ^2) Boot from local         localboot EOF # про параметр ks=http://192.168.0.1/centos6.ks будет объяснено дальше # вместо этого параметра, тем кому не нужно автоматическая инсталляция # могут указать method=http://mirror.yandex.ru/centos/6.3/os/x86_64

Небольшой troubleshooting: проверить что работает сервер можно командой:
tftp 192.168.0.1 -c get /pxelinux.0
Если ответ timeout, то обратите на правила фаервола. Особенно если вы настраиваете данный механизм на сервере, который раздает интернет. Ответ может SNAT'ится на другой интерфейс. Детекция комплекса проблем связанных с недоступностью и не работой данного сервиса, организуется с помощью утилиты tcpdump. Пример:
tcpdump  -nn -v  port 69
Также не стоит забывать что опция -s в файле /etc/xinetd.d/tftp указывает на то что tftp сервер будет запускаться в secure режиме, т.е. директория передаваемая как "рабочая" будет chroot'ится, и соответственно в связи с этим конфиги и запросы должны быть спроектированы от корня / и находится в доступности chroot-директории.


 Конфигурирование dhcp :


В конфиге /etc/dhcp/dhcpd.conf необходимо добавить (либо в корне конфига либо в секции subnet для нужной сети):

allow booting;
allow bootp;
class "pxeclients" {
    match if substring(option vendor-class-identifier, 0, 9) = "PXEClient";
    next-server 192.168.0.1;
    filename "/pxelinux.0";
}

где, 192.168.0.1 - адрес tftp сервера (xinetd)

Так-же стоит не забывать, что dhcp сервер должен будет раздавать ip-адрес для загруженной виртуальной машины. Если данного конфига не имеется, то можно воспользоваться примерно таким:

subnet 192.168.0.1 netmask 255.255.255.0 {
        option routers 192.168.0.1;
        option subnet-mask 255.255.255.0;
        option domain-name-servers 192.168.0.1, 8.8.8.8;
        option broadcast-address 192.168.0.255;
        range 192.168.0.100 192.168.0.200;
}

Затем требуется перезапустить dhcp-сервер:

service dhcpd restart
chkconfig dhcpd on


Конфигурирование nginx:


# добавляем свежий nginx-репозиторий
cat >> /etc/yum.repos.d/nginx.repo << EOF
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=0
enabled=1
EOF

# инсталлируем 
yum install nginx -y

# создаем наш конфиг 
cat >> /etc/nginx/conf.d/anaconda.conf << EOF
server {
        listen          80;
        server_name     _;

        location / {
                autoindex  on;
                root /var/tftpboot;
        }

}
EOF
# server_name _ - означает обрабатывать все имена, включая обращение по "нашему" ip 192.168.0.1
# root /var/tftpboot; - берется путь из переменной TFTP_DIR, описанной в "первом" разделе
# autoindex on - требуется для _просмотра_ файлов и директорий


Дальше для тех кто хочет разместить файлы инсталляции у себя локально, то делаем что нить вроде :

# переходим в директорию tftpboot (логично хранить все относящееся к pxe в одном месте)
cd /var/tftpboot  
mkdir storage
# копируем файлы из ранее примонтированного iso образа CentOS
cp -R /mnt/tmp/* storage/
# перезапускаем и добавляем в автозагрузку nginx
service nginx restart
chkconfig nginx on
# теперь они доступны по http://192.168.0.1/storage/ 

Конфигурирование Anacond-скрипта:

 

Итак, в секции инсталляции tftp-сервера, я обещал позже объяснить что за параметр
ks=http://192.168.0.1/centos6.ks

Это файл автоматической инсталляции системы, в котором указанно будет откуда брать пакеты, как разбить жесткий диск и т.д.
Заранее извиняюсь, т.к. он у меня получился очень огромный, но т.к. данное описание довольно специфическое и по мне, так не очень полезное без данной секции, то я приведу его весь целиком да еще и с комментариями.

# указание делать все автоматом, "втихаря", "потекстовей", и т.д.
install
autostep
reboot
text
skipx
# откуда брать файлы установки, если нету локально
# то можно указать как вариант yandex зеркало,
# но учтите это намного медленнее, и разработчики
# anaconda не гарантируют что корректно будут обрабатываться
# длительные "интернет-задержки" и прочих "радостей" от сети интернет
#url --url=http://mirror.yandex.ru/centos/6.3/os/x86_64
url --url=http://192.168.0.1/storage/
lang ru_RU.UTF-8
keyboard us
# сеть автозагрузка и загрузка по dhcp, установка пароля рута
network --onboot yes --device eth0 --bootproto dhcp --noipv6
# пароль для рута, можно сгенерировать командой:
# python -c 'import crypt; print(crypt.crypt("root", "$6$sault"))'
# пароль root
rootpw  --iscrypted $6$sault$ecgltBzRSOYpf5UEWlpCtTsJMyVRIcRnqnuK4hoXxA3p/KgLYqNG.rTsH4CgUqqLTuLnCd.QDQ58anD8FU9561
# разрешить в правилах фаервола ssh
firewall --service=ssh
authconfig --enableshadow --passalgo=sha512
# отключаем selinux, чаще для стандартных задач он не нужен
selinux --disabled
timezone --utc Europe/Moscow

bootloader --location=mbr --driveorder=vda --append="crashkernel=auto rhgb quiet"
zerombr
# для kvm диск называется vda (я создаю 10гиговый lvm раздел) 
clearpart --all --drives=vda
part /boot --fstype=ext4 --size=500
part pv.253002 --grow --size=1
volgroup vg --pesize=4096 pv.253002
# тут все довольно очевидно и самочитабельно, размеры в MB
logvol / --fstype=ext4 --name=root --vgname=vg --size=1024
logvol /var --fstype=ext4 --name=var --vgname=vg --size=1024
logvol /var/log --fstype=ext4 --name=var_log --vgname=vg --size=512
logvol /usr --fstype=ext4 --name=usr --vgname=vg --size=2048
logvol /home --fstype=ext4 --name=home --vgname=vg --size=512
logvol /tmp --fstype=ext4 --name=tmp --vgname=vg --size=512
logvol swap --name=lv_swap --vgname=vg --size=2048
# указание где искать стандартный репозиторий 
repo --name="CentOS"  --baseurl=http://192.168.0.1/storage --cost=100

# только минимал
%packages --nobase
@core
%end

%pre

# пост инсталяционный скрипт, лог пишем для дебага наших скриптов
%post --log=/var/log/_anaconda-post.log
rpm -Uvh http://mirror.yandex.ru/epel/6/`uname -i`/epel-release-6-8.noarch.rpm
# обновляем систему
yum update -y
# красивое приглашение консоли
echo "" >> /etc/bashrc
echo "export PS1='\[\033[01;31m\]\H(\[\033[01;32m\]\u\[\033[01;31m\]) \[\033[00m\]\t \[\033[01;34m\]\w \[\033[00m\]- '" >> /etc/bashrc
# меняем rsyslog на syslog-ng 
yum install syslog-ng syslog-ng-libdbi -y &&
chkconfig --del rsyslog &&
service rsyslog stop &&
service syslog-ng start &&
chkconfig --add syslog-ng &&
chkconfig syslog-ng on

# добавляем в конфиг "логирование" команд
cat >> /etc/syslog-ng/syslog-ng.conf << EOF
destination d_bash { file("/var/log/bash_log"); };
filter f_bash       { program("bash_log"); };
log { source(s_sys); filter(f_bash); destination(d_bash); };
EOF

cat >> /etc/bashrc << EOF
function log2syslog
{
  declare COMMAND
  COMMAND=\$(fc -ln -0)
  logger -p local1.notice -t bash_log -i -- "\$\$ \${USER}:\${COMMAND}"
}
trap log2syslog DEBUG
EOF
service syslog-ng restart

# конфиг любимого редактора (приведен не весь)
cat >> /root/.vimrc << EOF
syntax on
set number
EOF

# ставим необходимое по, синхронизируем время
yum install ntp vim bash-completion sudo -y
ntpdate gentoo.org
chkconfig ntpd on

# организовываем хостнейм из newvirt_последняя цифра айпи адреса
NAME=newvirt_`ifconfig |grep 'inet addr'|grep  -v 127|awk '{print \$2}'|sed s/'.*\.'//`
sed s/HOSTNAME=.*/HOSTNAME=$NAME/ -i /etc/sysconfig/network

# высылаем себе письмо что виртуалка готова, в письме высылаем ip и ключ
# * подготовка
yum install expect telnet -y
IP=`ifconfig |grep 'inet addr'|grep  -v 127|awk '{print $2}'`
mkdir /root/.ssh && chmod 700 /root/.ssh
ssh-keygen -t rsa -f /root/.ssh/id_rsa -N '' -q && cd /root/.ssh
cat id_rsa.pub >> authorized_keys && rm -f id_rsa.pub && chmod 600 authorized_keys
KEY=`cat id_rsa`
rm -f id_rsa

EMAIL=fura@gmail.com

# * отсылка письма
/usr/bin/expect << EOF
set timeout 5
spawn telnet gmail-smtp-in.l.google.com 25
expect "220 mx.google.com ESMTP.*"
send "HELO mail.mywork.ru\n"
expect "250 mx.google.com at your service"
send "MAIL FROM:<admin@mywork.ru>\n"
expect "250 2.1.0 OK.*"
send "RCPT TO:<${EMAIL}>\n"
expect "250 2.1.5 OK.*"
send "DATA\n"
expect "354  Go ahead.*"
send "From: <admin@mywork.ru>
To: <${EMAIL}>
Subject: PXE Boot Success

Master, my ip is : ${IP}.

Private KEY:
${KEY}

\n"
send ".\n"
expect "250 2.0.0 OK.*"
send "QUIT\n"
exit
EOF
#конец ^_^

Заключение:

 

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



Комментариев нет:

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