100%를 한번에 바꾸는건 어려워도 1%를 100번 바꾸는건 쉽다.

생각정리 자세히보기

개발/Deploy

[Deploy] Docker란?

dc-choi 2024. 7. 29. 19:04
반응형

최근 사이드 프로젝트나 회사에서 Docker가 편리하여 자주 사용하게 되었습니다.

 

그냥 사용하는 것 보다는 왜 사용하는지 알기 위해서 글을 작성하며 내용을 정리하려고 합니다.

 

이 글은 Docker가 설치되었다는 전제하로 설명할 예정입니다!

 

Docker란?

한줄로 쉽게 요약을 하자면 Container 기반 가상화 기술입니다. Container란 소프트웨어를 실행하는 데 필요한 모든 것을 하나의 패키지로 묶어 독립적으로 실행할 수 있는 가상화 기술을 말합니다.

 

기존의 가상화 기술의 단점을 보완하면서 애플리케이션을 독립적으로 실행할 수 있는 환경을 제공하여 일관된 배포와 관리가 가능하게 합니다.

 

어떤 부분이 달라졌지?

자세한 설명을 위해서 기존 가상화 기술과 Docker를 비교하면서 설명을 드리도록 하겠습니다.

 

기존의 가상화 기술은 Hypervisor 위에서 동작하며 OS를 새로 구축하고 그 OS안에 여러 패키지를 설치하게 됩니다. 하지만 이는 결과적으로 하나의 Host OS에서 다른 OS가 새로 만들어지게 되므로 각 OS마다 Kernel이 생성됩니다. 이로 인해 각 Kernel마다 하드웨어에 접근하게 되므로 중복된 시스템 자원을 사용하게 됩니다. 또한 가상화 기술은 각 OS마다 새로 부팅하는 과정에서 소요 시간도 많이 걸리게 됩니다.

 

이런 이유로 인해 기존 가상화 기술을 사용하게 된다면 더 많은 리소스가 사용되게 됩니다.

 

이를 보완하기 위해 나온 기술이 Container이며 Docker의 경우 Host OS안에서 동작하게 됩니다. 따라서 하나의 Host OS에서 하드웨어에 접근하게 되므로 효율적으로 시스템 자원에 접근하게 됩니다. 또한 Docker는 필요한 패키지만 가지고 있어 기존 가상화 기술보다 더 빠르게 시작할 수 있습니다. 그러나 마냥 좋아보이는 Docker에도 장단점이 있습니다.

 

Docker의 장단점

장점

  1. 일관된 환경 제공: 개발, 테스트, 프로덕션 환경에서 동일한 설정과 환경을 유지할 수 있어 배포와 실행의 일관성을 보장합니다.
  2. 경량화 및 빠른 실행: 컨테이너는 가상 머신보다 더 적은 리소스를 사용하며, 애플리케이션 실행 속도가 빠릅니다.
  3. 이식성: Docker 이미지는 어디서든 동일하게 동작하므로, 클라우드, 온프레미스 등 다양한 환경에서 쉽게 배포할 수 있습니다.
  4. 확장성 및 관리 용이성: 여러 컨테이너를 손쉽게 관리하고 오케스트레이션 도구(Kubernetes 등)를 이용해 확장성과 복원력을 강화할 수 있습니다.
  5. 의존성 관리: 각 컨테이너는 자체적으로 필요한 라이브러리와 의존성을 포함하고 있어, 의존성 문제를 최소화할 수 있습니다.

단점

  1. 복잡성 증가: Docker와 관련된 개념(예: 이미지, 컨테이너, 볼륨, 네트워크 등)을 이해하고 관리하는 데 초기 학습 곡선이 존재합니다.
  2. 데이터 관리의 어려움: 상태를 가지는 애플리케이션의 경우, 컨테이너가 유실될 때 데이터를 유지하는 방법에 대한 추가적인 고민이 필요합니다.
  3. 복잡한 네트워킹: 다수의 컨테이너가 통신하는 복잡한 네트워킹 설정이 필요할 수 있으며, 이를 제대로 설정하지 않으면 성능 저하나 연결 문제를 겪을 수 있습니다.

 

Docker 용어 정리

먼저 Docker에서 사용하는 용어에 대한 설명을 하도록 하겠습니다.

Dockerfile

Docker Image가 생성되기 위한 과정을 서술한 스크립트입니다. 작성된 Dockerfile을 기반으로 Build를 하게 되면 Docker Image가 만들어집니다. 아래는 Java기반 Spring Boot 애플리케이션을 실행하는 예제입니다.

# 먼저 필요한 패키지를 설치하고 두 스테이지를 합치기
FROM amazoncorretto:17 as builder

# gradle 설정 및 소스 코드 복사
COPY gradlew .
COPY gradle gradle
COPY build.gradle .
COPY settings.gradle .
COPY src src

# 타임존 설정
ENV TZ=Asia/Seoul
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# 실행 권한 주고 gradle 실행
RUN chmod +x ./gradlew && ./gradlew bootJar -x test

# 나머지 빌드를 위한 스테이지
FROM amazoncorretto:17

# 타임존 설정
ENV TZ=Asia/Seoul
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# 생성된 JAR 파일을 app.jar로 복사
COPY --from=builder build/libs/*.jar app.jar

# RUNTIME 환경변수 인자 설정
ARG PROFILE
ENV SPRING_PROFILES_ACTIVE=${PROFILE}
ENV SPRING_PROFILES_INCLUDE=file,secret

# Java 실행
ENTRYPOINT ["java", "-jar", "-Dspring.profiles.active=${SPRING_PROFILES_ACTIVE},${SPRING_PROFILES_INCLUDE}", "app.jar"]

 

Docker Image

위에서 설명한 Dockerfile을 build한 결과물로 Container를 실행하기 위한 Template입니다. 즉 Container를 실행할 수 있도록 재사용 및 공유가 가능한 파일입니다.

 

Docker Container

실제로 실행되는 프로세스입니다. Docker Image를 사용하여 해당 프로세스를 가동할 수 있습니다.

 

Docker Volume

기본적으로 Container는 삭제되면 해당 설정이 전부 삭제됩니다. Container가 삭제되어도 Volume에 저장하면 기존 설정이 삭제되지 않습니다.

 

Docker Hub

Docker Image를 저장하는 Remote Public Repository입니다. 비슷한 예시로 GitHub가 있습니다.

 

Docker 명령어

그 다음으로는 자주 사용되는 Docker 명령어에 대해서 설명을 드리도록 하겠습니다.

 

docker build --build-arg PROFILE={profile} -t {image}:{tag} .

 

Dockerfile이 위치한 곳에서 {profile}의 인자값을 넣어주는 {image}:{tag}라는 이름을 가진 Docker Image를 생성합니다.

 

{profile}은 임의로 지정한 환경변수이며 어떤 환경에서 실행할지 결정하도록 하는 환경변수입니다.

 

docker run -d --name={name} --restart="always" -p {외부 port}:{docker port} {image}

 

{image}를 데몬으로 재시작할 수 있게 {외부 port}:{docker port}로 포워딩하여 {name}을 가진 컨테이너 실행하는 명령어입니다.

 

Docker의 경우 Host OS와 분리되기 때문에 포워딩 해주지 않으면 네트워크 연결이 어렵습니다.

 

docker ps

 

도커에 올라가있는 컨테이너를 확인합니다.

 

docker start {container}

 

{container}를 실행합니다.

 

docker stop {container}

 

{container}를 중지합니다.

 

docker rm {container}

 

{container}를 삭제합니다.

 

docker pull {image}

 

Docker Hub에서 {image}에 해당하는 이미지를 가져옵니다.

 

docker images

 

현재 가지고 있는 Docker Image를 보여줍니다.

 

docker exec -it {container} {shell}

 

{shell}을 사용하여 Container 내부로 접근합니다.

 

Docker Compose

단일 서버에서 여러개의 컨테이너를 하나의 서비스로 정의해 컨테이너의 묶음으로 관리할 수 있는 작업 환경을 제공하는 관리 도구입니다.

 

Docker Compose를 사용하게 되면 일일히 Docker 명령어를 치지 않아도 Container 관리가 가능합니다.

 

compose.yaml이 파일의 기본 이름이고 따로 이름을 변경해줄 수 도 있습니다.

 

compose.yaml 예시

하단 예시는 Nginx, Spring Boot, MySQL, Redis를 한번에 관리할 수 있는 compose file 예시입니다.

services:
  nginx:
    container_name: my-nginx
    image: nginx
    ports:
      - 80:80
      - 443:443
    volumes:
      - /usr/local/docker/data/nginx/build:/home
      - /usr/local/docker/data/nginx/logs:/logs
      - /usr/local/docker/data/nginx/conf:/etc/nginx/conf.d
      - /usr/local/docker/data/nginx/ssl:/etc/letsencrypt
  spring-docker:
    container_name: my-server
    image: server:dev
    ports:
      - 8080:8080
    volumes:
      - /usr/local/docker/data/app/logs:/home/spring/logs
  db:
    container_name: my-db
    image: mysql:8.0
    environment:
      - MYSQL_DATABASE=${MYSQL_DATABASE}
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
      - MYSQL_USER=${MYSQL_USER}
      - MYSQL_PASSWORD=${MYSQL_PASSWORD}
    ports:
      - 3306:3306
    command:
      - --character-set-server=utf8mb4
      - --collation-server=utf8mb4_unicode_ci
  redis:
    container_name: my-redis
    image: redis:7-alpine3.17
    ports:
      - 6379:6379

 

Docker Compose 명령어

Docker Compose에서 자주 사용하는 명령어를 설명드리도록 하겠습니다.

 

해당 명령어는 compose.yaml이 위치한 경로에서 실행되어야 합니다.

 

docker compose up -d

 

compose.yaml에서 설정을 불러와 데몬으로 시작합니다.

 

docker compose down

 

compose.yaml에서 설정을 불러와 종료합니다.

 

docker compose ps

 

compose.yaml에서 설정된 컨테이너가 잘 동작하는지 확인한다.

반응형

'개발 > Deploy' 카테고리의 다른 글

[Deploy] Docker Image Size를 줄여 성능 개선  (3) 2024.10.10
[Deploy] Nginx 설치 및 HTTPS 적용  (0) 2022.07.12