Docker 네트워크 구조

- Docker는 네트워크에 내부 IP를 순차적으로 할당한다.
- Docker engine은 컨테이너를 생성할 때 각 컨테이너에 고유한 내부 IP 주소를 할당합니다. 이 내부 IP 주소는 컨테이너가 동작하는 동안 유지되며 컨테이너 간 통신에 사용된다.
- 내부 IP는 컨테이너를 재시작 할때마다 변경될 수 있다.
- 컨테이너를 재시작하면 Docker는 내부 IP 주소를 변경할 수 있다. 따라서 컨테이너 간의 통신은 동일한 Host명 또는 Service Discovery Machanism 을 사용하여 수행하는 것이 좋다.
- 내부 IP는 Docker가 설치된 Host, 즉 내부망에서만 쓸 수 있는 IP이므로 외부와 연결되어야 한다.
- 내부 IP는 Docker가 설치된 Host 내부 네트워크에서만 유효한 IP 주소입니다. 외부 네트워크와 연결되기 위해서는 Docker의 Port 매핑 기능이나 네트워크 프록시 등을 사용하여 내부 IP와 외부 IP 간의 통신을 가능하게 할 수 있다.
- 컨테이너를 시작할 때 마다 Host에에 veth(Virtual Ethenet)라는 네트워크 인터페이스를 생성한다.
- 이 veth 인터페이스는 컨테이너의 네트워크와 호스트의 네트워크를 연결하는 역할을 한다.
- veth 인터페이스는 호스트의 eth0, eth1 등과 연결되어 있다.
- docker0 브리지는 각 veth 인터페이스와 바인딩돼 호스트의 eth0 인터페이스와 이어주는 역할을 한다.
- 컨테이너를 생성하면 기본적으로 docker0 브리지를 통해 외부와 통신할 수 있는 환경을 사용할 수 있지만 사용자의 선택에 따라 여러 네트워크 드라이버를 쓸 수 있다.
*네트워크 드라이브 : Bridge, Host, none, Container, Overlay
Docker Network 확인
docker network ls

Docker networkt 상세 정보 확인
docker network inspect bridge

- 네트워크의 자세한 정보를 확인 가능하다.
- 서브넷이 172.17.0.0/16 으로 생성되어 있어, 컨테이너 생성시 자동으로 해당 대역을 부여한다.
- 네트워크에 대한 설정 없이 컨테이너를 생성하면, docker0 브리지를 사용한다.
브리지 네트워크 (Bridge Network)
- docker0이 아닌 사용자 정의 브리지를 새로 생성해 각 컨테이너에 연결하는 네트워크 구조이다.
- 컨테이너는 연결된 브리지를 통해 외부와 통신한다.
bridge 네트워크 생성
docker network create --driver bridge mybridge

mybridge 라는 네트워크를 생성한다.
생성한 bridge 네트워크를 사용해 컨테이너 생성
docker run -i -t --name mynetwork_container --net mybridge ubuntu:20.04


- 컨테이너 내부에서 ip addr show 를 입력하면 새로운 IP 대역이 할당된다.
- 브리지 타입의 네트워크를 생성하면 Docker는 IP 대역을 차례대로 할당한다.
컨테이너에 할당된 Network 연결 끊기
docker network disconnect mybridge mynetwork_container


- 생성된 사용자 정의 네트워크는 docker network connect, disconnect 를 통해 컨테이너에 유동적으로 붙이고 뗄 수 있다.
- 네트워크를 떼어내면 ip addr show 를 통해 확인할 수 있다.
컨테이너에 Network 할당하기
docker network connect mybridge mynetwork_container
docker attach mynetwork_container

Custom Network 생성
docker network create --driver=bridge \
--subnet=172.72.0.0/16 \
--ip-range=172.72.0.0/24 \
--gateway=172.72.0.1 \
my_custom_network

- 네트워크의 서브넷, 게이트웨이, IP 할당 범위 등을 임의로 설정하려면 네트워크를 생성할 때 --subnet, --ip-range, --gateway 옵션을 추가한다.
- 단, --subnet과 --ip-range는 같은 대역이어야 한다.
호스트 네트워크 (Host Network)
- 네트워크를 호스트로 설정하면 호스트의 네트워크 환경을 그대로 쓸 수 있다.
- 별도로 생성할 필요 없이 기존의 host라는 이름의 네트워크를 사용한다.
Host 네트워크를 사용하여 컨테이너 생성
docker run -i -t --name network_host --net host ubuntu:18.04

- 호스트 모드로 설정된 컨테이너는 Docker 엔진이 설치된 호스트 머신과 동일한 네트워크 환경을 공유한다.
- 또한, 호스트모드로 설정된 컨테이너는 별도의 포트 포워딩 없이 컨테이너 내부의 애플리케이션을 직접 서비스 할 수 있다.
- 호스트 모드는 특정 네트워크 설정이나 포트 포워딩을 필요로 하지 않고 컨테이너 내부의 애플리케이션을 호스트 머신과 동일한 네트워크로 노출한다.
논 네트워크 (None Network)
- None, 말 그대로 아무런 네트워크를 쓰지 않는 것을 뜻한다.
None 네트워크로 컨테이너 생성
docker run -i -t --name network_none \
> --net none \
> ubuntu:18.04

컨테이너 네트워크

- '--net' 옵션을 사용하여 컨테이너를 다른 컨테이너의 네트워크 네임스페이스와 공유할 수 있다.
- 두 개의 컨테이너가 동일한 네트워크 네임스페이스를 사용하므로 내부 IP 주소 및 네트워크 인터페이스 MAC 주소 등의 속성이 공유된다.
- 예시) '--net container:[다른 컨테이너의 ID]'와 같이 '--net' 옵션을 사용하여 다른 컨테이너의 ID를 지정하면 해당 컨테이너와 동일한 네트워크 네임스페이스를 공유할 수 있다.
컨테이너 생성 후, 다른 컨테이너의 네트워크 네임스페이스 환경 공유
docker run -i -t -d --name network_container_1 ubuntu:18.04
docker run -i -t -d --name network_container_2 ubuntu:18.04

- 다른 컨테이너의 네트워크 환경을 공유할 때에는 내부 IP를 새로 할당받지 않으며, 호스트에 veth로 시작하는 가상 네트워크 인터페이스도 생성되지 않는다.
- 공유된 네트워크 환경을 사용하므로 다른 컨테이너와 동일한 내부 IP와 네트워크 인터페이스를 갖게 된다.
컨테이너2의 네트워크와 관련된 사항은 전부 컨테이너1을 따라간다.
docker run -itd --net container:network_container_1 --name network_container_2 ubuntu:18.04




- 하나의 Pod 내에 여러 개의 컨테이너를 실행할 수 있다.
- 이 경우, 컨테이너들은 같은 네트워크 네임스페이스와 같은 veth 인터페이스를 공유한다.
- 이로써, 컨테이너 간에 네트워크 통신이 가능해진다.
- 각 컨테이너는 자체 IP 주소를 가지지 않으며 Pod의 IP 주소를 공유한다.
- 그래서, 하나의 컨테이너가 IP 주소를 할당받으면, 다른 컨테이너도 같은 IP 주소를 사용한다.
- 이로써, 같은 Pod 내의 컨테이너는 서로를 localhost로 접근할 수 있게 된다.
브리지 네트워크와 --net-alias

- Docker의 브리지 네트워크를 사용하면 컨테이너 간에 네트워크 통신이 가능해진다.
- 브리지 네트워크는 Docker가 자동으로 생성하는 가상 네트워크로, 컨테이너가 연결되어 있다.
- 예시) 두 개의 컨테이너 생성 후 '--net-alias'옵션을 사용하여 호스트 네임을 설정
호스트네임을 ptty 지정하여 3개의 컨테이너 생성
docker run -i -t -d --name network_alias_container1 --net mybridge --net-alias ptty ubuntu:18.04
docker run -i -t -d --name network_alias_container2 --net mybridge --net-alias ptty ubuntu:18.04
docker run -i -t -d --name network_alias_container3 --net mybridge --net-alias ptty ubuntu:18.04

'docker run' 명령어에서 '--net' 옵션을 사용하여 컨테이너를 특정 네트워크에 연결하려고 하였으나, 해당 네트워크는 존재하지 않는다고한다.
Docker에서 네트워크를 사용하기 위해서는 네트워크를 먼저 생성해야한다.
docker network create mynetwork

docker inspect mynetwork

ping 테스트용 컨테이너 생성 후, 호스트네임으로 ping 테스트
docker run -i -t --name network_alias_ping --net mybridge ubuntu:18.04

ping test 오류 시 ping 테스트용 컨테이너 접속후 아래 명령어 실행 후 ping test 시도한다.
apt update
apt install -y iputils-ping
ping -c 1 ptty
ping -c 1 ptty
ping -c 1 ptty

- ping Test용 컨테이너에서 하나의 호스트네임으로 ping Test 진행한다.
- 컨테이너 3개의 IP로 각각 ping이 전송된 것을 확인했다.
- 매번 달라지는 IP로 로드밸런싱이 됨을 확인했다.
- Docker 엔진에 DNS가 내장되어 있어 ptty라는 호스트 이름을 -net-alias 옵션으로 ptty을 설정한 컨테이너로 resolve 하기 때문이다.
참고
https://captcha.tistory.com/70