[Docker] Container network

hugingstar·2025년 12월 1일

Docker

목록 보기
9/19
post-thumbnail

  • 도커는 컨테이너를 시작할 때마다 호스트에 veth 라는 네트워크 인터페이스를 동적으로 생성한다.

  • 컨테이너를 생성하면 기본적으로 docker0 라는 브릿지를 통해서 외부와 통신할 수 았는 환경이 있다. 하지만, 외부와의 통신을 위해서는 "네트워크 드라이버""라는 것이 필요한다 브릿지, 호스트, 논, 컨테이너, 오버레이 등이 있고, Weave, Flannel, Openvswitch라는 네트워크 드라이버도 있다.

1. Network 조회

  • 도커 컨테이너들의 네트워크를 설정하려면 먼저, 네트워크 리스트를 확인해보는 과정에서 부터 단계적으로 접근하는게 좋을 것 같다.

docker network ls

  • 네트워크 리스트를 보면, Bridge, Containing_default, host, none이렇게 있다. 그런데 이상태에서는 이게 어떤 것인지를 자세히 모르겠는데... 더 상세히 확인해봐야 겠다. 일단 DRIVER라는 단어가 두 가지가 있는데 두가지의 차이점 부터 정의를 내려야 문제가 해결될 것 같다.

  • 네트워크 주소들을 상세하게 볼려면, NAME을 기준으로 inspect 명령어를 사용해야 한다.

docker network inspect "NAME"

docker network inspect bridge

  • IPAM에 있는 Config 부분을 보면 네트워크 설정 방법을 상세하게 볼 수 있다.(이번 글에서는 네트워크 구성 방법에 대한 세부적인 방법에 초점을 맞춘다.)

  • Bridge 라는 NAME을 가지고 있는 네트워크는 172.17.0.0/16으로 Subnet이 설정되어 있다. 172.17.0.1로 게이트웨이가 설정되어 있다. 2개의 옥텟을 네트워크 주소로 놓고, 나머지 2개 옥텟을 호스트 주소로 만들어진 네트워크이다.

docker network inspect containing_default

  • containing_default라는 네트워크는 172.18.0.0/16 이라는 Subnet으로 설정되어 있고, 게이트웨이는 172.18.0.1로 설정되어 있다. 데이터가 나갈때는 게이트웨이로 나가고, 들어올 때는 서브넷 주소와 호스트 주소로 조합해서 신호가 간다는 것이다.

docker network inspect

  • host 네트워크를 보면, 특별하게 있지는 않는데... IPAM에도 null로 되어 있어서 혹시 어떤 작업을 해야 하면 직접 넣어줘야 하는 것 같다.

2. Network 생성

  • 기본적으로 있는 것에서 나아가서 이제는 내가 직접 네트워크를 도커 컨테이너를 사용해서 구성할 수 있어야할 것인데..

  • 먼저 docker network를 사용해서 이용하고자 하는 네트워크를 만든다.

docker network create --driver bridge initbridge

  • 네트워크 옵션을 추가해서 우분투 컨테이너를 한 번 생성해본다. 컨테이너 이름을 inital_network_container으로 설정하고, 네트워크는 initbridge에 연결한다. ubuntu:latest 라는 컨테이너가 활성화 될 것이다.
  • -i 옵션(--interactive) : 표준 입력(stdin)을 활성화해서, 컨테이너와 연결(Attach)되어 있지 않더라도 표준 입력을 유지한다. 보통 이 옵션을 사용하여 Bash에 명령을 입력항다.
  • -t 옵션(--tty) : TTY(pseudo-TTY)를 사용하는 모드로서, Bash를 사용하려면 이 옵션을설정해야 한다. 이 옵션을 설정하지 않으면, 명령을 입력할 수 있지만, 셀이 표시되지 않는다.

docker run -i -t --name inital_network_container --net initbridge ubuntu:latest

  • 첫번째 만든 컨테이너의 네트워크를 받아서 동일한 주소를 가지는 네트워크 만드는 방법

  • 여기서 ifconfig로 ip 주소를 확인해야 하는데 안되는 경우가 있다. 이런 경우에는 net-tool을 먼저 하나 설치하고 ifconfig를 해줘야 한다. 그런데 최신버전 우분투는 ifconfig 기본적으로 탑재되어 있지 않아서 업데이트 및 설치를 해주고 해야한다.
  • 이 부분은 혹시 나중에 기본 우분투 컨테이너에 뭔가를 개발하려고 할 때 중요한 부분이기도 하다. (실습할라면 계속 이거 쳐줘야 config 확인 가능)

apt-get update
apt-get install -y sudo
sudo apt-get install -y net-tools
ifconfig

  • inet 부분을 보면 172.18.0.2 넷마스크: 255.255.0.0, 브로드캐스트 172.19.255.255 으로 설정된 것을 볼 수 있다. 즉, 브릿지 타입으로 네트워크를 생성하면 도커는 IP 대역을 차례대로 할당한다.

2. Network 연결하기/연결 끊기

  • 네트워크 이름, 컨테이너 이름 순서대로 설정한다.

  • 떼어내진 네트워크 변동사항도 ifconfig로 확인할 수 있다.

  • 연결끊기 : 연결을 끊으면 자동으로다가 네트워크가 끊겨있을 것이다.

docker network disconnect initbridge inital_network_container
docker attach inital_network_container
ifconfig

  • 연결하기 : 연결을 하면 자동으로 inet address가 할당되어 있을 것이다.

docker network connect initbridge inital_network_container
docker attach inital_network_container
ifconfig

3. Network 커스텀하기

docker network create --drive=bridge --subnet=172.0.0/16 --ip_range=172.72.0.0./24 --gateway=172.72.0.1 "custom network name"

  • 커스텀시에 주의 사항으로는 Network의 서브넷, 게이트웨이, IP할당 범위등을 임의로 설정할 때 옵션들을 설정해야 한다.
  • subnet 옵션은 ip_range와 같은 대역에서 이뤄져야 한다.

4. Host 네트워크를 사용하여 컨테이너 생성하기

  • 호스트 모드로 설정해서 서비스하면 별도의 포트포워딩 없이 내부의 애플리케이션과 상호작용할 수 있다.
  • --net 옵션으로 호스트를 설정하면 컨테이너 내부에서 호스트의 네트워크와 동일하게 된다.
  • 뭔가 호스트와 직접적으로 연결해야할 때 많이 사용될 것 같다.

docker run -i -t --name inital_network_container --net host ubuntu:latest

5. 네트워크를 None 상태로 컨테이너 만들기

  • 때에 따라서 None으로 설정해놓고 컨테이너를 만들어야 할 수 있다.

docker run -i -t --name inital_network_container --net none ubuntu:latest

6. 네트워크를 별칭 짓기

  • --net-alias 옵션을 사용해서 네트워크의 별칭을 만들 수 있다. 만약에 최종 관제하는 하나의 컨테이너에서 ping을 모든 네트워크로 날리고자 하는데, 하나씩 ping을 하면 매우 복잡하니까 net-alias를 사용해서 동일한 네트워크를 공유하고 있는 컨테이너에 일괄로 통신을 확인할 수 있다.
  • 아래의 예시는 netbundle911이라는 동일한 네트워크를 공유하는 inital_network_container_code1, inital_network_container_code2, inital_network_container_code3이 실행되고 있다.
  • 네트워크가 꼭 있어야 한다.

docker network create --driver bridge initbridge
docker run -i -t -d --name inital_network_container_code1 --net initbridge --net-alias netbundle911 ubuntu:latest
docker run -i -t -d --name inital_network_container_code2 --net initbridge --net-alias netbundle911 ubuntu:latest
docker run -i -t -d --name inital_network_container_code3 --net initbridge --net-alias netbundle911 ubuntu:latest

  • 호스트 이름으로 어떻게 ping을 테스트 할 수 있을까? 테스트라기 위해서 하나 더 만들어본다. ping 테스트 할려면 iputils-ping도 깔아야 한다.

docker run -i -t --name net_alias_ping_test --net initbridge ubuntu:latest

apt-get -y update
apt-get install net-tools
apt-get install iputils-ping
ifconfig

  • 테스트용 컨테이너의 eth0는 172.19.0.5 주소를 가진다.

  • 컨테이너 3개로 한번에 ping이 전송된다. Round-robin 방식을 사용하기 때문에 매번 Ip가 달라질 것이다.
    -도커 엔진에 DNS가 내장되어 있기 때문에 netbundle911이라는 호스트 이름을 --net-alias를 netbundle911으로 설정한 컨테이너로 리볼빙(Revolving)한다.

ping -c 1 netbun911
ping -c 1 netbun911
ping -c 1 netbun911

7. 심화

7-1. 컨테이너 생성후에 다른 컨테이너의 네임스페이스 환경을 공유하기

  • 먼저 별도의 네트워크 설정 없이 컨테이너 2개를 만든다.
  • 다른 컨테이너의 네트워크 환경을 공유하면 내부 IP를 새롭게 할당받지 않는다는 점을 생각해야한다. 이러면, veth로 시작하는 가상네트워크 인터페이스도 생성되지 않는다.
  • inital_network_container_2 컨테이너의 네트워크와 관련된 사항은 전부 Network_container_1과 동일하게 설정해야한다. (2번 설정하는 곳에서 --net 옵션을 유심히 확인해야 한다.)

docker run -i -t --name inital_network_container_1 ubuntu:latest
docker run -i -t --name inital_network_container_2 --net container:inital_network_container_1 ubuntu:latest

  • 내부적으로 어떻게 구성되고 있는지를 살펴볼려면 exec를 사용해서 내부를 둘러봐야 한다.
  • IP 주소도 완전히 똑같은 것을 확인할 수 있다.

(바로 명령어 넣는 방법)(net-tools 다운되어 있어야 함.)

docker exec inital_network_container_1 ifconfig
docker exec inital_network_container_2 ifconfig

(net-tools 없어서 깔아야하는 상황)

docker exec -it inital_network_container_1 ifconfig /bin/bash
docker exec -it inital_network_container_2 ifconfig /bin/bash

  • Container 1번의 eth0 주소를 보면 172.17.0.2이다.

  • Container 2번의 eth0 주소를 보면 172.17.0.2이므로 네트워크를 공유하고 있기 때문에 동일하다.

(Kubernetes)에서 사용하는 Pod라는 개념을 가져와서 생각해보면 여러개의 컨테이너가 하나의 IP를 사용한다는 것은 veth를 하나로 사용하는 경우에 해당한다.

Reference
https://captcha.tistory.com/70

0개의 댓글