본문 바로가기
Cloud/Docker

[Docker] Docker Container 기초 이론

by Yoonsoo Park 2024. 11. 23.

1.  도커(Docker)컨테이너(Container)란?

 도커(Docker)컨테이너 기술을 기반으로 애플리케이션(응용 프로그램)과 그 런타임(실행 환경)을 패키지화하여 실행/관리하는 오픈 소스 플랫폼(PaaS)이다. 컨테이너(Container)리눅스 커널의 격리 기술*을 기반으로 애플리케이션과 런타임을 패키징하여 격리된 상태로 실행할 수 있는 기술이다. 쉽게 말하자면, 도커란 컨테이너를 실행/관리하는 기술이고, 컨테이너는 프로세스 단위의 격리 환경을 제공하여, 마치 프로세스 단위의 가상 머신이 있는 것과 같이 작동하게 해주는 기술이다(가상 머신과 같은 것은 아니다).

** 리눅스 커널의 격리 기술

1. namespace

  • 프로세스 상에서 사용하는 특정 자원에 대한 가시성을 제한하기 위해 리눅스 커널에 구현된 기능
  • 별도의 네임스페이스를 사용하는 프로세스간에는 서로의 자원을 볼 수 없도록 제한한다
2. cgroups(Control Groups)
  • 네임스페이스는 시스템자원에 대한 가시성을 제한하지만  자원을 사용하는 것을 막지는 못한다
  • CPU, Memory, Storage 등과 같은 자원을 제어하여 우선순위나 할당량 등을 통제하고 모니터링   있다
  • 이를 통해 컨테이너 간의 자원 경합을 방지하고, 안정적인 실행 환경을 제공한다
3. Chroot
  • 유니온 파일시스템(UnionFS) 같은 기술을 사용하여 계층화된 파일시스템을 구현한다

 

1) 컨테이너VM(Virtual Machine)의 차이?

 설명을 듣다 보면 컨테이너와 VM(가상 머신)이 유사하게 느껴질 것이다. 그렇다면 컨테이너와 VM의 차이점은 무엇일까? 아래의 그림을 보면서 이해해 보자. 

<컨테이너와 VM>

 

 위의 그림을 봤을 때, 컨테이너와 VM의 가장 큰 차이점은 VM이 물리적인 하드웨어를 가상화한 것이기 때문에 게스트 OS를 독립적으로 가지고, 그 위에서 애플리케이션을 실행시키는 것과 다르게, 컨테이너호스트 OS의 커널을 공유하되, 애플리케이션과 런타임만 독립적으로 구성한다는 것이다. 그림을 보면 각 컨테이너 안에 VM과 같이 게스트 OS가 있는 것이 아닌, 애플리케이션과 라이브러리만 존재하는 것을 볼 수 있다. 이러한 차이 덕분에, 컨테이너는 가상 머신과 다르게 실행 시, 게스트 OS를 부팅할 필요가 없어 빠르게 부팅되며, 가볍다는 장점이 있다. 하지만 컨테이너는 호스트 OS에 의존적이기 때문에, VM에 비해 비교적 보안이 취약할 수 있다는 단점이 있어, 환경에 따라 VM이 사용되는 경우도 많다. 

 

 

2) 도커의 구성 요소 및 도커 컨테이너와 이미지의 관계

다시 도커로 돌아와 뒤에 도커 및 컨테이너 관리 방법을 다룰 포스팅에서 언급할 도커의 구성 요소들에 대해 알아보자.

 

1. 도커 이미지(image)

  • 컨테이너를 만들고 실행하기 위한 읽기 전용(read-only) 파일 템플릿 
  • 애플리케이션 컨테이너 생성/실행을 위한 라이브러리, 설정 파일 등을 포함하고 있다
  • 매번 이미지를 받을 필요 없이, 하나의 이미지를 기반으로 여러 개의 컨테이너를 생성할 수 있음

2. 도커 컨테이너(container)

  • 이미지를 실행한 인스턴스
  • 도커는 소프트웨어를 컨테이너라는 표준화된 유닛으로 패키징

3. 도커 파일(dockerfile)

  • 도커 이미지를 생성하기 위한 설명서 
  • 코드로 이미지를 생성할 때, 어떤 OS를 사용할지, 어떤 애플리케이션,  라이브러리를 설치할지 등을 정의한다

4. 도커 엔진(enginer)

  • 컨테이너를 생성, 실행, 관리하는 기계
  • 컨테이너 실행 및 이미지 빌드 명령어들을 처리함

5. 도커 컴포즈(compose)

  • 여러 컨테이너를 조합해 애플리케이션을 실행하는 도구
  • yaml 파일의 형식으로 여러 컨테이너의 설정을 정의하고 관리

6. 도커 레지스트리(registry)

  • 도커 이미지를 저장하고 배포하는 저장소
  • Docker Hub(공식 레지스트리), 사설 레지스트리가 있음

 

위의 구성 요소들을 이용해 도커를 사용하는 방법을 간략하게 설명하자면 다음과 같이 설명할 수 있다. 

1) 도커 파일로 이미지를 만든다

2) 레지스트리에서 이미지를 받아온다(pull)

3) 받아온 이미지를 이용하여 컨테이너를 만들고 실행시킨다(run)

 

한 가지 더 알아두면 좋은 점은 이미지를 통해 컨테이너가 생성되는 방법이다. 

< 도커 이미지와 컨테이너의 구조 >

 

 위 그림처럼 도커의 파일 시스템은 레이어 구조로 구성돼있다. 각각의 레이어는 독립된 파일 시스템이며, 읽기 전용(read-only) 또는 읽기-쓰기(read-write) 방식으로 동작한다. 도커 이미지는 여러 개의 읽기 전용 레이어로 이뤄져 있고, 만약 도커 이미지에 변경사항이 있다면, 기존 레이어를 직접 수정하는 방식이 아닌, 변경된 내용을 레이어로 만들어 위에 덧붙이는 방식으로 저장된다. 

 

 그렇다면 도커 컨테이너는 어떻게 만들어지는 것일까? 도커 컨테이너를 생성/실행 시에는 필요한 이미지를 가져와 해당 이미지의 위에 읽기-쓰기 레이어를 올려 하나의 파일 시스템처럼 동작하게 한다. 만약 컨테이너에서 변경 사항이 생긴다면, 변경 사항은 모두 읽기-쓰기 레이어에 저장되고, 컨테이너가 삭제되면 읽기-쓰기 레이어도 삭제된다. 하지만 기존 이미지의 레이어는 그대로 유지된다. 

 

 

 

2. 도커와 컨테이너를 사용하는 이유

 

1. 일관된 실행 환경 제공

  • 문제: 개발, 테스트, 배포 환경이 다르면 애플리케이션이 다른 동작을 보일 수 있음
  • 해결: 컨테이너는 애플리케이션과 필요한 라이브러리, 설정 등을 묶어서 어디서든 일관된 환경에서 실행 가능

2. 빠른 배포 및 시작 

  • 문제: 전통적인 배포 방식은 시간이 오래 걸리고, VM은 부팅 속도가 느림
  • 해결: 컨테이너는 가볍고 빠르게 실행되며, 새로운 컨테이너를 몇 초 안에 생성할 수 있음

3. 효율적인 자원 사용

  • 문제: 가상 머신(VM)은 하드웨어 레벨에서 격리되고, 각 VM에 독립된 OS를 실행하므로 자원을 많이 소모
  • 해결: 컨테이너는 호스트 OS의 커널을 공유하기 때문에, VM보다 훨씬 가볍고 자원을 효율적으로 사용

4. 확장성

  • 문제: 사용자 트래픽 증가에 따라 애플리케이션 확장이 어려움
  • 해결: 컨테이너는 쉽게 복제되므로, 수평 확장(Scale-out)이 매우 간단함

5. MSA(Micro Service Architecture) 지원

  • 문제: 단일 모놀리식 애플리케이션은 유지보수와 확장이 어려움
  • 해결: 마이크로서비스 아키텍처에서 각 서비스(웹 서버, DB, API..)를 컨테이너로 분리하여 독립적으로 관리 가능

6. CI/CD 파이프라인 통합

  • 문제: 지속적인 통합 및 배포(CI/CD) 과정에서 테스트 환경 구축이 어려움
  • 해결: 컨테이너는 CI/CD 도구(Jenkins..)와 쉽게 통합되어, 일관된 테스트와 배포 환경을 제공

7. 운영 비용 절감 

  • 문제: 물리적 서버와 VM 기반 운영은 초기 투자와 유지 비용이 큼
  • 해결: 컨테이너는 더 적은 리소스로 더 많은 애플리케이션을 실행 가능하므로, 서버 비용과 운영 비용을 절감

 

 

 

 힘들지만 오늘도 해낸 나를 위한 한 마디,

"승리하면 조금 배울 수 있고, 패배하면 모든 것을 배울 수 있다", Chris Mattewson

 

"승리와 패배의 결과에 연연하지 말고, 그러한 결과의 이유를 되돌아보고 개선하자. 또한 피드백을 겸허히 받아들이자"