세미나 리눅스 서버 - lubang/calimap GitHub Wiki
본 글은 리눅스 기반으로 웹 서버를 구축하는 전반적인 과정을 정리해보았다. 어디까지나 Node 기반의 웹 어플리케이션을 돌리기 위한 환경이다. 밤 중에 정신없이 정리한 글이지만 그래도 혹시나 도움이 될지 몰라 저장한다.
약간 뒤죽박죽이긴 하지만 다음의 내용들이 정리되어 있다.
- 리눅스란?
- 리눅스 명령어
- 리눅스에 웹 서버 환경을 위한 구축
본 문서는 Linux의 설치와 개발을 위한 환경설정 및 명령어들을 설명한다. 리눅스를 처음 접해보는 사람을 대상으로 정리한 글로 최종 목표는 Web Service를 제공하는 리눅스 운영환경이다.
리눅스(Linux)는 컴퓨터 운영 체제의 하나이며, 그 커널을 뜻하기도 한다. 리눅스는 자유 소프트웨어와 오픈 소스 개발의 가장 유명한 표본으로 들 수 있다. 리눅스는 다중 사용자, 다중 작업(멀티태스킹), 다중 스레드를 지원하는 네트워크 운영 체제(NOS)이다.
엄밀하게 따지면 이 ‘리눅스’라는 용어는 리눅스 커널만을 뜻하지만, 리눅스 커널과 GNU 프로젝트의 라이브러리와 도구들이 포함된, 전체 운영 체제(GNU/리눅스라고도 알려진)를 나타내는 말로 흔히 쓰인다. 리눅스 배포판은 핵심 시스템 외에 대다수 소프트웨어를 포함한다. 현재 200여 종류가 넘는 배포판이 존재한다.
초기에 리눅스는 개개인의 애호자들이 광범위하게 개발하였다. 이후 리눅스는 IBM, HP와 같은 거대 IT 기업의 후원을 받으며, 서버 분야에서 유닉스와 마이크로소프트 윈도 운영 체제의 대안으로 자리잡았다.
리눅스는 데스크톱 컴퓨터를 위한 운영 체제로서도 인기가 늘어가고 있다. 지지자와 분석자들은 이와 같은 성공을 벤더 독립성과 적은 개발비, 보안성과 안전성에서 기인한다고 분석한다.
리눅스는 처음에 인텔 386 마이크로프로세서를 위해 개발되었으나 현재는 다양한 컴퓨터 아키텍처를 지원한다. 리눅스는 개인용 컴퓨터에서부터 슈퍼컴퓨터는 물론 휴대 전화, 스마트 TV, 개인용 비디오 레코더와 같은 임베디드 시스템까지 광범위하게 이용되고 있다.
위의 글은 위키백가에 정의된 리눅스의 설명이다. 여기서 가장 중요한 정보는 리눅스는 운영체제이며 리눅스는 커널과 GNU 프로젝트 라이브러리, 도구로 구성된다는 점이다. 리눅스를 사용하는 가장 큰 이유는 장기 운영 시의 안정성과 편리한 관리가 제공된다는 점이다.
리눅스의 안정성은 검증된 버전의 커널로 인해 제공된다. 리눅스는 LTS(Long-term support)와 일반 개발 버전으로 분리되어 배포된다. LTS의 경우, 최신 기능이 늦게 반영되나 안정적으로 검증된 기능들이 반영되는 버전으로 서버에 설치하기 용이하다. 개발 버전은 새로운 기술을 적용하거나 개발하기 위한 개발 환경에 적합하다. LTS와 개발 버전은 리눅스 벤더(CentOS, Redhat, Ubuntu)에 따라 기준이 정의되어 배포된다.
본 글에서 설명되는 리눅스는 CentOS 7.0을 기준으로 설명한다. Redhat Linux는 리눅스의 효율적인 사용을 위해서 유/무선 지원을 제공한다. 이러한 기능 및 지원을 받기 위해서 라이센스 비용을 지불하고 사용한다. 만약 이러한 유/무선의 지원을 받지 않는다는 CentOS를 이용하는 것이 효율적이다. CentOS는 Redhat의 리눅스 코드를 Open Source에 근간하여 배포되는 버전으로 동일한 기능과 사용법을 제공한다.
리눅스를 설치하는 방법은 다음과 같이 3개의 방법이 있다.
항목 | HW 설치 | 가상화 설치(Virtual Box) | 가상화 설치(Docker) |
---|---|---|---|
설명 | 일반적인 설치 방법 | Virtual Box에 가상화 이미지로 설치 | Docker를 이용한 가상화 설치 |
성능 | 100%(기준) | 80% | 95% |
난이도 | 100%(기준) | 110% | 130% |
장점 | 지금까지 설치했던 방식(익숙한 인터페이스) | 가상화를 통한 이중화, 확장을 제공 | 가상화 이미지를 이용한 설치 |
단점 | 백업 및 이중화를 위한 고민이 필요 | 가상화를 이용한 Snapshot 관리(이중화 제공, 안정성의 증가) | HW 설치와 유사한 성능에 가상화를 이용한 편리한 관리 |
위와 같이 다양한 설치 방법이 있고 운영자에게 따라 이러한 방법들을 자유롭게 적용할 수 있다. 실질적인 운영을 생각한다면 HW 설치 & 가상화 설치(Docker) 방법이 유용하다. 특히 Docker의 경우, 빠른 속도로 개선이 되고 있으며 운영체제 및 HW의 지원을 통해서 리눅스를 직접 HW 설치하는 것과 성능 차이가 거의 없어지고 있다.
HW 직접 설치하는 방법은 매우 간단하다. 리눅스를 배포 사이트에서 다운로드 받아서 설치한다. 최근에 배포되는 리눅스(CentOS, Ubuntu)는 GUI 설치환경을 제공하기 때문에 쉽게 설치할 수 있다. Virtual Box에 설치하는 방법은 가상화 이미지만 만든 뒤, HW 설치와 동일하다.
- https://www.centos.org/download/ 에 접속하여 최신 CentOS ISO 파일을 다운로드
- DVD(혹은 USB)에 ISO 설치 패키지를 해제
- DVD(혹은 USB)로 부팅하여 GUI Guide에 따라서 CentOS 설치
Docker를 이용한 리눅스 설치는 HW & Virtual Box를 이용한 것과는 다른 방식으로 진행된다. 그 이유는 다음과 같은 Docker의 특성으로 인해 생겨난다.
도커(Docker)는 2013년에 등장한 새로운 컨테이너 기반 가상화 도구이다. 도커는 계층화된 파일시스템(AUFS, BTRFS 등)을 사용해 가상화된 컨테이너의 변경사항을 모두 추적하고 관리한다. 이를 통해서 컨테이너의 특정 상태를 항상 보존해두고, 필요할 때 언제 어디서나(단, Docker가 설치만 되어있다면) 이를 실행할 수 있도록 도와주는 도구이다.
도커는 단순한 가상 머신을 넘어서 어느 플랫폼에서나 재현가능한 어플리케이션 컨테이너를 만들어주는 걸 목표로 한다. LXC(리눅스 컨테이너)라는 독특한 개념에서 출발하는 Docker의 가상화는 기존에 운영체제를 통째로 가상화하는 것과는 접근 자체가 다르다. 가상 머신이라고 하기에는 격리된 환경을 만들어주는 도구에 더 가깝다. 즉, 컨테이너만 받으면 리눅스 환경을 독립적으로 구성할 수 있는 것이다.
$ docker pull centos
$ docker run -rm -i -t centos:7.0 /bin/bash
위의 명령어는 CentOS 7.0을 설치하는 방법이다. 대부분의 OS, 프레임워크는 Docker 컨테이너 형태로 자신들의 제품을 배포한다. 이러한 경우에는 docker pull 명령을 이용하면 해당 컨테이너를 다운로드 받을 수 있다. 다운로드 된 컨테이너는 docker run 명령어를 이용하여 실행한다. 위의 명령어는 docker 컨테이너를 다운로드 하고 실행한다.
Docker에 대한 상세한 내용은 http://pyrasis.com/private/2014/11/30/publish-docker-for-the-really-impatient-book 사이트에 공개된 "가장 빨리 만나는 도커(Docker) 출간 및 원고"를 참고한다.
설치를 완료하면 다음과 같은 폴더가 생성된다. 각 폴더 이름과 의미는 다음과 같다.
폴더 | 설명 |
---|---|
/bin | 기본 명령어가 위치 |
/boot | 커널이미지가 존재 |
/dev | 장치를 사용할때 필요한 특수파일이 위치 (hda,hdb,hdc,hdd:하드,CDROM fd0:플로피 ttyS0,ttyS1..:com포트 sda,sdb..:스카시장치 lp0:프린터) |
/etc | 애플리케이션 및 서버 프로그램의 환경설정에 필요한 설정파일 저장 |
/usr | 리눅스 바이너리 프로그램을 설치하는 곳, 패키지 설치시 대부분 이곳에 저장 |
/home | 각 계정의 이용자가 사용하는 공간 |
/lib | 부팅과 시스템 운영에 필요한 공유라이브러리 및 커널 모듈저장 |
/lost+found | 파일시스템이 이상일 있을때 구동되는 fsck 명령에 의해 사용됨 (평소에 빈폴더임) |
/mnt | CDROM,플로피등의 장치의 마운트 포인트를 제공함 |
/opt | 덩치가 너무 큰 몇몇 리눅스 패키지를 설치할때 사용함 |
/proc | 가상파일 시스템으로 프로세스와 시스템 정보를 제공. 파일명으로 존재하는 디렉토리는 커널정보를 숫자로 존재하는 디렉토리는 현재 실행되고 있는 프로세스의 정보를 담고 있음. |
/root | root의 홈디렉토리. 가능한 많은 데이터를 저장하지 않는 것이 좋음 |
/sbin | 시스템 운영에 사용되는 명령어가 들어있음 |
/chroot | 프로그램을 감옥환경에서 돌릴때 루트공간 |
/chache | 플락시 서버 돌릴때 필요한 공간 |
/var | 시스템의 로그파일이 저장되는 곳, 가변자료들이 저장, 로그, 스풀, mysql db등 |
/tmp | 템프파일,시스템재구동시 모두 삭제됨, 프로세스 진행중 필요에 의해 임시로 저장 |
리눅스는 GUI를 제공하지만 아직까지는 다양한 Command 도구와 명령어들이 강력하다. 특히 프로그램 의존성과 설치관리를 효과적으로 제공한다. 이는 개발 생산성 및 시스템 안정성에 큰 영향을 준다. 이러한 리눅스의 패키지 관리 시스템을 영향을 받아 개발 언어에도 의존성 관리 도구(maven, sbt, npm 등)을 기반으로 구성된다.
본 절에서는 프로그램 구현 시 가장 밀접하게 관련된 패키지 설치 관리 및 시스템 관리, 파일 검색 관련 명령 그리고 자주 사용되는 명령어를 정리한다.
CentOS의 패키지 의존성 관리는 yum 이라는 프로그램을 통해 이루어진다. yum은 CentOS 설치 시 자동으로 설치된다. yum은 Yellow dog Update으로 불리고 RPM(Redhat Package Manager)의 단점을 극복하기 위해 만들어졌다. RPM의 경우, 의존성을 가진 패키지가 설치되지 않은 경우 설치를 정상적으로 완료하지 못하는 문제가 있었다. 이러한 문제를 해결하기 위해서 yum은 패키지 저장소를 관리하고 특정 패키지를 설치 시 필요한 모든 의존 패키지를 검색하여 함께 설치한다.
$ yum install 패키지명
위의 명령을 통해서 설치를 수행한다.
$ yum update -y
설치된 패키지 중 업데이트가 필요한 경우에는 yum -y update 명령을 이용하여 모든 패키지를 업데이트 한다. CentOS를 처음 설치한 뒤에는 위와 같이 패키지를 최신 버전으로 업데이트 한다.
$ yum remove 패키지명
삭제는 패키지명을 위와 같이 입력하여 삭제한다.
위와 같이 yum을 사용하는 경우는 온라인(인터넷 연결)이 되는 상태이다. 하지만 프로젝트를 수행할 때는 대부분 해당 기간의 보안 규정 상 인터넷이 안되는 경우가 많다. 이러한 경우에는 RPM을 이용하여 설치해야 한다. RPM은 해당 라이브러리를 배포하는 사이트에서 다운로드 받을 수 있다.
$ rpm -ivh 패키지명
위와 같이 패키지를 설치할 수 있고 삭제는 다음과 같다.
$ rpm -ev 패키지명
기상청, 항우연 프로그램 구현 시 외부 패키지를 사용하는 경우에는 RPM 설치 방법을 반드시 오프라인 상에서 수행하여 인터넷이 되지 않는 경우에도 배포할 수 있는 환경을 고려해야 한다.
시스템 컨트롤은 프로그램을 서비스로 등록하여 시스템 시작 시 자동으로 시작되도록 설정하는 방법이다. CentOS 6.0의 경우에는 'service start 데몬명'의 형식으로 제공되었는데 CentOS 7.0부터는 systemctl 로 변경되었다. 다음은 프로그램 구현 혹은 리눅스 상태 확인을 위해서 자주 사용되는 System Control 명령이다.
$ sudo systemctl status network // 네트워크 상태정보 보기
$ sudo systemctl restart network // 네트워크 재시작
Crontab은 리눅스의 스케줄 관리 프로그램으로 정의된 스케줄 시점에 스크립트 혹은 데몬을 실행하는 기능을 제공한다.
$ systemctl start/stop/status crond // 크론탭 실행/중단/상태 보기
위와 같이 크론탭을 실행 관리를 할 수 있다. 크론탭을 멈춘 뒤 아래와 같이 크론탭 설정 파일을 수정하여 주기적으로 수행하는 일들을 정의할 수 있다.
$ vi /etc/crontab
Minutes | Hour | Day of Month | Month of Year | Week Day | Command |
---|---|---|---|---|---|
(0-59) | (0-23) | (1-31) | (1/jan-12/dec) | (0-6/sun-sat) | Command/script |
크론탭은 위와 같이 구성되고 실질적으로 04:30분에 스크립트를 실행하는 구문은 다음과 같다.
30 4 * * * /home/user/script.sh
리눅스에서 파일을 검색하는 명령어는 find 이다. find 명령어와 다양한 명령어들을 조합하여 다음과 같이 검색을 수행할 수 있다.
$ find -name '*.pl' // pl 확장자를 가진 파일 찾기
$ find / -name '*.pl' // 전체 하드에서 pl 확장자를 가진 파일 찾기
$ find / -name 'et*' -type d // 전체 하드에서 디렉토리 이름이 et로 시작하는 디렉토리 찾기
리눅스를 사용하기 위해서 자주 사용되는 명령어가 있다. 자주 사용되는 명령어는 다음과 같다.
명령어 | 설명 |
---|---|
ll | 전체폴더구조 보기 |
ls | 폴더구조 간단히 보기 |
ls -al | 숨긴파일 까지 다 보기 |
chmod 755 [디렉토리] | 파일권한변경 (내꺼, 같은그룹, 전체) |
chown -R ohhappy.wheel /home/ohhappy/* | /home/ohhappy하위의 모든 파일 디렉토리의 소유자를 ohhappy로 그룹을 wheel로 변경 |
more [파일명] | 파일내용을 페이지단위로 출력 (space:다음페이지, b:이전페이지) |
top | 시스템 프로세스 및 메모리 및 CPU 사용량 |
free -m | 메모리 보여줌(-m 메가단위, -k kb단위) |
df -h | 마운트되어있는 디스크 사용량 |
netstat -tu | 시스템에 연결된 소켓정보 |
ifconfig | 네트웍 장치설정 정보 |
ps -[옵션] | 현재 시스템에서 구동중인 프로세스 상태확인 (-a:전체사용자, -l:자세히보기, -x:제어터미널이 없는 프로세스, -f:pstree명령어와 같은 프리구조로 출력) (상태값: D:구동일시중지중, R:구동중, S:쉬는중, T:구동정지중, Z:좀비프로세스, W:메모리를 안쓰는 스와핑상태) |
pstree | 구동중인 프로세스를 투리구조로 보여줌 |
kill -9 [프로세스번호] | 프로세스 강제종료 |
killall -9 [프로세스이름] | 프로세스 강제종료 |
shutdown -h now | 시스템 종료 (-k : 메시지만전달, -r : 재부팅, -h : 셧다운후 종료 -c:셧다운중지) |
운영 환경에서 가장 중요한 것은 보안이다. 방화벽을 통해서 특정 IP, Port만을 허용하여 안정적인 네트워크 통신만을 이루어지게 설정한다.
방화벽 포트를 여는 방법은 다음과 같다.
$ firewall-cmd --permanent --add-port=5432/tcp
$ firewall-cmd --permanent --add-port=9091/tcp
$ firewall-cmd --permanent --add-port=9092/tcp
$ firewall-cmd --permanent --add-port=9093/tcp
$ firewall-cmd --permanent --add-port=9094/tcp
$ firewall-cmd --permanent --add-port=80/tcp
$ firewall-cmd --reload
방화벽을 사용하지 않아도 되는 경우에는 다음과 같이 방화벽 사용을 해제한다.
$ systemctl stop firewalld
$ systemctl disable firewalld
Postgresql은 RDB 중 하나로 MySQL와 함께 많이 사용되는 데이터베이스이다. Postgresql은 MySQL에 비해 속도는 늦으나 대용량의 자료가 저장되는 경우 세밀한 Index 관리를 통해서 평균적으로 소요되는 처리 속도는 보장할 수 있다.
Postgresql은 다음의 명령어를 통해 설치한다.
$ yum install postgresql-server
$ postgresql-setup initdb
$ systemctl enable postgresql
$ systemctl start postgresql
다음의 명령어를 이용하여 사용자 & DB를 생성한다.
$ su - postgres
$ createuser lubang
$ createdb lubang_db
$ psql
$ alter user lubang with encrypted password '암호';
$ grant all privileges on database lubang_db to lubang;
$ \q
$ exit
다음은 보안을 위해서 접속 가능한 IP & port를 설정한다.
$ su - postgres
$ vi data/postgresql.conf
// 다음의 구문 앞에 #을 제거
listen_addresses = 'localhost'
port = 5432
pg_hba.conf 파일은 보안을 허용하는 ip 및 서브넷마스크 정보이다.
$ vi data/pg_hba.conf
host all all 127.0.0.1/32 trust
위와 같이 마지막 컬럼의 ident를 trust 로 수정한다.
NGINX는 Apache WebServer와 동일한 웹서버 엔진이다. Apache WebServer에 비해 필요한 기능만 추출하여 가볍고 작은 용량으로 만들어졌고, 그러한 특징을 기반으로 동시 처리 속도가 Apache WebServer에 빠르다.
본 절에서는 Web Service 운영을 위해 NGINX 설치를 설명한다.
$ sudo yum install epel-release // NGINX 가 포함된 패키지 레포지토리 추가
$ sudo yum install nginx
$ sudo systemctl start nginx
벌써 웹 서버 구축을 완료하였다. 방화벽에 포트를 해제 하기 위해서 다음과 같이 설정한다.
$ sudo firewall-cmd --permanent --zone=public --add-service=http
$ sudo firewall-cmd --permanent --zone=public --add-service=https
$ sudo firewall-cmd --reload
위와 같이 설정을 완료하면 http://localhost 로 접속하면 다음과 같은 NGINX 기본 웹화면이 나타난다.
이로서 웹 서버를 운영하기 위한 리눅스 환경을 모두 구축하였다.
본 절에서는 리눅스에서 개발을 하기 위한 개발 환경 설정이다. 개발을 위해 필요한 Git, Java 설치는 다음과 같다.
$ yum install wget git
wget은 HTTP Post를 테스트 하기 위해 사용하는 도구이다. git은 소스코드 버전 관리를 위한 도구이다. 이는 웹 개발 시 필수적인 도구로 설치한다. Git은 위와 같이 설치한 뒤, global 설정을 다음과 같이 한다.
$ git config --global user.name "Donggeun Bang"
$ git config --global user.email purebuddy@지멜
Java는 open-jdk와 Oracle 배포 버전이 있다. openjdk는 Java 스펙 분석을 통해서 오픈 소스로 만들어지는 패키지이다. openjdk는 Yum을 통해 설치가 가능하다.
하지만 Java의 최신 스펙은 openjdk에 반영되지 않기 때문에 최신 기술 및 Java 라이브러리를 사용하기 위해서는 Oracle에서 배포하는 패키지를 설치해야 한다. 설치 방법은 다음과 같다.
사이트에서 rpm 버전을 다운로드한다. Java는 최신버전의 JDK(jdk-8u31-linux-x64.rpm)을 설치한다.
$ rpm -ivh jdk-8u31-linux-x64.rpm
리눅스를 이용한 개발환경 및 명령어 스터디의 내용 결과는 다음과 같다.
리눅스는 Command 기반으로 모든 환경 및 처리를 수행한다. 물론 GUI도 많은 발전과 지원을 하고 있지만 실질적으로 리눅스를 사용하는 궁극적인 목적, 안정적인 서버 운영의 측면을 보았을 때는 대부분의 작업을 Terminal에서 수행하게 된다.
이러한 작업들을 수월하게 하기 위해서는 위에서 언급하는 '자주 사용하는 명령어'는 자유롭게 사용할 수 있도록 숙지가 필요하다. 또한 GUI로 조작하지 않기 때문에 더욱 빠르게 처리할 수 있지만 오히려 불편한 방식도 존재한다. 이러한 불편한 방식을 쉽게 처리하기 위해서는 Shell Script 를 숙지하면 좋다. 혹은 Python와 같은 스크립트 언어를 공부하여 사용하는 것을 추천한다.
이러한 스터디를 통한 리눅스를 이용한 서버 운영 및 개발 환경 구축의 특징은 다음과 같다.
리눅스 서버 운영
- 이미 검증된 안정성
- 다양한 레퍼런스
- 대부분의 프레임워크, 라이브러리가 리눅스는 기본적으로 제공
- MS에 비해 Vendor 의존적인 내용이 거의 없음 (대부분의 패키지가 오픈소스로 개발되어 확장성 및 독립성이 뛰어남)
- 높은 가상화(LXC) 기반의 Docker 사용 환경
리눅스 개발 환경
- VIM 및 EMACS와 같은 강력한 텍스트 에디터 도구 존재
- Boost, C/C+ 신규 스펙 등의 새로운 프레임워크 및 라이브러리 제공 (윈도우에서는 이를 사용하기 위한 매우 복잡한 단계-prebuild-가 필요)
- ASP/NET 기반의 웹 서비스 운영 (Linux도 지원한다고 2015년 발표하였지만 대부분이 지원되지 않고 있는 상태)
- 운영자가 GUI 기반으로 시스템을 관리 및 운영하는 경우
리눅스는 매우 효과적인 운영체제이다. 그 중에서도 가장 큰 특징은 오픈소스 기반의 특성으로 인해서 매우 다양한 라이브러리들을 기본적으로 제공하고 있고 개발 시에도 많은 활용이 가능하여 개발 소요시간을 최소화 시켜준다는 점이다.
하지만 현재 C#이라는 개발 언어는 윈도우 환경에서만 안정적으로 운영되고 있다. 이러한 제약을 피하기 위해서 Java를 사용하는 것은 Programming Language 측면에서 아쉬운 방향이다. C#은 높은 추상화와 효과적인 개념을 제공하기 때문이다. 그러함에도 Java를 택한 가장 큰 이유는 C#에서는 구성하기 힘든 ALM(Application Lifecycle Management)이 쉽게 제공되기 때문이다. 사실 쉽다기 보다는 저렴하다고 표현하는 것이 더 적합하다. ALM을 통해서 도출할 수 있는 정보들을 개발 언어를 뛰어넘어서 높은 설계 품질과 시각화를 제공한다. 그리고 이러한 도구들이 대부분 리눅스에서 운영되도록 구성되어 있다.
소프트웨어의 품질 및 패키지 관리, 그리고 이러한 시스템을 장기간 운영하기 위해 많이 사용되는 리눅스는 필수적인 학습 대상이다.