수학과의 좌충우돌 프로그래밍

[배포]Azure 를 이용한 배포, 서버패턴과 Docker 본문

웹프로그래밍/배포

[배포]Azure 를 이용한 배포, 서버패턴과 Docker

ssung.k 2019. 5. 26. 17:42

이번에는 Docker 에 대해서 알아보고자 합니다. 그리고 이를 쉽게 이해하기 위해서 먼저 immutabel infrastructure 패러다임서버 패턴을 먼저 알아보겠습니다.

immutable infrastructure 패러다임

이미지 기반 애플리케에션 배포 시나리오입니다. 여기서 이미지라고 하는 것은 Docker image 할 때 그 image로서 뒤에서 다시 한 번 다루도록 하겠습니다. 이름에서도 알 수 있듯이 인프라가 만들어지고 거의 변경하지 않습니다. 만약 변경할 일이 생긴다면 기존에 있던 배포된 서버를 수정하는 것이 아니라 기존 서버는 날리고 새로운 것을 다시 배포하여 관리합니다. 이 방법이 절대적으로 좋은 방법이라기 보다는 이렇게 하면 보다 유연하게 배포할 수 있을 거라는 생각에 나온 패러다임입니다.

snowflake (눈송이) 서버 패턴

서버를 한 번 셋업하고 나서 설정을 변경하고 패치를 적용하는 등의 업데이트를 지속적으로 적용, 운영하는 서버 관리 방식을 말합니다. 새로운 서버를 만들때 동일한 환경을 구성하기 어렵고, 누락된 설정이나 패치 등에 의해서 장애가 발생할 수도 있습니다. 한 번 설정을 하고 나면 다시 설정이 불가능하기 힘들기 때문에 마치 녹아버린 눈과 같다하여, 이름을 붙였습니다.

phoenix 서버 패턴

다시 태어나는 피닉스 처럼, 한 번 생성된 서버는 수정해서 다시 쓰지 않고 서버를 새로 만들기 때문에 다음과 같은 이름을 붙였습니다. 새로운 서버를 세팅할 때 마다 처음 OS 설치부터 소프트웨어, 설정 변경까지 모두 반복해야하는 탓에 매번 긴 시간이 소요됩니다. 이를 개선하기 위해서 베이스 이미지를 만들어 놓고 차이가 나는 부분만 재설정 합니다. 이 과정에서 Docker 와 같은 도구들을 활용하게 됩니다.

Docker 가 무엇이고 이를 어떻게 사용하는 것일까요? 이제 Docker 에 대해서 알아보도록 하겠습니다.

Docker란?

실제 사회에서 물류 분야에서는 컨테이너를 만들어서 화물을 운반하게 됩니다. 이러한 개념을 컴퓨터세계에도 도입시켰고 이러한 컨테이너 시스템 중 하나가 Docker 입니다. 어려운 개념이고 알아야 할 것이 많지만 우선 배포를 하기 위한 개념, 명령어 위주로 다뤄보도록 하겠습니다. Docker 는 빠르고 가벼운 가상화 솔루션이기 때문에 핫 합니다.

위에서 몇 번 image에 대해서 언급했었습니다. Docker image 란 애플리케이션과 그 실행환경, OS 를 모두 포함한 소프트웨어 패키지 입니다. 실행한 필요한 모든 것이 다 담겨 있기 때문에 플랫폼에 상관없이 Docker image만으로 실행이 가능합니다. 원도우, 맥, 리눅스, Azure, AWS 등 어디서든 실행할 수 있다는 말입니다. 물론 Docker image 를 실행시키는 Docker Engine은 존재해야 하겠죠. 하나의 Docker image로는 다수의 container 를 생성할 수 있습니다. 생성된 Docker container 는 다양한 방식으로 사용할 수 있겠지만 요즘에는 쓰고 바로 버리는 식으로, 즉 immutabel infrastructure 패러다임으로 많이 접근을 합니다. 또한 Docker container는 독립적이기 때문에 이에 문제가 생기거나 해킹을 당한다고 하더라도 Docker engine이 구동되는 원래의 서버에는 영향을 끼치지 않습니다.

image와 container의 개념이 헷갈리고 와닿지 않을 수 있어서 사용되는 부분을 생각해보면, Docker image로 Docker container 를 만들고 이를 개개인에게 서비스 해준다고 생각하면 되겠습니다.

Docker의 특징

Docker 내에서 어떤 프로세스가 도는 지 명확히 하기 위해서 하나의 Docker 내에서 다양한 프로세스가 구동되는 것을 지양합니다. 물론 이러한 방식이 버그를 발생시키거나 다른 문제를 유발하는 것은 아닙니다. 따라서 대게, 하나의 Docker 내에서 한 종류의 프로세스 만을 구동합니다. 예를 들어 데이터베이스 container,cache container 이런 식으로 구분을 해줍니다. 또한 Docker 내에서 프로세스를 background 로 구동하는 것보다는 foreground 형식으로 구동하길 권장합니다. 이 이유에 대해서는 뒤에서 실습을 하면서 자세히 설명하도록 하겠습니다. 또한 하나의 Docker container 안에 하나의 프로세스가 존재하기 때문에 실행로그를 표준출력으로 출력할 수 있습니다.

Container Orchestration

orchestration 이라는 말은 오케스트라를 생각하시면 됩니다. 오케스트라에서는 한 악기, 한 명의 연주자만이 존재하는 것이 아니라 여러 사람, 다양한 악기가 각자의 위치에서 연주를 하면 이 합주가 하나의 곡을 완성시킵니다. 이와 비슷하게 하나의 서버에서도 여러 Docker container가 존재하게 됩니다. 그 이유는 위에서 말했듯이, 한 container 안에 하나의 프로세스만을 권장하기 때문입니다. 이 container 들을 어떻게 배치하고, 장애나 복구는 어떻게 할지, 이 외에도 추가 제거 확정 노출 연결 등 다양한 이슈에 대해서 다뤄줘야 합니다.

이러한 이슈를 다뤄주는 tool이 존재하는데 구글의 kubernetes, Docker Swarm 등이 있으며 이번에는 웹서비스 전용인 Azure containers for web app 서비스를 사용할 예정입니다.

Docker registry

github은 코드저장소, git을 위한 서비스라고 하면, docker registry 는 Docker 이미지 저장소, Docker 를 위한 서비스 입니다. 대표적인 저장소는 Docker Hub 으로 아래 url 로 접속할 수 있습니다.

https://hub.docker.com/

Docker images 는 로컬에 저장되어 있으니 다른 사람과 공유하고 싶을 경우 이를 사용하여 편하게 쉽게 공유하고 관리할 수 있습니다. Docker hub 외에도 각 클라우드 벤더에서 저장소 지원 해줍니다. Docker hub 를 사용할 경우 접속하고 다운 받는 시간적 비용이 발생하게 되는데 각 클라우드에서 이를 할 경우 이를 줄일 수 있기 때문에 사용에 이점이 있습니다. azure container registryaws elastic container registy 등이 있습니다.

Dockerfile

Docker 이미지를 만들 때 docker build 라는 명령어로 이미지를 만들게 됩니다. 이 때 수행할 명령과 설정들을 시간 순으로 기술한 파일을 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.0:8000"]
  • FROM

    base image 운영체제 설정

  • RUN (1)

    shell 명령어로서, && 는 앞선 명령이 성공하면 뒤에 명령을 성공하겠다는 뜻입니다. 패키지 관리자를 업데이트하고 필요한 것들을 install 합니다.

  • RUN (2)

    마찬가지로 shell 명령어로서 code 라는 디렉토리를 만듭니다.

  • WORKDIR

    code 를 working directory 로 지정합니다.

  • ADD (1)

    호스트 쪽의 requirements.txt 를 image 측의 /code/ 로 copy 합니다.

  • RUN (3)

    방금 복사해온 requirements.txt 를 실행합니다.

  • ADD (2)

    호스트 쪽에 있는 모든 파일을 /code/ 쪽으로 copy 합니다.

  • EXPOSE

    호스트 쪽으로 노출시킬 포트를 기재해줍니다. 이를 했다고 해서 아직 연결된 것은 아니지만 이 과정이 없다면 후에 연결을 할 수 없습니다. 실제 연결은 후에 컨테이너를 띄우는 명령어, docker run -p 호스트의 포트:컨테이너의 포트 로서 두 포트를 연결해주게 됩니다.

  • CMD

    docker run 을 할 때 이 명령을 같이 수행합니다. 리스트의 각 원소들을 " " 로서 연결해주어서 python3 /code/manage.py runserver 0.0.0.0:8000 을 수행합니다.

Comments