Docker Bridge Network 의 함정

Seok·2021년 10월 30일
2

Docker

목록 보기
7/7
post-thumbnail

docker-compose를 이용해서 로컬에서 stage 환경과 유사한 개발환경을 제공하는 프로젝트를 진행하면서 docker-compose up 명령을 2번이상 수행하게 되었을 때(docker-compose 의 수정사항으로 compose를 업데이트 하는경우) 컨테이너끼리의 컨테이너명으로는 통신이 불가능한 현상이 발생했고, 이를 해결하기 위해 리서치한 내용을 정리했다.


Docker network

공식문서에서 크게 6가지 분류로 설명하고있다. 각 네트워크의 종류와 간략한 설명은 아래와 같다.

Bridge

  • Default Network 드라이버, network driver를 명시하지 않으면 기본으로 Bridge로 설정된다.
  • 통신이 필요한 독립 실행형 컨테이너에서 어플리케이션을 실행할 때 사용한다.

Host

  • 독립 실행형 컨테이너일때, 컨테이너와 Docker 호스트 간의 네트워크 격리를 제거하고 호스트의 네트워킹을 직접 사용한다.
  • Linux 에서만 실행이 가능하고, Mac, Window에서는 사용이 불가능하다.

Overlay

  • 여러 도커 데몬을 연결할 때 사용한다.
  • docker swarm 서비스와 독립실행 컨테이너간, 혹은 서로다른 docker 데몬에 있는 두개의 독립 실행형 컨테이너간의 통신이 필요할 때 사용한다.

Macvlan

  • 컨테이너에 MAC 주소를 할당하여 네트워크에서 물리적 장치로 표시할 수 있다.

None

  • 모든 네트워킹을 비활성한다.

Network Plugin

  • 써드파티 네트워크 플러그인을 사용할 때 사용한다.

왜 컨테이너 주소로 연결이 불가능했을까?

해당 오류를 직면하고, 관련 경험이 없다보니 많이 해맸고, 운이 좋게도 이것저것 시도해보다가 각 컨테이너의 네트워크 드라이버를 bridge로 명시해주어 해결할 수 있었지만 이게 왜 내가 원하는대로 동작하는지 알 수 없었다.

나에게 그런 오류가 발생했던 이유는 docker의 기본 네트워크 드라이버중 Bridge 네트워크 드라이버에 함정이 있었기 때문이었다.

docker 공식문서에 network 페이지에는 의심갈만한 내용이 없지만, Bridge 네트워크를 사용하는 튜토리얼 페이지와 use Bridge network 페이지에서 특이한 내용이 있었다. 두 내용의 설명방법은 다르지만 같은 부분은 기본으로 제공되는 bridge사용자가 정의한 bridge를 구분해서 설명하고 있었다.

그리고 그 내용은 요것이었다.

User-defined bridges provide automatic DNS resolution between containers.

컨테이너이름으로 해당 컨테이너와 통신하는 기능은 automatic DNS resolution 이 제공되어 가능한 기능이었고, 컨테이너에 네트워크를 명시하지 않아서 할당되는 기본 Bridge 네트워크는 이 기능을 제공하지 않았고, 사용자가 정의하여 추가된 Bridge 네트워크는 이 기능을 제공한다는 것이다....

엥?? 나는 이때까지 컴포즈에서 컨테이너명으로 통신했는데??

이때까지 docker-compose를 실행할때에 있어서 항상 컨테이너명으로 통신하도록 사용했다. 한 서비스가 다른 서비스와 통신을하기위한 엔트포인트도 모두 컨테이너명:포트로 정의시켜놨었고, 잘 동작했었다.

하지만 도커의 문서대로라면 내가 생성하지 않은Bridge 네트워크를 사용하면 컨테이너명으로는 통신이 애초에 불가능해야했다.

그래서 docker-compose 공식문서의 network 파트를 살펴봤다.

By default Compose sets up a single network for your app. Each container for a service joins the default network and is both reachable by other containers on that network, and discoverable by them at a hostname identical to the container name.

컴포즈는 기본적으로 실행시키는 앱에 대해 단일 네트워크를 생성한다고 한다. 그래서 컨테이너명을 통해 통신이 가능하다.

그럼 왜 compose를 재실행했을땐 못하는걸까?

이 내용또한 같은 문서에 존재했다.

If you make a configuration change to a service and run docker-compose up to update it, the old container is removed and the new one joins the network under a different IP address but the same name. Running containers can look up that name and connect to the new address, but the old address stops working.
If any containers have connections open to the old container, they are closed. It is a container’s responsibility to detect this condition, look up the name again and reconnect.

컨테이너가 업데이트 될 때, IP주소와 컨테이너이름의 연결은 컨테이너의 책임이다

그랬다. 공식문서에 너무나 친절이 내가 왜 불가능한지 다 적혀있었다.

컴포즈로 실행시 서비스 디스커버리는 제공하지 않았고, 난 기본으로 제공하는 Bridge 네트워크를 사용했기 때문에 컨테이너가 재실행될 때 변경된 IP와 컨테이너명의 연결이 불가능했었다.

정말 운좋게 내가 했던방법 Bridge 네트워크를 선언하고, 명시적으로 해당 네트워크 드라이버를 사용하도록 한게 올바른 해법이었다.

공식문서를 잘 읽도록 하자!


출처

profile
🦉🦉🦉🦉🦉

0개의 댓글