도커(Docker)는 Linux의 응용 프로그램들을 소프트웨어 컨테이너 안에 배치시키는 일을 자동화하는 오픈소스 프로젝트이다. - Wikipedia -
한마디로 소프트웨어를 컨테이너라는 표준화된 유닛으로 패키징하는 기술을 도커(Docker)라고 하는데 여기서 컨테이너에는 라이브러리, 시스템 도구, 코드, 런타임 등 소프트웨어를 실행하는데 필요한 모든 것이 포함되어 있습니다.
우리가 사용하는 Windows10 OS위에 가상 머신(VM)으로 Guest OS를 구동하는 걸 비교하여 생각하면 이해하기 쉬울 것 같습니다
Virtual Machines vs Containers
Environment Disparity
예를 들어 도커(Docker)를 사용하면 개발환경이 Windows 10 OS인 곳에서 개발한 코드가 실제 운영하는 서버의 OS가 Linux OS라도 개발환경에서 실행했던 코드와 동일하게 실행될 수 있도록 해주는 겁니다.
이런일이 가능한 이유는 도커(Docker) 컨테이너들은 각각 독립적으로 분리,격리(isolation)되어 있기 때문입니다.
isolation
그러므로 기존에 서버마다 서비스와 기능을 나누어 구성했다면, 도커(Docker)를 사용하면 한개의 서버, 한 개의 OS위에 여러개의 도커(Docker) 컨테이너를 각각 독립적으로 서비스와 기능을 구현할 수 있게 된 것입니다.
즉 환경격차와 격리의 장점이 있는 도커(Docker)를 사용하면 개발자와 관리자는 환경에 구애받지 않고 애플리케이션을 신속하게 배포 및 확장할 수 있으며 코드가 문제없이 실행될 것임을 확신 할 수 있습니다.
여러 개의 컨테이너로부터 이루어진 서비스를 구축, 실행하는 순서를 자동으로 하여, 관리를 간단히하는 기능이다.
Docker compose에서는 compose 파일을 준비하여 커맨드를 1회 실행하는 것으로, 그 파일로부터 설정을 읽어들여 모든 컨테이너 서비스를 실행시키는 것이 가능하다.
Docker Compose는 다중 컨테이너 애플리케이션을 정의 공유할 수 있도록 개발된 도구로
단일 명령을 사용하여 모두 실행 또는 종료할 수 있도록 개발된 도구
docker 보다 간결함
간단한 html을 만들고 nginx로 연결하려면 아래와 같이 docker 명령어를 입력해야 한다.
컨테이너 80 포트를 로컬 8080 포트와 매핑하고, 종료시 컨테이너를 삭제하기 위해 --rm 옵션을 주었고
로컬의 특정 경로의 폴더 혹은 파일을 참고하도록 volume 옵션을 통해 현재 경로 $(pwd)를 nginx 컨테이너 내에 /usr/share/nginx/html에 매핑해주자.
이 모든 과정은 이해할 수는 있지만 살짝 verbose하다. compose를 사용하면 이런 번거로운 cli를 작성하지 않고,
docker-compose.yml을 활용할 수 있다.
docker run -it -p 8080:80 --rm -v $(pwd):/usr/share/nginx/html/ nginx
컨테이너 간 연결이 쉬워진다.
아래는 postgres와 django-sample이란 컨테이너를 연결한 것이다.
--link 옵션을 주어서 django-sample 컨테이너에게 db라는 이름으로 postgres 컨테이너의 존재를 알린 것이다.
{연결할 컨테이너 이름}:{해당 컨테이너에서 참고할 이름}
역시나 verbose하다.
docker run --rm -d --name postgres \
-e POSTGRES_DB=djangosample \
-e POSTGRES_USER=sampleuser \
-e POSTGRES_PASSWORD=samplesecret \
postgres
docker run -d --rm \
-p 8000:8000 \
-e DJANGO_DB_HOST=db \
--link postgres:db \
django-sample
특정 컨테이너끼리만 통신할 수 있는 가상 네트워크 환경을 관리하는데 너무 명령어가 길어진다.
--network 옵션을 통해서 특정 네트워트 내에만 존재하는 컨테이너끼리만 통신할 수 있도록 만들어주었다.
django2의 경우 해당 네트워크 내에 존재하지 않는 컨테이너이기 때문에 --link로 연결해도 통신할 수 없게 된다.
너무 verbose하다...
// network 생성
docker network create --driver bridge web-service
// 해당 network를 활용하여 컨테이너 실행
docker run --rm -d --name postgres \
--network web-service \
-e POSTGRES_DB=djangosample \
-e POSTGRES_USER=sampleuser \
-e POSTGRES_PASSWORD=samplesecret \
postgres
docker run -d --rm --name django1 \
--network web-service \
-p 8000:8000 \
-e DJANGO_DB_HOST=db \
--link postgres:db \
django-sample
docker run -d --rm --name django2 \
-p 8001:8000 \
-e DJANGO_DB_HOST=db \
--link postgres:db \
django-sample
우리는 서비스를 서버 위에 실행시킬 때 가끔 여러 개의 서비스들이 필요할 경우가 있습니다.
예를 들어 새로 만든 application가 사용하는 database는 mysql을 사용한다고 가정한다면
mysql를 설치/실행 한 뒤 우리가 만든 application을 서버 위에 실행을 시켜야 합니다.
그런데 docker-compose는 여러 개의 서비스를 한 번에 정의를 가능하게 합니다.
위에 예시로 들었던 서비스를 실행하려면 아래와 같이 정의만 해주면 됩니다.
services:
nhn_app:
image: nhn_app_v2
nhn_mysq:
image: mysql
이렇게 하나의 문서에 여러 개의 컨테이너를 정의할 수 있습니다.
docker-compose up
이라는 명령어 하나로 문서에 정의한 서비스들이 한꺼번에 컨테이너로 실행되고
반대로 docker-compose down
이라는 명령어로 정의한 모든 서비스를 내릴 수도 있습니다.
물론 먼저 실행되어야 하는 순서까지 지정이 가능합니다.
이렇게 단일 명령을 사용하여 편하게 서비스를 실행 또는 종료시킬 수 있는 장점이 있습니다.
Docker compose를 사용하기 위해서는, 크게 나눠 아래의 세 가지 순서로 이루어진다.
1 ) 각각의 컨테이너의 Dockerfile를 작성한다(기존에 있는 이미지를 사용하는 경우는 불필요).
2 ) docker-compose.yml를 작성하고, 각각 독립된 컨테이너의 실행 정의를 실시한다(경우에 따라는 구축 정의도 포함).
3 ) "docker-compose up" 커맨드를 실행하여 docker-compose.yml으로 정의한 컨테이너를 개시한다.
Docker compose는 start, stop, status, 실행 중의 컨테이너의 로그 출력, 약간의 커맨드의 실행이과 같은 기능도 가지고 있다.
docker-compose.yml 파일은 아래와 같이 yaml으로 Docker 컨테이너에 관한 실행 옵션(build 옵션도 포함되어 있는 경우도 있다)를 기재한 파일이 된다.
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
links:
- redis
redis:
image: redis
# yaml의 기재 방법에 대해서는 아래의 링크를 참고.
# https://docs.docker.com/compose/compose-file/
이 파일에 기재되어 있는 내용은 기본적으로 docker build, docker run 커맨드 지정하는 것이 가능한 옵션이 되지만, Docker compose의 yaml 파일로써 기술하는 것으로 여러 개의 컨테이너로부터 만들어진 서비스를 조감하여 보는 것도 가능해져, 보존성의 수고를 가볍게 한다.
출처: https://engineer-mole.tistory.com/221 [매일 꾸준히, 더 깊이]