[책 공부] 개발자를 위한 쉬운 도커

6 minute read

책 소개

개발자를 위한 쉬운 도커

그동안 도커에 대해서 듣기만 했지만 제대로 공부를 한적이 없었습니다. 이번 기회를 통해 공부를 하게 됐고, 이 책은 도커의 원리, 구성, 왜 탄생하게 되었는지, 실무에서는 어떻게 쓰이는지에 대해 자세하게 설명하고 있습니다. 그래서 도커를 공부하고 싶다면 이 책을 꼭 추천합니다!

서버 운영 방식

도커는 컨테이너를 관리하는 소프트웨어이다. 컨테이너는 서버를 효율적으로 사용하기 위한 가상화 기술이다.

엔터프라이즈 환경에서 기업이 서비스를 운영할 때 하나의 서비스는 다양한 종류와 역할을 가진 여러 서버로 구성된다. 이때 기업에서 여러 서버를 운영하는 방법은 크게 3가지로 나뉜다.

  1. 베어메탈(bare metal): PC 한 대에 운영체제를 설치하고, 그 OS에서 여러 소프트웨어를 운영하는 방식
  2. 하이퍼바이저, 컨테이너: 서버 운영에 가상화 기술을 활용한다. 서버의 수나 실행되는 소프트웨어는 동일하지만 중간에 VM이나 컨테이너가 추가된 형태이다.

가상화 기술은 물리적인 컴퓨팅 환경 내에서 여러 개의 논리적인 컴퓨팅 환경을 만들 수 있는 기술로 정의할 수 있다.

하이퍼바이저를 실행하는 OS를 호스트OS라 부르고, 호스트OS는 물리적인 하드웨어 서버를 관리한다. 하이퍼바이저는 이 호스트OS의 자원을 이용해 새로운 가상의 OS인 게스트OS를 실행한다. 즉, 호스트OS는 물리서버를 직접 관리하고 게스트OS는 호스트OS의 리소스를 나눠 사용하는 논리적인 공간이다. 이렇게 논리적으로 분리된 게스트OS를 가상머신이라고 부른다. 가상머신에서는 웹 서버, WAS, DB 서버 등의 프로그램을 프로세스로 실행한다. 여기서 프로세스란 실행중인 프로그램을 의미한다. 하이퍼바이저는 다양한 커널 간의 요청을 관리하고, 가상머신에 필요한 리소스를 할당한다. 이를 통해 다양한 종류의 게스트OS를 격리된 공간에서 사용 가능한 것이다. 하이퍼바이저 역할을 하는 소프트웨어는 제조사별로 다양하며, VirtualBox가 그중 하나이다.

컨테이너 가상화

컨테이너 가상화는 하이퍼바이저 가상화보다 가볍고 빠르며, 이는 현대 애플리케이션 운영에서 중요한 요소이다. 소비자의 요구사항이 빠르게 변화함에 따라 애플리케이션도 신속하게 대응할 수 있어야하기 때문이다. 컨테이너의 의미가 격리된 공간을 말한다. 즉, 컨테이너 가상화는 하이퍼바이저 없이도 커널의 기능을 사용하는 것이 가상화 기술이다. 호스트OS의 커널을 공유하는 것은 컨테이너 가상화의 중요한 특징이다.

도커

커널의 가상화 기술은 일반 사용자가 직접 다루기에 복잡한데, 이러한 어려움을 해결하기 위해 2013년에 도커(Docker)가 등장했다. 도커는 컨테이너 가상화 기술을 쉽게 사용할 수 있게 해주는 오픈소스 도구이다. 그리고 도커와 같은 도구를 컨테이너 플랫폼이라고 한다.

도커는 클라이언트와 컨테이너를 관리하는 도커 데몬(docker daemon) 서버로 구성되는데, 도커 데몬이 클라이언트가 커널의 기능을 이용할 수 있도록 API를 제공한다. 즉, 컨테이너를 생성하거나 삭제하려면 도커 데몬에 API 요청을 보내면 된다.

실행과정

  1. 현재 실습 PC에 도커를 설치해 호스트OS로 사용중
  2. docker run nginx CLI가 명령어를 컨테이너 실행 API에 맞게 변환해 도커 데몬으로 전달
  3. 도커 데몬은 요청을 분석한 뒤 컨테이너 런타임을 통해 컨테이너 생성
  4. nginx 컨테이너의 프로세스가 요청을 받아 웹페이지 제공
  5. 이러한 컨테이너는 디스크, 네트워크, 메모리, CPU 등의 자원이 완전히 격리된 공간으로 실행되며 이를 통해 여러 서버를 안전하게 운영할 수 있다.

이미지

컨테이너 가상화는 호스트OS의 공간을 격리해서 컨테이너를 생성하고, 그 내부에서 프로그램을 실행하는 방식이다. 컨테이너를 실행하려면 이미지가 필요하다. 이미지는 컨테이너에서 프로그램을 실행하는데 필요한 모든 것이 포함된 압축 파일이다. 이미지는 파일 시스템의 특정 시점을 저장해 놓은 압축 파일이다. 이 이미지에는 프로그램, OS, 구성요소들이 모두 포함되어 있다. 이렇게 준비된 이미질로 컨테이너를 실행하면 프로그램을 빠르게 실행할 수 있다.

앞서 docker run nginx를 실행했었는데, 여기서 nginx가 이미지인 것이다. 이 이미지를 기반으로 생성한 격리된 실행 환경이 컨테이너인 것이다.

이미지의 장점은 크기가 작아서 인터넷에 저장하고 공유하기에 편리하다. 사용자는 다른 사람이 만든 이미지를 내려받아 사용할 수 있으며, 직접 이미지를 제작해서 사용할 수도 있다.

컨테이너를 실행하려면 이미지가 필요합니다. 실행 가능한 프로그램과 실행에 필요한 모든 환경이 준비된 파일 시스템으로, 이 이미지를 기반으로 컨테이너가 실행된다.

이미지

  • 실행 가능한 소프트웨어 + 실행에 필요한 환경
  • 디스크 공간 차지

컨테이너

  • 실행 상태의 이미지
  • 이미지 1 : N 컨테이너
  • 컨테이너 실행시 CPU, 메모리 사용
  • 컨테이너 간 리소스 격리
  • 실행시 격리된 가상 공간 생성
  • 컨테이너 실행시 프로세스도 함께 실행

이미지의 최대 장점은 프로그램뿐 아니라 실행환경까지 포함하므로 도커만 설치돼 있으면 모든 서버에서 동일한 환경을 구성할 수가 있다. 따라서 도커를 사용하면 소프트웨어 배포와 환경 구성을 일관성 있게 유지할 수 있다.

이미지 레지스트리

이미지 레지스트리는 이미지를 저장하는 저장소이다. Github의 레포지토리와 비슷하다. Github는 소스코드를 저장하지만 이미지 레지스트리는 이미지를 저장한다. 이미지를 저장하는 공간은 3가지로 나뉜다.

  • 로컬 스토리지: 도커가 설치된 호스트OS의 스토리지로, 사용자 PC의 특정 폴더에 이미지를 저장한다.
  • 프라이빗 레지스트리: 주로 기업 환경에서 사용된다.
  • 퍼블릭 레지스트리: 누구나 접근할 수 있는 온라인 저장소이다.

컨테이너를 실행할 때 docker run 명령과 이미지 이름을 입력하면 도커는 가장 먼저 로컬 스토리지에서 해당 이미지를 찾는다. 이미지가 있다면 다운로드 없이 바로 컨테이너를 실행한다.

이미지가 없으면 도커는 온라인 레지스트리에서 이미지를 다운로드한 뒤 로컬 스토리지에 저장하고, 이후 컨테이너를 실행한다. 한 번 로컬 스토리지에 다운로드한 이미지는 계속 사용할 수 있다.

프라이빗 레지스트리

프라이빗 레지스트리는 두 가지 방식이 있는데,

  1. 서버에 직접 레지스트리 소프트웨어를 설치하는 방식: 하버(Harbor)나 도커 프라이빗 레지스트리 같은 소프트웨어를 사용
  2. 클라우드 서비스를 이용하는 방식: AWS의 ECR(Elastic Container Registry), Azure의 ACR(Azure Container Registry) 등을 사용

퍼블릭 레지스트리는 가입만 누구나 이미지를 자유롭게 업로드하거나 다운로드 할 수 있다. 도커 허브 같은 서비스를 제공한다.

이미지 빌드

이미지 빌드 들어가기 전에 IaC(Infrastructure as Code)라는 개념을 이해하는 것이 중요하다. 기존 서버 관리자는 대시보드를 클릭하거나 명령어를 실행해 사내 인프라를 관리했었다. 하지만 사람이 직접 작업하면 실수하기 쉽고, 인프라 상태의 변경 기록을 체계적으로 관리하기 어렵다. IaC는 이러한 작업을 코드로 관리하는 방식으로, 프로그램이 코드를 읽어 인프라를 관리하므로 사람이 직접 관리하는 것보다 더 빠르고 안전하다.

도커는 IaC 방법론을 활용해 도커파일(Dockerfile)이라는 파일로 파일시스템의 상태를 정의하고, 이를 기반으로 이미지를 만든다. 빌드 방식에서는 도커파일을 분석해 도커가 자동으로 컨테이너를 생성하고 커밋한다.

멀티 스테이지 빌드

일반적인 빌드 방식에서는 이미지에 소스코드와 외부 라이브러리 파일이 포함되어 많은 저장 공간을 차지한다. 반면, 멀티 스테이지 빌드는 첫 번째 빌드 스테이지에서 maven 이미지를 사용하고, 두 번째 실행 스테이지에서는 openjdk 이미지를 사용한다. 빌드 스테이지에서는 소스코드로 애플리케이션을 빌드하고, 생성된 JAR 파일을 실행 스테이지로 복사한다. 최종적으로 생성된 이미지에는 자바 런타임과 JAR 파일만 포함돼 있어 이미지 크기를 효과적으로 줄일 수 있다.

도커 네트워크

물리 서버는 공인망이나 사설망을 통해 공인IP 또는 사설IP를 할당받는다. 이 상태에서 PC에 여러 컨테이너를 실행하면 각 컨테이너는 어떻게 IP를 할당받게 될까? 컨테이너 간 통신은 어떻게 이뤄질까? 이러한 문제를 도커의 가상 네트워크 기술로 해결할 수 있다. 가상 네트워크란 물리적인 인터넷 케이블이나 공유기 없이 서버 내에서 논리적으로 정의한 네트워크이다.

브리지 네트워크

도커를 설치하고 실행하면 브리지 네트워크(bridge network)라는 가상 네트워크가 자동으로 생성되며, docker0 브리지가 생성되어 가상 공유기 역할을 수행한다. 브리지 네트워크는 보통 172.17.0.1 대역의 IP주소를 사용한다. 브리지 네트워크는 컨테이너 간 통신을 위해 각 컨테이너에 IP주소를 할당한다. 이처럼 소프트웨어로 논리적인 네트워크 환경을 구성하는 기술을 SDN(Software Defined Network)이라고 한다.

또한 도커는 컨테이너가 사용할 수 있는 내부 DNS 서버를 기본적으로 제공한다.

볼륨

도커의 볼륨은 컨테이너에 상태를 부여하는 핵심 기능이다. 여기서 상태는 컨테이너가 실행되는 동안 생성되거나 변경된 데이터를 말한다. 예를 들어, 데이터베이스에 저장된 정보, 사용자가 업로드한 파일, 로그 기록 등이 상태에 해당한다. 컨테이너는 기본적으로 스테이트리스(stateless) 특징을 가지고 있기 때문에 컨테이너가 종료되면 컨테이너 내에서 발생한 모든 변경사항이 사라진다. 그래서 이러한 컨테이너 영속성을 부여하기 위한 기능이 도커 볼륨이다.

  • 컨테이너가 삭제되거나 재시작돼도 데이터를 안전하게 유지
  • 여러 컨테이너가 같은 데이터를 공유
  • 서비스의 안정성과 데이터의 일관성 유지

도커 볼륨은 컨테이너 외부에 독립적인 저장 공간을 제공한다. 그리고, 여러 컨테이너가 같은 볼륨을 마운트하고 공유할 수 있다.

마운트란 컴퓨터 시스템에서 외부 저장 장치나 파일 시스템을 특정 티렉터리에 연결하는 것을 의미한다.

  1. 단일 컨테이너에서의 다중 볼륨 사용
  2. 다중 컨테이너에서의 하나의 볼륨 공유

이미지 관리

이미지의 레이어를 효과적으로 관리하고 이미지 크기를 줄이는 방법

도커 파일로 이미지를 빌드할 때, 보통 지시어 하나당 새로운 레이어가 하나 추가된다. 레이어가 많아지면 빌드 속도가 느려지며, 이미지 관리가 복잡해지는 등의 문제가 발생한다.

이미지를 빌드할 때는 레이어 수를 최소화하는 것이 중요한 최적화 전략이다. 또한 이미지 크기를 줄이면 네트워크 사용량이 줄어 배포 속도가 빨라지고 전반적인 시스템 효율성이 높아진다.

  • 이미지에 많은 명령을 실행해야할 때 && 연삱자와 RUN 지시어로 통합하면 하나의 레이어만 추가되는 효과가 있다.
  • scratch 이미지를 사용한 이미지 경량화

도커 컴포즈

도커 컴포즈(Docker Compose)는 여러 컨테이너를 실행하는 환경을 효율적으로 관리하는 도구이다. 많은 컨테이너를 동시에 관리하는 기능을 수행하며, 헌번의 명령어로 모든 컨테이너, 네트워크, 볼륨을 동시에 생성할 수 있으며, 전체 환경을 한꺼번에 종료할 수 있다.

도커 컴포즈를 사용하면 개발 환경을 운영 환경과 동일하게 PC에 빠르게 구성할 수 있다. 예를들어, docker run 명령을 여러번 입력해 각 컨테이너를 실행해야 했다면 도커 컴포즈를 사용하면 docker compose up 명령어 하나로 모든 환경을 한번에 구성할 수 있다. 이는 개발 프로세스를 크게 간소화하고 효율성을 높이는 장점중 하나이다.

도커 컴포즈는 docker-compose.yml 파일로 동작한다.

Comments