Docker) Network에 대해서 공부해보기

2023. 3. 13. 00:33개발/Docker

저번에 docker-compose로 여러 개의 컨테이너를 묶고 고정 ip가 되어 있는 상태에서 진행을 하려고 했는데, network에 대한 개념이 부족해서, 잘 안된 적이 있습니다.

그래서 각 개념에 대해서 대략적으로 알아야 할 것 같아서 정리를 하고자 합니다.

 

일단 gateway부터 알아보기 시작했습니다.

 

Gateway란?

네트워크에서 다른 네트워크로 연결하는 역할을 하는 네트워크 장비라고 합니다.

일반적으로는 라우터 혹은 스위치가 Gateway 역할을 한다고 합니다.

예시

- 다른 언어를 사용하는 두 사람 사이에 통역사나 번역기와 같다고 합니다. 

- 다른 화폐를 사용하는 두 국가 사이에 환전소

 

예를 들어, 집에서 인터넷을 사용할 때는 가정 내부의 컴퓨터와 모바일 기기들이 하나의 네트워크로 연결되어 있습니다. 

그러나 인터넷으로 정보를 조회하거나 파일을 다운로드하려면, 가정 내부의 네트워크를 벗어나 인터넷에 연결된 다른 네트워크로 데이터를 전송해야 합니다. 이때, 가정 내부의 라우터를 Gateway로 사용하여 인터넷으로 데이터를 전송할 수 있습니다.

즉, Gateway는 네트워크 간의 데이터 전송을 중개하는 역할을 합니다. 

컴퓨터나 모바일 기기 등이 인터넷에 접속할 때에는 Gateway를 통해 다른 네트워크로 연결되며, 데이터를 주고받을 수 있습니다.

 

API Gateway란?

마이크로서비스 아키텍처에서 사용되는 패턴 중 하나로, 클라이언트와 백엔드 서비스 사이에 위치하여 API 요청을 받아 적절한 백엔드 서비스로 라우팅하고, 결과를 클라이언트에게 반환하는 역할입니다.

 

Docker-Compose Gateway

서비스(container) 간 통신을 하기 위해서는 서로의 IP 주소와 포트 번호를 알아야 하는데, Docker Compose에서는 이를 위해 gateway를 사용합니다.

원래라면 컨테이너들 끼리 통신을 하기 위해서는 각각의 ip주소와 포트를 알아야 하지만, docker-compose는 이를 보다 간단하게 처리하기 위해 gateway를 제공합니다.

 

서비스 간 통신에서 gateway는 중개자 역할을 한다고 합니다.

각 서비스는 gateway를 통해 다른 서비스와 통신하게 되며, gateway는 각 서비스의 IP 주소와 포트 번호를 알고 있기 때문에 통신이 가능해집니다. 이를 통해 Docker Compose에서 간단하게 서비스 간 통신을 구성할 수 있습니다.

 

물론 gateway를 명시하지 않아도 서비스 간 통신은 가능하지만,, 구성을 하게 되면 서비스 간 통신을 더 쉽게 하고 분리하는 데 도움이 된다고 합니다.

 

Default-Network

기본적으로 Docker Compose는 하나의 디폴트 네트워크에 모든 컨테이너를 연결합니다.

default name은 docker-compose.yml 가 위치한 디렉토리 이름 뒤에 _default가 붙는다../test/docker-compose.yml이라고 하면 test_default로 생기게 된다.

 

docker-compose를 실행하면 먼저 네트워크를 생성해 놓고, 각 컨테이너를 구동한 후 네트워크에 연결시킨다.

 

내릴 때는 반대 순서로 먼저 컨테이너 종료하고 네트워크를 제거한다.

 

조회 방법

docker network 조회하는 명령어를 통해, 네트워크를 확인할 수 있다.

docker network ls

 

컨테이너 간 통신

docker-compose exec [container 1] ping [container 2]

주의 사항

host port : container port

services:
  web:
    build: .
    ports:
      - "8001:8000" # host_port:container_port

 

호스트 컴퓨터에서 web 서비스 컨테이너 접속

curl -I localhost:8001

같은 네트워크 내의 다른 컨테이너에서 web 서비스 컨테이너 접속

docker-compose exec [container 2] curl -I web:8000

 

 

 

subnet이란?

네트워크가 작은 조각으로 쪼개져 있는 경우 이러한 조각을 서브넷이라고 부릅니다. 

한 마디로 서브넷은 작은 네트워크라고 할 수 있습니다. 

네트워크 성능 개선을 위해 네트워크 관리지가 효율적으로 자원을 분배하는 것이 바로 서브네팅(subnetting)이라 합니다.

즉, IP 주소를 그룹으로 나누어 관리하는 방법입니다.

서브네팅은 서브넷 마스크(Subnet Mask)를 통하여 수행

 

subnet이 필요한 이유

이러한 기술들은 결국 각 클래스로 나눠진 네트워크를 운영 중인 서비스의 규모에 맞게 분할

  • 낭비되는 IP주소 자원을 최소화하려는 것이 주된 목적
  • 다른 이유로는 브로드 캐스팅을 사용할 때
    • 특정 네트워크에 연결된 모든 기기에 하나의 메시지로 동시에 데이터를 보내는 것
    •  네트워크의 규모를 줄여서 브로드 캐스팅으로 인한 부하를 줄일 수 있는 것

subnet 마스크란?

서브넷 마스크는 IP 주소 체계의 Network ID와 Host ID를 분리하는 역할

일단 아래 예시로 IP 주소에 대해서 이야기 하자면, IP(Internet Protocol) 주소는 컴퓨터나 장치들이 인터넷상에서 서로를 식별하고 통신하기 위해 사용하는 고유한 주소입니다. 이는 네트워크 계층에서 사용되며, 일반적으로 32비트 또는 128비트의 이진수로 표현됩니다.

 

192.168.123.132 같은 경우 IPv4에 해당하며, 32 비트의 이진수로 구성된다고 합니다.

보통 4 개의 8비트 블록으로 구성된 10진수로 표현한다고 합니다.

 

IP 주소(192.168.123.132)에서 192.168.123은 네트워크를 나타내며, 132는 네트워크 연결된 기기를 나타낸다고 합니다.

 

네트워크 ID는 IP 주소에서 네트워크를 구분하는 일련의 비트입니다. 이는 서로 다른 네트워크 상의 호스트 간에 통신을 가능하게 합니다.

 

호스트 ID는 IP 주소에서 네트워크 ID를 제외한 부분입니다. 이는 해당 네트워크에서 호스트를 식별하는 데 사용됩니다.
아래 값들은 이진수로 표현하게 되면 다음과 같이 나온다
192 = 1x2^7 + 1x2^6  + 0x2^5+ 0x2^4+ 0x2^3+ 0x2^2+ 0x2^1+ 0x2^0  (11000000)

 

아래로 IPv4에서는 클래스를 다음과 같이 나눠서 주소 체계를 사용한다고 합니다.

그래서 위와 같은 경우 C class에 해당합니다.

주소 체계와 서브넷 마스크는 IP 주소에서 네트워크 ID와 호스트 ID를 구분하는 데 사용됩니다. IP 주소 체계는 호스트 ID와 네트워크 ID의 비트 수를 정의하고, 서브넷 마스크는 IP 주소를 서브넷으로 분할할 때 각 서브넷의 네트워크 ID와 호스트 ID를 구분합니다.

 

암튼 subnet 이라는 것은 네트워크 주소고 subnet mask를 통해서 사용할 subnet 범위를 점한다고 보면 되는 것 같습니다.

 

클래스는 다음과 같이 이렇게 표현해질 수 있다. 

 

예를 들어, IP가 192.168.10.1 이고, default subnet mask가 255.255.255.0이 된다.

 

왜냐하면 C클래스 IP주소의 기본 서브넷마스크는 255.255.255.0이다.

서브넷 마스크는 CIDR(앞에서부터 몇비트까지가 네트워크 ID인지)로 표기되기도 한다. 

 

CIDR(Classless Inter-Domain Routing)

CIDR의 full name은 Classless Inter-Domain Routing으로 클래스 없는 도메인 간 라우팅 기법

 

255.255.255.0은 CIDR 표기법으로 /24가 된다.

255은 2진수로 표현하면, 11111111이 된다.

만약 서브넷팅을 해보자.

호스트 ID로 사용하던 비트 부분을 앞부분부터 차례로 서브넷 ID로 바꿔야 한다.

C 클래스에서 호스트 ID 1비트로 서브넷 ID로 바꾸면 192.168.10.0/25가 된다.

이렇게 되면 25개의 1이 있다고 보면 된다. 

그러면 앞에서부터 1이 25개가 있는 것과 같다.

11111111.11111111.11111111.10000000 (1이 25개)

이걸 바꾸면 (255.255.255.128이 된다)

그러면 129부터 255개까지가 되는 거니까 (255-129+1 = 127) 127개만 사용할 수 있다. 

 

이렇게 되면 아래처럼 NETWORK ID와 HOST ID가 저런 식으로 될 수 있다. 

 

 

IP주소에서 192.168.10.1/25 이라고 하면 총 사용할 수 있는 호스트는 다음과 같다.

서브넷 마스크가 2^7-2로 126개가 된다.

(-2 는 네트워크 주소와 브로드캐스트 주소 때문이다)

192.168.10.1부터 192.168.10.126을 의미합니다.

192.168.10.0은 네트워크 주소이고, 192.168.0.127은 브로드캐스트 주소입니다.

 

IP 주소 192.168.10.2/25이라고 하면, 따라서 호스트 범위는 192.168.10.1에서 192.168.10.126까지입니다.

그러나 이 범위에서 네트워크 주소와 브로드캐스트 주소를 제외하면 실제로 사용 가능한 호스트 주소 범위는 192.168.10.2에서 192.168.10.126까지입니다.

따라서 192.168.10.2/25 IP 주소의 호스트 범위는 192.168.10.2에서 192.168.10.126입니다.

 

  네트워크 주소(일반적) 브로드캐스주소(일반적) 범위  
192.168.10.1/25 192.168.10.1 192.169.10.127 192.168.10.2~ 192.168.10.126  
192.168.10.2/25 192.168.10.2 192.169.10.127 192.168.10.1~ 192.168.10.126 192.168.10.2는 사용 불가능

IP 주소의 브로드캐스트 주소는 해당 네트워크에서 모든 호스트들에게 데이터를 전달하는 주소

브로드캐스트 주소는 서로 다른 IP 주소에서 겹치지 않도록 설정

192.168.10.1/24와 192.168.11.1/24으로 나누기 

혹은

서브넷 마스크를 다음과 같이 할 수도 있다. 아래와 같이 구성하면 겹치지 않게 된다. 동일한 subnet mask 255.255.255.192를 가지지만, 호스트 범위가 겹치지 않게 된다.

  네트워크 주소(일반적) 브로드캐스주소(일반적) 범위  
192.168.10.0/26 192.168.10.0 192.169.10.63 192.168.10.1~ 192.168.10.62  
192.168.10.64/26 192.168.10.64 192.169.10.127 192.168.10.65~ 192.168.10.126  

 

 

 

 

Docker0, veth, eth0은 모두 Docker Network에서 사용되는 용어입니다.

 

  • docker0:
    docker0은 Docker Network에서 기본적으로 생성되는 가상 네트워크 인터페이스로, 호스트와 컨테이너 간의 통신을 위한 브리지 역할을 합니다. Docker0은 Docker Engine 설치 시 자동으로 생성되며, 컨테이너가 생성될 때마다 해당 컨테이너가 Docker0에 연결됩니다.
  • veth:
    veth는 가상 이더넷 인터페이스를 생성하는 데 사용되는 페어 디바이스(pair device) 중 하나입니다. veth 페어는 한쪽 끝에는 컨테이너에 할당되고, 다른 한쪽 끝은 호스트에 할당됩니다. 이를 통해 호스트와 컨테이너 간의 통신이 가능해집니다.
  • eth0:
    eth0은 veth의 한쪽 끝에 해당하는 가상 이더넷 인터페이스입니다. eth0은 컨테이너에서 네트워크를 사용하기 위해 필요한 인터페이스 중 하나이며, 컨테이너가 생성될 때마다 자동으로 생성됩니다.

    따라서, Docker Network에서 컨테이너는 호스트와 veth 페어로 연결되며, veth의 한쪽 끝인 eth0을 통해 네트워크에 연결됩니다. 호스트와 컨테이너 간의 통신은 Docker0 브리지를 통해 이루어지며, 다른 컨테이너와의 통신은 해당 컨테이너가 연결된 Docker Network를 통해 이루어집니다.

 

데이터 통신을 하는 방식은 다양하겠지만, port 포워딩을 통해서 보통 하게 된다.

포트 포워딩은 호스트와 컨테이너 간의 네트워크 통신을 위해 사용하는 브리지 네트워크를 통해 컨테이너에 접근하고, 호스트에서는 해당 포트를 통해 컨테이너와 통신하는 방식

따라서 호스트와 컨테이너가 동일한 네트워크에 속하지 않아도, 호스트와 컨테이너 간의 데이터 통신이 가능

예를 들어 컨테이너에서 8080 포트를 사용한다고 치자 8000:8080

host port 8000 포트와 container port 8080을 연결하여, 호스트에서 8000 포트로 요청을 보내면 docker는 8080 포트로 포워딩하여 컨테이너와 데이터 통신이 가능해진다.

이러한 방식을 통해 

 

 

 

 

왼쪽 같은 경우 두 컨테이너가 서로 다른 네트워크에서 실행되고 있어서 통신이 안되지만,

오른쪽 같은 경우, 같은 네트워크에 있기 때문에 가능하다.

 

 

참고

https://lamarr.dev/networkingbeginner/2020/03/22/09.html

 

Layer3 서브넷팅(Subnetting) - 라마개발일기

IP를 통해 구분된 네트워크를 더욱 세분화 하는 서브넷팅 기술에 대해서 정리해보았다.

lamarr.dev

https://jjaekjjaek.tistory.com/entry/Subnet-mask%EC%84%9C%EB%B8%8C%EB%84%B7-%EB%A7%88%EC%8A%A4%ED%81%AC-%EB%B9%84%ED%8A%B8-%EB%B3%84-%EC%A0%95%EB%A6%AC

https://code-lab1.tistory.com/34#:~:text=%EC%84%9C%EB%B8%8C%EB%84%B7%EC%9D%80%20IP%20%EC%A3%BC%EC%86%8C%EC%97%90%EC%84%9C,%EB%B6%84%EB%A6%AC%ED%95%98%EB%8A%94%20%EC%97%AD%ED%95%A0%EC%9D%84%20%ED%95%9C%EB%8B%A4.

 

[네트워크] 서브넷, 서브넷마스크, 서브넷팅이란? | 서브넷팅 예제

서브넷의 등장 배경 흔히 사용되는 IPv4 주소 체계는 클래스를 나누어 IP를 할당한다. 하지만 이 방식은 매우 비효율적이다. 예를 들어 어떤 기관에 A 클래스를 할당한다고 하면 16,777,214개의 호스

code-lab1.tistory.com

 

.

728x90