I/O Scheduling 은 운영체제가 여러 프로세스로부터 I/O 요청을 받았을 때 이에 대한 우선순위를 정해서 실행시켜주는 것을 말한다.

 

일반적으로 OS 내에 있는 스케줄러는 throughput 과 latency 를 고려하여 설계되며 하드디스크 검색으로 낭비되는 시간을 최소화하고, 우선적으로 필요한 프로세스들에게 I/O 요청을 할당하는 것이 주 목표이다.

 

I/O Scheduler 의 종류로는 다음과 같은 것들이 있다.

 

- Noop Scheduler : 커널이 스케줄링을 위해 별다른 작업을 하지 않는다. SSD 또는 RAID 디스크를 사용하는 경우 스케줄러의 동작이 오히려 디스크의 성능에 부하를 줄 수 있다는 점에 착안하였다.

 

- CFQ(Completely Fair Queueing) : 기본 스케줄러로, 각 프로세스마다 Round Robin 알고리즘에 의해 스케줄링이 수행된다. 각 작업을 마친 후 일정 time slice 만큼 기다린 후 다른 프로세스로 제어를 넘긴다. Synchronous 작업이 Asynchronous 작업보다 우선순위가 높다.

 

- Deadline : I/O 대기 시간의 한계를 정해놓고 데드라인이 가까운 작업부터 제어를 할당한다. 지연에 최적화되어있으며 I/O 가 몇몇 프로세스에 집중되어 있을 때 유용하기 때문에 Database 시스템에 주로 사용된다.

 

- Anticipatory : 연속된 read 요청의 경우 미리 처리량을 예측해서 요청을 스케줄링하는 방식으로 응답시간이 중요한 경우에 유용하다. 

 



운영체제는 시스템의 Disk partition 상에 파일들을 연속적이고 일정한 규칙을 갖고 저장하는데, 이러한 파일을 관리하는 규칙을 File System이라 한다.


FileSystem 의 구조


Unix/Linux 계열의 운영체제는 Tree 형태의 계층적인 파일구조를 구성한다. 다음은 File System 을 구성하는 요소들이다.


- Super block : 슈퍼블록은 FileSystem에 의존하는 정보를 가지며 FileSystem 의 크기 등과 같은 File System 의 전체적인 정보를 포함한다.


- inode(Index node) : 아이노드(inode)는 파일의 이름을 제외한 해당 파일의 모든 정보를 갖고 있다.

갖고있는 정보로는 파일의 소유권, 권한(Permission), 실제 데이터가 있는 물리적 주소, 파일의 형태, 크기, 링크 수, 수정/사용 시간 등이 있다.

파일 이름은 inode 의 번호와 함께 directory 안에 저장된다.

각 파일들은 1개씩의 inode를 갖고 있으며, 파일 시스템 내에서 파일의 이름을 key 로 식별되는 inode 숫자를 통해 식별 가능하다. (즉, inode는 파일 시스템 내에서 유일하다.)


- data block : 데이터블록은 inode 에 포함된다. inode 는 몇개의 data block 을 포함하고 있으며, 각 데이터 블록은 파일들의 데이터를 실제로 저장하고 있다.


- Directory block : 파일 이름과 inode 번호를 저장한다.


- Indirection block : 간접 블록은 추가적인 데이터 블록을 사용하기 위한 포인터들이 할당되는 공간이다. 

실제로 inode 는 적은 수의 데이터블록을 갖고 있으며 더 많은 데이터블록이 필요할 경우 이를 동적으로 가리킬 포인터가 저장된다.


- Hole : 홀은 inode 나 간접 블록 안의 데이터 블록의 주소로 특별한 값을 저장한다. 

hole 을 파일 안에 구조화되지만 hole 을 위한 실질적인 disk 공간은 할당되지 않는다. 단지 0바이트가 파일 안에서 특정 공간을 차지하고 있다고 가정하는 것이다.


위의 개념들 중에서 중요하고도 특징적인 개념은 Inode 의 개념이다.

파일시스템은 inode 를 참조하여 파일의 정보를 다룰 수 있다.


( * 참고로 현재 파일시스템 내의 Total Block / Free Block, Total Inode / Free Inode 정보는 [stat -f "파일이름"] 명령어를 통해 조회가능하다.)


또한 위의 내용들을 자세히 이용하기 위해서는 Nix 계열의 파일시스템인 EXT에 대해서도 알아야 한다. EXT에 대해선 다음 포스팅에 추가한다.




 Linux 서버 관리를 하다가 자주 마주치는 것 중 하나가 서버의 포트 및 방화벽 문제라고 할 수 있는데 삽질하면서 알아낸 바를 정리해두었다.


CentOS, Fedora 등의 리눅스에서 포트 방화벽을 확인 하는 방법

- iptables –-list

- iptables -L(리스팅) -v(자세히)


Ubuntu 에서 포트 방화벽을 확인하는 방법

- sudo ufw status


Ubuntu 에서 포트 방화벽을 활성화 / 비활성화 하는 방법

- sudo ufw enable

- sudo ufw disable


CentOS, Fedora 등의 리눅스에서 포트를 추가하는 방법 (WhiteList)

- iptables -I INPUT 1 -p tcp –-dport 80 -j ACCEPT (80 번 Input 포트를 1번으로 추가)

- iptables -I OUTPUT 2 -p tcp –-dport 8080 -j ACCEPT (8080번 Output 포트를 2번으로 추가)


Ubuntu 에서 포트를 추가하는 방법 (WhiteList)

- sudo ufw allow <port>/<optional: protocol> (sudo ufw allow 443/tcp)


CentOS, Fedora 등의 리눅스에서 포트 WhiteList를 제거하는 방법

- iptables -D INPUT 2 (INPUT 2번째 규칙 제거)


Ubuntu 에서 포트 WhiteList를 제거하는 방법

- sudo ufw deny <port>/<optional: protocol>


Iptables 를 이용한 포트포워딩

- iptables -t nat -A PREROUTING -p tcp -m tcp –dport 80 -j REDIRECT –to-ports 8080

- iptables -t filter -A FORWARD -p tcp -m tcp –dport 80 -j ACCEPT


정확히는 삽질한 부분은 클라우드 환경에서 인스턴스의 외부 Security Group 보안설정을 고려하지 않은 채, 인스턴스의 방화벽을 직접 건드린 부분이었으나,

외부 방화벽 제어 로직 역시 다르지 않으므로 기본적인 내용은 익혀두자.



서버 인스턴스를 관리하면서 자주 사용하게 되는 몇가지 시스템 모니터링을 위한 유틸리티 들을 정리해보았다



- Top : 시스템의 전반적인 운용상황을 확인할 수 있다. CPU / 메모리 / 부하율 등을 한번에 확인할 수 있다. Top –d 2 와 같이 하면 초단위로 refresh 한다. –q로 하면 실시간으로 반영된다. 윈도우의 작업 관리자와 같은 역할을 수행한다.


- Uptime : 서버의 전체적인 부하율을 확인하고자 할 때 사용한다

그냥 uptime 만 치면 한줄로 출력이 되며 현재시간, 부팅 후 꺼지지않고 운용된 시간, 현재 시스템에 로그인한 사용자 수(/var/run/utmp참조), 1분, 5분, 15분 간 서버 시스템 부하율 을 표기한다.


- Vmstat : 현재 리눅스 자원사용률 모니터링 도구로, 이름은 Virtual Memory Statistics 이지만 가상 메모리 이외에 실행 대기 중인 프로세스 수(r), 가상 메모리 사용량(swpd), 입출력 IO, 유휴 메모리(free), 버퍼 메모리(buff), 캐시 메모리(cache), 초당 인터럽트 수(in), 초당 컨텍스트 스위칭 수(cs), 유휴시간(id), 커널모드 소비 시간(sy), 입출력대기시간(wa) 등 다양한 내용 조회 가능하다.


- Iostat : 부팅 이후 Block IO 상태를 나타낸다.


- Free : 메인 메모리 사용량을 보여준다.


- Strace : System call tracer. 리눅스 최강의 디버깅 도구. 리눅스 시스템콜 추적 도구. 프로세스 대상을 선택하면 대상에 대한 시스템콜을 추적할 수 있고 프로세스가 받는 Signal에 대한 정보도 얻을 수 있다. 

간단하게 strace ./helloWorld 와 같이 사용하면 helloWorld 프로그램을 추적하게 되고 –o trace.log 와 같이 매개변수를 넘겨주면 trace.log 파일에 추적 로그가 남게 된다. 또한 –c 옵션을 이용해 통계도 낼 수 있다. –p 옵션을 사용하면 실행중인 프로세스에 대한 추적 또한 가능하다. 


- Tcpdump : 커맨드라인 네트워크 트래픽 모니터링 툴이자 패킷 분석 툴. 

Tcpdump –I eth0 과 같이 사용하면 지정된 eth0이더넷에 대해 패킷을 뜨게 되고 –w test.log 와 같이 test.log 에 로그를 기록할 수 있다. 확인은 –r test.log 와 같은 방식으로 해야 한다. 혹은 당연히 tcpdump –I eth0 > testout.log 와 같이 리다이렉트해줘도 된다.


- Netstat : 시스템의 네트워크 연결 목록(tcp, u에, 소켓)을 보여준다. 

Tcp (t), udp(u), DNS 질의끄기(n), Listen(l), 프로세스 명 표시(p), 라우팅정보(r) 과 같은 파라미터를 –뒤에 붙여 사용한다. 

(ex) netstat -nltp


- lsb_release -a : 리눅스의 버전을 확인하는 명령어. 특히 Dependency 관리를 위해 알아볼 때 종종 사용한다.

cat /etc/issue : 리눅스의 버전을 확인하는 명령어. 몇몇 버전의 경우 /etc/issue 에 버전 정보가 포함되어 있다.

- stat : 파일 또는 파일 시스템 상태를 조회한다. 파일크기, Inode 번호, 링크 갯수, Permission, UID, GID, 접근/수정/변경 일시 확인 가능하다.

(예시)

> stat xxx.log
File: ‘xxx.log’
Size: 11008296 Blocks: 21512 IO Block: 4096 regular file
Device: -----/----- Inode: 269769074 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 500/ user) Gid: ( 500/ user)
Access: 2018-10-04 00:00:03.158986433 +0900
Modify: 2018-10-04 15:02:18.999757886 +0900
Change: 2018-10-04 15:02:18.999757886 +0900
Birth: -

> stat -f xxx.log

File: ‘xxx.log’
ID: -----------        Namelen: 255 Type: xfs
Block size: 4096 Fundamental block size: 4096
Blocks: Total: 25677313 Free: 23658809 Available: 23658809
Inodes: Total: 102759424 Free: 102490423


- du(disk usage) : directory 용량 확인. 현재 폴더 내 파일들의 용량을 확인할 수 있다.

- df : 리눅스 파일시스템 사용량 확인. 디스크 사용량 / 용량 포함.


- find : 파일 이름으로 시스템을 검색하는 명령어

 (1) find -name "파일이름"     > 파일이름에 해당하는 파일 검색

 (2) find -name "*.txt"     > 파일 확장자가 txt인 모든 파일 검색

 (3) find / -name "*.txt"     > 루트에서부터 txt 확장자를 가진 모든 파일 탐색

 (4) find / -name "code" -type d  > 디렉터리 이름이 code 인 모든 디렉토리 검색






리눅스에서 사용되는 Alias란 긴 명령어나 복잡한 명령어 등을 사용자가 알맞게 정의하여 사용할 수 있도록 저장해놓고 불러올 수 있게 하는 별칭을 정하는 기능이다.


 예를 들어 관리해야할 여러 서버가 있고, 우리는 Linux 쉘에서 login 명령어를 통해 각 서버에 접속할 수 있다고 가정해보자.

이 때 개발 서버(dev)는 login 명령어를 통해 바로 접근할 수 있지만 실제 운영 서버(real)는 보안 키워드인 -secure 를 입력해야한다고 가정해보자. 가령


login dev_001                    > 1번 개발서버에 로그인


login -secure real_001          > 1번 운영서버에 로그인


서버가 많아지고 커맨드가 다양해진다면 타이핑은 매우 불편하며 효율적이지도 않다.


이 때 alias 키워드를 쓰면 좀더 단순해질 수 있다.


Alias 키워드를 사용하면 login “SERVER명” 과 같이 긴 명령어도 login_server 와 같은 명령어로 치환할 수 있다.


 Alias 설정을 보기위해서는 alias 커맨드를 입력하면 된다.

Alias 의 추가를 위해서는 ~/.bashrc 파일을 열어서 alias 단축명=’실행할명령어’ 를 입력해주면 된다. 이 후 /.bashrc 파일의 적용을 위해서 source ~/.bashrc 를 명령어로 입력하면 된다.


위의 예시에 적용해보자.



<~/.bashrc>


alias dev_001='login dev_001'


alias real_001='login -secure real_001'



위와 같이 설정하면, 이제 쉘에서는


dev_001                            > 1번 개발 서버에 로그인


real_001                            > 1번 운영 서버에 로그인


과 같은 단순한 키워드로 커맨드 이용이 가능하다. 활용도가 무궁무진하니 자주 쓰는 명령어로 꼭 익혀두자



 Grep 은 워낙 유명한 리눅스의 패키지이며 그만큼 쓸일이 많으므로 다음의 기본 사용법 정도는 꼭 알아두도록 하자.


 Grep 명령어는 파일 전체를 뒤져서 정규표현식에 해당하는 모든 행들을 출력하는 기능을 한다.


(ex) grep nw datafile -> datafile에서 nw를 포함하는 행 검색


grep nw d* -> d로 시작하는 모든 파일에서 nw를 포함하는 행을 검색


grep <keyword> * -> 모든 파일에서 키워드를 검색


grep '^n' datafile -> n으로 시작하는 datafile 내의 모든 행을 출력


grep '4$' datafile -> 4로 끝나는 datafile 내의 모든 행을 출력


grep '[^0-9]' datafile -> datafile 내에서 숫자가 아닌 문자를 하나라도 포함하는 모든 행을 출력


grep '[a-z]{9}' datafile -> datafile 내에서 소문자가 9번 이상 반복되는 문자열을 포함하는 모든 행을 출력한다.



 grep 실행시 다음 옵션을 부여함으로써 유용하게 정보를 가공할 수도 있다.


-r(하위 디렉토리를 모두 검사)

 

-n(행 번호를 함께 출력)


-i(대소문자 미구분)


-l(행 대신 파일명만 출력)


-w(정확히 일치하는 경우만 검색)


-v(포함되지 않은 행을 출력)


주로 사용하는 건 위의 옵션들이다. 더 많은 옵션은 다음 링크를 참조하자. 예제도 아주 잘 정리되어있다.

(https://en.wikibooks.org/wiki/Grep)


(ex) grep -v 'ffl' datafile > edit

// datafile에서 ffl이 있는 행만을 추출하여 edit 파일에 씀.


(ex) grep -rl "*print$"

// 현재 폴더를 루트로 하여 서브 디렉토리를 모두 검사하여 print 로 끝나는 행을 가진 파일의 이름을 출력.


 특히 서버에서 로그 분석 작업을 할 때, Grep 은 tail 과 함께 밥먹듯이 사용한다.

어느정도 프로젝트에서 자주 사용하는 정규식 포맷을 메모하여 grep 사용 시 적용시키는게 유용하다.




 실무를 하다보면 프로젝트에 따라 배치 스크립트를 작성할 일이 종종 있다.

그럴 때 듣게 되는 Daemon Process 라는 단어가 있는데, Background Process와 유사하면서도 의미가 조금 달라 헷갈리기 쉽다.


 Daemon Process 와 Background Process 모두 사용자와 상호작용하는 Foreground가 아닌 Background에서 동작하지만 둘 사이에는 차이가 있다. 


 일반적인 데몬은 터미널을 갖지 않는다. (유저와 상호작용하지 않는다.) 정확히는 데몬은 그 자체로 Process Group Leader로 부모가 1번 pid를 갖는 init으로 세팅된다. 즉, 독자적인 Session 을 갖고있으며 Linux System 자체가 아닌 별도의 독립된 Parent process를 갖지 않는다. 리눅스의 cron, smartd 와 같은 스케줄링 & 모니터링 프로세스들은 바로 이 Daemon Process 의 형태를 갖는다.


 백그라운드 프로세스는 이와 다르게 터미널을 통해 상호작용이 가능하다. 별도의 Parent process를 가질 수 있으며 Parent process와 세션이 공유되기 때문에 Parent process가 받는 Signal 의 영향을 받는다. (부모 프로세스가 종료되면 같이 종료된다.)



 Daemon Process의 조건 3가지는 다음과 같다.

(1) Fork로 자식 프로세스 생성 후 부모 프로세스를 종료 – 자식 프로세스의 ppid(소유 프로세스)를 pid 가 1인 init으로 양도


(2) Setsid를 이용하여 새로운 세션을 만들고 생성된 자식의 pid가 세션의 제어권을 가지도록 한다. – 세션이란 프로그램 그룹의 모음인데 세션 생성시 ttv를 부여하지 않게 되면 터미널을 갖지 않는 세션이 생겨나며 세션의 리더가 된다.


(3) 프로세스의 위치를 루트로 옮겨주면 경로 작업 수행에 유리하다(선택)


 * 또한 윈도우에서는 데몬을 서비스라고 부른다.




리눅스에서 서버를 구축 시 별도의 파티션을 마운트 하는 경우가 종종 있다.


특히 운영 중이던 서버에 로그를 위한 파티션이나, Static inhouse 를 위한 독립된 저장소를 구축하는 경우가 있다.


주로 이런 리소스 들을 인프라팀에서 제공해주긴 하지만, 결국 인스턴스에 알맞게 사용하는건 개발팀의 몫이 되는데, 간단히 마운트 하는 방법을 정리해보았다.


1.      Sudo fdisk -l df 명령어를 통해서 파티션 정보를 확인한다. (타겟 /dev/xvdf)


2.      Mkfs -t (파일시스템타입) /dev/xvdf 명령어를 이용해서 마운트하고자 하는 파일 시스템을 생성 포맷한다.


3.      Sudo mount /dev/xvdf /srv : /srv 폴더에 /dev/xvdf 디스크를 마운트한다.


매우 간단하지만 리눅스의 명령어들이 흔히 그렇듯 사용하지 않으면 까먹게 된다.


자주 사용할 일은 없지만 정리해놓고 알아두도록 하자.




개인적인 목적으로 사용할 때에나 개발을 위한 더미 환경을 구축해서 사용할 때나 VirtualBox 는 좋은 도구이다.(무료이기도 하고...)


처음에 환경을 세팅할 때 잘 몰랐던 부분 중 하나인 네트워크 세팅 방법을 정리해두었다.


(1) NAT : 각 가상머신을 별도의 가상 네트워크로 할당하여 호스트를 Gateway로 한 NAT를 구성하는 방식이다. 가상 머신이 호스트와 별도의 네트워크로 묶이기 때문에 가상머신 끼리의 연결은 지원되지 않는다.


(2) Bridged Network : 호스트 네트워크를 이용한 Bridged Network를 구성한다. 호스트와 동일하게 사용할 수도 있고 혹은 별도의 네트워크 설계도 가능하다. 단, IP 구성이 원활하지 않은 경우에 제한적이다.


(3) Host Only Network : Internal network 처럼 호스트와 격리된 네트워크를 구성하지만 호스트와 통신이 지원되고 DHCP를 이용한 IP할당이 가능하다. 가상머신들과 호스트 간의 네트워킹은 가능하나 인터넷이 안되므로 NAT방식과 같이 사용된다.


이 외에도 몇가지 방식들이 더 있으나, 하위호환 되면서 유명한 3가지 방법들만 정리해두었다.


방법들이 다양하지만 관건은 독립된 가상환경의 OS를 같은 망으로 묶을 것인가 아니면 별도의 독립 망으로 연결하고 터널링을 할 것인가에 따라 분류되는 듯 하다.


이 방법들을 활용하면 VM에서 직접 인터넷에 붙이거나 아니면 호스트의 인터넷 연결을 빌려 사용하거나, 또는 설정을 하지않음으로써 Private Subnet 처럼 가상환경을 구성할 수도 있다.


필자의 경우에는 주로 더미 환경 구축에 사용하므로 Private Subnet 으로 격리시키고 이런저런 테스트를 해보는 편이다.




배치 작업을 할때, 이용할 수 있는 도구는 많지만 개인적으로 가장 손꼽는 프로그램은 Linux 에서 기본적으로 제공해주는 크론탭(Crontab) 이라고 생각한다. 사용하기도 쉽고 강력한 스케줄링 기능을 할 수 있다.


다음은 크론탭의 사용방법이다.


- crontab -e : 크론탭 편집기 실행. VI 가 기본으로 실행된다.

- crontab -i : 크론탭의 내용 조회


- 크론탭 작성 방법


*                *                    *                *                *

분(0-59)       시간(0-23)       일(1-31)       월(1-12)       요일(0-7)


- 매분 실행

* * * * * /home/script/test.sh


- 특정 시간 실행

# 매주 월요일 오전 5시에 test.sh 실행

0 5 * * 5 /home/script/test.sh


- 반복 실행

# 매일 매시간 0분, 20분, 40분에 test.sh 실행

0, 20, 40 * * * * /home/script/test.sh


- 범위 실행

# 매일 1시 10분 부터 30분까지 매분 test.sh 실행

10-30 1 * * * /home/script/test.sh


* 크론탭은 한줄에 한 명령어만 작성해야 하며 #을 통해 주석을 달 수 있다.


또한 실행하는 쉘에 Redirection (>) 을 연결함으로써 출력을 리다이렉트할 수 있으며 이를 통해 로깅이 가능하다.

+ Recent posts