[Docker] 도커가 뭔데?

devicii·2025년 3월 26일

클라우드

목록 보기
2/3
post-thumbnail

1. 도커가 바꾼 개발바닥

1-1 도커란 무엇인가?

클라우드 시대에도 애플리케이션 배포와 관리는 여전히 복잡했다. 2013년 등장한 도커(Docker)는 "어디서나 동일하게 실행되는 표준화된 소프트웨어 패키징"이라는 새로운 방식을 제시하며 등장했다. 2025년 현재는 전 세계 58.3% 이상의 기업이 프로덕션 환경에서 도커를 활용하고 있다고 한다.

1-2 도커를 왜 써야 하는가?

개발자라면 "내 컴퓨터에서는 잘 돌아가는데..."라는 말을 한 번쯤 해본 경험이 있을 것이다. 도커는 이런 문제를 근본적으로 해결해준다.

1. 환경 일관성 보장

개발, 테스트, 운영 환경 간의 차이로 인한 문제 해소
"작동했는데 왜 안돼?"라는 소모적인 논쟁 종식
모든 팀원이 정확히 동일한 환경에서 작업 가능

2. 리소스 효율성

VM보다 가볍고 빠른 실행 환경 제공
호스트 시스템 자원을 더 효율적으로 활용
동일 하드웨어에서 더 많은 애플리케이션 실행 가능

3. 빠른 배포와 확장

애플리케이션 구성 요소를 독립적으로 패키징하여 배포 가능
필요에 따라 컨테이너를 빠르게 시작하거나 종료
CI/CD 파이프라인 통합 용이

1-3 도커의 핵심 개념

컨테이너 가상화
도커의 컨테이너 기술은 리눅스 커널의 cgroups와 namespace 기능을 기반으로 구현된다고 한다. 전통적인 가상 머신(VM)이 하이퍼바이저를 통해 전체 운영체제를 가상화하는 반면, 도커 컨테이너는 호스트 커널을 공유하며 프로세스 수준의 격리를 제공한다. 덕분에 200MB 크기의 우분투 컨테이너가 전체 VM(보통 1GB 이상) 대비 80% 이상의 디스크 공간을 절약할 수 있다.

https://jhyonhyon.tistory.com/51

1-4 도커와 가상머신과의 차이

가상머신(VM): 하이퍼바이저를 통해 완전한 OS를 가상화

  • 장점: 완벽한 격리
  • 단점: 무겁고 느림 (1GB+ 크기)

도커 컨테이너: 호스트 OS커널을 공유하며 프로세스 수준에서 격리

  • 장점: 가볍고 빠름 (200MB 크기, VM 대비 80% 공간 절약)
  • 단점: 호스트 OS에 의존적

도커는 리눅스 커널의 cgroupsnamespace 기술을 활용해 프로세스를 격리하므로 VM보다 훨씬 효율적

1-5 도커의 핵심 구성요소

  1. 도커 데몬: 백그라운드에서 실행되는 서비스로 REST API를 통해 요청 처리
  2. 도커 클라이언트: 사용자가 명령어를 입력하는 인터페이스 (CLI)
  3. 이미지: 애플리케이션과 그 종속성을 포함한 읽기 전용 템플릿
  4. 컨테이너: 이미지의 실행 가능한 인스턴스
  5. 레지스트리: 이미지를 저장하고 공유하는 저장소 (ex: Docker Hub)
┌────────────────────────────────────┐
│            호스트 시스템               │
│  ┌───────────┐    ┌───────────┐    │
│  │ 컨테이너 A  │    │ 컨테이너 B   │    │
│  │  APP A    │    │  APP B    │    │
│  │  Libs     │    │  Libs     │    │
│  └───────────┘    └───────────┘    │
│         │              │           │
│  ┌─────────────────────────────┐   │
│  │        도커 데몬               │   │
│  └─────────────────────────────┘   │
│         │              │           │
│  ┌─────────────────────────────┐   │
│  │         호스트 OS             │   │
│  └─────────────────────────────┘   │
└────────────────────────────────────┘

1.5 도커의 구성요소

도커 데몬: 백그라운드에서 실행되는 서비스로 REST API를 통해 요청 처리
도커 클라이언트: 사용자가 명령어를 입력하는 인터페이스 (CLI)
이미지: 애플리케이션과 그 종속성을 포함한 읽기 전용 템플릿
컨테이너: 이미지의 실행 가능한 인스턴스
레지스트리: 이미지를 저장하고 공유하는 저장소 (ex: Docker Hub)

2. 도커가 클라우드 환경에 가져온 변화

2-1 개발 및 배포 프로세스 변화 사례

도커는 CI/CD 파이프라인을 크게 변화시켰다고 한다.

  1. 개발자가 코드 커밋
  2. 자동으로 Docker 이미지 빌드
  3. 레지스트리에 이미지 푸시
  4. 컨테이너 서비스에 자동 배포

일례로 기존의 배포 시간을 45분에서 7분 이내로 단축시켰으며, Netflix와 같은 기업은 하루 500회 이상의 프로덕션 배포를 수행할 수 있게 되었다.

넷플릭스의 애플리케이션 컨테이너화

2-2 마이크로서비스 아키텍처의 실현

모놀리스 방식: 하나의 큰 애플리케이션에 모든 기능 포함

  • 장점: 단순한 개발 및 배포
  • 단점: 확장성 제한, 유지보수 어려움

마이크로서비스 방식: 작은 독립 서비스들의 조합

  • 장점: 독립적 확장/배포, 기술 다양성
  • 단점: 분산 시스템 복잡성

도커 기반 마이크로서비스는 각 서비스를 독립적으로 확장할 수 있게 해줍니다. Uber의 경우 5,000개 이상의 도커 서비스가 Kubernetes 클러스터에서 운영되며, 트래픽 급증 시 필요한 서비스만 자동으로 확장된다.

2-3 기업에서의 도커 활용 사례

PayPal의 사례

  • 연간 2,400만 달러의 인프라 비용 절감
  • 배포 주기를 7일에서 1시간으로 단축
  • 개발자 생산성 30% 향상

Netflix의 사례

  • AWS 기반 20만 코어에서 매일 50만 컨테이너 처리
  • 2,000회 이상의 일일 배포 자동화
  • Chaos Monkey 테스트로 99.999% 가용성 유지

페이팔 사례

3. 도커 실습해보기

3-1 도커 설치하기

각 운영체제별 설치 방법은 다음과 같다:

Ubuntu Linux

# 필요한 패키지 설치
sudo apt-get update
sudo apt-get install apt-transport-https ca-certificates curl software-properties-common

# Docker 공식 GPG 키 추가
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

# Docker 저장소 추가
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

# Docker 설치
sudo apt-get update
sudo apt-get install docker-ce

# 사용자를 docker 그룹에 추가 (sudo 없이 실행하기 위함)
sudo usermod -aG docker $USER

macOS

Windows:

설치가 완료되면 다음 명령어로 도커가 제대로 설치되었는지 확인:

docker --version
docker run hello-world

3-2 기본 도커 명령어 실습

이미지 관련 명령어

# 이미지 검색
docker search nginx

# 이미지 다운로드
docker pull nginx

# 다운로드한 이미지 목록 확인
docker images

# 사용하지 않는 이미지 정리
docker image prune

컨테이너 관련 명령어

# 컨테이너 실행
docker run -d -p 80:80 --name my-nginx nginx

# 실행 중인 컨테이너 목록 확인
docker ps

# 모든 컨테이너 목록 확인 (중지된 컨테이너 포함)
docker ps -a

# 컨테이너 로그 확인
docker logs my-nginx

# 컨테이너 중지
docker stop my-nginx

# 컨테이너 시작
docker start my-nginx

# 컨테이너 삭제 (중지 상태여야 함)
docker rm my-nginx

# 컨테이너 강제 삭제 (실행 중이어도 삭제)
docker rm -f my-nginx

3-3 간단한 웹 애플리케이션 컨테이너화 실습

이번에는 간단한 Node.js 웹 애플리케이션을 컨테이너화해보자.

  1. 프로젝트 디렉토리 생성 및 초기화:
mkdir docker-node-app
cd docker-node-app
npm init -y
npm install express
  1. app.js 파일 생성:
// app.js
const express = require('express');
const app = express();
const PORT = process.env.PORT || 3000;

app.get('/', (req, res) => {
  res.send('안녕하세요! 도커로 실행 중인 Node.js 애플리케이션입니다.');
});

app.listen(PORT, () => {
  console.log(`서버가 포트 ${PORT}에서 실행 중입니다.`);
});
  1. Dockerfile 생성:
FROM node:latest -alpine

WORKDIR /app

COPY package*.json ./

RUN npm install

COPY . .

EXPOSE 3000

CMD ["node", "app.js"]
  1. 도커 이미지 빌드:
docker build -t my-node-app .
  1. 컨테이너 실행:
docker run -d -p 3000:3000 --name node-app-container my-node-app
  1. 웹 브라우저에서 http://localhost:3000으로 접속하여 확인

3-4 Docker Compose 활용하기

여러 컨테이너를 함께 실행해야 하는 경우 Docker Compose를 활용하면 편리하다. 간단한 Node.js + MongoDB 애플리케이션을 예로 들어보자.

  1. docker-compose.yml 파일 생성:
version: '3'
services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      - MONGO_URI=mongodb://mongo:27017/myapp
    depends_on:
      - mongo
  
  mongo:
    image: mongo
    ports:
      - "27017:27017"
    volumes:
      - mongo-data:/data/db

volumes:
  mongo-data:
  1. app.js 파일을 MongoDB 연결을 포함하도록 수정:
const express = require('express');
const mongoose = require('mongoose');
const app = express();
const PORT = process.env.PORT || 3000;
const MONGO_URI = process.env.MONGO_URI || 'mongodb://localhost:27017/myapp';

mongoose.connect(MONGO_URI)
  .then(() => console.log('MongoDB에 연결되었습니다.'))
  .catch(err => console.error('MongoDB 연결 오류:', err));

app.get('/', (req, res) => {
  res.send('도커 컴포즈로 실행 중인 Node.js + MongoDB 애플리케이션입니다.');
});

app.listen(PORT, () => {
  console.log(`서버가 포트 ${PORT}에서 실행 중입니다.`);
});
  1. package.json 업데이트 (mongoose 추가):
npm install mongoose
  1. Docker Compose로 실행:
docker-compose up -d
  1. 중지하기:
docker-compose down

4. 도커 활용을 위한 고급 개념

이미지 최적화 기법

  1. 멀티 스테이지 빌드: 빌드 환경과 실행 환경을 분리하여 최종 이미지 크기 70% 감소
# 멀티 스테이지 빌드 예시
FROM node:18 AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM nginx:alpine
COPY --from=build /app/build /usr/share/nginx/html
EXPOSE 80
  1. Alpine 기반 이미지: 일반 이미지 대비 85% 용량 절약
  2. 레이어 캐싱 최적화: 변경이 적은 레이어를 먼저 배치하여 빌드 시간 60% 단축

보안 강화 방안

# 보안 강화 설정 예시
version: '3.8'
services:
  web:
    image: myapp:secure
    user: "1000:1000"  # 루트 권한 사용 방지
    read_only: true    # 파일시스템 변경 방지
    security_opt:
      - no-new-privileges  # 권한 상승 방지
    cap_drop:
      - ALL  # 모든 특수 권한 제거

이러한 보안 설정은 NIST SP 800-190 표준에 따라 컨테이너 취약점 발생률을 줄인다고 한다.

5. 마무리

5-1 쿠버네티스와의 관계

도커는 현재 개발자 중심 전략으로 Docker DesktopBuildKit에 집중하고 있다. 쿠버네티스가 점차 컨테이너 오케스트레이션 표준으로 자리잡았지만, 여전히 78%의 쿠버네티스 클러스터가 도커로 빌드된 이미지를 사용한다.

5-2 서버리스 컨테이너의 부상

AWS Fargate, Google Cloud Run 등 서버리스 컨테이너 서비스가 연평균 150% 성장하고 있으며, 2025년에는 전체 컨테이너 워크로드의 40%를 차지할 전망이다. 인프라 관리 부담 없이 컨테이너 기반 애플리케이션을 실행할 수 있는 점이 제일 강력하다.

5-3 결론

도커는 단순한 가상화 도구를 넘어 클라우드 네이티브 생태계의 핵심 인프라 1황이다. 2025년 현재 90% 이상의 포춘 500대 기업이 도커를 프로덕션에 사용하며, 컨테이너화된 워크로드의 68%가 Kubernetes와 연동되어 있다. 시장의 니즈와 편의성 때문에 도커 기반의 개발환경은 계속 커지지 않을까 싶다.


참고자료

추가사항

  • 커널 공유 구조의 보안 취약성
    컨테이너가 호스트 커널을 공유함으로써 발생하는 Zero-Day 취약점 전파 위험은 CVE-2024-21626 사례에서 확인된 바 있다. SELinux와 AppArmor의 필수 적용이 강조되는 NIST SP 800-190 Rev.2 표준에서는 네임스페이스 격리만으로는 Cgroups의 자원 제어 한계를 보완할 수 없다 (2025.04.03) 링크텍스트
profile
흘러가는대로 사는

0개의 댓글