본문 바로가기

Docker에서 macOS 호스트 포트에 접근하기

기술적인 이야기/기타 개발 2019. 7. 19.
반응형

개인적으로 삽질했던 도커(Docker) 관련 경험을 하나 풀어서 메모해본다. 내용은 도커 컨테이너에서 macOS의 호스트에 열려있는 포트에 접근하는 방법에 대한 것이다.

하려는 것

회사 보안 정책 상 그냥은 접근할 수 없는 여러 서버들이 있다. 개발 중인 프로그램에서 정식으로 배포하지 않고 개발 서버로 이 서버에 접속하려면 VPN을 활성화 한 다음 SSH 터널링을 이용해 호스트에 포트를 열고 이 포트를 직접 접속하는 수밖에 없다.

도커를 쓰지 않고 이렇게 터널링으로 뚫어놓은 포트에 접근하는 것은 사실 아무 문제도 없다. 편하게 막 쓰면 된다.

그런데 도커를 사용하게 되면 문제가 발생한다. 컨테이너 내부에서는 당연히 호스트의 포트 상황을 전혀 모르기 때문에 어떻게든 알려줘야 한다. 그런데 컨테이너를 띄울 때 -p XXXX:YYYY 옵션으로 포트를 연결시키려 하면 이미 호스트에서 열려있는 포트라고 에러가 뜬다. 결국 컨테이너는 바보가 되어서 아무 일도 못 하는 상태가 되었다.

이런 문제는 어떻게 해결해야 할까?

해결은 가능한가?

애초에 도커 자체가 리눅스 기반에서 발명(?)된 도구인지라 리눅스 환경이 아니면 좀 맞지 않는 것들이 있다. 예를 들자면 macOS에서는 bridge0 같은 네트워크 브릿지도 없고 ping도 안 되는 등 좀 제약이 있는 편이다. 아무것도 안 해도 CPU 처묵처묵이라는 다른 문제도 있고...

이 문제의 경우도 리눅스에서도 그냥 되지는 않는다. 하지만 쉬운 해결법이 하나 있다. network 모드를 host로 설정하면 아무 문제없이 접근이 가능하다. --network host 옵션을 줘서 컨테이너를 띄울 수도 있고, Docker Compose를 쓴다면 아래처럼 docker-compose.yml 파일에 명시할 수도 있다.

network_mode: host

물론 기존 접속 방식과 달라지는 만큼 동일한 동작을 하는 건 아니겠지만 적어도 컨테이너 이미지 자체를 수정하지 않고 호스트의 포트를 접근하는 것이 가능하다.

자 그런데... 지금까지의 이야기는 리눅스에서의 해결법이다. 그렇다면 macOS에서는 못 하는 건가?

뭐 일단 못 하는 것처럼 보이긴 하지만 아예 불가능한 것은 아니다.

반응형

컨테이너에서 macOS 호스트 포트에 접근하기

일단 한 가지 결론 먼저 이야기하자면, 그냥은 불가능하다. 앞서 설명했지만 브릿지도 없고 호스트 네트워크 모드도 이용할 수가 없다.

대신 컨테이너 내부에서 돌아가는 프로세스의 설정을 고쳐서 어떻게든 돌려보는 것은 가능했다. Docker에서는 자체적으로 host.docker.internal라는 도메인 네임을 가상으로 제공해주는데 이를 이용하면 도커 인스턴스 내부에서 호스트의 포트에 접속하는 것이 가능하다.

예를 들어 내 호스트에 SSH 터널링으로 뚫어놓은 2181 포트에 접근하려 한다면 컨테이너 내부의 프로세스가 접속하려는 주소를 host.docker.internal로 설정하고 포트 번호를 2181로 적으면 된다.

좀 더 직접적인 예를 들자면, macOS에서 mongodb를 27017 포트로 돌리고 있고 특정 컨테이너에서 이 mongodb에 접속하고자 한다면 컨테이너 내부에서는 아래와 같은 주소로 호스트에 접속하는 것이 가능하다.

mongo://host.docker.internal:27017/dbname

표현하는 방법은 어떤 언어에서 어떤 프레임워크로 어떻게 설정해서 쓰는지에 따라 다른 거고 이 글에서는 그냥 힌트만 줄 수밖에 없다. 모든 개발자의 환경을 고려할 수는 없다는 건 모두들 이해해 주시리라 믿는다.

비슷하게 만약 게이트웨이에 접근해야 한다면 gateway.docker.internal 주소를 이용 할 수 있으니 참고하자.

관련글

728x90
반응형

댓글