리눅스 시스템의 부팅과 종료
>리눅스 시스템 부팅
* BIOS (Basic Input Output System) 시작
- 부트 순서에 따라 CD-ROM 또는 하드 디스크에서 운영체계 소프트웨어를 검색
- 하드 디스크의 경우 부트 매체에서 첫 512Byte 를 읽음 (MBR - Master Boot Record)
시스템 시동과 관련된 특수한 정보가 포함되어 있다.
* UEFI (Unified Extensible Firmware Interface)
- UEFI 기반 시스템은 부트 섹터를 사용하지 않고 대신 UEFI 펌웨어는 NVRAM (비활성 RAM)에 저장되어 있는 원하는 운영 체제에 대한 정보를 활용하는 부팅 관리자가 있다
- 컴퓨터의 기타 운영 체제용 부트 로더는 "EFI 시스템 파티션" (ESP) 에 일반 파일로 저장되며, 펌웨어는 이를 읽고 시작한다.
- 시스템은 NVRAM 에서 원하는 부트 로더의 이름을 찾거나 기본 이름 /EFI/BOOT/BOOTX64.EFI로 되돌아간다.
* Master Boot Record (MBR) - Boot Loader
- MBR의 첫번째 446 Byte에 운영체계 시동을 담당하고 있는 최소한의 시작 프로그램이 있다.
* GRUB (GRand Unified Boot Loader)
- 일반 Linux 파일 시스템을 읽을 수 있으므로 Linux 파티션에서 운영 체제 커널을 찾아서 RAM에 로드하고 시작시킨다.
- GRUB 은 boot loader 뿐만 아니라 boot manager로도 사용되므로 사용자의 기호에 따라 다양한 Linux 커널 또는 다른 운영 체제를 실행할 수 있다.
* 부팅이 가능한 CD-ROM 또는 DVD 에서 부팅
- Linux 컴퓨터를 CD로부터 부팅하려면 CD-ROM 이 하드디스크보다 펌웨어 부팅 순서에서 앞서 있어야 한다.
- BIOS 에서 CD-ROM 부팅은 하드 디스크 (또는 플로피 디스크)를 부팅하는 것과는 다르다.
"EL Torito" 표준에서 기본적으로 두가지 방법을 정의
- 부팅 가능한 플로피 디스크의 이미지를 CD-ROM 에 포함시키는 것(BIOS가 2.88MiB일 수도 있음)
- CD-ROM 에서 직접 부트하는 것으로 특수 부트 로더 (예: Linux용 ISOLINUX) 가 필요하다.
* PC 부팅
- 최초 코드인 BIOS 가 실행되고 여러 단계의 BIOS 가 있다.
- 내장 BIOS 는 마더 보드에 부착되어 있는 일부 장치, 즉 일반적으로 IDE 및 SATA 컨트롤러 (및 디스크), 네트워크 인터페이스, 전원 및 온도 측정기 및 시스템 하드웨어 등에 대해 알고 있으며 SCSI 카드는 대개 연결된 장치만 인식한다.
- BIOS 는 일반적으로 시스템이 부팅을 시도할 장치를 선택할 수 있도록 하는데, 일반적으로 DVD, USB드라이브, 하드 디스크 등과 같이 순서가 지정된 기본 목록을 설정할 수 있고, PXE를 사용한 네트워크 부팅도 일반적인 옵션이다.
- 일단 BIOS 가 부팅할 장치를 선택하면 장치의 첫 번째 블록 512바이트를 읽는다. 이 512 바이트 세그먼트를 마스터 부트 레코드 (MBR) 라고 한다.
MBR에는 2차 보도 부팅 프로그램인 "Boot Loader"를 로드할 파티션을 컴퓨터에 알려주는 프로그램이 들어있다.
- 기본 MBR에는 디스크의 첫번째 파티션에서 boot loader 를 가져오도록 컴퓨터에 지시하는 간단한 프로그램이 들어있다.
일부 시스템은 여러 운영체제 및 커널을 처리할 수 있는 보다 복잡하고 정교한 MBR을 제공하기도 한다.
- MBR이 부팅할 파티션을 선택하면 해당 파티션에 구체적인 boot loader를 로드한다. 이 로더가 커널 로딩을 담당한다.
* GRUB (GRand Unified Boot loader)
- GRUB 는 CentOS 및 Red Hat Enterprise Release 6 버전부터 시스템과 함꼐 제공되는 부트 로더
- GRUB 는 GNU 프로젝트가 개발한 것으로 Intel 프로세서가 장착된 대부분의 UNIX 및 Linux 시스템의 기본 부트 로더
- GRUB 의 역할은 사전에 취합된 목록에서 커널을 선택하고 관리자가 지정한 옵션으로 해당 커널을 로드하는 것
- 대체로 bootable 디바이스의 MBR (Master Boot Record) 에 저장되어 있다.
* GRUB 계보의 두 가지
- GRUB Legacy (Original GRUB)
모든 시스템 예제에서 사용
- GRUB2
CentOS7에 처음 도입
GRUB를 대체할 것으로 기대하고 있으나 여전히 GRUB를 사용
Config 파일의 문법이 조금 다를 뿐 기본적인 개념은 GRUB Legacy와 유사하다.
* MBR (Master Boot Loader) 와 GRUB
- Bootalbe 디스크의 파티션 확인
# fdisk -l /dev/sda
- 처음 512 Byte 내의 466 Byte에 부트 로더가 있다.
# dd if=/dev/sda of=/tmp/sda.mbr count=1 bs=512
- 부트로더 삭제
# dd if=/dev/zero of=/dev/sda count=1 bs=512
- Bootable 디스크의 파티션 정보가 없음을 확인, 재부팅하면 부팅 안됨
- MBR 복구
# dd if=/tmp/sda.mbr of=/dev/sda count=1 bs=512
- 디스크 파티션 확인
* GRUB 이해
- GRUB2 구성 파일 - /boot/grub2/grub.cfg
# grub2-mkconfig -o /boot/grub2/grub.cfg 명령어를 이용하여 생성
/etc/default/grub
/etc/grub.d/<template script files> 를 이용
# ls -l /etc/default/grub
# ls -l /etc/grub2.cfg
# ls /etc/grub.d
> 리눅스 시스템 종료
* shutdown
- 시스템을 종료하기 전에 일정 시간 대기하기
대기 시간동안 shutdown은 점차 짧은 간격으로 로그인 한 모든 사용자에게 시스템 중단 알림 메시지를 전송한다
대부분의 shutdown 버전에서는 시스템을 중지할지, 단일 사용자 모드로 전환할지 또는 재부팅할지를 지정할 수 있고, 경우에 따라 fsck할지 여부를 지정할 수 도 있다.
* shutdown 명령어 옵션
Linux /sbin/shutdown time -r -h - -f
Solaris /usr/sbin/shutdown -gsecs -i6 i0 -iS -
HP-UX /etc/shutdown secs -r -h - -
AIX /sbin/shutdown +time -r -h -m -
* shutdown -c 옵션으로 shutdown 을 취소할 수 있다.
* shutdown 관 알림 메시지
# sudo shutdown -h +15 "Going down for scheduled maintenance. Expected downtime is i hour."
# shutdown -c
- 시스템에 로그인한 사용자가 shutdown 메시지를 수신
* halt
- halt 명령은 시스템을 종료하는데 필요한 필수 작업을 수행한다.
- halt 자체로도 실행 가능하지만 shutdown -h 에 의해서도 호출된다.
- halt 는 시스템 종료에 대한 로그를 기록하고 불필요한 프로세스를 종료하며 sync 를 호출한다.
- 파일 시스템 쓰기가 완료 될 때까지 대기 한 다음 커널을 종료한다.
- -n 옵션을 사용하면 sync 를 호출하지 않는다.
* reboot
- reboot 은 halt 와 거의 동일하나 시스템 종료 대신 재부팅을 한다.
- shutdown -r 옵션이 reboot 을 호출한다.
> startup 스크립트로 작업하기
* 표준 부트 순서에서 사용자 쉘이 실행된 시점에서 init 은 시스템 시작 스크립트를 실행한다.
- startup 스크립트는 sh 또는 bash 로 해석되는 보통의 쉘 스크립트이다.
* 대부분의 시스템은 스크립트가 번호가 매겨지고 순서대로 실행된다.
- 스크립트는 /etc/init.d 에 보관되며, 링크는 /etc/rc.d/rd0.d, /etc/rc.d/rc1.d 등에 생성됨
* startup 스크립트가 하는 작업
- 표준시간대 설정
- fsck 를 이용하여 디스크 검사
- 시스템 디스크 마운트
- /tmp 디렉토리에서 이전 파일 제거
- 네트워크 인터페이스 구성
- 네트워크 서비스와 데몬 실행
> Init 프로세서와 실행 레벨 (run level)
* init 프로세서는 부팅이 끝나고 가장 먼저 실행되는 프로세스로 가장 중요한 데몬이다.
* init 프로세스는 모든 사용자 프로세스와 일부 시스템 프로세스의 조상으로 pid 가 "1"이다.
* init 프로세스는 7가지의 실행 레벨 (run level)을 정의한다.
- level 0 시스템이 완전히 종료 된다.
- levels 1 and and S 단일 사용자 모드는 나타낸다.
- levels 2 and through 5 네트워킹 기능을 지원하는 실행 레벨이다. (level 2 제외)
- level 6 재부팅 실행 단계이다.
* 일반적으로 기본 실행 레벨은 2 또는 3이고 실행 레벨 5는 X-windows 로그인시 사용된다.
* 단일 사용자 모드는 줄곧 init 실행 레벨 1이다.
- 모든 네트워크 및 원격 로그인 프로세스를 종료하고 최소한의 소프트웨어만 실행되도록 한다.
- 관리자는 시스템이 단일 사용자 모드로 부팅 될 때마다 root 암호를 묻도록 해야할 필요성이 있다.
S 실행 레벨이 탄생하여 이 문제를 해결해 준다.
* /etc/inittab 파일
- init 에게 각 run level 에서 수행할 작업을 알려준다, 즉 init 프로세서가 특정 시스템 실행 레벨을 어떻게 설정해야 하는지 설명해 준다.
# cat /etc/inittab
* 확인 방법
# runlevel &$who -r
# systemctl get-default (기본 실행 레벨 확인)
* 데비안/우분투 계열 실행 레벨
- 0 : 종료
- 1 : 단일 사용자 모드 & 2~4 : 다중 사용자 모드
- 5 : 그래픽 디스플레이 (GUI)
- 6 : Reboot
* 레드햇/centos 계열 실행 레벨
- 0 : 종료
- 1 : 단일 사용자 모드 & 2 : 다중 사용자 모드 & 3 : 완전한 사용자 모드
- 4 : Unused
- 5 : GUI 다중 사용자 모드
- 6 : Reboot
* /etc/inittab 파일
- init 에게 각 실행 레벨에서 수행할 작업을 알려준다.
- 머신이 부팅할 때 init 프로세스는 실행 레벨 0 에서 /etc/inittab 에 설정된 기본 실행 레벨로 올라간다.
- 인접한 실행 레벨 사이를 전환하기 위해 init 은 /etc/inittab 에서 해당 전환에 대해 지정된 작업을 실행하고, 시스템이 종료될 떄는 동일한 진행이 역순으로 진행된다.
* # telinit <run level> 또는 # init <run level>
- 시스템이 부팅된 후 실행 레벨을 변경
- # telinit 3 : 실행 레벨을 3으로 변경, 즉 graphic 모드에서 tty 모드로 전환
- # telinit 6 : 시스템이 재부팅 된다.
- # telinit 0 : 시스템이 종료된다.
* 기본 실행 레벨 지정하기
- # systemctl get-default
- # systemctl set-default
- # systemctl default
* Startup 스크립티
- Startup 마스터 스크립트는 etc/init.d 디렉토리에 위치
- 각 스크립트는 하나의 데몬이나 시스템의 구체적인 내용을 담당
스크립트는 start와 stop을 독립 변수로 받아서 서비스를 초기화하거나 중지한다
restart의 경우 일반적으로 stop 다음에 start를 실행하는 것과 동일하다
- 시스템 관리자는 init.d 스크립트를 실행하여 개별 서비스를 수동으로 시작하고 중지할 수 있다.
- /etc/init.d 에 있는 스크립트는 개별 서비스를 시작하고 중지할 수 있지만 init 에 의해 실행되는 마스터 제어 스크립트에는 어떤 실행 레벨을 수행하기 위해 어떤 스크립트(추가 독립변수와 함께)가 실행되어야 하는지에 대한 추가 정보를 필요로 한다.
- 시스템을 새로운 실행 레벨로 전환할 때 init.d 디렉토리를 직접 참조하지 않고 마스터 스크립트는 rc<level>.d 라는 디렉토리를 찾는다.
<level>은 입력할 실행 레벨이다.
* rc<level>.d 디렉토리
- rc<level>.d 디렉토리에는 init.d 디렉토리의 스크립트를 다시 가리키는 symbolic 링크가 있다.
링크의 이름은 S 또는 K로 시작하며 그 다음에 시퀀스 번호와 스크립트가 제어하는 서비스의 이름이 따라온다.
init 이 낮은 실행 레벨에서 높은 실행 레벨로 전환할 때는 S로 시작하는 모든 스크립트를 오름차순으로 실행한다. 이 때 스크립트 인수로 start를 갖는다.
init 이 상위 실행 레벨에서 낮은 실행 레벨로 전환할 때는 K로 시작하는 모든 스크립트를 내림차순으로 실행한다. 이 때 스크립트 인수로 stop을 갖는다.
* 시스템에 데몬을 언제 시작할지 알리기 위해서 symbolic 링크를 해당 디렉토리에 두어야 한다.
- 실행 레벨 2에서 cupsd (프린트 데몬) 를 시작하고 시스템 종료 전에 중지하려면 다음과 같은 링크가 있으면 된다.
# ln -s /etc/init.d/cups /etc/rc2.d/S80cups
실행레벨 2로 진입할 때 수행할 마지막 작업 중 하나로써 /etc/init.d/cups 시작 스크립트를 실행하고 start 인수로 스크립트를 실행하라는 의미
# ln -s /etc/init.d/cups /etc/rc0.d/K80cups
* RedHat 시스템 startup
- 각 실행 레벨에서 init 은 새로운 실행 레벨을 인수로 하여 /etc/rc.d/rc<level> 스크립트를 호출한다.
- /etc/rc.d/rc<level> 는 대개 "일반" 모드에서 제어 스크립트를 실행한다.
"확인" 모드에서도 실행될 때는 각 개별 시작 스크립트를 실행하기 전에 확인 메시지가 출력된다.
- startup 스크립트는 /var/lock/subsys 디렉토리에 잠금파일을 저장한다.
startup 스크립트와 이름이 같은 잠금 파일이 있으면 해당 서비스가 이미 실행되고 있음을 나타낸다.
startup 스크립트는 start 명령이 주어지면 잠금 파일을 작성하고 stop 을 수행할 때 제거한다.
- /etc/rc.d/rc.local 파일
startup 스크립트의 일부로 실행되는 마지막 스크립트
사이트만을 고유 옵션 또는 부팅 후 수행할 작업을 추가하기에 좋다.
> systemd
* system-v init 시스템의 대안으로 Lennart Poettering와 Kay Sievers 가 개발
* systemd 는 모든 리눅스 주요 배포판이 향후 표준 init 시스템으로 고려하고 있다.
- Debian, Fedora, RHEL, CentOS, Ubuntu, openSUSE 및 SLES
* systemd 는 서비스, 통신 채널 또는 장치와 같은 관리 대상이 될 시스템의 추상화 부분을 unit 단위로 사용한다.
- "Targets"은 System-V init의 실행 레벨 (run level) 을 대체하며 관련 unit을 수집하는 데 사용된다
* multi-user.target은 기존의 실행 레벨 3에 해당
# ls -l multi-user.target
# systemctl get-default
- "Target"은 디바이스의 가용성에 따라 필요한 소프트웨어를 시작한다.
System-v init 은 Bluetooth 하드웨어가 실제로 사용 가능한지 여부와 관계없이 Bluetooth 소프트웨어를 구성하는 즉시 시작하는 반면 systemd는 해당 디바이스가 가용할 때 시작한다.
> System-v 에서 지원되지 않는 systemd가 제공하는 기능 등
* systemd는 인식된 하드웨어에 의존하지 않고, "요청이 있을 시 (on demand)" 서비스 활성화를 지원한다.
* systemd는 서비스를 시작할 때 프로세스 환경이나 자원 제한 등을 고려하여 매우 정교한 제어가 가능
- 특정 서비스에 대해서 파일 시스템 보기를 제한하는 것
- 서비스가 개인적인 /tmp 디렉토리를 가질 수 있도록 하는 것
- 개별적 네트워크 환경을 제공하는 것
* 원하는 경우, 서비스의 로깅 출력은 systemd가 처리하고 서비스는 표준 출력 장치에 메시지를 출력
* systemd는 기본 배포와 로컬 사용자 맞춤을 깔끔하게 분리하여 구성 유지관리를 더 쉽게 한다
* systemd에는 C에서 시스템 초기화를 처리하는 여러가지 도구가 포함되어 있으며 "실행레벨 S" 스크립트가 별도로 수행해야하는 작업을 거의 수행한다.
- 이들을 사용하면 부팅 프로세스가 상당히 빨라지고 교차 배포 표준화를 가능하게 한다.
* Systemd는 System-V init 및 기타 이전 버전과 최대한의 호환성을 제공한다.
- System-V init 의 init 스크립트를 지원하거나 /etc/fstab 파일에서 파일 시스템을 마운트 한다.
> 실행 중인 systemd 와 상호작용 하기
* systemctl
- 서비스 start (systemctl start <service>) 또는 서비스 stop (systemctl stop <service>)
> Unit 파일
* systemd 의 장점은 모든 구성 파일에 대해서 통합된 파일 포맷 (Unified file format) 을 사용한다는 것
- 실행하여야할 서비스, 디바이스, 통신채널, 파일 시스템, 기타 인공물 등에 대하여 동일한 포맷 사용
- system-v 는 /etc/inittab, /etc/fstab 및 /etc/inetd.conf 등 각각의 모든 단일 파일은 다른 모든 파일과 문법적으로 다르다.
* Unit 파일 문법
- [Unit]
Unit에 대한 일반적인 정보를 포함한다.
- [Install]
Install 에 대한 구체적인 정보를 포함한다.
- $ man systemd.unit(5)
[Unit] 섹션에서 사용하는 모든 옵션 리스트가 설명되어 있다.
> Unit 파일의 예
* console-getty.service
> Unit 종류
* .service
- systemd에 의해서 제어되고 실행되는 시스템 상에 있는 프로세스
- 백그라운드에서 실행되는 프로세스도 포함한다.
- 서비스가 이름으로 호출되었으나 해당 unit 이 없으면 동일한 이름을 가진 system-v 의 스크립트를 실행
* .socket
- 클라이언트 프로그램이 서버에 접속할 때 사용할 수 있는 통신 종단점이 TCP/IP 소켓 또는 내부 소켓
* .mount
- 시스템 내의 마운트 포인트로 파일 시스템이 마운트되어야 할 디렉토리를 말한다.
- 디렉토리 경로에서 "/" 는 "-"로 대체되고 alphanumeric 문자는 hexadecimal 로 대체
- /home/lost-found -> -home-lost/x2dfound (# systemd-escape/home/lost-found)
* .target
- 시스템 부팅 중 또는 다른 시스템 상태로 전환할 때 "target" 또는 다른 장치의 동기화 지점
- System-V 의 실행레벨 (run level) 과 유사하고, .swap, .automount, .timer, .path 등이 있다.
> 의존성 (Dependencies)
* 서비스 파일 (예 : example.service) 의 [Unit] 섹션에 있는 다양한 옵션을 사용하여 명사적 의존성을 지정할 수 있습니다.
* Requires
- 기타 unit 의 목록을 지정한다.
- 현재 unit 이 활성화 되면 목록에 있는 unit 도 활성화 된다.
- 순서와는 무관하다
- Requires = network.target syslog.service
* Wants / Conflicts
- Requires 보다는 약한 형식으로 목록화된 unit 실행이 실패하더라도 프로세스 전체에는 영향이 없다.
- Requires 와는 반대로 목록에 있는 unit 는 해당 unit 가 실행될 때 종료된다.
* Before (After)
- unit 목록들의 실행순서를 정해준다.
- example.service 가 "Before=example2.service" 옵션을 포함하고 있는 경우
example2.service 가 example.service 가 실행될 때 까지 지연된다.
> systemctl 명령어 옵션
* unit 에 대한 명령어 (예)
- list-units
systemd 가 알고 있는 unit 을 보여준다.
- start/stop
매개변수 언급된 하나 이상의 unit 을 실행시키거나 중지시킨다.
- reload
매개 변수로 언급된 unit 에 대한 구성을 다시 시도한다.
백그라운드 서비스에 관하여 systemd 로 하여금 다시 구성하고자 할 경우
# systemctl daemon-reload
- restart
매개변수로 언급된 unit을 재구동 한다.
- isolate
해당 unit 을 시작시키고 다른 모든 unit 은 종료시킨다.
system-v 의 기본 실행 레벨 (run level) 변경이 해당됨
> Unit 설치
* # systemctl list-unit-files
- systemd 를 사용하여 새로운 백그라운드 서비스를 사용 가능하게 하려면 unit 파일이 필요하다.
# systemctl list-units | tail
# systemctl enable <unit>
- 시스템 부팅 시 실행되도록 하기 위해서 unit 을 "활성화" 하거나 필요 시 시작할 수 있도록 표시해둔다.
# systemctl disable <unit>
- unit 을 비활성화 시킨다.
* systemd 의 [install]
- systemd 는 특정 unit 가 multi-user.target 통합되어야 하는지를 어떻게 아는가
# systemd reenable <unit>
# systemctl disable
# systemctl enable