컨테이너 내부에서 네트워크를 사용하는 방법에 대해 알아본다.
도커 컨테이너를 사용하면 각 컨테이너는 한 가지 주요 작업만 하는 것이 권장된다.
컨테이너에 하나의 데이터 베이스를 올리고, 다른 컨테이너에 웹앱을 올리는 등의 방식을 이용한다. 그런데 이렇게 하면 컨테이너는 서로 독립적이고 별개여서 서로 데이터를 주고 받을 수가 없다는 문제가 발생한다.
이를 해결하기 위한 방법 중 하나로, 컨테이너 간의 통신을 이용 한다.
정확히는 도커 컨테이너 네트워크를 이용하는 것이다.
컨테이너 <-> host machine
컨테이너 <-> some-api.com
컨테이너 <-> 컨테이너
노드 애플리케이션은 다른 사이트에 HTTP요청을 보낸다.
이는 도커화된 앱에서 가능한 통신 중 하나로, HTTP 요청을 다른 웹사이트나 웹 API로 전성하는 방법이다.
host machine에서 실행되는 MongoDB에 연결한다.
노드 애플리케이션은 host machine에서 실행되는 MongoDB와 통신할 수 있다.
이 MongoDB는 컨테이너에 있지 않다.
# 도커에 설치한 mongodb 컨테이너를 검사
$] docker container inspect
도커화된 컨테이너의 코드와 local host machine과의 통신을 위해
터미널에 표시되는 IPAdress 복사하여 하드 코딩 해둔 주소(localhost:27017 // 27017포트는 MongoDB의 디폴트 포트) 대신 host.docer.internal
을 사용한다.
그러면 application이 다른 컨테이너와 그곳의 MongoDB 데이터베이스에 연결된다.
이렇게 해서 다른 컨테이너와 통신할 수 있게 되고, 완전히 분리된 데이터 베이스를 사용할 수 있다.
그러나 위 방법에는 단점이 있다.
- 컨테이너의 ip주소를 찾아야하고,
- 만약 mongodb 컨테이너의 ip 주소가 변경되면
- 그걸 찾아서 새 이미지를 빌드해야한다.
(NodeApp에서 ip주소를 하드코딩하기 때문)
그래서 이거보다 더 쉬운 방법이 있다!!
- 도커로 컨테이너 네트워크를 만들 수 있다. (네트워크라고도 부른다.)
- 다중 컨테이너가 있을 때 컨테이너 간의 통신을 허용 하는 것이다.
$] docker run
명령어에 --network
옵션을 추가하면 모든 컨테이너를 같은 네트워크에 밀어 넣을 수 있다.
볼륨과 달리 네트워크의 경우 도커는 자동으로 볼륨을 생성하지 않는다.
네트워크를 사용하여 컨테이너를 실행하려면 직접 컨테이너를 만들어야한다.
# docker network create 사용하여 네트워크를 만든다.
# (favorites-net은 커스텀 네트워크 이름)
$] docker network create favorites-net
# 기존의 모든 네트워크 검사.
# 내장된 디폴트 네트워크도 볼 수 있다.
$] docker network ls
# 이렇게 입력하면 컨테이너가 시작된다.
$] docker run -d --name mongodb --network favorites-net mongo
네트워크에 컨테이너를 넣으면 노드 애플리케이션에서 하드코딩했던 MongoDB 컨테이너의 ip 주소 대신
$] docker run --name favorites --network favorites-net -d --rm -p 3000:3000 favorites-node
코드가 변경되었으니 이미지 리빌드 하면 된다.
이 때는 노드 애플리케이션을 재실행 할 때 포트 노출해줘야한다.
반면, 다른 컨테이너가 연결되는 MongoDB 컨테이너와 같은 컨테이너를 시작하면, (favorites컨테이너를 MongoDB 컨테이너에 연결하듯) 컨테이너에 연결하기 위해 실행할 때 포트(-p 옵션)를 적을 필요가 없다.
도커는 소스코드 읽지 않고, 컨테이너의 이름을 보고, 코드에 플러그인된 컨테이너의 ip 주소를 연결한다.
점점 정리가 산으로 가는 것 같다..