이 장에서는 지금까지 설명한 인프라 기초 지식과 Docker 커맨드 및 Dockerfile 코드로 구축한 인프라를 바탕으로 여러 컨테이너를 통합하여 관리하기 위한 툴인 Docker Compose를 사용하여 웹 시스템 실행 환경을 구축하는 방법에 대하여 설명합니다.
6-1 Docker로 구축하는 웹 시스템에 대한 기초 지식
3계층 웹 시스템 아키텍처
각각의 기능과 역할에 맞는 여러 대의 서버로 애플리케이션 실행을 위한 인프라를 구성하는 것을 인프라 아키텍처라 합니다.
시스템에서 많이 사용하고 있는 웹 애플리케이션의 대표적인 인프라 아키텍처인 3계층 웹 시스템 아키텍처는 다음과 같이 각 기능을 가진 3개의 서버로 구성되어 있습니다.
프론트 서버
클라이언트의 웹 브라우저에서 전송된 HTTP request를 받아 HTTP response를 보내는 서버로 '웹 프론트 서버' 또는 '웹 서버'라고 함
Apache HTTP Server, nginx, Microsoft의 IIS(Internet Information Services) 등의 미들웨어가 동작
처리량이 많이 부하가 클 때에는 스케일 아웃으로 서버 대수를 늘리고 로드 밸런서 등으로 부하를 분산시킴
애플리케이션 서버
업무를 처리하는 서버
GlassFish와 Apache Tomcat, JBoss Application Server, IBM의 WebSphere Application Server, Oracle의 Oracle Application Server 등의 미들웨어로 구현
PHP나 Perl 실행 환경이 필요할 때에는 Apache HTTP Server에 mod-perl이나 mod-php 등을 함께 설치
데이터베이스(DB) 서버
영구적인 데이터를 관리하기 위한 서버
데이터는 DBMS(Database Management System) 기능을 가진 MySQL이나, PostgreSQL, Oracle의 Oracle Database, IBM의 DB2 등의 미들웨어에서 관리
높은 가용성이 필요하기 때문에 클러스터링 기술로 이중화하는 경우가 많음
성능을 높이기 위해 상황에 따라 OS나 미들웨어의 매개변수 설정을 변경하는 등 튜닝하는 것이 좋음
데이터 관리
시스템을 운영하다보면 다양한 데이터가 생성·축적되며 이 데이터는 프로그램이 종료된 후에도 스토리지 등에 저장됩니다. 이를 영속 데이터라 하며 시스템 가동 시간에 따라 증감하고 변화합니다. 스토리지 저장 공간은 한정되어 있고 장애로 인해 데이터가 소실될 수도 있으므로 이를 잘 관리하는 것이 중요합니다.
데이터 백업 및 복원
서버 장애에 대비하여 데이터를 백업
테이프 장치 등의 물리 매체 또는 클라우드상의 스토리지 등에 보관
재해 대책의 일환으로 원격지에 보관하기도 함
로그 수집
여러 서버를 통합 모니터링하는 경우에는 일반적으로 로그 수집을 위한 전용 서버를 설치
UNIX 계열의 OS인 경우에는 syslogd 데몬으로 커널과 애플리케이션 로그를 관리
Docker는 컨테이너를 통해 서버 기능을 제공
서버 컨테이너: 애플리케이션에서 실행 모듈과 각종 라이브러리 모듈 및 미들웨어 설정 파일 등을 저장
데이터 전용 컨테이너: 시스템 구동 시 생성되는 데이터 저장(로그, 데이터, ...)
소실되면 안되는 중요한 데이터는 데이터 전용 컨테이너에 저장
Docker 컨테이너 간 링크
컨테이너들을 연계할 때 Docker의 링크 기능을 사용
링크 기능은 컨테이너 구동 시 docker run 커맨드로 다음과 같은 형식의 link 옵션을 지정하여 사용
docker run --link <접속하고자 하는 컨테이너명:alias명> <이미지명> <실행 커맨드>
#postgres를 사용하여 데이터베이스 서버 기능을 가진 'dbserver' 컨테이너 구동
docker run -d --name dbserver postgres
#'dbserver 컨테이너에 'pg'라는 alias명으로 링크를 설정한 appserver 웹 애플리케이션 서버 구동
docker run -it --name appserver --link dbserver:pg centos /bin/bash
#appserver의 환경변수 확인
set | grep PG
위와 같은 명령을 통해 서버를 구동하고, appserver의 환경변수를 확인해보면, 다음과 같이 링크로 연결된 dbserver에 접속하기 위해 prefix로 컨테이너의 alias명인 <PG_>가 붙어있는 것을 볼 수 있습니다.
예를 들어 'PG_PORT_5432_TCP_ADDR'라는 환경변수에는 앞서 링크로 연결된 dbserver에 할당된 IP address가 설정됩니다. 설정이 완료된 appserver 컨테이너에서 dbserver 컨테이너로 ping을 확인하려면 다음의 커맨드를 실행합니다.
#appserver 컨테이너에서 dbserver 컨테이너로 ping 확인(컨테이너 내에서 실행)
ping $PG_PORT_5432_TCP_ADDR
appserver 컨테이너의 /etc/hosts에 네트워크 설정 정보가 기록됩니다. 이를 통해 다음과 같이 링크로 연결된 dbserver에 pg라는 이름으로 ping 커맨드를 날릴 수도 있습니다
#/etc/hosts에 기록된 네트워크 설정 정보 확인(컨테이너 내에서 실행)
cat /etc/hosts
#링크로 연결된 dbserver에 pg라는 이름으로 ping(컨테이너 내에서 실행)
ping pg
Docker 컨테이너 리소스는 분산되어 있으므로 컨테이너끼리 액세스가 필요할 때에는 이와 같이 링크 기능을 사용합니다. 단, 링크 기능은 동일한 호스트 머신에서 구동 중인 컨테이너 사이에서만 액세스할 수 있으므로 주의해야 합니다.
※ 참고
Linux에서는 '/etc/hosts' 파일에 각 호스트의 호스트명과 IP address 매핑을 저장하고 확인합니다.
6-2 Docker Compose 설치
Docker Compose
Docker Compose는 여러 컨테이너를 하나로 관리할 수 있는 툴입니다. Docker Compose는 'docker-compose.yml' 파일에 컨테이너 구성 정보를 정의하여 동일한 호스트상의 여러 컨테이너를 하나로 관리할 수 있습니다.
Docker Compose는 Docker사가 제공하는 툴이며 여기에서는 최신 버전인 1.8.0을 기준으로 설명합니다.
Docker Compose 설치
Docker Compose는 아래의 GitHub에 공개되어 있으며, Windows용의 Docker Toolbox에는 설치되지 않습니다.
#컨테이너 라벨 설정#배열 형식으로 지정labels:-"com.example.description=Accountingwebapp"-"com.example.department=Finance"#hash 형식으로 지정labels:com.example.description:"Accountingwebapp"com.example.department:"Finance"
Lorry는 docker-compose.yml을 생성하는 기능뿐만 아니라 이미 생성된 docker-compose.yml을 수정하는 기능도 가지고 있습니다. 별도의 사용자 등록 절차도 필요 없기 때문에 편리하게 사용할 수 있다는 것이 장점입니다.
[참고] Docker Compose의 설정 파일
Docker Compose의 설정 파일로는 다음 4가지가 대표적입니다. 파일명이 다음 4가지 이외의 이름인 경우에는 f 옵션으로 설정 파일을 지정해주어야 합니다.
docker-compose.yml
docker-compose.yaml
fig.yml
fig.yaml
Fig는 Docker 컨테이너 구성관리 툴 중 하나로, Orchard Labs에서 개발했으며 2014년 Docker사로 합병되었습니다.
6-4 Docker Compose 커맨드
여기에서는 Docker Compose를 사용하기 위하여 알아두어야 할 커맨드에 대해 설명합니다.
Docker Compose의 커맨드
Docker Compose 커맨드(docker-compos)에는 서브 커맨드가 몇 가지 있습니다. 주로 사용되는 서브 커맨드는 다음과 같습니다.
서브 커맨드
설명
up
컨테이너 생성 및 구동
scale
생성할 컨테이너 개수 지정
ps
컨테이너 목록 확인
logs
컨테이너 로그 출력
run
컨테이너 실행
start
컨테이너 구동
stop
컨테이너 중지
restart
컨테이너 재가동
kill
실행중인 컨테이너 강제 종료
rm
컨테이너 삭제
docker-compose 커맨드는 docker-compose.yml을 저장한 디렉터리에서 실행합니다. 현재 디렉터리가 아닌 다른 디렉터리에서 docker-compose.yml을 실행해야 하는 경우에는 f 옵션으로 파일 경로를 지정합니다.
#docker-compose.yml을 기반으로 컨테이너 생성 및 구동
docker-compose -f ./sample/docker-compose.yml up
서브 커맨드 뒤에 컨테이너명을 지정하면 해당 컨테이너만 조작할 수 있습니다.
#특정 컨테이너 중지
docker-compose stop dbserver
여러 개의 컨테이너를 한 번에 생성(up)
docker-compose.yml을 기반으로 여러 컨테이너를 생성하고 구동할 때에는 docker-compose up 커맨드를 사용합니다.
#여러 개의 컨테이너를 한 번에 생성
docker-compose up [옵션] [서비스명]
실행중인 컨테이너를 중지시킬 때에는 Ctrl + C를 누릅니다.
컨테이너를 백그라운드에서 실행시킬 때에는 d 옵션을 사용합니다. d 옵션으로 구동시키면 프롬프트 화면으로 돌아갑니다.
#여러 컨테이너를 한 번에 생성 및 구동
docker-compose up
#여러 컨테이너를 백그라운드에서 구동
docker-compose up -d
다음 명령을 통해 위에서 작성한 docker-compose-pig.yml을 기반으로 pig-trace-application 컨테이너들을 생성하고 구동시켜 봅시다.
cd /opt/gopath/src/github.com/hyperledger/pig-trace-application/packages/pig-lifecycle
#pig-trace-application 컨테이너를 한 번에 백그라운드에서 생성 및 구동
docker-compose -f docker-compose-pig.yml up -d
생성할 컨테이너 개수 지정(scale)
생성할 컨테이너의 개수를 지정할 때에는 docker-compose scale 커맨드를 사용합니다.
#생성할 컨테이너 개수 지정
docker-compose scale [서비스명=개수]
예를 들어 docker-compose.yml에 serverA와 serverB가 정의되어 있고, serverA 컨테이너를 10개, serverB 컨테이너를 20개 구동하고자 한다면 다음의 커맨드를 실행합니다.
#컨테이너 개수 지정
docker-compose scale serverA=10 serverB=20
YAML 설정 파일의 이름이 기본 이름이 아닐 경우에는 -f 옵션으로 해당 파일을 지정해주어야 합니다.
#docker-compose-pig의 컨테이너 개수 지정
docker-compose -f docker-compose-pig.yml scale pig-enrollment=3
※ 하나의 컨테이너를 여러 개 구동하려고 한다면, 이름과 포트번호가 충돌이 나지 않도록 잘 설정해주어야 합니다.
위 소스를 실행하기 위해 docker-compose-pig.yml 파일에서 pig-enrollment 서비스 부분을 다음과 같이 수정하였습니다.
여러 컨테이너 목록을 확인하고자 할 때에는 docker-compose ps 커맨드를 사용합니다.
#여러 컨테이너 확인
docker-compose ps [옵션] [서비스명]
docker-compose ps 커맨드로 구동한 컨테이너 목록을 확인할 수 있습니다.
커맨드를 실행하면 구동 중인 컨테이너명, 실행중인 커맨드, 상태, 포트를 확인할 수 있습니다. -q 옵션을 사용하면 컨테이너 ID만 출력됩니다.
또한, Docker Compose를 사용하여 구동하는 경우에도 일반 Docker 커맨드를 사용할 수 있습니다.
#여러 컨테이너의 목록 확인
docker-compose ps
#컨테이너 ID 확인
docker-compose ps -q
#Docker 커맨드로 컨테이너 확인
docker ps
YAML 설정 파일의 이름이 기본 이름이 아닐 경우에는 -f 옵션으로 해당 파일을 지정해주어야 합니다.
#docker-compose-pig의 컨테이너 목록 확인
docker-compose -f docker-compose-pig.yml ps
#컨테이너 로그 확인
docker-compose logs
YAML 설정 파일의 이름이 기본 이름이 아닐 경우에는 -f 옵션으로 해당 파일을 지정해주어야 합니다.
#docker-compose-pig의 컨테이너의 로그 확인
docker-compose -f docker-compose-pig.yml logs
컨테이너 로그를 확인할 때에는 docker-compose logs 커맨드를 사용합니다.
컨테이너에서 커맨드 실행(run)
Docker Compose에서 구동한 컨테이너에서 새로운 커맨드를 실행하고자 할 때에는 docker-compose run 커맨드를 사용합니다. 다음 커맨드는 docker-compose run 커맨드에서 구동한 serverA 컨테이너의 /bin/bash를 실행하고 있습니다.
#컨테이너에서 커맨드 실행
docker-compose run serverA /bin/bash
YAML 설정 파일의 이름이 기본 이름이 아닐 경우에는 -f 옵션으로 해당 파일을 지정해주어야 합니다.
#docker-compose-pig의 컨테이너에서 커맨드 실행
docker-compose -f docker-compose-pig.yml run pig-enrollment /bin/sh
여러 컨테이너 구동·중지·재가동(start/stop/restart)
Docker Compose를 사용하면 여러 컨테이너를 한 번에 구동·중지·재가동 할 수 있습니다.
#여러 컨테이너를 한 번에 구동
docker-compose start
#여러 컨테이너를 한 번에 중지
docker-compose stop
#여러 컨테이너를 한 번에 재가동
docker-compose restart
특정 컨테이너만 조작하고자 한다면 커맨드 값으로 컨테이너명을 입력합니다. 예를 들어 serverA 컨테이너만 재기동하고자 한다면 다음 커맨드를 실행시킵니다.
#특정 컨테이너 재가동
docker-compose restart serverA
YAML 설정 파일의 이름이 기본 이름이 아닐 경우에는 -f 옵션으로 해당 파일을 지정해주어야 합니다. docker-compose-pig의 컨테이너를 모두 중지시켜 봅시다.
#docker-compose-pig의 컨테이너를 한 번에 중지
docker-compose -f docker-compose-pig.yml stop
여러 컨테이너 강제 종료 및 삭제(kill/rm)
실행 중인 컨테이너를 강제로 중지시킬 때는 docker-compose kill 커맨드를 사용하여 컨테이너에 시그널을 보낼 수 있습니다.
시그널이란 프로세스 간의 통신을 위한 것으로서 Linux 커널에서 사용합니다. 실행 중인 프로세스를 중지시키고 다른 프로세스를 실행할 때나 프로세스를 강제 종료하고자 할 때 사용할 수 있습니다.
예를 들어 다음 커맨드를 실행하면 컨테이너에 키보드 인터럽트인 SIGINT 시그널이 보내지며 Ctrl + C를 입력한 것과 동일하게 동작합니다.
#컨테이너에 시그널 보내기
docker-compose kill -s SIGINT
옵션 지정 없이 docker-compose kill을 실행하면 프로세스를 강제 종료하는 SIGKILL을 보냅니다.
주요 Linux 시그널은 다음과 같습니다.
시그널
설명
SIGHUP
프로그램 재기동
SIGINT
키보드로 인터럽트. Ctrl + C 입력과 동일
SIGQUIT
키보드로 중지. Ctrl + \ 입력과 동일
SIGTERM
프로세스 정상 종료
SIGKILL
프로세스 강제 종료
SIGSTOP
프로세스 일시 정지
YAML 설정 파일의 이름이 기본 이름이 아닐 경우에는 -f 옵션으로 해당 파일을 지정해주어야 합니다. docker-compose-pig의 컨테이너를 모두 강제 종료시켜 봅시다.
#docker-compose-pig의 컨테이너를 한 번에 강제 종료
docker-compose -f docker-compose-pig.yml kill
여러 컨테이너를 한 번에 삭제할 때에는 docker-compose rm 커맨드를 실행시킵니다. f 옵션을 지정하면 확인 메세지 없이 바로 삭제할 수 있습니다.
#여러 컨테이너 한 번에 삭제
docker-compose rm
YAML 설정 파일의 이름이 기본 이름이 아닐 경우에는 -f 옵션으로 해당 파일을 지정해주어야 합니다. docker-compose-pig의 컨테이너를 모두 삭제시켜 봅시다.
#docker-compose-pig의 컨테이너를 한 번에 삭제
docker-compose -f docker-compose-pig.yml rm -f
This one takes every .mp4 file in a directory and rescales it to 1920x1080, and adds a frame counter on the top and bottom left. (Two counters to detect possible tearing artefacts while rendering from ffplay)
for i in `ls *.mp4` ; do ffmpeg -i ${i} -vf "[in]scale=1920:1080[middle];[middle]drawtext=fontfile=/Library/Fonts/Arial.ttf: text=%{n}: x=lh/2: y=h-(3*lh/2): fontcolor=white: box=1: boxborderw=4: boxcolor=0x000000ff: fontsize=32[middle2];[middle2]drawtext=fontfile=/Library/Fonts/Arial.ttf: text=%{n}: x=lh/2: y=lh/2: fontcolor=white: box=1: boxborderw=4: boxcolor=0x000000ff: fontsize=32[out]" -y 1080p/${i} ; done
Rename captures frames without timecode
Using rename
sudoapt-getinstallperl# On Ubuntu - rename comes with perl
brewinstallrename# On Mac
rename's/(frame.*)-[^\.]*(.*)/$1$2/g'*
Using pure bash
forfileinframe*-*.y;domv$file${file%%-*.y}.y;done
This renames all files with names like frame213-143920102.y to frame213.y.
Linux (Ubuntu) installation instructions
The instructions on this page will allow you to compile ffmpeg from source on Ubuntu, Debian, or Mint, including many important libraries.