Developer

도커와 컨테이너 본문

42seoul/ft_server

도커와 컨테이너

DPhater 2020. 9. 7. 22:40

Docker

Docker는 컨테이너 기반의 오픈소스 가상화 플랫폼이다. 쉽게 말하면 지금까지 우리가 써보았던 가상 머신과 비슷하다. 차이점으로는 검색해보면 가장 많이 나오는 "기존 가상 머신(VM) 보다 가볍다"라고 말할 수 있다. 앞의 말처럼 Docker는 VM보다 경량화된 방식으로 Guest OS를 설치하지 않는다. 

출처 : https://www.docker.com/resources/what-container

위의 그림은 기존 VM의 동작을 보여주는데 Guset OS를 설치해 구동되고, OS위에 다른 OS들이 동작하기 때문에 단일 OS에 비해 속도가 느려질 수밖에 없다. 또한 이미지에 OS가 포함되어야 하기때문에 용량도 커질 수 밖에없다. 가상화 기술의 관심이 많아지면서 다양한 방법으로 이러한 문제를 해결하였지만 여전히 OS위에 OS를 올려 실행하는 방법으로는 하드웨어 성능을 충분히 사용하기는 어렵다. 그래서 등장한 것이 컨테이너 기술이다.

출처 : https://www.docker.com/resources/what-container

위의 그림은 Docker의 동작을 보여준다. Guest OS가 설치되어있지 않은 것을 확인할 수 있다. Docker의 경우 OS 자원을 Host와 공유하여 사용한다. 호스트의 시스템 콜을 직접 호출하기 때문에 guest OS를 설치하는 것보다 훨씬 빠른 속도로 동작할 수 있다. 

Container and Image

도커를 공부하다 보면 container와 image를 많이 볼 수 있는데 image는 실행파일, container는 프로세스라고 생각하면 된다. 실제 실행파일, 프로세스와는 다르지만 둘의 관계가 실행파일 프로세스와 같다고 생각하면 된다. 

 

이미지는 도커 컨테이너를 구성할 파일 시스템과 필요한 애플리케이션 설정을 하나로 합친 것으로 docker hub에 있는 원하는 이미지를 pull 해서 사용할 수 있으며 직접 배포할 때 이 이미지를 통해 배포할 수 있다. 이러한 이미지는 Dockerfile을 통해서 구성할 수 있다. 

Dockerfile

Dockerfile은 앞에서 말했듯이 이미지를 만들기 위한 설정 파일이다. Dockerfile에 작성된 순서대로 이미지를 생성한다. 도커 파일만 읽을 수 있다면 해당 이미지가 어떻게 구성되어있는지 알 수 있다. 

Dockerfile을 작성하기 위한 몇 가지 명령어만 살펴보자.

 

1. FROM <image> : <tag>

FROM은 기반 이미지를 설정한다. FROM debian:buster과 같이 도커 파일에 작성해서 사용한다.

위에 작성된 명령어 중 debian은 이미지 이름이고, : 뒤에 buster은 태그로 버전을 나타낸다.  태그는 입력하지 않으면 latest가 된다.

 

2. RUN

RUN은 기반 이미지 위에서 명령을 실행하는 명령어다. RUN은 이미지를 build 할 때 사용되는 명령어이며 이후에 나오는 CMD 나 ENRTYPOINT와는 다르다는 것을 알아야 한다. 명령어 사용 방법은 터미널에서 수행하는 명령어 앞에 RUN 명령어를 붙여주면 된다.  RUN apt-get update처럼 작성하면 된다. 물론 명령어는 기반 이미지에서 사용가능한 명령어를 작성해줘야한다.

 

3. CMD

RUN은 이미지를 빌드할 때 실행되는 명령어라면 CMD는 컨테이너가 실행되었을 때 수행되는 명령어다. 

RUN과 마찬가지로 CMD apt-get update 처럼 사용할 수 있으며 CMD ["실행파일" , "매개변수", "매개변수"]와 같이 작성할 수도 있다.

 

docker run 명령어로 컨테이너에서 실행할 명령을 전달 인자로 줄 수 있는데 이렇게 사용자가 docker run 명령의 전달인자로 실행할 명령어를 작성하면 CMD는 실행되지 않는다. 

 

예를 들어 CMD echo "i am CMD"라고 Dockerfile을 작성하였을 때

docker run <image>로 실행시키면 CMD가 실행되어 i am CMD가 출력되지만

docker run <image> echo "i am not" 과같이 명령어를 직접 전달해주면 CMD는 실행되지 않고 i am not이 출력된다.

 

4.ENTRYPOINT

CMD와 마찬가지로 컨테이너가 실행되었을 때 무조건 수행되는 명령이다. CMD와의 차이는 docker run 명령으로 이미지를 실행할 때 전달 인자를 주게 되면 ENTRYPOINT의 파라미터로 인식한다(exec form의 경우). ENTRYPOINT와 CMD가 같이 사용되면 CMD를 ENTRYPOINT의 파라미터로 인식한다.

 

예를 들어 

FROM debian:buster
CMD ["CMD"]
ENRTYPOINT ["bin/echo", "ENTRYPOINT "]

와 같이 작성되어있는 dockerfile을 빌드해 실행시키면 ENTRYPOINT CMD가 출력된다.

출처 : https://docs.docker.com/engine/reference/builder/#understand-how-cmd-and-entrypoint-interact

위의 표는 CMD와 ENRTYPOINT의 표이다

 

CMD와 ENRTYPOINT를 적절하게 잘 사용해야 한다. 보통 컨테이너가 수행될 때 변경하지 않을 명령어는 ENRTYPOINT를 사용하는 것이 좋고 해당 명령어의 default 인자를 CMD로 작성하는 것이 좋다. 

 

5.COPY

COPY는 로컬의 파일을 이미지에 복사한다. 

COPY <복사하려는 파일> <이미지에서 파일을 복사할 경로>와 같이 사용할 수 있다.

 

6.ADD

COPY와 마찬가지로 파일을 이미지에 복사한다.

ADD <복사하려는 파일> <이미지에서 파일을 복사할 경로> 와 같이 사용한다.

COPY는 파일 그대로를 복사하는 반면 ADD 같은 경우 복사하려는 파일에 URL을 입력하면 다운로드해 컨테이너에 추가하고, 특정 압축파일은 압축을 해제해 복사한다.

 

ADD COPY의 복사하려는 파일은 Dockerfile을 기준으로 같은 디렉터리 혹은 하위 디렉터리의 파일만 추가할 수 있다. 

 

7. WORKDIR

WORKDIR <절대 경로>와 같이 사용하며 RUN, CMD에서 사용한 명령이 실행될 디렉터리를 지정한다. 

 

8.EXPOSE

노출시킬 (Host와 연결할) 포트를 설정한다.

 

9.RUN, CMD, ENTRYPOINT format

RUN, CMD, ENRTYPOINT 명령은 경우 두 가지 format으로 작성할 수 있다.

RUN <command>                                           (shell form)

RUN ["excutable", "param1", "param2"]                (exec form)

 

CMD command param1 param2

CMD ["excutable", "param1", "param2"]

CMD ["param1", "param2"]

 

ENTRYPOINT command param1 param2

ENTRYPOINT ["excutable", "param1", "param2"]

 

Shell form은 /bin/sh -c <command>로 명령을 실행한다. exec form은 실행 파일을 직접 호출하며 쉘 처리가 발생하지 않는다. 쉘을 통해 호출되지 않기 때문에 exec form의 경우 환경변수를 사용할 수 없다. 

Docker공식 문서에 따르면 exec형식을 권장한다. 만약 exec형식으로 환경 변수를 사용하고 싶다면 

ENTRYPOINT ["/bin/bash", "-c", "$변수"]와 같이 사용할 수 있다. shell form의 ENRTYPOINT는 CMD 또는 docker run의 전달 인자를 무시한다.  

Docker 명령어

1. 이미지 관련 명령어

  • docker build [option] PATH
    = Dockerfile로 이미지 빌드하는 명령어 
    = 아래의 사진은 Dockerfile이 있는 디렉터리에서 명령을 실행했기 때문에 경로를.으로 지정해주었다.
    = -t옵션은 이미지 이름을 지정하는 옵션이다.
    = docker build 명령을 수행하면 Dockerfile에 작성되어있는 순서대로 이미지가 빌드된다.

docker build

  • docker images
    = docker image 확인하는 명령어 

docker images

  • docker rmi <image id>
    = docker image 삭제하는 명령어
    = 컨테이너가 있을 경우 삭제가 되지 않는데 -f 옵션으로 컨테이너까지 모두 삭제 가능하다.

docker rmi 수행

  • docker rmi 'docker images -q'  || docker rmi $(docker images -q)
    = 모든 이미지 삭제

2. 컨테이너 관련 명령어

  • docker run [option] image [command] [param] 
    = docker 컨테이너를 실행하는 명령어
    = OPTION
       -d : 컨테이너를 background에서 실행시키는 옵션
       -i  : docker가 표준입력으로 명령을 입력받을 수 있도록 하는 옵션(상호 입출력 가능하게)
       -t  : tty 활성화 하는 옵션(내부의 쉘을 이용가능하게 하는 옵션), 보통 -i와 같이 사용해 -it로 사용
       --name : 컨테이너의 이름을 지정하는 옵션
       -p host_port : container_port : 컨테이너와 host의 포트를 연결하기 위한 옵션 
       --rm : 컨테이너가 종료될 때 컨테이너를 삭제하는 옵션

docker run

  • docker ps
    = 실행 중인 컨테이너 목록을 보여주는 명령어
    = -a옵션을 추가하면 모든 컨테이너 목록을 보여준다.

docker ps

  • docker stop container_id
    = 컨테이너를 종료하는 명령어

docker stop

  • docker stop 'docker ps -a -q'  ||  docker stop $(docker ps -a -q)
    = 모든 컨테이너 중지
  • docker rm 'docker ps -a -q'   || docker rm $(docker ps -a -q)
    = 모든 컨테이너 삭제
  • docker attach container_id
    = 컨테이너에 접속하기 위한 명령어

Docker 실행

docker 컨테이너는 메인 프로세스가 종료되면 함께 종료한다. CMD 혹은 ENTRYPOINT로 실행시킨 명령이 종료되면 컨테이너도 함께 종료되는 것이다. 따라서 명령이 종료되지 않도록 실행시키려는 서비스의 바이너리 파일을 컨테이너의 포그라운드에서 실행해 컨테이너가 종료되지 않도록 해야 한다. (혹은 bash와 같이 종료 되지않는 프로그램을 실행시켜도 된다....하지만 이렇게하면 나중에 잘못된 방법이라는걸 알게되겠지..)

'42seoul > ft_server' 카테고리의 다른 글

ft_server 서버 돌려보기  (3) 2020.09.13
ft_server 과제 이해하기  (2) 2020.09.08
Comments