[DE] docker

박경국·2022년 2월 21일
0

Data Engineering

목록 보기
12/16
post-thumbnail

상황1. 늘어난 접속량을 처리하기 위해 서버를 증설한다. 기존의 서버의 환경을 증설하는 서버1,2,3에 구현해야 한다.

상황2. 같은 서버에 여러 서비스를 구현한다. 각 서비스는 IP, 포트, 방화벽, 사용하는 언어의 버전이 모두 다르다(ex. 새로운 서비스는 Java8, 기존 서비스는 Java7에서 구동).

1. docker란?

  • 도커는 어플리케이션 실행 환경을 이미지화합니다.
  • 도커는 OS를 격리화하여 실행 환경을 독립적으로 관리하는 기술입니다.

도커에 대한 이 두 가지 설명이 상황1과 상황2를 해결할 열쇠가 됩니다. 두 가지 설명만 보면 가상머신과 구분이 어려울 수 있습니다. 가상머신과 도커의 가장 큰 차이는 가상머신은 OS 위에 다른 OS를 실행하는 반면, 도커는 OS 위에 리눅스의 컨테이너 기술로 각 환경을 격리한다는 점입니다.

이 차이 덕분에 도커는 가상머신과 다른 방식으로 컴퓨터의 리소스를 활용합니다. 가상머신은 컴퓨터의 리소스를 정확히 1/n합니다. 3개의 가상머신이 있다면 컴퓨터의 성능을 각자 1/3씩 사용합니다. OS 위에 OS를 구동하는 것인만큼 필요한 리소스도 많을텐데, 가상머신은 좋은 성능을 내기 어려워집니다. 이를 리소스 격리성이라고 합니다. 대신 가상머신은 서버 별로 완전한 격리가 가능합니다.

반면 도커는 리눅스 컨테이너라는 기술을 사용합니다. 리눅스 컨테이너는 필요한 라이브러리와 어플리케이션을 모아서 별도의 컴퓨터 환경을 만듭니다. 이때 리소스는 각 컨테이너가 필요한만큼 가져갑니다. A 환경(서버)가 sleep 상태라면 B 환경(서버)가 모든 리소스를 사용할 수 있습니다. 이러한 도커의 특징을 세 가지로 정리할 수 있을 것 같습니다.

  • 프로세스 구획화
    A 컨테이너에서 작동하는 프로세스는 그 컨테이너 안에서만 접근할 수 있습니다. A 컨테이너에서 실행되는 프로세스는 B 컨테이너의 프로세스에 영향을 줄 수 없습니다.

  • 네트워크 구획화
    컨테이너 하나에 하나의 IP 주소가 할당됩니다. 기능, 목적 별로 컨테이너를 구성하여 하나의 컴퓨터에서 여러 개의 서버를 운영할 수 있습니다.

  • 파일시스템의 구획화
    컨테이너 안에서 사용되는 디렉토리도 마찬가지로 구획화되어 있습니다. 컨테이너의 명령이나 파일 등에 접근하기 위해서는 개별 컨테이너의 경로로 접근해야 합니다. 외부에서 컨테이너의 명령이나 파일 등에 쉽게 접근할 수 없다는 의미입니다.

2. docker image / container / compose

도커는 크게 image, container로 이루어져 있습니다. 그리고 여러 개의 container를 유기적으로 활용하기 위한 compose도 있습니다. 이외에도 사용설명서라고 할 수 있는 dockerFile, hub 등이 있지만, 기본적으로 image를 어떻게 구성하고, container를 어떻게 실행할 지에 관한 설명이므로 image와 container에 대한 이해가 선행되어야 합니다.

1) docker image

상황1로 돌아가서 하나의 환경을 다른 곳에 구현하기 위해서는 어떻게 해야할까요? 설치하려는 컴퓨터 환경을 확인하고, 필요한 패키지와 프로그램을 하나하나 설치해야하지만, docker를 이용하면 손 쉽게 해결할 수 있습니다.

docker image는 구현하려는 개발 환경을 사진 찍은 것처럼 이미지화합니다. 그리고 이 이미지로 저장된 항목이 함께 연결되어 동작하도록 문서나 명령어 형태로 저장할 수 있습니다.

이렇게 이미지화된 개발 환경을 docker hub에 올리면 github에서 clone, pull하는 것처럼 언제든 어디서든 이미지화된 개발 환경을 구현할 수 있습니다. 그리고 이 개발 환경은 컴퓨터에 바로 설치되지 않고, 컨테이너라는 독립된 가상 환경에 설치됩니다.


#docker hub에서 이미지를 가져옵니다.
$ docker image pull {Registry_Account/Repositoy_Name}:{Tag}

#컴퓨터에서 이미지를 찾고, 없다면 hub에서 내려받은 뒤 실행합니다.
$ docker run {Registry_Account/Repositoy_Name}:{Tag}

2) docker container

container는 image가 실행된 결과라고 이해하면 쉽습니다. docker hub에서 사용하려는 프로그램, 환경을 pull한 뒤, image에 있는 documents에 따라 image가 동작합니다. 그리고 이 동작은 container라는 독립적인 환경에서 이루어집니다.

#도커 이미지를 {name}이라는 이름으로 실행합니다.
$ docker container run --name {Name} {Regi/Repo_Name:tag}

#현재 실행 중인 container를 image로 만들어라
$ docker container commit {이미지로 만들려는 컨테이너 이름} {저장하려는 이미지 이름 : tag}

3) docker compose

독립된 컨테이너들이 함께 동작할 수 있도록 연결지어주는 방식입니다. .yml 확장자 파일로 동작에 필요한 요소들을 지정해줄 수 있습니다. 프론트엔드와 백엔드가 별도의 컨테이너에서 동작하는 경우 각각의 네트워크가 분리되어 있기 때문에 서로 데이터를 주고 받지 못합니다. docker compose를 이용하면 이러한 문제를 해결할 수 있습니다.

version: '3'
services:
  database:
    # Dockerfile이 있는 위치
    build: ./database
    # 내부에서 개방할 포트 : 외부에서 접근할 포트
    ports:
      - "3307:3306"
  backend:
    build: ./backend
    # 연결할 외부 디렉토리 : 컨테이너 내 디렉토리
    volumes:
      - ./backend:/usr/src/app
    ports:
      - "5000:5000"
    # 환경변수 설정
    environment: 
      - DBHOST=database
  frontend:
    build: ./frontend
    # 연결할 외부 디렉토리 : 컨테이너 내 디렉토리
    volumes:
      - ./frontend:/home/node/app
    ports:
      - "8080:8080"

*얄코님의 <가장 쉽게 배우는 도커>의 실습 내용 중 일부입니다.

위와 같이 yml 파일을 구성하면 services에 포함된 dockerfile이 서로 연결됩니다. backend는 환경변수(DBHOST=database)를 통해서 database에 접근할 수 있게 됩니다.

0개의 댓글