Docker 란?

쓰리원·2023년 1월 28일

Docker

목록 보기
1/1
post-thumbnail

이 글에서는 도커에 대한 간단한 개념을 다뤄보도록 하겠습니다. 시리즈물로 도커에 대한 공부를 진행할 예정입니다.

1. Docker란?

도커(Docker)는 애플리케이션을 신속하게 구축, 테스트 및 배포할 수 있게 해주는 컨테이너화 플랫폼입니다. 애플리케이션과 그 실행에 필요한 모든 것(라이브러리, 시스템 도구, 코드, 런타임 등)을 컨테이너라는 표준화된 단위로 패키징하여, 개발 환경이나 서버 환경에 관계없이 동일하게 작동하도록 보장합니다.

1. 도대체 왜 사용하는 건가요?

"제 컴퓨터에선 잘 됐는데..." 라는 말을 없애기 위해서입니다.
개발 환경과 실제 서버 환경이 달라 발생하는 오류를 원천적으로 차단합니다. 애플리케이션이 어디서든 똑같이 실행되도록 보장하는 것이죠.

2. 핵심 비유: '미니 생태계, 테라리움'

쉽게 비유하자면, 도커는 '어디에나 둘 수 있는 완벽한 미니 생태계, 테라리움(Terrarium)'과 같습니다.

도커는 '어디에나 둘 수 있는 완벽한 미니 생태계, 테라리움(Terrarium)'과 같습니다.

  • 식물 : 내가 만든 애플리케이션
  • 흙, 물 : 실행에 필요한 라이브러리와 각종 도구들
  • 유리 벽 : 외부와 완벽히 격리된 독립 환경

이 테라리움을 통째로 옮기기만 하면, 어느 곳(서버)에 두든 식물은 똑같이 자랍니다. 테라리움 안에는 식물(애플리케이션)뿐만 아니라, 그 식물이 자라는 데 필요한 흙, 자갈, 수분, 영양분(라이브러리, 시스템 도구 등)이 모두 갖춰져 있습니다.

이처럼 도커는 애플리케이션이 필요로 하는 환경 전체를 하나의 '독립된 생태계(컨테이너)'로 만들어, 어디서든 문제없이 똑같이 작동하도록 보장하는 기술입니다.

2. Docker의 등장이유

1. 과거의 문제점들

1. 의존성 지옥 (Dependency Hell)

  • 여러 애플리케이션이 동일한 서버에 설치된 라이브러리나 패키지를 공유하면서,
  • 서로 다른 버전 요구나 충돌로 인해 정상 동작하지 않는 문제가 잦았습니다.

2. 환경 불일치

  • 대표적인 말: “제 컴퓨터에서는 잘 되는데요?”
  • 개발 환경(로컬)과 운영 환경(서버)이 다르기 때문에, 코드가 서버에서는 에러가 나는 일이 흔했습니다.

2. 해결책으로서의 VM

이 문제를 해결하기 위해 가상 머신(VM, Virtual Machine)이 등장했습니다. VM은 각 애플리케이션을 위한 독립된 운영체제(Guest OS)를 통째로 가상화하여 환경을 완벽히 분리했습니다. 하지만 OS 자체를 포함하기 때문에 매우 무겁고 느리며 자원을 많이 차지하는 단점이 있었습니다.

이러한 VM의 단점을 보완하기 위해 등장한 것이 바로 컨테이너(Container) 기술이며, 이 컨테이너 기술을 누구나 쉽고 편리하게 사용할 수 있도록 만든 것이 도커(Docker)입니다.

3. VM vs 컨테이너

가상 머신과 컨테이너는 모두 격리된 실행 환경을 제공하는 기술이지만, 그 방식은 전혀 다릅니다. 가장 핵심적인 차이는 운영체제(OS)를 어떻게 다루느냐에 있습니다.

1. 가상 머신(Virtual Machine, VM)

VM은 물리 서버 위에 설치된 하이퍼바이저(Hypervisor)를 통해 완전히 독립적인 컴퓨터(게스트 OS)를 여러 개 생성하는 방식입니다.

  • VM 하나는 CPU, 메모리, 저장공간 등 하드웨어 자원을 가상화하여 자체 운영체제를 실행합니다.
  • 이 게스트 OS는 실제 물리 서버의 OS(호스트 OS)와 완전히 분리되어 있어, 시스템 충돌이나 보안 침해로부터 강력한 격리를 제공합니다.
  • 대표적인 하이퍼바이저로는 VMware ESXi, Microsoft Hyper-V, KVM, VirtualBox 등이 있습니다.
  • 구조 요약 : 하드웨어 → 호스트 OS → 하이퍼바이저 → 게스트 OS → 애플리케이션

2. 컨테이너(Container)

컨테이너는 하이퍼바이저 없이 호스트 OS의 커널을 직접 공유하면서, 각각의 애플리케이션과 그 의존 환경을 논리적으로 분리하여 실행하는 경량 가상화 기술입니다. 프로세스 및 파일 시스템, 네트워크 등을 분리하여 마치 별도의 시스템처럼 동작합니다.

  • 대표적인 컨테이너 런타임은 Docker, containerd, Podman 등이 있으며, 이들은 리눅스 커널의 기능들(Namespace, cgroup 등)을 활용하여 가벼운 격리 환경을 구현합니다.
  • 컨테이너는 운영체제를 자체적으로 포함하지 않기 때문에 매우 가볍고 빠르게 실행할 수 있습니다.
  • 구조 요약 : 하드웨어 → 호스트 OS → 컨테이너 엔진(Docker 등) → 앱 및 런타임 환경

3. 무거운 안전 vs. 가벼운 속도

1. 가상 머신의 장점

  • 강력한 보안 격리
    각각의 VM은 독립된 OS를 포함하므로, 하나의 VM이 공격받아도 다른 VM이나 호스트 시스템에 영향을 주지 않습니다. 금융기관이나 정부 기관에서 선호되는 이유입니다.

  • 이기종 OS 가능
    맥OS에서 윈도우 VM을 실행하거나, 윈도우 서버에서 리눅스 VM을 실행하는 것처럼, 다른 운영체제 실행이 가능합니다.

  • 고립된 시스템 테스트에 적합
    예: 윈도우10, 윈도우11, Ubuntu 20.04, Ubuntu 22.04 등 다양한 OS 기반의 테스트 환경을 구축할 때 유리합니다.

2. 가상 머신의 단점

  • 높은 자원 소모
    각 VM이 OS 전체를 포함하므로 수 GB 이상이며, 부팅 후 대기 상태만으로도 CPU 및 RAM을 상당히 소비합니다.

  • 부팅 및 실행 속도 느림
    마치 실제 컴퓨터를 켜는 것처럼 부팅 시간이 수 분 걸릴 수 있으며, 복제나 이관도 무겁습니다.

  • 관리의 복잡성
    패치, 업그레이드, 백업 등 OS 단위의 작업을 VM마다 수행해야 합니다.

3. 컨테이너의 장점

  • 초경량 환경
    컨테이너는 운영체제를 포함하지 않기 때문에 이미지 크기가 작고, 시작 속도도 수 초 내외로 매우 빠릅니다.

  • 개발과 배포의 민첩성
    DevOps, CI/CD 파이프라인에 매우 적합하며, 코드 변경 → 테스트 → 배포까지의 사이클이 짧습니다.

  • 자원 효율성
    수십~수백 개의 컨테이너를 하나의 서버에서 동시에 운영할 수 있으며, 리소스 할당도 유연합니다.

  • 애플리케이션 이식성
    Docker 이미지로 애플리케이션을 패키징하면, 어떤 환경에서도 동일하게 실행할 수 있어 "한 번 빌드하면 어디서든 실행"이 가능합니다.

4. 컨테이너의 단점

  • OS 커널 의존성
    호스트 OS의 커널을 공유하므로, 윈도우 호스트에서는 윈도우 컨테이너만 실행 가능하며, 리눅스는 리눅스만 됩니다.

  • 상대적으로 낮은 보안 격리
    Namespace, cgroup 등의 논리적 격리이기 때문에, 호스트 커널에 취약점이 있을 경우 전체 컨테이너가 영향을 받을 수 있습니다.

  • Persistent 환경 구축 복잡
    데이터베이스처럼 상태를 유지해야 하는 앱은 별도로 스토리지를 연결하고 관리해야 하므로 VM에 비해 약간의 관리 복잡성이 생길 수 있습니다.

4. 언제 VM, 언제 컨테이너를 쓸까?

상황추천 기술이유
서로 다른 운영체제에서 테스트가 필요할 때VM완전히 별개의 OS 실행 가능
보안이 최우선인 업무 (예: 금융, 공공기관)VM높은 격리성과 안정성
마이크로서비스 기반의 시스템 운영 시컨테이너빠른 배포와 확장성
DevOps, CI/CD 자동화 환경 구축컨테이너빠른 실행, 이식성, 통합성
여러 앱을 동일 OS에서 운영하고자 할 때컨테이너리소스 효율적 분산 가능

실제로 많은 기업들은 하이브리드 구조를 채택하고 있습니다.

  • VM을 통해 물리 서버를 논리적으로 분할.
  • 그 내부에서 Docker 기반 컨테이너 클러스터(Kubernetes 등)를 운용하는 방식.

이러한 구조는 VM의 안정성과 컨테이너의 민첩성을 모두 확보할 수 있는 전략으로, 클라우드 플랫폼(AWS, Azure, GCP)에서도 널리 채택되고 있습니다.

5. 핵심 비교 요약표

항목가상 머신 (VM)컨테이너 (Container)
비유단독 주택아파트
격리 방식하이퍼바이저 기반 OS 격리커널 공유 기반 논리적 격리
커널독립적인 게스트 커널호스트 OS 커널 공유
크기크고 무거움 (수 GB)작고 가벼움 (수십~수백 MB)
부팅 속도느림 (분 단위)빠름 (초 단위)
OS 호환성자유롭고 유연함제한적 (호스트 OS 기반)
이식성낮음 (환경에 민감함)매우 높음 (Docker 이미지 기반)
보안 격리매우 강함상대적으로 약함
적합한 용도이기종 OS, 보안, 테스트 환경DevOps, MSA, 대규모 확장 서비스

4. Docker의 주요 구성 요소

1. Docker Image

Docker Image는 컨테이너(Container)를 만들기 위한 템플릿입니다.단순히 실행 파일만이 아닌, 아래의 모든 요소가 포함된 전체 실행 환경 패키지입니다

1. 코드 (Source Code)

실제 여러분이 작성한 애플리케이션의 핵심 로직입니다.

  • 웹사이트라면: index.html, style.css, app.js]
  • Node.js라면: server.js, routes/api.js
  • Python 앱이면: main.py, views.py

2. 라이브러리 (Libraries)

애플리케이션이 동작하기 위해 외부에서 가져오는 도구들입니다. 보통 npm install, pip install 같은 명령어로 설치하죠.

  • Node.js: express, axios, dotenv
  • Python: flask, requests, pandas

예를 들어 import flask 라고 했는데 flask가 없다면 앱은 실행 도중 에러가 발생합니다.

3. 종속성 (Dependencies)

코드나 라이브러리를 실제로 실행하기 위해 필요한 시스템 도구들입니다.

  • bash (터미널 명령어를 실행하려면 필요)
  • curl, wget (인터넷에서 파일 가져올 때 사용)
  • openssl (HTTPS 통신 필요 시)
  • 시스템 명령어: ls, cp, chmod, sh, tar 등

어떤 앱은 단순한 코드 실행 외에도 시스템 도구에 의존합니다. 이런 도구가 없다면 컨테이너 내부에서 오류가 발생할 수 있어, 이미지 빌드 시 함께 포함시킵니다.

4. 운영체제 레벨 설정 (OS Base)

컨테이너 내부에서 사용할 수 있는 기초적인 OS 환경을 제공합니다.

  • ubuntu:22.04 → 우분투 리눅스 기반 (전체 OS 기능)
  • alpine → 매우 가벼운 리눅스 배포판 (작지만 빠름)
  • node:18 → Node.js가 사전 설치된 우분투 기반 이미지

Docker Image는 단순히 코드만 담는 것이 아닙니다. 코드를 실행할 환경 자체가 포함되어야 함
컨테이너는 실제 OS를 따로 설치하지 않지만, 리눅스 기반의 기본 파일 시스템이 필요합니다.

5. 실행 명령어 (Startup Command)

컨테이너가 시작될 때 자동으로 실행할 명령입니다.

  • Node 앱: node server.js
  • Python 앱: python main.py
  • Web 서버: nginx -g "daemon off;"
CMD ["node", "server.js"]

이렇게 설정해두면, 누군가 이 이미지를 기반으로 컨테이너를 실행할 때

docker run my-app

→ 자동으로 node server.js 명령어가 실행됩니다.

2. Dockerfile

Dockerfile은 Docker Image를 자동으로 생성하기 위한 설정 파일(스크립트) 입니다. 이 파일에 적힌 내용대로 Docker가 이미지를 하나하나 단계별로 명령을 해석하고 실행해서 최종적으로 하나의 완성된 Docker Image를 만들어 줍니다.

수동으로 이미지를 만든다고 생각해 보세요

docker run -it ubuntu
apt install nodejs
copy 내코드 /
npm install
  • 불편하고 반복적이죠?
  • 개발자가 다르면 환경도 달라질 수 있어요.

그래서 이 모든 작업을 미리 스크립트로 저장해놓고, 자동으로 이미지를 생성하는 것이 바로 Dockerfile입니다.

Dockerfile 예제

FROM node:18              # 1. Node.js가 포함된 이미지 사용 (운영체제 + 런타임 포함)
WORKDIR /app              # 2. 이후 작업할 디렉토리를 /app으로 설정
COPY . .                  # 3. 현재 프로젝트 폴더의 모든 파일을 이미지 안 /app으로 복사
RUN npm install           # 4. npm으로 라이브러리 설치
CMD ["npm", "start"]      # 5. 컨테이너가 실행되면 'npm start' 명령을 자동 실행
  • node:18 이미지를 베이스로 가져옵니다.
  • 이미지 내부의 /app 폴더를 기준 작업 디렉토리로 설정
  • 코드와 package.json 등을 복사
  • npm install을 통해 node_modules 생성
  • 사용자가 docker run 하면 npm start 실행됨

3. Docker Container

Docker Container는 Docker Image로부터 생성된 실행 가능한 실체입니다. 쉽게 말해, Image가 요리법(설계도)이라면, Container는 실제로 요리된 음식(실행 중인 앱)입니다.

1. 컨테이너는 운영체제 수준에서 독립된 환경을 제공

요소격리됨?설명
파일시스템각 컨테이너는 자신의 파일만 접근 가능
메모리다른 컨테이너와 메모리 공간 공유 안함
네트워크독립된 IP, 포트 사용 가능
프로세스호스트와 별도의 프로세스 공간 사용

즉, 마치 작은 가상 서버처럼 느껴집니다. 하지만 VM보다 훨씬 가볍고 빠릅니다.

컨테이너 실행 예제

docker run -d --name web nginx:1.25
  • run 컨테이너 생성 + 실행
  • -d 백그라운드(Detached) 모드로 실행
  • --name web 컨테이너 이름을 web으로 지정
  • nginx:1.25 사용할 Docker 이미지 (웹 서버)

이 명령어는 nginx 웹서버를 컨테이너로 실행시킵니다.

2. 상태 저장: 볼륨(Volume)

기본적으로 컨테이너는 일시적인 환경입니다. 컨테이너가 삭제되면 데이터도 함께 사라집니다. 하지만 중요한 데이터가 있다면? 예: DB, 로그, 업로드 파일 등 → 이를 보존하기 위해 Volume을 연결합니다.

docker run -d -v /mydata:/data myapp
  • /mydata 호스트의 실제 디렉토리
  • /data 컨테이너 내부의 디렉토리

컨테이너가 데이터를 /data에 쓰면, 실제로는 /mydata에 저장됨

5. reference

https://docs.docker.com/guides/
https://opensource.microsoft.com/blog/2019/07/15/how-to-get-started-containers-docker-kubernetes/
https://helpezee.wordpress.com/category/docker/

profile
가장 아름다운 정답은 서로의 협업안에 있다.

0개의 댓글