[Docker] 도커를 사용하여 컨테이너화 하기

도커는 애플리케이션과 그 모든 종속성을 컨테이너 형태로 패키징하여 어느 환경에서도 애플리케이션이 원활하게 작동하도록 하는 컨테이너화 플랫폼입니다. 도커는 애플리케이션을 컨테이너를 사용하여 더 쉽게 만들고, 배포하고, 실행할 수 있도록 설계된 도구입니다.

컨테이너화

컨테이너화는 사용자 공간에서 여러 가상 컨테이너를 생성하는 OS 기반 가상화입니다. 컨테이너는 같은 호스트 커널을 공유하지만, 각기 다른 네임스페이스와 리소스 제어 메커니즘을 통해 서로 격리됩니다. 컨테이너 기반 가상화는 하드웨어 가상화와 가상 디바이스 드라이버의 오버헤드가 있는 하이퍼바이저와 비교할 때 다른 수준의 추상화 격리를 제공합니다.

각 가상 머신 인스턴스는 가상화된 하드웨어 위에서 전체 운영 체제가 실행됩니다.

반면 컨테이너는 운영 체제 수준에서 프로세스 격리를 구현하여 이러한 오버헤드를 피합니다. 이러한 컨테이너는 호스트 머신의 동일한 운영 체제 커널 위에서 실행되며, 각 컨테이너 내에서 하나이상의 프로세스가 실행될 수 있습니다.

컨테이너에서는 메모리를 사전에 할당할 필요가 없으며, 컨테이너 생성 시 동적으로 할당됩니다.

반면 가상 머신에서는 먼저 메모리를 사전에 할당하고 가상 머신을 생성해야 합니다.

컨테이너화는 가상 머신보다 리소스 활용도가 높고 부팅 시간이 짧습니다.

컨테이너는 모든 환경에서 실행될 수 있습니다. 컨테이너는 모든 리소스를 운영 체제 수준에서 가상화합니다.

도커 아키텍처

도커 클라이언트, 도커 호스트에서 실행되는 도커 데몬, 도커 허브 레지스트리로 구성됩니다. 도커는 클라이언트-서버 아키텍처를 가지며, 클라이언트는 REST API, SOCKET IO 및 TCP의 조합을 사용하여 도커 호스트에서 실행되는 도커 데몬과 통신합니다. 도커 이미지를 빌드하려면 클라이언트에서 빌드 명령을 실행하여 도커 데몬이 주어진 입력에 따라 이미지를 빌드하고 도커 레지스트리에 저장합니다. 이미지가 없으면 클라이언트에서 pull 명령을 실행하여 도커 데몬이 도커 허브에서 이미지를 가져오게 하면 됩니다. 이미지를 실행하려면 클라이언트에서 run 명령을 실행하여 컨테이너를 생성할 수 있습니다.

도커의 구성 요소

  • 도커 클라이언트와 서버: 도커는 클라이언트-서버 아키텍처를 가지고 있습니다. 도커 서버는 모든 컨테이너를 포함하고 있으며 도커 클라이언트는 CLI 또는 REST API를 통해 요청을 받아 이를 처리합니다. 클라이언트와 데몬은 같은 호스트에 있을 수도 있고 다른 호스트에 있을 수도 있습니다.
  • 도커 이미지: 읽기 전용 템플릿을 사용하여 도커 컨테이너를 빌드하는 데 사용됩니다. 모든 이미지는 기본 이미지에서 시작합니다. 기본 이미지는 ubuntu 나 fedora 등이 있습니다. 기본 이미지는 처음부터 생성할 수도 있고, 필요한 애플리케이션을 추가할 수 있습니다.
  • 도커 파일: 도커 파일은 도커 이미지를 빌드하는 방법을 설명하는 명령어가 포함된 텍스트 파일입니다. 
  • 도커 레지스트리: 도커 이미지를 저장하는 저장소입니다. 여러 사용자가 애플리케이션을 공동으로 빌드할 수 있습니다.
  • 도커 컨테이너: 도커 이미지의 실행 인스턴스입니다. 컨테이너에는 애플리케이션 실행에 필요한 모든 것이 포함되어 있어 애플리케이션을 격리된 방식으로 실행할 수 있습니다.

도커 컴포즈(docker compose)

다중 컨테이너 애플리케이션을 생성할 수 있는 도구입니다. 여러 컨테이너로 구성된 애플리케이션을 설정하고 실행하는 것을 더 쉽게 만들어줍니다. 만약 nodejs와 mysql이 필요한 애플리케이션이 있다면, 두 컨테이너를 서비스로 시작하는 파일을 하나 만들어 각각을 따로 시작할 필요 없이 애플리케이션을 실행할 수 있습니다. 다중 컨테이너 애플리케이션은 YAML 파일로 정의하며, docker-compose-up 명령을 통해 애플리케이션을 포그라운드에서 시작할 수 있습니다. -d 옵션을 추가하면 애플리케이션을 백그라운드에서 시작할 수 있습니다.

도커 네트워크

컨테이너를 생성하고 실행할 때 도커는 기본적으로 IP 주소를 할당합니다. 도커는 요구에 맞게 네트워크를 설계할 수 있도록 해줍니다. 네트워크를 확인하려면 다음 명령을 실행합니다.

docker network ls

도커에는 다음과 같은 세 가지 유형의 네트워크가 있습니다.

  • 브리지 네트워크: 새로운 도커 컨테이너가 --network 인수 없이 생성되면 도커는 기본적으로 해당 컨테이너를 브리지 네트워크에 연결합니다. 브리지 네트워크에서는 동일한 호스트내의 모든 컨테이너가 IP 주소를 통해 연결될 수 있브니다. 브리지 네트워크는 도커 호스트의 범위가 하나일 때 생성됩니다.
  • 호스트 네트워크: 새로운 도커 컨테이너가 --network=host 인수와 함께 생성되면 컨테이너는 도커 데몬이 실행 중인 호스트 네트워크 스택으로 들어갑니다. 이 네트워크에서는 호스트의 모든 인터페이스가 접근 가능합니다.
  • none 네트워크: 새로운 도커 컨테이너가 --network=none 인수와 함께 생성되면 컨테이너는 자체 네트워크 스택으로 들어갑니다. 이 네트워크에서는 컨테이너에 IP 주소가 할당되지 않아 서로 통신할 수 없습니다.

특정 네트워크를 컨테이너에 할당하려면 docker run 명령의 --network 옵션을 사용합니다.

docker run --network="<network-name>"

특정 네트워크에 대한 정보를 얻으려면 다음 명령을 사용합니다.

docker network inspect "<network-name>"