컨테이너 내부에는 eth0과 lo 네트워크 인테페이스가 있다. 외부에서 컨테이너 내부에 있는 네트워크 인터페이스 ip에 접근하기 위해서는 외부와 연결되어야 하는데 컨테이너를 시작할 때마다 호스트에 veth로 시작하는 네트워크 인터페이스를 생성하여 외부와 컨테이너를 연결할 수 있다.
veth의 v는 virtual을 의미하며 실행중인 컨테이너 수만큼 생성되어있다.
ifconfig 명령어를 사용하여 네트워크 구성을 살펴보자
출력해보면 eth0은 공인 IP 및 내부 IP가 할당되어 실제 외부와 통신할 수 있는 호스트의 네트워크 인터페이스이다.
또한 veth 네트워크 인터페이스도 생성된 것을 확인할 수 있는데 각 컨테이너의 eth0과 연결되어 있다.
여기서 처음 보는 docker0 이라는 브리지가 생성된 것을 확인할 수 있는데 각 컨테이너의 veth 네트워크 인터페이스와 바인딩 되어 eth0 인테페이스와 연결해주는 역할을 한다.
도커 네트워크
컨테이너 실행 시 기본적으로 Docker0 브리지를 통해 외부와 호스트가 연결이 가능했다. 이와 마찬가지로 Docker에는
브리지(bridge), 호스트(host), 논(none), 컨테이너(container) 등 Docker0과 비슷한 기능을 수행하는 여러가지 네트워크 드라이버들이 존재한다.
sudo docker network ls
해당 명령어를 입력하면 위의 이미지와 같이 3개의 네트워크가 존재한다. 브리지 네트워크는 컨테이너 생성시 자동으로 연결됐던 Docker0 브리지를 사용하도록 되어있다. 따라서 아무 설정을 하지 않으면 자동으로 docker0 브리지를 사용한다.
sudo docker network inspect bridge
bridge의 네트워크를 보면 서브넷-172.17.0.0/16, 게이트웨이-172.14.0.1으로 설정되어 있는 것을 확인할 수 있다.
1. 브리지 네트워크
위에서 말했듯 아무런 설정도 하지 않는다면 자동으로 docker0 브리지를 사용한다. 사용자 정의를 통해 docker0 브리지가 아닌 새로 생성하여 각 컨테이너에 연결하는 네트워크 구조이다.
docker network create --driver bridge mybridge
mybridge라는 새로운 브리지 타입의 네트워크를 생성하는 명령어다.
sudo docker run -i -i \
--name mynetwork \
--net mybridge \
ubuntu:14.04
컨테이너 생성시 --net 옵션을 통해 mybridge 네트워크를 사용할 수 있도록 설정이 가능하다.
컨테이너 내부에 들어가 ifconfig 명령어를 입력하여 네트워크 정보를 살펴보면 172.18 대역의 내부 IP가 할당된 것을 확인할 수 있다.
사용자 정의 네트워크는 유동적으로 컨테이너에 붙이거나 뺄 수가 있다.
sudo docker network disconnect mybridge mynetwork
sudo docker network connect mybridge mynetwork
해당 명령어로 네트워크를 붙였다 빼는 것이 가능한데 none, host 네트워크의 경우 해당 기능을 사용할 수 없다.
sudo docker network create --driver=bridge \
--subnet=172.72.0.0/16 \
--ip-range=172.72.0.0/24 \
--gateway=172.72.01.1 \
my_custom_network
서브넷, 게이트웨이, ip 할당 범위 등 옵션을 통해 설정이 가능하며 subnet과 ip할당 범위는 같은 대역이야 한다.
2. 호스트 네트워크
sudo docker run -i -t \
--name network_host \
--net home \
ubuntu:14.04
사용자 정의 네트워크와 달리 --net 옵션에 host를 사용하였다. 호스트의 네트워크 환경을 그대로 사용할 수 있으며 별도의 생성 없이 host만 사용하면 된다. 컨테이너 내부에 진입하여 네트워크 정보를 확인하면 호스트의 네트워크와 동일한 것을 확인할 수 있다.
호스트 네트워크 사용 시 컨테이너 내부의 애플리케이션을 별도의 포트 포워딩 없이 서비스가 가능하다.
3. 논 네트워크
sudo docker run -i -t \
--name network_none \
--net none \
ubuntu:14.04
논 네트워크는 말 그대로 아무 네트워크도 사용하지 않는다는 것을 의미한다. 따라서 외부와 단절이 된다. 컨테이너 내부에 접속하여 네트워크 정보를 확인하면 io이외에는 아무것도 존재하지 않는다.
4. 컨테이너 네트워크
sudo docker run -i -t -d \
--name network_container_1 \
ubuntu:14.04
-i -t -d 옵션 같이 사용시 컨테이너가 생성과 동시에 실행되지만 내부에 진입하지는 않는다.
sudo docker run -i -t -d \
--name network_container_2 \
--net container:network_container_2 \
ubuntu:14.04
네트워크 환경이 복사될 컨테이너(network_container_1) 먼저 생성 후 복사할 컨테이너(network_container_2)를 생성한다.
이 때 --net 옵션에 container:복사하고자하는 컨테이너 (network_container_1)를 작성하면 똑같은 네트워크 환경이 구성된다.
5. 브리지 네트워크 + --net-alias
컨테이너 생성 시 브리지 네트워크와 net-alias 옵션을 같이 사용하면 호스트의 이름으로 네트워크에 접근이 가능하다.
sudo docker run -i -t -d \
--name network_alias_container_1 \
--net mybridge \
--net-alias examhost \
ubuntu:14.04
sudo docker run -i -t -d \
--name network_alias_container_2 \
--net mybridge \
--net-alias examhost \
ubuntu:14.04
sudo docker run -i -t -d \
--name network_alias_container_3 \
--net mybridge \
--net-alias examhost \
ubuntu:14.04
3개의 컨테이너를 생성했고 host 이름인 examhost로 방금 생성한 3개의 컨테이너에 접근이 가능하다.
sudo docker run -i -t \
--name network_alias_container_ping \
--net mybridge \
ubuntu:14.04
접근이 가능한지 테스트하기 위해 핑을 테스해볼 컨테이너를 생성했다. 해당 컨테이너에 접속하여 ping을 찍어보겠다.
ping -c 1 examhost
ping -c 1 examhost
ping -c 1 examhost
핑을 3번 날려보면 각각의 컨테이너
172.18.0.2
172.18.0.3
172.18.0.4
로 ping이 전송된 것을 확인할 수 있다. 라운드 로빈(round-robin) 방식으로 ip를 결정한다. 도커 엔진에 내장 DNS가 examhost이라는 호스트 이름을 --net-alias 옵션으로 examhost을 설정한 컨테이너로 변환하기 때문이다.
Docker 내장 DNS를 통해 호스트 이름으로 컨테이너의 IP를 찾을 수 있다. mybridge에 속한 컨테이너에서 examhost로 다른 컨테이너에 접근 시 DNS서버는 라운드 로빈 방식을 이용하여 IP 목록을 반환한다.
apt-get update
apt-get install dnsutils
network_alias_container_ping 컨테이너 내부에 들어가 DNS 도메인 이름에 대응하는 IP를 조회하는 도구인 dig를 설치한다.
dig examhost
해당 명령어를 사용하면 반환되는 IP의 리스트를 확인할 수 있다.
'Docker' 카테고리의 다른 글
7. Docker 컨테이너 자원 정의 (0) | 2024.07.17 |
---|---|
6. Docker 컨테이너 로깅 (0) | 2024.07.16 |
4. Docker 볼륨 (0) | 2024.07.05 |
3. Docker 컨테이너 애플리케이션 (1) | 2024.07.02 |
2. Docker 엔진 (0) | 2024.07.02 |