[내일 출근인데 어떡하지] Docker 개념부터 실행까지 🐳

Judy·2023년 5월 21일
0

Docker 를 이용해서 인스턴스를 생성하고 웹 서버를 구동해 주세요

만약 신입사원인 당신에게 퇴근 전에 갑자기 이렇게 퀘스트가 주어지면 어떨까요?
Docker 를 다뤄 보기는커녕 무엇인지조차 모르는데 말이죠!
'내일 출근인데 어떡하지 😱' 라는 생각에 우선 걱정이 앞설 테고
어떤 자료를 찾아보고 공부해야 할지 막막하지 않을까요?

'내출어' 시리즈는 이 글을 읽는 분들이 이러한 상황에 처했다고 가정했을 때
오늘 밤, 하나의 주제에 대해 한 편의 글을 읽고 나면 내일의 출근이 더 이상 막막하지 않도록
간략한 기초 이론/개념과 팁을 드리는 것이 목표입니다! 🙌

기존의 도커 메뉴얼과 포스팅이 많아서 제 글에서는 어떻게 차별화할까 고민하다가
도커 입문 강의와 현업에서 배운 내용들을 모두 한번에 정리했습니다.
(도커 입문 강의는 2023년 4월에 진행된 '원티드 프리온보딩 백엔드 코스' 입니다.)

1. Introduction

Docker?

컨테이너화 된 애플리케이션을 배포, 관리 및 실행하기 위한 오픈소스 플랫폼

  • 컨테이너 기반 가상화 도구
    • 리눅스 컨테이너 기술인 LXC(Linux Containers) 기반 애플리케이션을 컨테이너라는 단위로 격리하여 실행하고 배포하는 기술
    • 리눅스 커널을 공유하면서 프로세스를 격리된 환경에서 실행
  • 애플리케이션을 컨테이너라는 단위로 격리하여 실행하고 배포하는 기술
    • 애플리케이션을 빠르게 개발하고, 효율적으로 배포, 관리할 수 있음

Container (컨테이너)

  • 컨테이너는 가상화 기술 중 하나
  • 호스트 운영체제 위에 여러 개의 격리된 환경을 생성 각각의 컨테이너 안에서 애플리케이션을 실행

Virtualization (가상화)

  • 하나의 물리적인 컴퓨터 자원 (CPU, 메모리 저장장치) 등을 가상으로 분할하여 여러 개의 가상 컴퓨터 환경을 만들어 내는 기술
  • 물리적인 컴퓨터 자원을 더욱 효율적으로 사용할 수 있음
  • 서버나 애플리케이션 등을 운영하는 데 있어 유연성과 안정성 제공

정리

  • Docker 와 같은 컨테이너 가상화 기술을 통해 하나의 서버에 다수의 컨테이너를 실행하면 컨테이너끼리 서로 영향을 끼치지 않고 독립적으로 실행됨
  • 실행중인 컨테이너에 접속하여 명령어 입력, 패키지 설치 등 다양한 작업을 할 수 있음
  • CPU 혹은 메모리를 제한할 수 있으며 호스트 디렉토리에 마운트하여 내부 디렉토리로 사용할 수 있음
  • Docker 와 같은 컨테이너 가상화 방식을 사용하면 개발 단계부터 테스트 및 프로덕션에 이르기까지 일관된 환경을 유지할 수 있고 환경 구축이 빠름
    • 하나의 프로세스(컨테이너)를 실행하는데 필요한 모든 파일을 이미지로 만들어 놓고 제공하기 때문!

2. Architecture


https://docs.docker.com/get-started/overview/

도커 데몬(Docker daemon = dockerd)

  • 도커 엔진의 핵심 구성 요소
  • 도커 호스트에서 컨테이너를 관리하고 실행하는 역할
  • 컨테이너를 생성, 시작, 중지, 삭제하는 등의 작업을 수행
  • 컨테이너 이미지를 관리하고
  • 외부에서 이미지를 다운로드하고 빌드하는 작업을 수행

도커 클라이언트 (Docker Client)

  • Docker와 상호 작용
  • docker 명령어를 사용하면 Docker daemon으로 보내어 실행

도커 오브젝트 (Docker Object)

도커 파일 (Docker File)

  • 도커에서 이미지를 생성(빌드)하기 위해 텍스트 파일 (=일종의 템플릿)
  • 기본 이미지, 애플리케이션 종속성, 구성 및 기타 필수 컨테이너(인프라) 구성 요소를 정의
    • 베이스가 될 도커 이미지, 도커 컨테이너 안에서 수행한 명령, 환경변수 등의 설정, 도커 컨테이너 안에서 작동시킬 데몬 실행과 같은 컨테이너 구성 정보 기술

이 도커 파일을 빌드하면 도커 이미지 가 생성됩니다.
또는 도커 파일을 따로 만들고 빌드하는 대신 Docker Hub 에서 미리 만들어진 이미지를 다운로드하여 이용할 수 있습니다.

도커 이미지 (Docker Image)

  • 도커 컨테이너를 생성하기 위한 읽기 전용 템플릿
  • 애플리케이션, 그에 필요한 모든 종속성을 포함
  • 도커 이미지를 도커 레지스트리에 저장하여 애플리케이션을 배포하고 여러 서버에서 동시에 실행할 수 있음

이 도커 이미지를 실행하면 도커 컨테이너가 생성됩니다.
Docker에서 공식적으로 제공해주는 이미지가 있으며 사용자는 해당 이미지 혹은 다른 개발자들이 만들어 놓은 이미지를 사용하여 본인만의 커스텀 이미지를 만들 수 있습니다.

도커 레지스트리 (Docker Registries)

  • 도커 이미지를 관리하고 저장하는 곳

도커 레지스트리에는 이미지를 만들어 push할 수 있으며 push된 이미지는 다른 사람들과 공유할 수 있습니다.
(저는 GitHub 와 유사하다고 이해했습니다. 오픈소스를 GitHub 에 올려 두면 직접 모든 코드를 작성하지 않고 git clone 으로 내려받기만 해도 즉시 필요한 코드와 기능을 이용할 수 있으니까요!)

도커 컨테이너 (Docker Container)

  • 한 도커 이미지의 실행 가능한 인스턴스
  • 애플리케이션을 실행하기 위한 모든 파일과 설정 정보를 포함하는 패키지
  • 이미지를 실행시켜 컨테이너라는 가상화 공간을 만들며, Docker만 올바르게 설치되었다면 어디서든지 저장소로부터 이미지를 가져와 컨테이너를 실행시킬 수 있음.

3. Lifecycle

도커 이미지가 컨테이너로 생성되고 실행될 때의 라이프 사이클입니다.

https://techmormo.com/posts/docker-made-easy-3-container-lifecycle/

우리는 당장 내일 출근해야 하므로 😂
컨테이너를 실행하기 위해 필요한 명령어 중 run 만 빠르게 훑어보시는 것을 추천드리고요,
docker run 명령어 사용 예시 및 옵션은 이어지는 4. Practice! 섹션에서 소개합니다.

4. Practice!

Docker 에 'Airflow' 웹서버를 올리고 구동하는 실습을 해 보겠습니다.
실습에 필요한 주요 Docker 명령어도 함께 소개합니다.
(명령어 소개에 🐳 이모지를 달아서 눈에 잘 띄도록 했습니다.)

(💡Tip) Airflow 는 python 을 이용해서 workflow 를 작성하고 스케줄링, 모니터링을 할 수 있는 플랫폼입니다.

본 실습에서는 Docker File 을 작성하고 빌드하여 Docker Image 를 만들지 않고
대표적인 도커 레지스트리 사이트인 Docker Hub 에서 이미지를 pull 받아 컨테이너 인스턴스를 생성하는 방법과
Airflow 공식 문서에서 Docker-compose.yaml 파일을 다운로드하여 컨테이너 인스턴스를 생성하는 방법 2가지를 소개합니다.

Docker Install (CLI)

Docker 는 GUI 를 지원하지만 실전에서는 리눅스 서버에서 CLI 로 작업하는 경우가 많을 것입니다.
Docker 홈페이지에서 CLI 설치방법을 소개하고 있으니 따라해 보시고
https://docs.docker.com/engine/install/ubuntu/
영어로 쓰여 있어서 따라하기 어렵거나 이 글을 따라해도 설치가 잘 되지 않는다면
많은 블로그에서 docker 설치 방법을 소개하고 있으니 구글링해보세요 😉

🐳 Docker Install (Ubuntu OS)

# get-docker.sh 다운로드
$ curl -fsSL https://get.docker.com -o get-docker.sh

# ll 명령어로 현재 디렉토리에 get-docker.sh 파일 확인
$ ll

# get-docker.sh 실행하여 Dokcer 설치
$ sh get-docker.sh

Build Docker Image (생략가능)

Airflow 공식 문서를 참고하여 도커 이미지를 생성하고 빌드합니다.
https://airflow.apache.org/docs/docker-stack/build.html

Airflow 이미지를 만들고 빌드하기 위해서는
먼저 Dockerfile 을 만들고 아래 내용을 복사해서 붙여넣습니다.

Dockerfile

FROM apache/airflow:2.6.1
USER root
RUN apt-get update \
  && apt-get install -y --no-install-recommends \
         vim \
  && apt-get autoremove -yqq --purge \
  && apt-get clean \
  && rm -rf /var/lib/apt/lists/*
USER airflow

이미지를 직접 만들지 않고 apache 에서 제공하는 이미지를 이용하고 싶다면
Docker Hub 에서 미리 만들어진 이미지를 내려받아 이용할 수 있습니다.
아래 캡쳐는 Docker Hub 홈페이지에 있는 Airflow 공식 이미지 예제이며,
docker pull apache/airflow 명령어를 이용해 이미지를 내려받을 수 있습니다.

🐳 Docker pull

docker pull apache/airflow

Dockerfile 을 빌드하여 이미지 파일을 생성합니다.

🐳 이미지 생성 (Docker file build)

# = 현재 디렉토리에서 Dockerfile을 읽어 도커 이미지를 만들고,
# 해당 이미지에 airflow 라는 tag 를 붙여라
docker build -t airflow .

이미지가 잘 생성되었거나 다운로드되었는지 확인해 볼까요?

🐳 생성 혹은 다운로드된 이미지 리스트 출력

docker images

사실 도커 명령어는 다음과 같이 각각 따로 존재하지만

  • docker create : 컨테이너 생성
  • docker start : 컨테이너 실행
  • docker pull: 도커 이미지 내려받기 (pull)

일반적으로 이 기능들을 한꺼번에 수행할 수 있는 docker run 을 사용합니다.

Docker Run

아래와 같은 명령어를 입력할 시 로컬에서 해당 이미지를 먼저 찾아본 후 없다면 자동으로 Docker 저장소인 DockerHub에서 해당 이미지를 찾습니다.
그 후 곧바로 해당 이미지를 불러와 컨테이너를 실행합니다.

🐳 Docker run

# 기본 명령어
docker run airflow

docker run 명령어와 함께 사용하는 몇 가지 옵션을 소개합니다.

  • --name <name> : 컨테이너 이름 지정
    지정하지 않으면 도커가 랜덤한 단어-단어 조합으로 컨테이너 이름을 지정해 줍니다.

  • -d : 컨테이너를 백그라운드에서 실행
    많은 경우 컨테이너를 백그라운드에서 실행해야 하는데요,
    -d 옵션을 사용하면 컨테이너가 detached 모드에서 실행되며, 실행 결과로 컨테이너 ID만 출력합니다.
    옵션 없이 실행했다면 해당 터미널에서 Ctrl + C를 눌러서 빠져나오는 순간 해당 컨테이너는 종료될 것입니다.
    실제 Production 환경에서 실행될 컨테이너는 대부분 백그라운드 프로세스로 실행됩니다.

  • -p : 포트 포워딩
    포트를 매핑함으로써 Docker 컨테이너 내에서 실행되는 서비스에 호스트 머신에서 지정한 호스트 포트를 사용하여 접근할 수 있습니다.

# docker run -\
-name <name> \
-p <host_port(=포트포워딩할 포트)>:<container_port(=Airflow 기본 포트)> \
-d apache/airflow

# 호스트 머신의 포트 8000 을 컨테이너 내부의 포트 8080 과 연결
# = 호스트 머신의 포트 8000으로 전송된 모든 트래픽은 컨테이너 내부의 포트 8080으로 전달
docker run --name airflow -d -p 8000:8080 apache/airflow
  • -rm : 컨테이너가 종료될 때 컨테이너와 관련된 리소스(파일 시스템, 볼륨)까지 제거
    컨테이너를 일회성으로 실행할 때 주로 사용합니다.

  • -it : 실행중인 컨테이너에 쉘(shell) 접속

    • -i : 컨테이너의 표준 입출력을 사용하겠다는 의미입니다.
    • -t : 컨테이너의 pseudo tty(가상 터미널)를 통해 접속하겠다는 의미입니다.

-i 옵션과 -t 옵션은 같이 쓰이는 경우가 매우 많은데요,
위의 두 옵션을 추가하여 실행중인 컨테이너의 쉘(Shell)에 접근하여 연속으로 명령어를 입력할 수 있습니다.
(= 컨테이너를 종료하지 않고 터미널의 입력을 계속해서 컨테이너로 전달)

-it 옵션은 이렇게 docker run 명령어와 함께 사용할 수도 있고

# airflow 이미지 다운로드 후 설치까지 한번에
docker run --rm -it apache/airflow /bin/bash 

docker exec 명령어와 함께 사용할 수도 있습니다.

🐳 실행중인 컨테이너에 쉘(shell) 접속

docker exec -it 'container name' /bin/bash

Volume

Docker 컨테이너(container)에 쓰여진 데이터는 기본적으로 컨테이너가 삭제될 때 함께 사라지게 됩니다.
Docker에서 돌아가는 많은 애플리케이션들은 컨테이너의 생명 주기와 관계없이 데이터를 영속적으로 저장을 해야 할 뿐만 아니라 많은 경우 여러 개의 Docker 컨테이너가 하나의 저장 공간을 공유해서 데이터를 읽거나 써야 합니다.

이렇게 Docker 컨테이너의 생명 주기와 관계없이 데이터를 영속적으로 저장할 수 있도록 Docker는 두가지 옵션을 제공하는데요.
첫번째는 Docker 볼륨(volume),
두번째는 바인드 마운트(bind mount)입니다.

이 중 첫번째인 docker 볼륨을 이용하는 옵션은 `-v 입니다.

  • -v : 도커 볼륨 마운트

Docker Network

Airflow 웹서버도 DB도 컨테이너에서 잘 실행되고 있는데, DB 에 연결이 되지 않는다면!?
Docker 컨테이너(container)는 격리된 환경에서 돌아가기 때문에 기본적으로 다른 컨테이너와의 통신이 불가능하지만 여러 개의 컨테이너를 하나의 Docker 네트워크(network)에 연결시키면 서로 통신이 가능해집니다.

-network : 컨테이너가 사용할 네트워크 지정

🐳 Docker 네트워크 목록 조회

docker network ls

최종적으로 이 모든 옵션을 조합한 docker run 입니다.

🐳 Docker run

docker run —rm -it -v <host:container_dir> -p <host_port:container_port> —network <network_name> -d apache/airflow

Airflow 인스턴스가 정상적으로 생성되고 실행되는지 확인해 볼까요?

🐳 컨테이너 출력

# 실행중인 컨테이너 리스트를 출력
docker ps

# 실행이 종료된 것을 포함하여 모든 컨테이너 리스트를 출력
docker ps -a

Airfow 인스턴스가 정상적으로 실행되면 총 4개의 컨테이너가 생성되고 서비스가 실행되어야 하는데
4개 중 airflow-webserver 만 정상적으로 실행되었어요.

정상적으로 실행되고 있지 않거나 재설치가 필요하다면 컨테이너와 이미지를 모두 삭제해 봅니다.

🐳 컨테이너, 이미지 삭제

# 모든 컨테이너를 삭제
docker rm $(docker ps -a -q)

# 모든 이미지를 삭제
docker rmi $(docker images -q)

다른 방법을 찾다가 공식문서의 'Running Airflow in Docker' 에서는
이미지를 다운로드하는 방법 대신 docker compose 를 이용하는 방법을 소개하고 있기에 따라해 보았습니다.

Docker Compose

  • 여러 개의 컨테이너로부터 이루어진 서비스를 구축하고 실행하는 순서를 자동으로 하여 관리를 간단히 하는 기능
  • Compose 파일을 준비하여 커맨드를 1회 실행

Airflow 는 공식 문서에서 docker-compose.yaml 파일과 설명을 제공하고 있습니다.
(파일) https://airflow.apache.org/docs/apache-airflow/2.6.1/docker-compose.yaml
(설명) https://airflow.apache.org/docs/apache-airflow/stable/howto/docker-compose/index.html

docker-compose.yaml 파일을 직접 다운로드하여 docker 가 설치된 리눅스 서버로 옮기거나
서버에서 curl 를 이용해 다운로드합니다.

🐳 Download Docker Compose File

curl -LfO 'https://airflow.apache.org/docs/apache-airflow/2.6.1/docker-compose.yaml'

docker-compose.yaml 을 열어 설정값을 확인하고
우리가 사용해야 할 조건과 환경에 맞게 값을 수정합니다.

예를 들어 이미 사용중인 DB에 연결해야 할 경우
docker-compose.yaml 파일을 수정하여 Airflow 웹서버에 DB를 연결해 줍니다.
DB는 리눅스 서버의 로컬에 설치하여 이용할 수도 있고,
Airflow 를 구동하는 것과 마찬가지로 컨테이너를 이용할 수도 있습니다.

Airflow 는 최초로 실행하기 전에 간단한 환경설정이 필요한데요,
다음과 같이 컨테이너와 마운팅될 디렉토리를 생성해 주고

mkdir -p ./dags ./logs ./plugins

호스트, 컨테이너 파일 권한도 설정해 줍니다.

echo -e "AIRFLOW_UID=$(id -u)\nAIRFLOW_GID=0" > .env

환경설정을 적용하기 위해 DB를 초기화하고 로그인 계정을 생성합니다.

🐳 DB 초기화 & 계정 생성

docker-compose up airflow-init

초기화가 정상적으로 실행되면 다음과 같은 결과를 볼 수 있습니다.

airflow-init_1       | Upgrades done
airflow-init_1       | Admin user airflow created
airflow-init_1       | 2.1.3
start_airflow-init_1 exited with code 0

이제 Airflow 를 실행하여 서비스를 시작합니다!

🐳 Airflow 실행

docker-compose up -d # -d: 백그라운드 실행

Airflow 컨테이너가 정상적으로 실행되는지 확인해 볼까요?

🐳 컨테이너 출력

# 실행중인 컨테이너 리스트를 출력
docker ps

# 실행이 종료된 것을 포함하여 모든 컨테이너 리스트를 출력
docker ps -a

다음과 같이 4개의 컨테이너가 생성되어 서비스가 정상적으로 실행되고 있습니다 🙌

CONTAINER ID   IMAGE						COMMAND                  CREATED       STATUS                PORTS						NAMES
98b105a77dff   airflow-airflow-triggerer	"/usr/bin/dumb-init …"   5 days ago    Up 5 days (healthy)   8080/tcp					airflow-airflow-triggerer-1
c096fedcb8a5   airflow-airflow-webserver	"/usr/bin/dumb-init …"   5 days ago    Up 5 days (healthy)   0.0.0.0:8088->8080/tcp, 
																												:::8088->8080/tcp	airflow-airflow-webserver-1
afa3b087e76a   airflow-airflow-worker		"/usr/bin/dumb-init …"   5 days ago    Up 5 days (healthy)   8080/tcp					airflow-airflow-worker-1
8f52396a2618   airflow-airflow-scheduler	"/usr/bin/dumb-init …"   5 days ago    Up 5 days (healthy)   8080/tcp					airflow-airflow-scheduler-1

Reference

Docker : 나만의 도커 이미지 만들기 부터, 클라우드 배포까지!
https://github.com/drum-grammer/docker-pro-wanted
Docker 학습하기
https://wikidocs.net/book/7507
Docker 네트워크 사용법
https://www.daleseo.com/docker-networks/
[Docker] 도커 컨테이너 - 라이프사이클 및 명령어
https://seosh817.tistory.com/353
Running Airflow in Docker
https://wooiljeong.github.io/server/docker-airflow/

그림과 실습으로 배우는 도커 & 쿠버네티스
(시중에 나온 도커 그림책(?) 중 가장 그림이 많고 예뻐서 가벼운 입문용으로 추천합니다.)
http://www.yes24.com/Product/Goods/108431011
https://velog.io/@jiyeong/그림과-실습으로-배우는-도커쿠버네티스
https://ugong2san.tistory.com/4202

profile
NLP Researcher

0개의 댓글