홈으로 돌아가기

Docker 컨테이너 네트워킹 설명: 실용 가이드

이 포괄적인 가이드는 Docker 컨테이너 네트워킹을 기초부터 설명하며, 기본 브리지의 한계, 사용자 정의 브리지의 장점, 주요 네트워크 드라이버, DNS 서비스 검색, 포트 게시 및 실용적인 구성 단계를 다룹니다. 개발자와 시스템 관리자가 안전하고 격리된 확장 가능한 컨테이너화된 애플리케이션을 구축하는 데 필요한 지식을 제공합니다.

Docker 네트워킹: 컨테이너 완벽 가이드
Advertisement 728x90

Docker 컨테이너 네트워킹: 실전 가이드

Docker를 사용하기 시작하면 가장 먼저 마주치는 복잡한 문제 중 하나는 컨테이너들이 서로 그리고 외부 세계와 어떻게 통신하는지입니다. Docker 컨테이너 네트워킹을 간단히 설명하자면, 이 통신을 가능하게 하는 가상 네트워크와 규칙의 시스템으로, 컨테이너화된 애플리케이션에 격리, 보안 및 연결성을 제공합니다. 이러한 개념을 이해하는 것은 단순히 이론적인 것이 아니라 안전하고 확장 가능하며 유지 관리가 용이한 컨테이너 배포를 구축하는 데 필수적입니다.

배울 내용

Docker의 네트워킹 모델의 핵심 개념을 기본 브리지부터 특수 드라이버까지 이해하고, 컨테이너를 위한 안전하고 격리된 네트워크를 구성하는 방법을 배웁니다. 마지막에는 민감한 서비스를 격리하고 원활한 서비스 검색을 가능하게 하며 일반적인 연결 문제를 해결하는 네트워크 토폴로지를 설계할 수 있게 됩니다. 핵심 요점은 사용자 정의 브리지 네트워크가 대부분의 프로덕션 사용 사례에서 기본 브리지보다 훨씬 우수하다는 것입니다.

Docker 네트워킹의 핵심

본질적으로 컨테이너 네트워킹은 컨테이너가 서로 연결 및 통신하고, Docker가 아닌 네트워크 서비스와도 통신할 수 있는 능력을 의미합니다. 기본적으로 컨테이너는 네트워킹이 활성화되어 있으며 나가는 연결을 만들 수 있습니다. 컨테이너는 IP 주소, 게이트웨이, 라우팅 테이블 및 DNS 서비스를 갖춘 네트워크 인터페이스를 보지만, 자신이 연결된 네트워크의 종류나 피어가 Docker 컨테이너인지 여부에 대한 정보는 없습니다.

Google AdInline article slot

Linux에서 Docker Engine이 처음 시작되면 "기본 브리지" 네트워크라는 단일 내장 네트워크를 생성합니다. --network 옵션 없이 컨테이너를 실행하면 이 기본 브리지에 연결됩니다. 기능적으로는 작동하지만, 이 기본 설정에는 상당한 제한 사항이 있으며, 가장 두드러진 것은 컨테이너 간 자동 DNS 확인이 없다는 점입니다.

사용자 정의 브리지 네트워크: 더 나은 선택

진지한 애플리케이션의 경우 사용자 정의 브리지 네트워크를 만들어야 합니다. 이러한 사용자 정의 네트워크는 기본 브리지에 비해 몇 가지 중요한 이점을 제공합니다:

  1. 자동 DNS 확인: 사용자 정의 브리지의 컨테이너는 컨테이너 이름이나 별칭으로 서로를 확인할 수 있습니다. 예를 들어, web 컨테이너는 호스트 이름 db를 사용하여 db 컨테이너에 연결할 수 있습니다. 이는 기본 브리지에서는 불가능하며, 레거시 --link 플래그나 수동 /etc/hosts 조작이 필요합니다.

    Google AdInline article slot
  2. 더 나은 격리: --network가 지정되지 않은 모든 컨테이너는 기본 브리지 네트워크에 연결되어 관련 없는 컨테이너가 통신할 수 있는 위험이 발생합니다. 사용자 정의 네트워크는 범위가 지정된 네트워크를 제공하여 명시적으로 연결되지 않는 한 컨테이너를 서로 격리합니다.

  3. 실시간 연결 및 분리: 실행 중인 컨테이너를 다시 시작하지 않고도 사용자 정의 네트워크에 연결하거나 분리할 수 있습니다. 기본 브리지에서 컨테이너의 네트워크를 변경하려면 중지하고 다시 생성해야 합니다.

  4. 구성 가능한 브리지: 각 사용자 정의 네트워크는 자체 설정(MTU 및 방화벽 규칙 등)으로 구성할 수 있어 다양한 애플리케이션 요구에 맞게 네트워크를 조정할 수 있습니다.

    Google AdInline article slot

사용자 정의 브리지 네트워크 생성 및 사용 방법

사용자 정의 브리지 네트워크를 만들고 사용하는 것은 간단합니다. 이는 안전하고 관리 가능한 Docker 네트워킹 설정의 기초입니다.

1단계: 네트워크 생성

docker network create my-secure-network

기본적으로 브리지 네트워크가 생성됩니다. -d 플래그로 드라이버를 지정할 수도 있습니다(예: docker network create -d bridge my-net).

2단계: 이 네트워크에서 컨테이너 실행

docker run -d --name web --network my-secure-network nginx
docker run -d --name db --network my-secure-network postgres

web 컨테이너는 이제 호스트 이름 db를 사용하여 db 컨테이너와 통신할 수 있습니다.

3단계: 실행 중인 컨테이너를 네트워크에 연결

docker network connect my-secure-network already-running-container

컨테이너는 동시에 여러 네트워크에 연결될 수 있으며, 이는 프론트엔드가 외부-facing 네트워크와 내부 백엔드 네트워크 모두에 연결되는 복잡한 네트워킹 패턴을 만드는 강력한 기능입니다.

주요 네트워크 드라이버 및 사용 사례

Docker의 네트워킹은 플러그 가능하며, 드라이버를 사용하여 핵심 기능을 제공합니다. 다음은 주요 드라이버에 대한 설명입니다.

드라이버 설명 가장 적합한 경우
bridge 기본 네트워크 드라이버. 호스트에 개인 내부 네트워크를 생성합니다. 컨테이너가 서로 통신해야 하는 단일 호스트 애플리케이션. 표준적이고 가장 일반적인 선택입니다.
host 네트워크 격리를 제거합니다. 컨테이너가 호스트의 네트워크 스택을 직접 공유합니다. 성능이 중요한 애플리케이션 또는 많은 포트나 네트워크 수준 작업을 관리해야 하는 서비스(예: 네트워크 전체 DNS/DHCP 서비스인 Pi-hole). 보안 경고: 이 모드는 주요 격리 계층을 제거합니다.
none 컨테이너의 네트워킹을 비활성화합니다. 루프백 인터페이스(lo)만 있습니다. 고도로 격리된 작업 예: 오프라인 배치 처리 또는 네트워크 액세스가 필요 없는 작업.
overlay 여러 Docker 데몬을 연결하여 호스트 간 통신을 가능하게 합니다. Docker Swarm 클러스터 및 다중 호스트 애플리케이션.
macvlan 컨테이너에 MAC 주소를 할당하여 물리적 네트워크 장치로 나타나게 합니다. 레거시 애플리케이션 또는 VM 마이그레이션 컨테이너가 물리적 네트워크에 직접 있어야 하는 경우.
ipvlan macvlan과 유사하지만 고유 MAC 주소가 없으며 IPv4/IPv6 주소 지정에 대한 완전한 제어를 제공합니다. 할당할 수 있는 MAC 주소 수에 제한이 있는 네트워크 환경.

대부분의 개발자에게 bridge 드라이버, 특히 사용자 정의 브리지가 주요 도구가 될 것입니다.

호스트 모드 심층 이해

host 네트워크 드라이버는 강력하지만 특수한 도구입니다. 컨테이너와 Docker 호스트 간의 네트워크 격리를 제거하여 컨테이너가 호스트의 네트워크 스택을 직접 사용하게 합니다. 한 실무자가 언급했듯이, 이는 DNS 및 DHCP 서비스와 같은 브로드캐스트 트래픽 처리가 필요한 서비스에 이상적입니다.

⚠️ 중요 경고: 호스트 네트워킹은 크로스 플랫폼 친화적이지 않습니다. Linux 호스트에서만 예상대로 작동합니다. macOS 및 Windows(Docker Desktop을 통해)에서는 가상 머신 구현으로 인해 다르게 동작합니다. 또한 컨테이너에 대한 Docker의 DNS 서비스 검색 기능을 사용할 수 없으며 호스트 모드에서 다른 네트워크에 연결할 수 없습니다.

Docker Compose 예시:

version: "3"
services:
  web:
    image: nginx:latest
    network_mode: host

이 컨테이너는 호스트의 IP 주소에서 직접 액세스할 수 있습니다. ports 지시문이 필요하지 않습니다.

포트 게시: 컨테이너를 외부 세계에 연결

기본적으로 브리지 네트워크의 포트는 호스트 외부에서 액세스할 수 없습니다. 서비스를 외부에서 사용할 수 있게 하려면 -p 또는 --publish 플래그를 사용하여 포트를 게시합니다.

docker run -d -p 8080:80 --name webserver nginx

이것은 Docker 호스트의 포트 8080을 컨테이너의 포트 80에 매핑합니다. 호스트 IP의 포트 8080으로 들어오는 트래픽은 컨테이너로 전달됩니다.

  • 모든 노출된 포트를 게시하려면 -P 플래그를 사용합니다.
  • 로컬호스트로만 액세스를 제한하려면 127.0.0.1에 게시합니다: docker run -p 127.0.0.1:8080:80 nginx.
  • 동일한 브리지 네트워크의 컨테이너가 서로 통신하기 위해 포트를 게시할 필요는 없습니다. 컨테이너 이름과 포트를 사용하여 직접 통신할 수 있습니다.

DNS 및 서비스 검색

기본적으로 컨테이너는 Docker 호스트의 DNS 설정을 상속받습니다. 그러나 중요한 차이점이 있습니다:

  • 기본 브리지 네트워크: 컨테이너는 호스트의 /etc/resolv.conf 파일 복사본을 받습니다.
  • 사용자 정의 네트워크: 컨테이너는 127.0.0.11에 있는 Docker 내장 DNS 서버를 사용합니다. 이 서버는 외부 DNS 조회를 호스트의 구성된 서버로 전달합니다. 이 내장 DNS가 컨테이너 이름 확인을 가능하게 합니다. 컨테이너 내부의 애플리케이션이 Docker DNS 서버를 명시적으로 쿼리해야 하는 경우 주소 127.0.0.11을 사용해야 합니다.

--dns, --dns-search--dns-opt와 같은 플래그를 사용하여 컨테이너별로 DNS 설정을 재정의할 수 있습니다.

실전 워크플로우: 컨테이너 네트워크 변경

컨테이너의 네트워크 구성을 변경할 수 있지만 중요한 제한 사항이 있습니다.

  1. 브리지 네트워크의 컨테이너: 실행 중인 컨테이너를 네트워크에 연결하거나 분리할 수 있습니다.

    # 실행 중인 컨테이너를 사용자 정의 네트워크에 연결
    docker network connect my-new-network my-container
    # 기본 브리지에서 분리
    docker network disconnect bridge my-container

    컨테이너를 마지막 네트워크에서 분리할 수 없습니다. 항상 최소 하나의 네트워크에 연결되어 있어야 합니다.

  2. 호스트 네트워크의 컨테이너: 실행 중인 컨테이너의 네트워크 구성을 변경하거나 다른 네트워크에 연결하는 것은 불가능합니다. 시도하면 다음과 같은 오류가 발생합니다:

    Error response from daemon: container sharing network namespace with another container or host cannot be connected to any other network

    네트워크를 변경하려면 컨테이너를 중지, 제거 및 다시 생성해야 하며, 동일한 환경 변수, 볼륨 및 기타 설정을 사용하여 구성을 유지해야 합니다.

자주 묻는 질문

기본 브리지와 사용자 정의 브리지 네트워크의 차이점은 무엇인가요? 가장 중요한 차이점은 자동 DNS 확인입니다. 사용자 정의 브리지의 컨테이너는 컨테이너 이름으로 통신할 수 있는 반면, 기본 브리지의 컨테이너는 IP 주소로만 서로 연결할 수 있습니다. 사용자 정의 네트워크는 또한 더 나은 격리와 실시간 컨테이너 연결/분리 유연성을 제공합니다.

로컬 네트워크나 인터넷에서 컨테이너에 액세스하려면 어떻게 해야 하나요? -p 또는 --publish 플래그를 사용하여 컨테이너의 포트를 게시해야 합니다. 예를 들어, -p 8080:80은 Docker 호스트의 포트 8080을 컨테이너의 포트 80에 매핑하여 서비스를 호스트의 IP 주소에서 사용할 수 있게 합니다.

컨테이너를 여러 네트워크에 연결할 수 있나요? 네, 이는 강력한 기능입니다. 컨테이너는 생성 시 --network 플래그를 여러 번 사용하거나 실행 중인 컨테이너에 docker network connect 명령을 사용하여 동시에 여러 네트워크에 연결될 수 있습니다. 이는 외부-facing 네트워크와 내부 개인 네트워크를 모두 갖춘 애플리케이션을 만드는 데 유용합니다.

Docker 호스트에서 컨테이너로 ping을 보낼 수 없는 이유는 무엇인가요? Docker Desktop for Mac 및 Windows에서는 가상 머신 내에서 네트워킹이 구현되는 방식 때문에 Linux 컨테이너에 직접 ping을 보낼 수 없습니다. 이는 알려진 제한 사항이며, docker0 브리지 인터페이스가 호스트에 표시되지 않습니다. 그러나 Windows 사용자는 Windows 컨테이너에 ping을 보낼 수 있습니다.

host 네트워크 드라이버는 언제 사용해야 하나요? host 드라이버는 기본 네트워크 성능이 중요하거나 서비스가 네트워크 수준 기능(예: DNS/DHCP 서버)을 처리해야 하는 특정 사용 사례에만 사용해야 합니다. 이는 보안 및 이식성을 희생하며, Linux에서만 안정적으로 작동하고 네트워크 격리를 제거합니다.

출처

— Editorial Team

Advertisement 728x90

다음 읽기