네트워크와 도커

    IP란?

    컴퓨터는 IP주소라는 주소를 가지고 통신한다. IP 주소는 총 32비트로 이루어져 있으며 . 을 기준으로 8비트씩 분리된다.

    💡 IP프로토콜을 사용하지 않고 MAC 주소만을 사용해 통신할 수도 있기는 함.

    (8비트.8비트.8비트.8비트)

    이렇다면 총 IPv4 체계에서 생성할 수 있는 주소의 개수는 $$2^{32}=4,294,967,296$$개, 즉 약 43억개이다. 전세계 인류가 80억명 정도이니, 인당 컴퓨터 하나씩만 한다고 해도 IPv4의 주소 범위를 뛰어넘는다. 이를 해결하기 위해 IPv6라는 새로운 표준이 제정되었지만, 아직 널리 사용되지는 못하고 있다.

    CIDR 표기법

    IP의 범위를 표기할 때에는 CIDR 표기법을 주로 사용한다. CIDR표기법은 시작 IP 주소를 표기하고 / 를 표기한 이후, 고정할 앞 n 개의 비트 개수를 표기해야 한다.

    192.168.0.0/16 → 192.168.0.0 – 192.168.255.255

    내부망(사설망)이란?

    공인IP는 ICANN에서 관리하고, ISP가 개인에게 할당한다.

    flowchart LR;
    subgraph ISP회원
    회원1;회원2
    end
    ICANN --1.1.0.0/16--> ISP --1.1.23.54--> 회원1
    ISP --1.1.27.23--> 회원2
    flowchart LR;
    subgraph ISP회원
    회원1;회원2
    end
    ICANN --1.1.0.0/16--> ISP --1.1.23.54--> 회원1
    ISP --1.1.27.23--> 회원2

    공인IP는 한정된 자원이기에 각 회원당 IP를 무한정 할당해 줄 수 없다. 하지만 한 회원당 컴퓨터를 하나만 사용하는 것은 아니니 공인IP를 여러 기기에서 동시에 사용할 수 있도록 해야 한다. 이를 가능하게 하는 것이 공유기(가정에서) 또는 라우터(기업에서)이다.

    💡 가정용 무선공유기는 방화벽+라우터+허브+AP+DHCP서버 등등..을 합쳐 하나로 만든 기기이다.

    라우터는 공인 IP를 받고, 내부망을 구축한다. 이때, 내부망에서는 공유기 임의로 내부에서만 사용할 수 있는 사설IP를 각 기기에 할당하는데, 이들 IP는 공인 IP와는 충돌하면 안 되기에, 내부망 IP로 사용할 수 있는 대역이 다음과 같이 정해져 있다.

    • Class A
      • 10.0.0.0/8 (16,777,216개)
    • Class B
      • 172.16.0.0/12 (1,048,576개)
    • Class C
      • 192.168.0.0/16 (65,536개)

    이들 범위 내부는 공인 IP로 할당하지 않는 범위로, 누구나 자유롭게 사용할 수 있다. 일반적인 가정에서는 Class C 범위를 주로 사용한다.

    flowchart TB;
    ISP --1.1.23.54--> 공유기
    subgraph 회원1의 공유기 내부망
    공유기 --192.168.0.2--> 컴퓨터1
    공유기 --192.168.0.3--> 컴퓨터2
    공유기 --192.168.0.4--> 셋톱박스
    공유기 --192.168.0.5--> 휴대폰
    end
    flowchart TB;
    ISP --1.1.23.54--> 공유기
    subgraph 회원1의 공유기 내부망
    공유기 --192.168.0.2--> 컴퓨터1
    공유기 --192.168.0.3--> 컴퓨터2
    공유기 --192.168.0.4--> 셋톱박스
    공유기 --192.168.0.5--> 휴대폰
    end

    위와 같은 그림대로, 공유기가 회원1의 가정 내 각 기기에 사설IP를 할당하였다.

    💡 IP를 자동적으로 할당하는 일은 공유기 내부의 DHCP서버가 한다. IP가 할당되면 ARP를 통해 기기 mac 주소와 IP 주소를 맵핑시킬 수 있다.

    컴퓨터가 IP를 할당받는 방법

    컴퓨터에는 NIC(네트워크 인터페이스 카드)가 내장되어 있습니다. 유선 NIC의 경우 RJ45 LAN 포트가 내장되어 있는 것이 대중적이며, 서버용 장비에는 SFP포트가 있어 사용환경에 맞게 여러 케이블을 사용할 수 있도록 한 것도 있습니다.

    무선 NIC의 경우 Wifi를 통해 무선으로 랜에 연결할 수 있도록 합니다.

    이러한 NIC와 라우터가 연결되면, 기본적으로 DHCP를 통해 자동으로 IP를 할당받으려 시도합니다.

    1. DHCP Discovery
      NIC와 라우터가 연결되었을 때, 브로드캐스팅 IP 주소(255.255.255.255), 67번 포트로 UDP패킷을 전송합니다.

      💡 255.255.255.255는 브로드캐스팅 주소로, 이 주소로 패킷을 전송하면 라우터는 랜에 존재하는 모든 컴퓨터에게 이 패킷을 전달하게 됩니다.

      💡 이때 랜에 연결하고자 하는 호스트는 자신의 주소가 없기 때문에, 출발지 주소는 0.0.0.0 입니다.

      flowchart
      subgraph 회원1의 라우터 내부망
      direction TB
      라우터 --192.168.0.2--o DHCP서버
      라우터 --?.?.?.?--o 컴퓨터1
      컴퓨터1 -- 255.255.255.255 : DHCP Discovery --> 라우터
      라우터 -.DHCP Discovery.-> DHCP서버
      end
      flowchart
      subgraph 회원1의 라우터 내부망
      direction TB
      라우터 --192.168.0.2--o DHCP서버
      라우터 --?.?.?.?--o 컴퓨터1
      컴퓨터1 -- 255.255.255.255 : DHCP Discovery --> 라우터
      라우터 -.DHCP Discovery.-> DHCP서버
      end
      classDiagram
      note "DHCP Discover\nAsrc:0.0.0.0:68\ndest:255.255.255.255:68\nyiaddr:0.0.0.0\ntransaction ID: 14"
    2. DHCP Offer
      해당 랜에 DHCP서버가 존재한다면, DHCP Server Discovery 메시지를 받은 후, 다시 브로드캐스팅을 통해 DHCP Server Offer 메시지를 전송합니다. 이때, Offer 에는 다음 정보들을 포함합니다.
      flowchart
      subgraph 회원1의 라우터 내부망
      direction TB
      라우터 --192.168.0.2--o DHCP서버
      라우터 --?.?.?.?--o 컴퓨터1
      라우터 --DHCP Offer --> 컴퓨터1
      DHCP서버 -- 255.255.255.255 : DHCP Offer --> 라우터
      end
      flowchart
      subgraph 회원1의 라우터 내부망
      direction TB
      라우터 --192.168.0.2--o DHCP서버
      라우터 --?.?.?.?--o 컴퓨터1
      라우터 --DHCP Offer --> 컴퓨터1
      DHCP서버 -- 255.255.255.255 : DHCP Offer --> 라우터
      end
      classDiagram
      note "DHCP Offer\nAsrc:192.168.0.2:68\ndest:255.255.255.255:68\nyiaddr:192.168.0.3\ntransaction ID: 14\nDHCP server ID: 192.168.0.2\nLifetime: 3600 secs"
      • 수신된 메시지의 트랜젝션 ID
      • 할당한 IP 주소
      • 서브넷 마스크
      • IP 주소 임대 기간
    3. DHCP Request
      랜 내부에는 DHCP서버가 여러개 있을 수 있으므로, DHCP Offer 중 하나를 선택해 DHCP Ack 메시지를 만들어 응답한다.
    4. DHCP Ack

    사설망(내부망)과 외부와 통신하는 방법

    사설망과 외부망이 통신하는 방법에는 크게 NAT테이블을 사용하는 방법과, 포트포워딩 테이블을 사용하는 방법이 있다. NAT 테이블은 아웃바운드 통신에서 사용할 수 있고, 포트포워딩 테이블은 인바운드 통신에서 사용할 수 있다.

    flowchart
    subgraph 기업의 내부망 165.232.123.5
    direction TB
    라우터1[라우터] --10.0.0.2--o 서버1
    라우터1[라우터] --10.0.0.3--o 서버2
    라우터1[라우터] --10.0.0.4--o 서버3
    라우터1[라우터] --10.0.0.5--o 서버4
    end
    subgraph 회원1의 라우터 내부망 152.242.291.281
    direction TB
    공유기 --192.168.0.3--o 컴퓨터1
    end
    flowchart
    subgraph 기업의 내부망 165.232.123.5
    direction TB
    라우터1[라우터] --10.0.0.2--o 서버1
    라우터1[라우터] --10.0.0.3--o 서버2
    라우터1[라우터] --10.0.0.4--o 서버3
    라우터1[라우터] --10.0.0.5--o 서버4
    end
    subgraph 회원1의 라우터 내부망 152.242.291.281
    direction TB
    공유기 --192.168.0.3--o 컴퓨터1
    end

    위와 같은 상황에서 컴퓨터 1이 특정 기업의 홈페이지에 접근하려 한다. 이때 회원1의 내부망에서는 NAT테이블로 아웃바운드 요청을 보내고, 기업의 내부망에서는 포트포워딩 테이블을 통해 인바운드 요청을 받는다.

    먼저, 컴퓨터 1이 기업의 공인 IP인 165.232.123.5 로 http 요청을 보낸다. 이 때, 공유기(가정에서의)가 NAT테이블에 사용 가능한 포트 하나를 확보하게 된다.

    공유기의 NAT테이블

    공인 IP공인 Port사설 IP사설 Port
    152.242.291.2811234192.168.0.380

    그 이후, 해당 패킷은 공유기가 다시 목적지를 향해 전송한다. 이때, 발송주소가 공유기의 공인 IP와 공유기가 할당한 공인 Port로 바뀌어 공인망을 통해 전달된다.

    💡 목적지 주소는 바뀌지 않는다. 즉 165.232.123.5:80 으로 계속 전달된다.

    공인망을 타고 기업의 라우터에 패킷이 도착하면, 이를 연결된 각 서버에 전달하여 처리해야 한다. 이때 이를 정의해 놓은 곳이 포트포워딩 테이블이다. 이 테이블은 NAT테이블과 다르게 사전 정의하지 않으면 (목적지 포트가 정의되어 있지 않으면) 패킷은 버려진다.

    기업측 라우터의 포트포워딩 테이블

    공인 IP공인 Port사설 IP사설 Port
    165.232.123.58010.0.0.280

    위와 같이 설정되어 있을 때, 공인 IP에 80번 포트로 요청이 전송되면 10.0.0.2:80 으로 전달하겠다는 뜻이다.

    flowchart
    subgraph 공인망
    direction TB
    subgraph "기업의 내부망 165.232.123.5"
    direction TB
    라우터1[라우터] --10.0.0.2--o 서버1
    라우터1[라우터] --10.0.0.3--o 서버2
    라우터1[라우터] --10.0.0.4--o 서버3
    라우터1[라우터] --10.0.0.5--o 서버4
    end
    subgraph 회원1의 라우터 내부망 152.242.291.281
    direction TB
    공유기 --192.168.0.3--o 컴퓨터1
    end
    컴퓨터1 --> 공유기 --> 라우터1 --> 서버1
    end
    flowchart
    subgraph 공인망
    direction TB
    subgraph "기업의 내부망 165.232.123.5"
    direction TB
    라우터1[라우터] --10.0.0.2--o 서버1
    라우터1[라우터] --10.0.0.3--o 서버2
    라우터1[라우터] --10.0.0.4--o 서버3
    라우터1[라우터] --10.0.0.5--o 서버4
    end
    subgraph 회원1의 라우터 내부망 152.242.291.281
    direction TB
    공유기 --192.168.0.3--o 컴퓨터1
    end
    컴퓨터1 --> 공유기 --> 라우터1 --> 서버1
    end

    전체적인 구조는 위와 같다.

    컴퓨터 1 –> 개인의 공유기 –> 공인망 –> 기업의 라우터 –> 서버1

    회원1의 내부망 기준에서는 아웃바운드, 기업의 입장에서 인바운드를 통해 외부망과 통신하는 예제를 살펴봤습니다.

    실습

    내부망 구축과 관련된 실습은 Proxmox 내부망 구축하기 글을 참고하세요. 이 글에서는 iptables 를 조금 더 쉽게 사용할 수 있도록 한 nftables를 통해 내부망을 구축하는 방법에 대해 알아봅니다.

    Domain

    지금까지는 IP 주소를 통해 컴퓨터간 통신을 하는 예제를 보았습니다. 다만 IP주소는 기억하고 사용하기 어렵기 때문에, 도메인으로 대체하게 되었습니다. 이를 위해서는 도메인과 IP를 매핑시켜주는 서버가 필요한데요, 이를 DNS서버라고 합니다.

    DNS 서버에는 4가지 분류가 있습니다.

    • DNS recursive resolver
    • Root DNS
    • TLD DNS
    • authoritative DNS
    flowchart
    컴퓨터 --example.com--> Resolver
    subgraph DNS
    direction LR
    
    Resolver[DNS Resolver] --> RootDNS --> com --> example.com
    subgraph TLD DNSs
    com[.com DNS]
    net[.net DNS]
    org[.org DNS]
    end
    
    subgraph Authoriative DNSs
    example.com
    example.net
    example.org
    end
    
    
    end
    flowchart
    컴퓨터 --example.com--> Resolver
    subgraph DNS
    direction LR
    Resolver[DNS Resolver] --> RootDNS --> com --> example.com
    subgraph TLD DNSs
    com[.com DNS]
    net[.net DNS]
    org[.org DNS]
    end
    subgraph Authoriative DNSs
    example.com
    example.net
    example.org
    end
    end

    컴퓨터는 처음에 DNS Resolver 로 example.com에 대한 IP주소를 요청합니다. Resolver 에 캐시가 존재한다면 즉시 리턴될 수 있지만, 아니라면 Root DNS로 넘어간 후, 각 TLD의 DNS로 넘어간 후 각 도메인의 DNS로 넘어가 해당 도메인에 대한 레코드를 조회할 수 있습니다.

    A레코드를 통해 IPv4 주소를 가르킬 수 있고, AAAA레코드를 통해 IPv6 주소를 가르킬 수 있습니다.

    💡 MX 레코드를 사용하면 [email protected] 과 같은 커스텀 도메인 이메일을 만들 수 있다.

    이러한 과정을 통해 모든 도메인의 IP 주소를 모두 알아낼 수 있습니다. 실제로 이를 실행하려면 터미널에서 nslookup명령을 사용할 수 있습니다.

    도커 네트워크

    도커는 가상의 내부망을 구축하여 각 컨테이너에 IP를 할당하게 된다. 도커 네트워크를 생성하면 자동으로 가상의 통신 장비와 브릿지, DNS가 추가되며, 물리 NIC를 대신해서 가상 네트워크 인터페이스가 시스템에 생성된다.

    도커 네트워크를 먼저 생성하자. 브릿지를 하나 만드는데, 10.0.0.0/24 범위를 사용하고, 게이트웨이(라우터)주소는 10.0.0.1 로 하겠다는 뜻이다.

    docker network create --driver bridge --subnet 10.0.0.0/24 --gateway 10.0.0.1 second-bridge

    그 후 containerA, B, C를 생성한다

    docker run -it --name containerA devwikirepo/pingbuntu bin/bash
    docker run -it --network second-bridge --name containerB devwikirepo/pingbuntu bin/bash
    docker run -it --network second-bridge --name containerC devwikirepo/pingbuntu bin/bash
    flowchart RL
    subgraph dockerNetwork
    subgraph second-bridge
    bridge2[bridge]
    DNS
    containerB
    containerC
    end
    subgraph "default"
    bridge1[bridge]
    containerA
    end
    end
    flowchart RL
    subgraph dockerNetwork
    subgraph second-bridge
    bridge2[bridge]
    DNS
    containerB
    containerC
    end
    subgraph "default"
    bridge1[bridge]
    containerA
    end
    end

    💡 기본적으로 생성되는 default 네트워크에는 DNS가 없다.

    💡 이때 생성된 DNS는 일반적인 도메인을 조회하기 위해 사용하는 것이 아닌, 내부망에서 사설 도메인을 사용하기 위해 사용하는 DNS로, 각 컨테이너의 IP대신 이름을 사용할 수 있도록 해 준다.

    위와 같이 설정되어 있을 것이다. 이때 같은 네트워크에 있지 않은 컨테이너 간에는 소통이 불가능하다.

    # containerA
    ping 10.0.0.2 #불가능
    ping 10.0.0.3 #불가능
    flowchart RL
    subgraph dockerNetwork
    second-bridge ~~~ default
    subgraph second-bridge
    bridge2[bridge]
    DNS
    containerB
    containerC
    end
    subgraph "default"
    bridge1[bridge]
    containerA
    end
    containerA --10.0.0.2--x containerB
    containerA --10.0.0.3--x containerC
    end
    flowchart RL
    subgraph dockerNetwork
    second-bridge ~~~ default
    subgraph second-bridge
    bridge2[bridge]
    DNS
    containerB
    containerC
    end
    subgraph "default"
    bridge1[bridge]
    containerA
    end
    containerA --10.0.0.2--x containerB
    containerA --10.0.0.3--x containerC
    end

    반면에, 같은 네트워크에 있는 B와 C는 IP주소 및 컨테이너 이름(DNS가 있을 때)을 통해 통신할 수 있다.

    # containerB
    ping 10.0.0.3
    ping containerB ## 두 명령은 동일하게 작동한다.
    flowchart TB
    subgraph dockerNetwork
    default ~~~ second-bridge
    subgraph second-bridge
    DNS
    containerB
    containerC
    end
    subgraph "default"
    containerA
    end
    containerB <--> containerC
    end
    flowchart TB
    subgraph dockerNetwork
    default ~~~ second-bridge
    subgraph second-bridge
    DNS
    containerB
    containerC
    end
    subgraph "default"
    containerA
    end
    containerB <--> containerC
    end

    도커 컨테이너와 포트포워딩

    docker run -d -p 8004:3000 --name greenColorApp --env COLOR=green devwikirepo/envnodecolorapp

    위와 같이 외부망 포트 8004번을 컨테이너 3000번에 연결시킬 수 있다.

    flowchart
    subgraph HOST
    subgraph DockerNetwork
    bridge --8004:3000--o greenColorApp
    end
    end
    flowchart
    subgraph HOST
    subgraph DockerNetwork
    bridge --8004:3000--o greenColorApp
    end
    end

    위와 같이 호스트 8004번 포트로 요청이 오면, greenColorApp 컨테이너로 3000번 포트로 전달된다. 라우터의 포트포워딩 테이블과 똑같이 작동하는 것이다. 브라우저로 localhost:8004 에 접근하면 초록 페이지가 나타난다.


    게시됨

    카테고리

    작성자

    태그:

    Obtuse의 테크 블로그 더 알아보기

    이 블로그에 새 글이 나올 때 마다 이메일로 알림을 받아보는 건 어때요?


    ※구독 버튼을 클릭하면 obtuse.kr의 개인정보 처리방침의 광고성 정보 수신에 동의하는 것으로 간주합니다.

    댓글

    “네트워크와 도커”에 대한 2개의 응답

    1. 냥 이치 니 산 냥 아리가또~ 아바타

      저런 괴랄한 것은 어디서 배운 것이냐 나도 알려줘라

      1.  아바타
        익명

        감사합니다 ㈜

    냥 이치 니 산 냥 아리가또~에 답글 남기기 응답 취소

    이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

    이 사이트는 스팸을 줄이는 아키스밋을 사용합니다. 댓글이 어떻게 처리되는지 알아보십시오.