docker 관련 내용 정리

docker 관련 내용 정리

2019, Feb 21    


목차


  • 도커란 무엇인가?

  • 쿠버네티스란 무엇인가?

  • 도커 설치 방법

  • 도커 기본 사용법


  • Immutable infrastructure 패러다임

  • 간략히 Docker 살펴보기

    • 도커란?

    • 도커만의 특징/유의사항

    • 컨테이터 Orchestration

    • 도커 레지스트리

    • 도커 파일(Dockerfile)

  • 도커 설치하기


도커란 무엇인가?


  • 도커는 가상 머신과 같이 독립적인 공간을 쉽게 가질 수 있게 하는 오픈소스 입니다.
  • 하지만 도커는 가상 머신에 비하여 다양한 장점을 가지고 있습니다. 도커는 가상 머신처럼 독립적으로 실행되지만 ① 가상머신보다 빠르고, ② 가상머신보다 다루기가 쉽고 ③ 가상머신보다 효율적입니다.
  • 앞에서 언급한 독립적인 공간이라 하면 프로세스, 파일 및 디렉토리, CPU, Memory I/O 등을 분리하는 것을 뜻합니다. 사실 도커없이는 굉장히 힘든 작업인데, 도커를 이용하여 이를 쉽게 구현할 수 있습니다.


Drawing


  • 지금까지 내용으로는 흔히 알고 있는 가상 머신과 비슷하다고 생각이 들 수 있습니다. 하지만 가장 큰 차이점을 위 그림과 같이 가상 머신(VM)에만 존재하는 부분이 도커에서는 필요 없다는 점입니다. 따라서 도커는 가상 머신보다 효율적으로 사용할 수 있습니다.


  • 도커에는 다양한 특징이 있는데 그 중 몇가지를 살펴보도록 하겠습니다.


  • 먼저 확장성입니다.
  • ① 도커가 설치되어 있다면 어디서든 컨테이너를 실행할 수 있고 ② 특정 회사나 서비스에 종속적이지 않으며 ③ 쉽게 개발서버를 만들 수 있고 테스트서버 생성도 간편합니다.


  • 다음으로 표준성입니다.
  • 컨테이너라는 표준으로 서버를 배포하므로 모든 서비스들의 배포과정이 동일해지는 장점이 있습니다.


  • 그리고 이미지 라는 특성이 있습니다.
  • 도커를 사용할 때, 이미지에서 컨테이너를 생성하기 때문에 반드시 이미지를 만드는 과정이 필요합니다.
  • 이미지를 만들 때, Dockerfile을 이용하여 이미지를 만들어서 처음부터 재현 가능하도록 관리할 수 있습니다. (가상 머신을 사용할 때에는 재현 가능하도록 관리하기가 어려운 점이 있었습니다.)
  • 사용자 측면에서는 빌드 서버에서 이미지를 만들면 해당 이미지를 이미지 저장소에 저장하고 운영서버 에서 이미지를 불러와서 사용하면 됩니다.


  • 다음으로 설정 관리에 특성을 가지고 있습니다.
  • 일반적으로 설정은 보통 환경변수로 관리를 합니다. MYSQL_PASS=password와 같이 컨테이너를 띄울때 환경변수를 같이 지정하여 이미지가 생성하도록 합니다.
  • 따라서 하나의 이미지가 환경변수에 따라 동적으로 설정파일을 생성하도록 만들어져야합니다.


  • 마지막으로 자원 관리 특성을 알아보겠습니다.
  • 컨테이너는 삭제 후 새로 만들면 모든 데이터가 초기화 됩니다. 따라서 업로드 파일을 외부 스토리지와 링크하여 사용하거나 S3같은 별도의 저장소가 필요합니다.


  • 도커의 이런 특성들로 인하여 대부분의 회사에서는 도커를 사용하여 개발 환경 관리를 할 수 있게 되었습니다.
  • 도커를 통하여 다른 프로세스와 격리되어 가상머신처럼 사용하지만 성능저하 (거의) 없고 복잡한 기술을 몰라도 사용할 수 있게 되었습니다.
  • 이미지 빌드 기록이 남고 코드와 설정으로 관리, 재현 및 수정이 가능해져서 여러 방면의 장점을 가지고 있습니다.


쿠버네티스란 무엇인가?


  • 쿠버네티스여러대의 서버여러개의 서비스를 관리하기 쉽게 해주는 툴입니다.
  • 이 글에서 쿠버네티스에 대하여 자세하게 알아보지는 않을 예정입니다만 3가지 특성을 통하여 쿠버네티스의 의미를 살펴보도록 하겠습니다.
  • 스케줄링
    • 컨테이너를 적당한 서버에 배포해 주는 작업
    • 여러 대의 서버 중 가장 할일 없는 서버에 배포하거나 그냥 차례대로 배포 또는 아예 랜덤하게 배포합니다.
    • 컨테이너 개수를 여러 개로 늘리면 적당히 나눠서 배포하고 서버가 죽으면 실행 중인 컨테이너를 다른 서버에 띄워줍니다.
  • 클러스터링
    • 여러 개의 서버를 하나의 서버처럼 사용
    • 작게는 몇 개 안 되는 서버부터 많게는 수천 대의 서버를 하나의 클러스터로 사용
    • 여기저기 흩어져 있는 컨테이너도 가상 네트워크를 이용하여 마치 같은 서버에 있 는 것처럼 쉽게 통신


도커 설치 방법


  • 도커는 기본적으로 리눅스에서 동작하는 프로그램입니다. 설치를 할 때에는 리눅스의 유형 (Ubuntu, CentOS 등)에 따라서 자동으로 최선 버전의 도커가 설치됩니다.
  • 먼저 리눅스에서 도커를 설치하기 위해서 다음 명령어를 이용하여 간단하게 설치할 수 있습니다.


  • sudo apt-get install curl
  • curl -s https://get.docker.com/ | sudo sh


  • 설치한 도커를 사용할 때, docker 일반 유저 사용 권한 문제가 발생하는 경우가 있습니다. 즉, docker 가 root 계정으로 설치되면 root 계정이 아닌 계정으로 docker 실행 시 permission 문제가 발생합니다. 예를 들어 Solving Docker permission denied while trying to connect to the Docker daemon socket와 같은 경고가 발생합니다.
  • 이 때, 로그인 한 계정에 docker 그룹을 추가하여 사용 권한 문제를 해결할 수 있습니다.


  • sudo usermod -aG docker $USER


  • usermod는 user modification의 약자로 사용자 계정의 정보를 변경합니다. -a는 계정에 정보를 추가하는 것이고 -G는 추가할 대상이 그룹임을 명시하는 것으로 종합하여 usermod -a -G <그룹> <계정>로 사용하였을 때, docker라는 그룹을 $USER에 그룹을 추가하게 되어 권한 문제를 해결할 수 있습니다.


  • 반면 윈도우와 리눅스에서 도커를 설치하는 방법은 조금 다릅니다. 왜냐하면 앞에서 설명한 바와 같이 도커는 기본적으로 리눅스 위에서 동작하기 때문입니다.
  • 따라서 아래와 같은 Docker for Mac 또는 Docker for Windows를 설치하여 Mac OS 또는 윈도우의 가상 머신 위에 docker가 설치되도록 합니다.
  • 가상 머신을 위해서 Mac OS에서는 xhyve를 윈도우에서는 Hypter-V가 사용되어집니다.


Drawing


  • 설치가 완료되면 docker version을 커맨드에 입력하여 정상적인 화면이 출력되는 지 확인해 봅니다.
  • 이 때, 도커는 Client - Sever 구조를 통하여 아래 그림과 같이 동작하는 프로세스를 가집니다.


Drawing


  • 먼저 ① Client 측에서 docker와 관련된 명령어를 입력하면 그 명령어에 따라서 ② docker의 서버 (host)에서 실제 동작을 하게 되고 ③ 그 결과를 다시 출력하게 됩니다. 즉, docker CLI는 도커 호스트에 명령을 전달하고 결과를 받아서 출력하는 역할을 한다고 정의할 수 있습니다.


도커 기본 사용법








Immutable infrastructure 패러다임


  • 도커를 알기 위해서 인프라 스트럭처의 큰 틀인 IIP(Immutable infrastructure paradigm)에 대하여 먼저 간략하게 알아보겠습니다.
  • IIP는 한번 어떤 인프라가 만들어지면 그것을 수정하지 않겠다는 패러다임인데 이것은 이미지 기반 애플리케이션 배포 시나리오에서 사용되고 있습니다.
  • 이 컨셉은 하나의 컴퓨터에서 한 서버를 관리하는 환경이 아닌 다수의 서버를 동적으로 관리하는 클라우드 기반에서 어떻게 유연하게 배포할 수 있을까에 대한 고민에서 나온 패러다임 입니다.
  • 즉, 기존의 서버를 관리한다는 개념 보다 어떻게 하면 서버를 잘 쓰고 버리는 지에 포커스를 둔 것이라고 보면 됩니다.
  • 이런 IIP에서는 다음 단계들을 통하여 이미지 배포를 통해 어떻게 하면 서버를 잘 쓰고 버리는 지에 초점을 맞춥니다.
    • 개발 단계에서 인프라를 구축합니다.
    • 개발 단계에서 dev test를 거칩니다.
    • 스태이징 단계에서 테스트를 거칩니다.
    • 테스트를 마치면 프로덕션에 적용합니다.
    • 문제가 생길 경우 현재 인프라를 수정하지 않고 새로운 버전의 인프라를 배포합니다.
  • 서버를 한번 세팅하고 나서 설정 변경이 필요할 때, 변경 부분을 지속적인 업데이트를 통해 관리 하는 것을 snowflake 서버 패턴이라고 합니다.
    • 이 경우 새로운 서버를 세팅하고자 할 때, 동일한 환경을 구성하기 어렵고 누락된 설정이나 패치 등에 의해서 장애가 발생하는 경우가 많습니다.
    • 한 번 설정이 되고 나면 다시 똑같이 설정하기가 어려워 마치 눈처럼 녹아버리는 서버 형태라고 해서 snowflake 라고 부릅니다.
  • 반면에 이 글에서 알아볼 서버 패턴은 phoenix 서버 패턴입니다.
    • 앞에서 설명한 IIP 컨셉이 적용된 서버 패턴입니다. 즉, 한번 생성한 서버는 거의 수정해서 쓰지 않습니다.
    • 대신에 새로운 서버를 세팅할 때 마다, 처음 OS 설치에서 부터 소프트웨어 인스톨, 설정 변경까지 모든 것을 반복합니다.
  • phoenix 서버 패턴의 컨셉을 보면 상당히 귀찮아 보이는데 이 글에서 다룰 도커를 이용하면 이 작업을 아주 편하게 할 수 있습니다.
  • 따라서 도커를 이용하면 snowflake 서버 패턴의 단점인 재사용성을 개선할 수 있고 phoenix 서버 패턴의 작업 반복성도 줄일 수 있어서 상당히 효율적이게 됩니다.


간략히 도커 살펴보기


도커란?


  • 도커는 빠르고 가벼운 가상화 솔루션 입니다.
  • 도커는 애플리케이션과 그 실행환경 / OS를 모두 포함한 소프트웨어 패키지이고 이것을 도커 이미지라고 부릅니다.
  • 도커는 플랫폼에 상관없이 실행될 수 있는 애플리케이션(도커 이미지 컨테이너)으로 도커 엔진만 설치되어 있으면 어디에서나 실행이 가능합니다.
    • 대상: 로컬 머신(윈도우/맥/리눅스), Azure, AWS 등등
    • 하나의 도커 이미지를 통해 다수의 컨테이너를 생성할 수 있습니다.
  • 생성된 도커 컨테이너는 바로 쓰고 버리는 것 (Immutable Infrastructure 패러다임)
    • 이전에 Virtual Machine을 사용할 때에는 한 번 생성하면 애지중지 관리를 하였지만 도커에서 컨셉상 그렇게 하진 않습니다.
  • 도커 컨테이너는 격리되어있어서, 해킹되더라도 도커 엔진이 구동되는 원래의 서버에는 영향을 끼치지 않습니다.


도커만의 특징/유의사항


  • 도커 내에서는 어떤 프로세스가 도는 지 명확히 하기 위해서 다양한 프로세스가 구동되는 것을 지양합니다.
    • 즉, 한 종류의 프로세스만을 구동하는 것을 지향합니다.
  • 또한 한 도커 내에서 프로세스를 백그라운드로 구동하는 것을 지양합니다.
    • 프로세스를 Foreground로 구동하는것을 지향합니다.
      • nginx 예시 : nginx -g daemon off;
    • 실행 로그도 표준출력(stdout)으로 출력합니다.
  • 즉, 도커는 한 프로세스를 Foreground형태로 돌리는 것을 지향하기 때문에 하나의 도커는 하나의 프로세스 처럼 느껴지게 됩니다.


컨테이터 Orchestration


  • 도커는 원칙적으로 한 프로세스만 돌리게 되므로 하나의 서버에 N개의 프로세스가 필요하면 N개의 도커 컨테이너가 필요한 것이 원칙입니다.
  • 그러면 다양한 서비스를 운영하려면 도커 컨테이너의 갯수도 많아지게 되므로 컨테이너 관리 툴이 필요하게 됩니다.
  • 예를 들어 컨테이너 자동 배치 및 복제, 컨테이너 그룹에 대한 로드 밸런싱, 컨테이너 장애 복구, 컨테니터 추가 또는 제거, 컨테이너 서비스 간의 인터페이스를 통한 연결 및 네트워크 포트 노출 제어등이 있습니다.
  • 도커 컨테이너를 관리하는 다양한 툴이 다양한 회사에서 제공되고 구글의 쿠버네티스도 그 종류 중 하나입니다.
  • 우리가 사용해 볼 도커 컨테이너 관리 툴은 MS의 Azure Container for Web App이고 웹서비스 전용 툴입니다.


도커 레지스트리


  • 깃의 저장소인 깃헙과 같이 도커 이미지 저장소를 뜻합니다.
  • 공식 저장소는 도커 Hub : https://hub.docker.com/ (Docker 계의 GitHub) 입니다.
  • Azure Containers for Web App 에서는 도커 레지스트리로부터 이미지를 읽어들여, 도커 컨테이너를 적재합니다.


도커 파일(Dockerfile)


  • 도커 파일은 도커 이미지를 만들 때, 수행할 명령과 설정들을 시간순으로 기술한 파일입니다.
  • 도커 파일의 이름은 Dockerfile이어야 하고 첫 글자는 대문자 이어야 됩니다.

  • 아래는 도커 파일의 예제입니다.


FROM ubuntu:16.04

RUN apt-get update && apt-get install -y python3-pip python3-dev && apt-get clean

RUN mkdir /code

WORKDIR /code

ADD requirements.txt /code/

RUN pip3 install -r requirements.txt

ADD . /code/

EXPOSE 8000
CMD ["python3", "/code/manage.py", "runserver", "0.0.0:8000"]


  • FROM ubuntu:16.04
    • 도커 이미지는 OS 정보를 가지고 있어야 합니다.
  • RUN apt-get update && apt-get install -y python3-pip python3-dev && apt-get clean
    • 각 OS에 맞는(리눅스는 Shell, 윈도우는 명령 프롬프트) 실행창에서 수행할 명령어를 입력합니다.
    • && 명령어로 연결된 것은 && 명령어 앞의 명령 수행이 정상적으로 완료되어야 뒤에 명령어가 수행된다는 의미 입니다.
      • 내부적으로 exit code의 return 값이 0이면 성공, 그 이외에는 실패라는 것을 이용기 때문이지요.
    • 반면 ;으로 명령어가 연결된다면 앞선 명령어의 성공 여부와 상관없이 수행되겠다는 의미가 됩니다.
  • WORKDIR /code/
    • 수행되는 workdir을 설정합니다.
  • ADD requirements.txt /code/
    • 도커 host측의 파일(requirements.txt)을 도커 이미지(/code/)로 복사하겠다는 의미 입니다.
  • ADD . /code/
    • 도커 host측의 파일을 도커 이미지로 모두 복사하겠다는 의미 입니다.
  • EXPOSE 8000
    • 호스트 측과 연결할 컨테이너 포트 번호를 입력합니다.
    • 포트는 호스트측 번호와 컨테이너측 번호가 따로 존재 합니다. 여기서 정의되는 것은 컨테이터 측의 포트 번호이고 이 포트 번호를 이용하여 호스트측의 포트와 연결합니다.
  • 여기 까지 사용된 명령어 들은 도커가 빌드할 때 사용되는 명령어들 입니다. 반면 CMD는 도커가 run 할 때 사용 되는 명령어 입니다.