디지털 라이프 電子的生活 My Digital Life

PXE 서버 설정 및 활용하기

미친도사 2021. 8. 11. 15:00

업무적으로 리눅스를 설치할 일이 많은데, 반복적인 경우나 동시에 여러대 설치하는 경우에 PXE 서버를 두고 쓰고 있다.

이 전반적인 과정이 한 방에 정리된 글이 없는 것 같아 글을 써본다. 

예전에 Kickstart에 관한 글을 쓴 적이 있긴한데, 최근에 회사 팀원들과 공유하고자 썼던 글인데, 블로그에도 약간 수정하여 옮긴다.

2018.08.30 - [디지털 라이프 電子的生活 My Digital Life] - RHEL/CentOS kickstart 활용하기

 

RHEL/CentOS kickstart 활용하기

최근에 장비 설치 지원하다 보니 기술 지원팀 직원들이 RHEL 혹은 CentOS의 kickstart를 활용한 OS 설치를 안 쓰시는 것 같아 소개글을 내부적으로 공유했는데, 그 내용을 블로그에도 남겨 봅니다. kicks

crazydoc.tistory.com


1 PXE 서버란?

1.1 개요

  • OS를 설치할 때 DVD-ROM을 만들거나 USB 플래시 드라이브로 설치하는 방법이 가장 일반적이긴 하나, 네트워크 어댑터의 PXE 부트 기능을 이용하여 설치할 수도 있다.
  • 이런 PXE 부트 기능을 통해 OS 설치 환경 혹은 diskless 부트 환경을 제공하는 서버를 통상적으로 PXE 서버라 부른다.
  • 이런 경우, 다음과 같은 장점을 생각해 볼 수 있다.
    • 여러 버전의 OS 설치 환경을 만들 수 있다.
    • 네트워크 속도에 따라 다르겠지만, 1GbE 환경만 해도 USB 플래시로 설치하는 것보다 빠르다.
    • 동시에 여러 시스템에 OS를 설치할 수 있다.
    • Kickstart 기능을 통해 설치 과정을 완전 자동화할 수 있고, 커스터마이징할 수 있다.

 

1.2 네트워크 구성 예시 (현재 구현된 환경)

 
1.3 서비스 진행 순서 (설치할 타겟에서의 액션 기준)

  • PXE로 네트워크 부팅 시도
  • DHCP 서비스를 통해 타겟에 대한 IP 할당 받은 후에 PXE 부트 메뉴 화면에 나옴
  • PXE 부트 메뉴에서 설치할 OS 선택
  • TFTP 서비스를 통해 OS의 설치용 커널 로딩
  • 커널 로딩 이후 NFS를 통해 설치 패키지 로드하고 설치 과정 진행 (이후 일반 USB나 DVD-ROM 설치와 동일) 


2 PXE 서버 구성하기

2.1 PXE 서버의 서비스의 조합

  • DHCP 서버
  • TFTP 서비스
  • NFS 혹은 HTTP

 

2.2 서비스 설정하는 방법은 RedHat 사이트의 문서를 참고하면 된다.

https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/installation_guide/chap-installation-server-setup

 

Chapter 24. Preparing for a Network Installation Red Hat Enterprise Linux 7 | Red Hat Customer Portal

The Red Hat Customer Portal delivers the knowledge, expertise, and guidance available through your Red Hat subscription.

access.redhat.com

  • 현재 사용 중인 설정을 기준으로 보완 설명한다.

 

2.3 기본 설치 패키지 (RHEL/CentOS 기준)

  • dhcp
  • tftp-server
  • nfs-utils

 

2.4 /etc/dhcp/dhcpd.conf  

#
# DHCP Server Configuration file.
#   see /usr/share/doc/dhcp*/dhcpd.conf.example
#   see dhcpd.conf(5) man page
#

option space pxelinux;
option pxelinux.magic code 208 = string;
option pxelinux.configfile code 209 = text;
option pxelinux.pathprefix code 210 = text;
option pxelinux.reboottime code 211 = unsigned integer 32;
option architecture-type code 93 = unsigned integer 16;

default-lease-time      1800; # 30 min
max-lease-time           3600; # 1 hour

subnet 192.168.200.0 netmask 255.255.255.0 {  
# 타겟 서버가 할당 받을 IP 대역 설정
        allow unknown-clients;
        range 192.168.200.101 192.168.200.200; 
# 타겟 서버의 IP 범위 (192.168.200.101~200)

        class "pxeclients" {
          match if substring (option vendor-class-identifier, 0, 9) = "PXEClient";
          next-server 192.168.200.254;  
# TFTP-SERVER의 IP. PXE 서버에 구현할 것이니, PXE 서버 IP를 적는다

          if option architecture-type = 00:07 {
            filename "shim.efi";
            } else {
            filename "pxelinux/pxelinux.0";
          }
        }
}

 

2.5 /etc/xinetd.d/tftp

# default: off
# description: The tftp server serves files using the trivial file transfer \
#       protocol.  The tftp protocol is often used to boot diskless \
#       workstations, download configuration files to network-aware printers, \
#       and to start the installation process for some operating systems.
service tftp
{
        socket_type             = dgram
        protocol                = udp
        wait                    = yes
        user                    = root
        server                  = /usr/sbin/in.tftpd
        server_args             = -s /var/lib/tftpboot
        disable                 = no   
## 기본적으로 yes로 되어 있는데, no로 설정하여 활성화
        per_source              = 11
        cps                     = 100 2
        flags                   = IPv4
}
  • TFTP 설정 파일에 언급된 /var/lib/tftpboot 위치가 TFTP 관련한 기본 디렉토리가 된다. dhcpd.conf에 언급된 shim.efi가 이 위치에 있어야 한다. shim.efi 파일은 위의 RedHat 문서를 참고하여 추출하여 사용한다.

 

2.6 /etc/exports

  • 네트워크로 설치할 OS의 설치 파일들이 저장되어 있는 위치들. 복수 지정 가능
/nfs/centos/c74A        *(ro)
  • 해당 위치에 ISO 파일을 압축을 풀어서 복사해 넣어도 되고, 해당 위치에 ISO 파일을 직접 마운트하여도 된다.

 

2.7 해당 서비스들을 시작하면 기본 준비는 된 것이다.

# systemctl restart dhcpd
# systemctl restart tftp
# systemctl restart nfs

3 설치할 OS 추가하기

예시로 CentOS 7.9를 PXE 서버에 구성해 본다.

3.1 준비한 ISO 파일을 특정 위치에 mount한다

# mkdir /nfs/centos/c79A
# mount -o loop CentOS-7-x86_64-DVD-2009.iso /nfs/centos/c79A
  • 이 설정을 매번 이용할 것이라면 /etc/fstab에 등록하면 된다

 

3.2 해당 디렉토리를 /etc/exports에 등록한다.

/nfs/centos/c74A        *(ro)
/nfs/centos/c79A        *(ro)

 

3.3 설치할 OS의 설치용 커널을 TFTP 디렉토리에 복사한다.

# mkdir /var/lib/tftpboot/c79A
# cp /nfs/centos/c79A/images/pxeboot/* /var/lib/tftpboot/c79A

 

3.4 부트 메뉴에 해당 OS를 추가한다.

  • /var/lib/tftpboot/grub.conf
menuentry 'CentOS 7.9 x86-64' {
  echo "Loading vmlinuz"
  linuxefi c79A/vmlinuz ip=dhcp inst.repo=nfs:192.168.200.254:/nfs/centos/c79A
  echo "Loading initrd.img"
  initrdefi c79A/initrd.img
  echo "Booting installation kernel"
}
  • linuxefi 행의 inst.repo=nfs:에는 PXE 서버에서 설치파일이 있는 NFS export 정보를 적으면 된다
  • 여러 OS의 경우에는 menuentry { … }만 계속 추가하면 된다.
  • 만약, 부팅 시에 적용할 커널 옵션이 있다면 linuxefi 뒤에 추가하면 된다.
menuentry 'CentOS 7.9 x86-64' {
  echo "Loading vmlinuz"
  linuxefi c79A/vmlinuz ip=dhcp inst.repo=nfs:192.168.200.254:/nfs/centos/c79A console=tty0 console=ttyS1,115200n8
  echo "Loading initrd.img"
  initrdefi c79A/initrd.img
  echo "Booting installation kernel"
}

 

3.5 여기까지 했으면 해당 서비스를 재시작하여서 변경사항을 반영한다.

# systemctl restart tftp
# systemctl restart nfs


4 Kickstart로 설치 자동화하기

4.1 Kickstart를 통해 설치 과정을 자동화할 수 있는데, 제일 쉬운 방법은 기존에 설치된 OS의 /root에 있는 anaconda-ks.cfg를 이용해서 설정을 추가하는 것이다. 이 파일을 NFS 접근이 가능한 디렉토리에 복사해 넣고 적당히 이름을 바꾼다. 예시에서는 /nfs/ks-centos79A.cfg로 설명하겠다.

 

4.2 system-config-kickstart로 기본 설정하기

  • PXE 서버의 GUI 환경에서 system-config-kickstart를 실행해서 /nfs/ks-centos79A.cfg를 불러들인다. 이후에 적당한 설정을 바꾼다.
  • Basic Configuration: 기본적인 설정을 입력한다. 암호를 입력해도 kickstart 파일엔 암호화되어 입력되어서 노출 우려는 없다. 여기에서는 아래 Advanced Configuration의 두 항목 중에 Reboot system after installation을 해 두면 설치가 끝나면 자동적으로 재부팅까지 한다.

 

  • Installation Method: Kickstart를 사용할 환경을 입력한다. CD-ROM으로 하면 USB 부팅에 사용할 수도 있다.

 

  • Boot Loader Options: UEFI 모드에서는 별 의미 없긴 하지만 커널 옵션을 추가하고 싶으면 여기에 넣어 주면 된다.

 

  • Partition Information: 파티션 설정에 대한 부분이다. Layout 부분에 원하는 파티션 구성을 넣으면 되는데, 자세한 것은 아래에 있는 Kickstart Syntax Reference를 참고해서 kickstart 파일에 수동으로 입력하는 것도 좋다.

 

  • Network Configuration: 동일한 서버에 여러 네트워크 인터페이스가 있다면 미리 설정할 수 있다. 

 

  • Authentication: 필요에 따라 설정해서 쓰면 될 듯. 보통은 안 건드린다.

 

  • Firewall Configuration: 설치 후에 SELinux를 비활성화시키거나, 방화벽을 미리 설정할 수 있다.

 

  • Display Configuration: 설치하고 나서 라이선스 동의 등의 초기 설정 화면 나오는 것을 끌 수 있다.

 

  •  Package Selection: 설치할 패키지를 설정할 수 있는 부분인데, GUI 툴에서는 안 된다. 그냥 수동으로 지정할 수 있다.

 

  • Pre-Installation Script: OS를 설치하기 전에 미리 작업할 게 있으면 여기에 기록하면 된다는데, 쓸 일 없다

 

  • Post-Installation Script: OS를 설치를 마치고, 미리 뭔가 시스템에 설정해야 하는 게 있으면 여기에 적어두면 편하다. 예제에선 GUI로 부팅하는 것을 Text로 부팅하게 하는 명령어를 넣어 놨는데, 설치 후에 반복적으로 설정해야 하는 것이 있다면 여기에 넣어두면 설치 후 작업을 줄일 수 있다.


4.3 실제 Kickstart 예제

# Use NFS installation media
nfs --server=192.168.200.254 --dir=/nfs/centos/c78A
#repo --name="CentOS"  --baseurl=nfs:192.168.200.254:/nfs/centos/c78A --cost=100
# System services
services --enabled="chronyd"
ignoredisk --only-use=sda
# Firewall configuration
firewall --disabled
# Network information
network  --bootproto=dhcp --device=eno1
network  --bootproto=dhcp --device=eno2
network  --bootproto=dhcp --device=ib0
network  --bootproto=dhcp --device=None
# Reboot after installation
reboot
# System timezone
timezone Asia/Seoul --ntpservers=tenthcircle.net,108.61.73.243
# System bootloader configuration
bootloader --append="crashkernel=auto console=tty0 console=ttyS1,115200 rd.driver.blacklist=nouveau nouveau.modeset=0" --location=mbr --boot-drive=sda
# Clear the Master Boot Record
zerombr
# Partition clearing information
#clearpart --all --initlabel --drives=sda
clearpart --all --initlabel
autopart --type=lvm

%packages
@base
@core
@development
chrony
kexec-tools
ipmitool
mc
minicom
screen
smartmontools
telnet
tree
vim
python3
@infiniband
opensm
%end

%post
systemctl set-default multi-user.target
%end

 

4.4 /var/lib/tftpboot/grub.conf에 추가하기

  • PXE 부트 메뉴에 inst.ks=라는 옵션을 추가하면 된다. 이런 식으로 필요한 설치 옵션을 계속 추가할 수 있다.
menuentry 'Kickstrt: CentOS 7.6 x86-64 for MGMT' {
  echo "Loading vmlinuz"
  linuxefi pxelinux/c76A/vmlinuz ip=dhcp inst.repo=nfs:192.168.200.254:/nfs/centos/c76A inst.ks=nfs:192.168.200.254:/nfs/ks-mgmt.cfg
  echo "Loading initrd.img"
  initrdefi pxelinux/c76A/initrd.img
  echo "Booting installation kernel"
}
  • 만약 해당 서버에 IPMI SOL로 접속해서 설치하고 있다면, 기본적인 grub 옵션에서는 설치 과정을 SOL 화면에서 볼 수 없다. 이 경우 console=ttyS1,115200n8 (ttyS1: BMC의 SOL이 serial port이 COM2에 baud rate가 115200bps인 경우)를 linuxefi 행 뒤에 추가하면 설치과정을 리다이렉트된 SOL 화면에서 볼 수 있다.


4.5 Kickstart Syntax Reference
https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/installation_guide/sect-kickstart-syntax

 

27.3. Kickstart Syntax Reference Red Hat Enterprise Linux 7 | Red Hat Customer Portal

The Red Hat Customer Portal delivers the knowledge, expertise, and guidance available through your Red Hat subscription.

access.redhat.com

 

4.6 현재 구성된 PXE Boot Menu

 

5 Diskless Boot Client 구성하기

5.1 기본 요구 패키지 설치

# yum -y install dracut-network nfs-utils

 

5.2 OS 패키지 설치

# mkdir -p /nfs/diskless/centos7/root
# yum groups install “Minimal Install” --releasever=7 --installroot=/nfs/diskless/centos7/root

 

5.3 Diskless client에 암호 설정하기

# python -c 'import crypt,getpass; \
print(crypt.crypt(getpass.getpass(), \
crypt.mksalt(crypt.METHOD_SHA512)))'
Password:
$6$EC1T.oKN5f3seb20$y1WlMQ7Ih424OwOn.....

 

5.4 Password: 프롬프트에 diskless client에 사용할 암호를 입력하면 암호화된 코드가 잔뜩 나온다. 이것을 diskless image의 shadow 파일에 넣어준다. 이 부분에 오류가 있으면 diskless로 부팅하고 나서 root로 로그인할 수 없으니 조심해서 입력한다.

# vi /nfs/diskless/centos7/root/etc/shadow
root:$6$EC1T.oKN5f3seb20$y1WlMQ7Ih424OwOn.....:16372:0:99999:7:::

 

5.5 Diskless client에 파일 시스템 정의하기

# vi /nfs/diskless/c79A/root/etc/fstab
none    /tmp         tmpfs   defaults   0 0
tmpfs   /dev/shm    tmpfs   defaults   0 0
sysfs   /sys         sysfs   defaults   0 0
proc    /proc        proc    defaults   0 0

 

5.6 Diskless client에 파일 시스템 정의하기

# vi /nfs/diskless/c79A/root/etc/fstab
none    /tmp         tmpfs   defaults   0 0
tmpfs   /dev/shm    tmpfs   defaults   0 0
sysfs   /sys         sysfs   defaults   0 0
proc    /proc        proc    defaults   0 0

 

5.7 PXE 부팅을 위한 부팅 커널 다운로드

# wget -P /var/lib/tftpboot/centos7/ \
http://mirror.centos.org/centos/7/os/x86_64/images/pxeboot/vmlinuz \
http://mirror.centos.org/centos/7/os/x86_64/images/pxeboot/initrd.img

 

5.8 만약 특정 버전의 부팅 커널이라면 3장의 PXE 설치용 커널을 그대로 이용해도 된다. 다만, 현재 설정된 yum repository 설정에 따라 5.3에서 설치된 패키지의 OS 버전과 부팅한 커널의 OS 버전의 차이가 있을 수는 있다.

 

5.9 grub.cfg에 메뉴 추가

  • 현재 구성된 /var/lib/tftpboot/grub.conf에 새로 구성한 메뉴를 추가한다. 예시에 있는 rd.driver.blacklist=nouveau 및 nouveau.modeset=0은 NVIDIA GPU 드라이버 설치를 위한 부가 옵션이다. 해당 없는 경우 생략 가능하다
menuentry 'Diskless: CentOS 7' {
  echo "Loading vmlinuz"
  linuxefi centos7/vmlinuz root=nfs:192.168.200.254:/nfs/diskless/centos7/root rw selinux=0 ksdevice= rd.driver.blacklist=nouveau nouveau.modeset=0
  echo "Loading initrd.img"
  initrdefi centos7/initrd.img
}

 

5.10 grub.cfg에 메뉴 추가

  • 현재 구성된 /etc/exports에 새로 구성한 디렉토리를 추가한다. 예시엔 두 줄로 표현되었지만 한 줄이어야 한다. 192.168.200.0/24는 현재 구성한 네트워크 대역으로 적절히 바꾸면 된다.
# vi /etc/exports
/nfs/diskless/centos7/root 192.168.200.0/24(rw,no_root_squash,no_subtree_check,fsid=root,sync)
# systemctl restart nfs



6 기타

  • 네트워크 설치에 사용할 PXE 부트 이미지(vmlinuz, initrd)는 같은 버전이라고 하더라도 DVD 이미지와 Everything 이미지의 PXE 부트 이미지가 다르다.
  • PXE diskless client 구성시, 특정 버전을 설치하고자 한다면, PXE 서버 측의 yum repository를 해당 버전용으로 만들어야 한다. (임시 local repository 구성 등 방법 가능)
반응형