[Docker Mastery] - 2

도커 네트워크 기초

시작

살펴보기

이번에는 컨테이너간 어떻게 서로간 통신이 가능한지 알아봅시다.
기본 TCP/IP. 서브넷, IP, 포트, 방화벽 같은 네트워크 개념이 필요하지만 차근차근 배워나가 봅시다.
docker container run -p 포트 명령을 알아보고 Docker 네트워킹 및 가상 네트워크 개념을 분석합니다.
또한 서로간 통신하는 것을 확인해봅시다.

도커 네트워크의 컨셉

우선 실제로 컨테이너를 실행하면 가상 브리지 네트워크에 속하게 됩니다. NAT 방화벽을 통해 라우팅하기 위해 연결하려는 네트워크는 실제로 호스트 IP 주소를 기본 인터페이스로 설정하여 컨테이너가 인터넷이나 네트워크로 인-아웃 됩니다.
SQL 서버가 있고, Apache 컨테이너가 있다면 두 컨테이너는 같은 네트워크에 있어야 하죠. -p 옵션을 사용해 네트워크에 노출하지 않고도 통신 가능한 네트워크를 만듭니다. 하지만 외부 네트워크와 통신은 불가능하죠.

p 명령어

p 명령은 개방하려는 호스트 포트:포워딩할 컨테이너 포트입니다.

bash
docker container run -p 80:80 --name webhost -d nginx
docker container port webhost

ip를 확인할 수도 있죠.

bash
# format 명령은 들어오는 텍스트를 필터링 합니다. grep 또한 사용할 수 있지민 format이 더 깔끔합니다.
docker container inspect --format '{{ .NetworkSettings.IPAddress }}' webhost

ifconfig를 통해 서브넷 주소를 확인해보면 다를 겁니다.

호스트 운영 체제가 나의 네트워크에 연결되어 있다면 물리적 네트워크 이더넷 인더페이스에 작은 방화벽이 존재합니다. 기본적으로 들어오는 트래픽을 차단하죠. -p 옵션을 사용하는 단계에서 포트를 열기 때문이죠. 컨테이너에서 나오는 것은 기본적으로 NAT에 연결될겁니다. 네트워크는 엣지 네트워크 처럼 작동하죠 가상 브릿지 네트워크 bridge/docker0와 같이말이죠. 이 네트워크는 호스트의 이더넷 인터페이스에 자동으로 연결됩니다.
nginx를 실행했을때 -p 80:80을 설정했죠. 이더넷 인터페이스에서 포트 80을 연결하고 가상 네트워크 80으로 포워딩합니다. 이후 두번째 컨테이너를 생성하면 동일 가상 네트워크 bridge/docker0에 속하게 됩니다. 두 컨테이너는 노출된 포트로 자유롭게 통신이 가능하죠 -p 옵션을 사용하지 않는다면 외부에서 오는 통신은 받지 못합니다.

컨테이너 별로도 -p 옵션을 사용하고 사용하지 않기도 할겁니다. 예로 새로운 가상 네트워크안에 웹서버는 8080:80으로 포워딩하고 DB는 -p 옵션을 사용하지 않습니다. 이렇게 되면 외부 트래픽은 들어올 수 없겠죠. 이렇듯 여러 콘셉트를 가진 컨테이너 환경을 구성할 수 있습니다.

network 명령어

  • docker network ls 생성된 네트워크 나열
bash
docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
e75c8de08e18   bridge    bridge    local
9a8678d011f6   host      host      local
e72a870acefb   none      null      local
  • docker network inspect 구성환경 확인
bash
docker network inspect bridge
[
    {
        "Name": "bridge",
        "Id": "e75c8de08e187f4fd4c2a53094c1780a022838526868b94c8c16de614f1b2165",
        "Created": "2024-01-15T16:07:00.143498919Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",
                    "Gateway": "172.17.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "5d4c7b3c219c36b75da78bb72077c373f6559a2d44de695160471511c865a9f3": {
                "Name": "webhost",
                "EndpointID": "19c38e7430438d716562c45c6344b8fec07bb87b7307ff408ff527d0bb1367c7",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {
            "com.docker.network.bridge.default_bridge": "true",
            "com.docker.network.bridge.enable_icc": "true",
            "com.docker.network.bridge.enable_ip_masquerade": "true",
            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
            "com.docker.network.bridge.name": "docker0",
            "com.docker.network.driver.mtu": "1500"
        },
        "Labels": {}
    }
]
  • docker network create --driver 특정 드라이버를 포함한 네트워크 구성
  • docker network connect
  • docker network disconnect