컨테이너 실행하기

Posted by yunki kim on September 6, 2021

  도커를 설치하고 구동하면 네이티브 처럼 설치된거 같다. 하지만 도커는 리눅스 컨테이너 이므로 실제로는 가상 머신에 설치되어 있다. 맥의 경우 도커는 xhyve라는 맥에서 제공하는 가상환경을 이용한다.

  도커를 설치 후 제대로 설치되었는 지 확인을 위해 다음과 같은 명령어를 실행해 보자.

  여기서 보면 클라이언트와 서버 총 두가지로 나뉘어서 버전이 출력 된다. 즉, 도커는 하나의 실행파일이지만 실제로는 클라이언트, 서버역할을 각각 실행할 수 있다. 도커 커맨드를 입력하면 도커 클라이이언트가 도커 서버로 명령을 전송하고 결과를 받아 터미널에 출력한다.

 

도커 실행

  도커는 docker run [OPTIONS] IMAGE:[:Tag|@DIGEST] [COMMAND] [ARG...]명령어로 실행할 수 있다. 여기에 자주 사용되는 옵션은 다음과 같다.

옵션 설명
-d detached mode, 백그라운드 모드
-p 호스트와 컨테이너의 포트를 연결(포워딩)
-v 호스트와 컨테이너의 디렉토리를 연결(마운트)
-e 컨테이너 내에서 상용할 환경변수 설정
-name 컨테이너 이름 설정
-rm 프로세스 종료시 컨테이너 자동 제거
-it -i, -t를 동시에 사용한 것으로 터미널 입력을 위한 옵션
-link 컨테이너 연결 [컨테이너명: 별칭]

  우분투 20.04 컨테이너를 생성해 보자.

  run 명령어의 경우 만약 해당 이미지 파일이 없다면 다운로드(pull)을 한 후 컨테이너를 생성하고 시작한다. 여기서는 컨테이너를 생성한 후 어떤 동작을 하라는 명령을 전달하지 않았기 때문에 컨테이너는 생성되자 마자 종료 된다. 컨테이너는 프로세스이기 때문에 실행중인 프로세스가 없으면 컨테이너는 종료 된다.

  이번엔 docker run --rm -it ubuntu:20.04 /bin/bash를 사용해 컨테이너를 실행해 보자. 여기서 -it는 bash쉘을 실행하고 키보드 입력을 위한 옵션이고, --rm은 프로세스 종료 시 자동 삭제를 위한 옵션이다. 

이번에는 mysql을 설치해 보자.

-e로 환경변수를 세팅했다. --name을 사용해 컨테이너의 ID대신 사용할 이름을 지정했다. 백그라운드에 띄우기 위해 -d를 사용했으며 기존에 로컬에 mysql이 설치되어 있기 때문에 호스트의 3307포트를 컨테이니의 3306포트에 연결했다.

명령어

  1. 컨테이너 목록 확인: docker ps [OPTIONS] (-a, --all)

  2. 컨테이너 중지: docker stop [OPTIONS] CONTAINER [CONTAINER...]

  3. 컨테이너 제거: docker rm [OPTIONS] CONTAINER [CONTAINER...]

  4. 이미지 목록 확인: docker images [OPTIONS] [PEPOSITORY[:TAG]]

  5. 이미지 다운로드: docker pul [OPTIONS] NAME[:TAG|@DIGEST]

  6. 이미지 삭제: docker rmi [OPTIONS] IMAGE [IMAGE...]

  7. 컨테니너 로그: docker logs [OPTIONS] CONTAINER (-f: 실시간 확인, --tail n: 마지막 개 로그 확인)

  프로그램 마다 로그 파일은 제각각이다. 따라서 도커에서 그런 로그를 내보내기 위해서 표준 스트림 중 stdou, stderr를 수집한다. 따라서 컨테이너에서 실행되는 프로그램의 로스 설정을 파일이 아닌 표준 출력으로 바꾸어야 한다. 

  8. 실행중인 컨테이너에 명령어를 실행하기: docker exec [OPTIONS] CONTAINER COMMAND[ARG...]

    exec는 run과 유사해 보인다. 하지만 run은 새로운 컨테이너를 만들어 실행하고 exec는 실행중인 컨테이너에 명령어를 내리는 거다.

 

컨테이너 업데이트

  컨테이너를 업데이트 하기 위해서는 새 버전의 이미지를 pull하고 기존 컨테이너를 stop 또는 rm한 뒤 새 이미지를 기반으로 새 컨테이너를 run하면 된다. 여기서 rm또는 stop은 컨테이너를 삭제 하는데 이러면 모든 데이터가 삭제 된다. 예를 들어 컨테이너에 디비가 있었다면 디비의 모든 데이터가 사라지게 된다. 따라서 모든 데이터가 사라지는 상황을 방지하기 위해 삭제시에도 유지해야 하는 데이터는 반드시 컨테이너 내부가 아닌 외부 서비스에 보관해야 한다. AWS S3를 사용하거나 또는 data volumes를 사용해야 한다. data volumes를 사용하면 해당 디렉토리는 컨테이너와 별도로 저장되고 컨테이너를 삭재해도 데이터가 지워지지 않는다.

1
2
3
4
5
docker run --3306:3306 \
  -e MYSQL_ALLOW_EMPTY_PASSWORD=true \
  --name mysql \
  -/my/own/datadir:/var/lib/mysql \ # <- volume mount
  mysql:5.7
cs

mysql컨테이너의 경우 위와 같이 -v를 사용하면 된다. 위 코드는 호스트의 /my/own/datadir 디렉토리를 컨테이너의 /var/lib/mysql디렉토리로 마운트 했다. 따라서 업데이트를 위해 기존 컨테이너를 삭제 한 뒤 동일한 디렉토리를 마운트 해주면 데이터는 삭제되지 않는다.

 

Docker Compose

  지금까지 도커를 커멘드라인에서 명령어로 작업했다. 하지만 컨테이너의 수가 많아 지고 작업이 복잡해 지면 새로운 방식이 필요 하다. 도커는 이에 대한 해결책으로 YAML을 사용한 Docker Compose라는 툴을 제공 한다. 

https://docs.docker.com/compose/

 

Overview of Docker Compose

 

docs.docker.com