[ Docker ]

본 글은 [ 시작하세요! 도커 / 쿠버네티스 ] 저서를 참고로 작성하였습니다.

Docker

도커(Docker)는 가상화 기술을 의미하는데 정확히는 가상화 컨테이너(container)에 어플리케이션(application) 배포를 자동화 시켜주는 오픈소스 엔진이다. 덕분에 가상화 환경 위에 어플리케이션을 배포하면서 어디서든 빠르고 가볍게 실행시킬 수 있게 되었는데 이는 곧 MSA, CI/CD와 잘 어울린다는 것을 의미한다.

잠깐! MSA란 무엇일까?

MSA(Micro Service Architecture)는 전체 어플리케이션을 특정 목적을 가진 어플리케이션 단위로 나누어 변경과 조합이 가능하게 하는 아키텍처를 의미한다. 이때 개별 어플리케이션은 독립적으로 실행, 배포되어도 문제가 없어야 한다. 우선 기존 방식인 Monolithic Architecture를 알아보자.

Monolithic Architecture란 MAS와 달리 모든 구성요소가 한 프로젝트에 통합되어 있는 형태를 의미한다. 따라서 소규모 프로젝트에는 유지보수가 용이하여 편리하지만 규모가 커질수록 다음와 같은 뚜렷한 단점이 나타난다.

  1. 전체 시스템 구조 파악에 어려움이 있다.
  2. 빌드, 테스트, 배포 시간이 오래걸린다.
  3. 부분적인 스케일 아웃(scale out)이 어렵다.
  4. 부분적인 오류가 곧 전체의 오류로 이어진다.

스케일 아웃과 스케일 업

  • 스케일 아웃(Scale out): 서버의 수를 늘려서 처리 능력을 향상시키는 방법 (수평 스케일)
  • 스케일 업(Scale up): 서버 자체를 증강하여 처리 능력을 향상시키는 방법 (수직 스케일)

MSA는 이러한 Monolithic Architecture의 단점을 극복하기 위해 만들어졌다. 그리고 이것이 목적에 맞게 잘 구현되기 위해 보통 REST API와 같은 방법으로 통신한다. 결과적으로 개별 배포가 가능하고 특정 서비스에 대한 확장(scale)이 용이하며 부분적 오류 처리가 수월하다. 하지만 MSA도 다음과 같은 단점은 존재한다.

  1. 한 트랜젝션의 처리 및 개별 어플리케이션 에러에 대한 처리가 필요하다.
  2. 개별 어플리케이션에 대한 테스트 때문에 테스트가 어려워진다.
  3. 개별 어플리케이션 데이터의 무결성을 확신하지 못한다.
  4. 서비스간 호출에 결국 API를 사용하기 때문에 지연(latency)이 늘어난다.

잠깐! CI/CD란 무엇일까?

CI(Continuous Integration)와 CD(Continuous Delivery/Deployment)는 단어 그대로 지속적 통합과 지속적 제공/배포를 의미한다. 이제 하나씩 알아보자.

  1. 지속적 통합: 새로운 코드 변경 사항이 정기적으로 빌드 및 테스트되어 공유 레포지토리에 통합된다. 분산 작업 상황에서 충돌 문제를 해결할 수 있다.
  2. 지속적 제공: 개별 개발자들이 적용한 변경 사항이 레포제토리에 자동으로 업로드되는 것을 의미한다.
  3. 지속적 배포: 개별 개발자의 변경 사항을 레포지토리에서 사용자가 사용 가능한 환경까지 자동으로 릴리스하는 것을 의미한다.

가상화(Virutualizatoin)

앞서 도커가 가상화 기술이라고 이야기했었다. 가상화 기술에는 대표적으로 두 가지가 있는데 하나씩 알아보자.

Hypervisor

기존의 가상화 기술이 이용한 방법이다. 물리적인 서버 위에서 여러 독립적인 운영체제가 돌아가는 구조로 하나의 물리적 서버에서 여러 운영체제가 실행되고 있지만 서로의 존재를 모르는 형태로 완전히 독립적이다. 이를 통해 한 서버에 여러 운영체제를 사용하며 서버의 리소스를 효율적으로 사용할 수 있게 되었다. 하지만 결국 각 운영체제를 독립적으로 실행하기 때문에 너무 무겁고, 부팅 시간이 길어지며 리소스를 많이 차지하게 되는 단점이 있다.

Container

Hypervisor와는 다르게 운영체제를 독립적으로 가상화하는 것이 아닌 유저의 공간을 가상화한다. 다시 말해 하나의 호스트 서버에 여러 독립적인 유저 공간이 생기는 것이다. 따라서 hypervisor보다 훨씬 가볍고 쉽게 독립적인 가상 환경을 실행시킬 수 있다.

도커의 가상화 기술은 곧 컨테이너를 의미하는데 하이퍼바이저와 다른 점은 emulator 없이 docker image라는 것만 사용하면 어디서든 쉽고 빠르게 테스트 및 배포가 가능하다는 것이다. 결과적으로 앞서 이야기한 MSA와 CI/CD에 잘 어울리는 환경인 것이다. 하지만 독립적인 운영체제가 아니기 때문에 운영체제가 다른 호스트에서는 실행시킬 수 없는 단점이 있다. (예를 들어 Linux 호스트로 유저 공간을 가상화했다면 Windows를 실행시킬 수 없다.)

도커의 구조

도커는 크게 4가지 부분으로 구성되어 있다.

Docker client / server

Docker는 클라이언트와 서버 구조로 이루어져 있다. 클라이언트가 서버에 명령을 전달하면 이를 서버가 실행시키는 것이다. 이때 Binary command가 곧 클라이언트를 의미하고 실제 컨테이너를 생성하고 이미지를 관리하는 주체는 서버이다. 도커 서버는 도커 엔진 프로세스에서 동작하는데 프로세스가 실행되어 준비된 상태를 도커 데몬(docker daemon)이라 한다. 클라이언트와 서버는 동일한 호스트 안에서 운영될 수도 있으며 서로 다른 호스트에서 운영될 수도 있다.

Docker image

Docker의 생명 주기(life cycle)에서 이미지는 곧 빌드(build) 부분에 해당한다. 컨테이너에 실행시키고 싶은 어플리케이션을 이미지로 빌드해서 실행하는 것이다. 중요한 개념이라 이에 관해 조금 더 자세히 설명해보려 한다.

우선 쉽게 설명해 이미지는 곧 레이어라서 탑을 쌓는다고 생각하면 편하다. 그렇다면 컴퓨터에서 가장 기반은 역시 부팅과 관련된 것이다. 따라서 도커 또한 base layer는 bootfs(Boot File System)으로 Linux 부트 파일 시스템으로 구성되어 있고 그 다음에는 root layer로 rootfs(Root File System)으로 Ubuntu 등의 실제 운영체제가 설치된다. 이때 도커의 rootfs는 계속해서 read-only 모드로 유지되는데 병합 마운트(union mount)을 사용하여 read-only 파일 시스템들을 rootfs 위에 덮는 구조로 되어 있기 때문이다.

Mount와 Union mount

  • Mount: 보통 하드웨어 장치를 리눅스에서 사용하기 위해 인식시켜주는 것을 의미한다.
  • Union mount: 동일한 디렉토리에 여러 파일시스템을 마운트하여 마치 하나의 파일 시스템만이 마운트 된 것처럼 사용하는 기술을 의미한다.

base가 되는 이미지를 부모 이미지라하며 맨 위의 이미지부터 가장 밑 부분까지 횡단하는 구조로 되어 있다. 결과적으로 여러 read-only 파일 시스템을 병합 마운트 기법으로 마지막에 하나의 파일 시스템으로 보이는 구조다. 이때 주의할 점은 마지막으로 read-write 파일 시스템을 layer 맨 위에 마운트한다는 것이다. 이는 컨테이너가 필요한 프로세서를 생성하고 실행하기 위해서이다.

Copy on write
위 도커와 같은 패턴을 의미한다. 도커 이미지를 빌드할 때 도커 파일이 file system / image가 되어 처음부터 다 빌드하는 것이 아닌 바뀐 파일만 마운트하게 된다. 결과적으로 속도가 훨씬 빠르며 디버깅이 용이해진다.

Docker registries

도커 이미지를 저장하는 레포지토리다. 마치 깃헙에 소스 코드를 저장하는 것처럼 도커의 이미지를 registries에 저장하는 것이다. Public과 private이 존재한다.

Docker containers

도커 이미지를 실행시키는 가상화 공간을 의미한다. 하나 이상의 프로세스를 실행시킬 수 있지만 하나의 프로세스만 실행시키는 것을 권장한다.

profile
글 쓰는 개발자입니다.

0개의 댓글