컨테이너 기술 - 도커



개요

도커는 컨테이너 기반의 오픈소스 가상화 플랫폼입니다.
다양한 프로그램, 실행환경을 컨테이너로 추상화하고 동일한 인터페이스를 제공하여 프로그램의 배포/관리를 단순하게 만들어 줍니다.



컨테이너

컨테이너는 격리된 공간에서 프로세스가 동작하는 기술입니다.


백엔드 프로그램, 데이터베이스 서버 메시지 큐 등.. 어떤 프로그램도 컨테이너로 추상화할 수 있으며
온프렘 환경, AWS, Azure, Google Cloud 등 어디에서든 실행할 수 있습니다.


도커는 기존 VM 방식과는 다르게 프로세스를 격리 시켜 시스템 자원을 프로세스가 필요한 만큼만 추가하고 성능적으로 거의 손실이 없는 환경을 만듭니다.
(새로운 컨테이너를 만드는데 걸리는 시간은 불과 1~2초입니다)


도커에서 가장 중요한 개념은 컨테이너와 함께 이미지라는 개념입니다.

컨테이너 이미지 레이어


  • 이미지는 컨테이너 실행에 필요한 파일과 설정값 등을 포함하고 있습니다.
  • 이미지는 불변성(Immutable)을 갖습니다.
  • 레이어 단위의 이미지를 포개는 방식으로 구성됩니다.


컨테이너는 이러한 이미지를 실행한 상태라고 볼 수 있습니다.
같은 이미지로 여러개의 컨테이너를 생성할 수 있고 컨테이너 상태가 변경/삭제되어도 이미지는 변하지 않고(불변) 그대로 남아있습니다.

예시

  • ubuntu 이미지
    ubuntu 실행을 위한 모든 파일


  • MySQL 이미지
    ubuntu 이미지를 기반으로 MySQL 을 실행하는데 필요한 파일, 실행 명령어, 포트 정보 등
    (레이어 단위의 이미지 구성)


  • Gitlab 이미지
    centos 를 기반으로 ruby, go, database, redis, gitlab source, nginx 등


위 예시와 같이 이미지는 컨테이너를 실행하기 위한 모든 정보를 갖습니다.
(이는 더이상 의존성 파일을 설치하고 컴파일하고 이것저것 할 필요 없음을 의미합니다)


도커 이미지의 용량을 보통 수백메가에서 수기가 넘는 경우도 흔합니다.
이렇게 큰 용량의 이미지를 관리하기 위해 Docker Hub 를 이용합니다.



도커 설치

도커는 리눅스 컨테이너 기술이므로 macOS 또는 윈도우에 설치할 경우 가상머신에 설치가 됩니다.


각 개발 환경에 따른 설치를 진행하시면 됩니다.


도커가 설치됩니다.

도커 설치중

리눅스의 경우 도커를 실행하기 위한 kernel 버전은 3.10.x 이상입니다.
(ubuntu 14.04 이상)



도커 허브는 도커 이미지를 저장하는 클라우드입니다.
회원가입/로그인을 합니다.

도커 허브 로그인



Create Repository 버튼을 눌러 이미지를 저장할 Repository 를 만듭니다.

도커 허브 저장소



적당한 Repository 이름과 Visibility(공개/비공개) 를 선택한 뒤 Create 버튼을 눌러 Repository 를 생성합니다.

도커 허브 저장소



도커 설치가 마무리 되었다면 간단한 도커 파일을 만들어 도커 허브에 푸시 해보겠습니다.
도커 파일은 컨테이너에 설치해야 하는 패키지, 소스코드, 명령어, 환경변수 설정 등을 기록한 하나의 파일입니다.
매번 반복되는 과정을 단순하게 간소화 시켜줍니다.

이미지 출처 : https://data-newbie.tistory.com/516



  1. 도커 파일 생성
    (윈도우의 경우) 빈 file 을 열거나
    (리눅스의 경우) vim 이나 cat 을 통해 도커 파일을 작성합니다.

    • 윈도우 docker file

        FROM busybox
        CMD echo "Hello world! This is my first Docker image."
      
    • 리눅스/macOS docker file

        ~ $ cat > Dockerfile <<EOF
        > FROM busybox
        > CMD echo "Hello world! This is my first Docker image."
        > EOF
      


    • FROM busybox : busybox 를 base image 로 지정하겠다는 명령어 입니다.
      busybox 는 여러 유닉스 standard utilities 도구들을 담아놓은 실행 파일입니다.
    • CMD echo : 컨테이너가 시작할 때 실행할 커멘드를 지정합니다.
      docker image 를 빌드할 때 실행되는 것이 아니라 docker container 가 시작될 때 실행됩니다.
      주로 docker image 로 빌드된 application 을 실행할 때 쓰입니다.

    도커 파일 명령어는 아래에서 자세하게 다뤄보겠습니다.


  1. 도커 파일 빌드
    도커 파일을 빌드하면 이미지가 생성됩니다.
    아래와 같이 콘솔에 입력합니다.

    docker build -t hellobuild:0.1 .

    • -t 옵션은 생성될 이미지의 이름을 지정합니다.
    • :0.1 은 태그 버전을 지정합니다.
    • . 은 현재 디렉토리를 의미합니다. (현 디렉토리의 Dockerfile 을 찾아 build 합니다)


    아래와 같이 빌드가 진행됩니다.

    도커 파일 빌드


    docker images 를 입력해보면 이미지가 성공적으로 생성되어 등록된 것을 볼 수 있습니다.

    도커 파일 빌드 이미지


  1. 도커 이미지 실행
    빌드한 이미지를 실행시켜 보겠습니다.
    아래와 같이 콘솔에 입력합니다.

    docker run hellobuild:0.1


    echo 명령어가 실행되는 모습을 볼 수 있습니다.


  1. 도커 허브에 push 하기
    빌드된 이미지를 도커 허브 저장소에 저장해보겠습니다.


    (원격지)터미널로 돌아와 다음 명령을 입력하여 도커허브에 로그인합니다.
    (도커 허브 아이디/패스워드를 입력합니다)

    ` $ docker login `

    도커 허브 터미널 로그인


    도커 이미지에 tag 를 지정합니다.

    ` $ docker tag [이미지 이름] [도커 허브 유저 아이디]/[도커 허브 저장소 이름] `

    예시

     docker tag hellobuild:0.1 cholnh1/test-repo
    


    태그가 적용된 이미지를 도커 저장소에 push 합니다.

    ` $ docker push [도커 허브 유저 아이디]/[도커 허브 저장소 이름] `

    예시

     docker push cholnh1/test-repo
    


    저장된 이미지를 pull 명령을 사용하여 어느 컨테이너에서든 사용할 수 있습니다.


    예시

     docker pull cholnh1/hello-repo:latest
    

    또는

     docker run -p 8080:8080 -d --rm cholnh1/hello-repo:latest
    



자주쓰는 도커 파일 명령어

  • FROM
    생성할 이미지의 베이스가 될 이미지를 뜻합니다.
    반드시 한번 이상 입력해야 합니다.
    베이스 이미지를 지정할 때는 OS와 버전까지 정확하게 지정해주는 것이 좋습니다.
    • FROM ubuntu:16.04


  • LABEL
    이미지에 메타데이터를 추가합니다.
    추후 이 라벨을 통해 조건을 검색하여 원하는 컨테이너, 이미지 등을 쉽게 찾을 수 있습니다.
    • LABEL "purpose"="test"


  • RUN
    이미지를 만들기 위해 컨테이너 내부에서 명령어를 실행합니다.
    주로 (apt-get, wget 과 같은)설치/업데이트에 사용되곤 합니다.
    여기서 주의할 점은 설치과정에서 별도의 입력이 불가능하기 때문에 -y 와 같은 입력을 붙여줘야 합니다.
    • RUN apt-get install apache2 -y
    • RUN ["/bin/bash", "-c", "echo hello > test2.html"]


  • ADD [from] [to]
    파일을 이미지에 추가합니다.
    • ADD test.html /var/www/html


  • WORKDIR
    명령어를 실행할 디렉토리를 지정합니다.
    bash 쉘에서 cd 명령어와 동일한 기능입니다.
    • WORKDIR /var/www/html


  • EXPOSE
    이미지에서 노출할 포트를 설정합니다.
    • EXPOSE 80


  • ENTRYPOINT
    컨테이너가 시작될 때 시작할 명령어를 지정합니다.
    (docker run 또는 docker start 명령 으로 컨테이너 생성/시작할 때 해당 스크립트가 실행됩니다)
    Dockerfile 에서 단 한번만 사용할 수 있습니다.
    따옴표로 구분되는 형식은 매개 변수를 지정하기 위해 띄어 쓰는것과 같은 효과입니다.
    • ENTRYPOINT ["java", "-jar", "/app.jar"]
    • ENTRYPOINT ["npm", "run", "serve"]


  • CMD
    컨테이너가 시작될 때 시작할 명령어를 지정합니다.
    한 번만 사용할 수 있으며, 주로 docker image 로 빌드된 application 을 실행할 때 쓰입니다.
    • CMD echo "hello world!"
    • CMD apachectl -DFOREGROUND
    • CMD ["npm", "run", "serve"]


    CMDENTRYPOINT 는 컨테이너가 생성될 때 실행되는 것은 동일하지만 docker run 명령에서 동작 방식이 다릅니다.
    docker run 명령에서 실행할 파일을 설정하면 CMD 명령은 무시됩니다.


  • ARG
    도커파일 빌드시에 설정하는 환경 변수들을 지정할 수 있는 명령어입니다.
    • ARG JAR_FILE=helloworld.jar


  • VOLUME
    호스트의 디렉토리를 컨테이너에 연결하는 명령어입니다.
    여러 설정파일, 데이터 등을 컨테이너에서 사용할 수 있게 해줍니다.
    주로 로그 수집과 같은 데이터 저장(호스트에 저장)에 쓰입니다.
    • VOLUME /helloworldVolume
    • VOLUME 호스트디렉토리 컨테이너디렉토리
    • VOLUME ["/data", "/var/log"]