새소식

개발

Docker(2) - Container 다루기

  • -

Docker 컨테이너 다루기

컨테이너의 라이프사이클

도커 컨테이너는 실행중, 정지, 파기의 3가지 상태를 가진다. 이를 라이프사이클이라고 하며, run 명령으로 최초 실행한 시점의 상태는 실행중 이다.
컨테이너들이 같은 이미지로부터 생성이 되었다고 하더라도 별개의 상태값을 지닌다. 이것이 컨테이너와 이미지의 큰 차이점이다.

실행 중 상태

run 명령의 인자로 지정된 도커 이미지를 기반으로 컨테이너가 생성되면 이 이미지를 생성했던 Dockerfile에 포함된 인스트럭션에 의해 애플리케이션이 실행된다.

HTTP요청을 받는 서버 애플리케이션이면 오류로 인해 종료되지 않는 한 실행중 상태가 지속된다. 이에 비해 명령이 바로 실행되고 끝나는 명령행 도구 등의 컨테이너는 실행중 상태가 길게 유지되지 않는다.

실행이 끝나면 정지상태가 된다.

정지 상태

실행중 상태의 컨테이너를 사용자가 명시적으로 정지하거나, 컨테이너 내부에서 실행된 애플리케이션이 정상/오류를 막론하고 종료된 경우에는 컨테이너가 정지상태가 된다.

컨테이너를 정지시키면 가상환경으로서는 더이상 동작 하지 않지만, 디스크에 컨테이너가 종료되던 시점의 상태가 저장되어 남는다. 그러므로 정지시킨 컨테이너는 언제든지 다시 실행할 수 있다.

파기 상태

정지 상태의 컨테이너는 명시적으로 파기하지 않는 이상 디스크에 그대로 남아있게된다. 같은 이미지로 빌드한 컨테이너라고 해도 실행시간 등 서로 다르고 애플리케이션의 처리 결과도 쌍이 하기 때문에 완전히 같은 컨테이너를 새로 생성 할 수는 없다.


Docker Container 명령어 관련 내용

run

컨테이너를 생성 및 실행하는 명령이다.
docker container run {options} {이미지명}{:태그} {명령} {명령인자...}
docker container run {options} {이미지ID} {명령} {명령인자...}

자주 사용하는 Options

  • -d : 인자를 단독으로 추가하면 백그라운드에서 컨테이너를 실행한다.
  • -p : 포트포워딩을 위해 사용하는 옵션
    -p host_port:container_port
  • --name : 컨테이너의 NAME컬럼에 해당되는 이름을 지정해주는 옵션
    개발용으로는 자주 사용되지만, 운영환경에서는 거의 사용되지 않는다. 지속해서 컨테이너를 생성하고 삭제하는 운영환경에서는 사용에 제약이 많기 때문이다.
    docker container run --name {컨테이너명} {이미지명}:{태그}
  • —rm : 옵션과 함께 생성된 컨테이너는 실행이 끝나면 자동으로 파기된다. 주로 명령행 도구가 담긴 컨테이너를 사용할때 유용하게 사용된다.

ls

실행중이거나 종료된 컨테이너의 목록을 보여주는 명령이다.

docker container ls {options}
docker ps {options}

아무 옵션 없이 실행할시 현재 실행중이 컨테이너의 목록이 출력된다.

$ docker container ls
CONTAINER ID   IMAGE                 COMMAND                  CREATED             STATUS          PORTS                                                  NAMES
32a96a19a95b   example/echo:latest   "go run /echo/main.go"   About an hour ago   Up 13 minutes   0.0.0.0:9000->8000/tcp, :::9000->8000/tcp              heuristic_rubin
12c8987fb183   redis                 "docker-entrypoint.s…"   9 months ago        Up 5 days       0.0.0.0:6379->6379/tcp, :::6379->6379/tcp              redis
e83172c15494   mysql                 "docker-entrypoint.s…"   10 months ago       Up 5 days       0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp   mysql-latest

목록에 표시되는 컬럼항목의 의미는 아래와 같다.

docker container ls COLUMN

자주 사용하는 Options

  • -q : 단일옵션으로 사용할시 CONTAINER ID(축약형)만 추출해준다

      $ docker container ls -q                                                                                                                                     127 ✘  15:25:23
      32a96a19a95b
      12c8987fb183
      e83172c15494
  • —filter : 특정 조건을 만족하는 컨테이너의 목록을 보고싶을때 사용한다.
    docker container ls --filter {"필터명=값"}
    필터명에서 컬럼에는 없는 ancestor 를 사용할수 있는데, 이는 컨테이너를 생성한 이미지 명을 기준으로 필터링해준다.

    =는 equal의 개념보단 contains의 개념으로 필터링을 이해하면 될것같다.

      $ docker ps --filter "name=red"
      CONTAINER ID   IMAGE     COMMAND                  CREATED        STATUS      PORTS                                       NAMES
      12c8987fb183   redis     "docker-entrypoint.s…"   9 months ago   Up 5 days   0.0.0.0:6379->6379/tcp, :::6379->6379/tcp   redis
  • -a : 이미 종료된 컨테이너를 포함한 모든 컨테이너 목록을 표현한다.
    docker ps -a

stop

실행중인 컨테이너를 종료할때 사용하는 명령이다.
docker container stop {컨테이너ID_또는_컨테이너명}

restart

파기하지 않은 정지 상태 컨테이너를 재시작하는 명령이다.

docker container restart {컨테이너ID_또는_컨테이너명}

rm

정지시킨 컨테이너(status=exited)를 완전히 파기할때 사용하는 명령이다.

docker container rm {컨테이너ID_또는_컨테이너명}

그러나 현재 실행중인 컨테이너는 이 명령어로만으로는 삭제할 수 없다.

자주사용되는 Options

  • -f : 강제로 삭제하는 명령어이다.
    docker container rm -f {컨테이너ID}

logs

현재 실행중인 특정 도커 컨테이너의 표준 출력 내용을 확인 하는 명령이다. 컨테이너 출력 내용 중 표준 출력으로 출력된 내용만 확인 할 수 있으므로 파일 등에 출력된 로그는 볼 수 없다.
docker container logs {options} {컨테이너ID_또는_컨테이너명}

실제 운영단계에서는 쿠버네티스를 통해 실행중인 컨테이너의 로그를 수집해 웹브라우저나 명령행 도구로 열람하게 해주는 기능을 사용하기 때문에 이 명령을 실제로 사용하는 경우는 그다지 많지 않다. 하지만 아무런 기능이 준비가 되지 않은 개발 단계에서는 디버깅 용도로 유용하다.

자주 사용되는 Options

  • -f : 새로 출력되는 표준 출력 내용을 계속 보여준다.

exec

실행중인 컨테이너에서 원하는 명령을 실행할 수 있다. 마치 컨테이너에 ssh로 로그인한 것 처럼 내부를 조작 할 수 있다.
docker container exec {options} {컨테이너ID_또는_컨테이너명} {컨테이너에서_실행할_명령}

$ docker container exec redis pwd
/data

redis 컨테이너의 작업디렉토리인 /data 가 정상적으로 출력되었다.

이러한 표준입력연결을 유지하는 -i 옵션과 유사 터미널을 할당하는 -t 옵션을 조합하면 컨테이너를 셸을 통해 다를수 있다. 이런 용도로 컨테이너를 사용하고 싶다면 -it 옵션을 붙인다.

$ docker container exec -it redis sh                                                                                                                             ✔  15:59:51
# pwd
/data
# echo "hi"
hi

이러한 명령은 컨테이너 내부의 상태를 확인하거나 디버깅 용도로 사용해야한다. 파일을 수정하는것은 의도치 않은 애플리케이션의 부작용을 초래 할 수 있음을 염두해야한다.

cp

컨테이너끼리 혹은 컨테이너와 호스트 간에 파일을 복사하기 위한 명령이다.
Dockerfile 내 정의된 COPY 인스트럭션은 이미지를 빌드할 때 호스트에서 복사해 올 파일을 정의하기 위한 것이고, docker container cp 명령은 실행중인 컨테이너와 파일을 주고받기 위한 명령이다. 또한 아직 파기되지 않은 정지상태의 컨테이너에 대해서도 실행 할 수 있다.
docker container cp {options} {컨테이너 ID_또는_컨테이너명}:{원본파일} {대상파일}

docker container cp {options} {호스트_원본파일} {컨테이너 ID_또는_컨테이너명}:{대상파일}

컨테이너 내의 /echo/main.go 파일을 호스트의 디렉토리 팡리로 복사하는 명령어를 입력해보자

$ docker container cp heuristic_rubin:echo/main.go .
$ ls
main.go

반대로 호스트쪽에서 컨테이너로 파일을 복사하는 명령어는 아래와 같다.

$ docker container cp host.txt heuristic_rubin:/tmp                                                                              1 ✘  16:08:35
$ docker container exec heuristic_rubin ls /tmp | grep host                                                                        ✔  16:08:55
host.txt

이 명령어 또한 디벙깅 중 컨테이너 안에서 생성된 파일을 호스트로 옮겨 확인하는 경우가 대부분이다.


참고도서 : 도커/쿠버네티스를 활용한 컨테이너 개발 실전 입문

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.