컨테이너 통신

EBAB!·2023년 7월 15일
0

Docker

목록 보기
10/15

가장 단순한 다중 컨테이너 모습은 백엔드-프론트엔드-데이터베이스 형태일 것입니다.

호스트를 이용한 통신

우선, 앞서 예시엔 없었던 예시인 데이터베이스 컨테이너를 실행합니다.

$ docker run --name mongodb --rm -d -p 27017:27017 mongo

mongodb라는 이름의 mongodb 데이터베이스를, 실행 중지시 삭제하도록 하고, 백그라운드에서 실행하고, 포트는 내외부를 27017로 설정해줍니다.
참고로 mongo는 docker hub에서 제공하는 mongodb 이미지입니다.


백엔드 컨테이너를 back이란 이름으로 실행했다고 하겠습니다. 여기서 중요한건 통신 포트입니다.
mongodb://host.docker.internal:27017/my_api
맨 앞에 컨테이너의 이름과 ://host.docker.internal:27017을 통해 컨테이너 내부에서 호스트를 통한 도커 컨테이너와 통신을 함을 알립니다.
host.docker.internal는 로컬 호스트 IP주소로 식별됩니다.


다음은 react 프론트엔드 이미지가 구현되어 있고 다음으로 실행되었다고 하겠습니다.

$ docker run --name front --rm -d- p 3000:3000 -it fonrt_image
  • -it는 react 프로젝트와 관련된 설정입니다. 이 설정이 없다면 react는 즉시 서버를 중지하는 방식입니다.(상호작용이 없다는 판단 하에)

이런 방식이라면 통신이 가능합니다. 하지만 비효율적입니다!



Docker network

비효율적인 이유는 간단합니다. 컨테이너간 통신을 굳이 호스트를 통해서 한다면 송수신하는 패킷이 호스트를 거친다음 컨테이너로 이동하기 때문입니다.

컨테이너는 하나의 프로세스이므로 IPC namespace 등과 같은 방법을 통해 통신이 가능하고 이를 효율적으로 설정해 주는것이 docker network입니다.

# 도커 네트워크 생성
# docker network create [network_name]

$ docker network create test_net

그리고 통신하고자 하는 컨테이너를 --network [network_name]옵션을 통해 네트워크에 넣줄 수 있습니다.

모두 새로운 옵션을 넣어 중지 후(자동 삭제) 재시작합니다.

# 데이터베이스
$ docker run --name db -v data:/data/db --rm -d -network test_net mongo

# 백엔드
$ docker run --name back --rm -d -network test_net back_image

# 프론트엔드
$ docker run --name front --rm -d -network test_net front_image

Point

모두 포트번호가 없습니다. 포트가 없어도 동일한 네트워크 안에서라면 통신이 가능하기 때문에 네트워크 설정을 하며 제외되었습니다.

백엔드는 통신 주소를 바꿔야합니다. 위에선 호스트를 경로로 지정했기에 포트번호도 있었지만 docker network의 db주소로 바꿔줍니다.
mongodb://db:27017/my_api
위처럼 docker network는 IP가 아닌 컨테이너 이름으로 통신 가능하며 DNS와 비슷한 느낌으로 자동 IP변환이 됩니다.

docker hub 사이트에서 mongodb 문서를 보면 /data/db에 데이터가 저장된다고 되어있기에 위와 같이 명명된 볼륨 설정을 해줍니다.

추가적으로 DB에 보안을 강화하기 위해 로그인 기능을 추가할 수 있습니다.
MONGO_INITDB_ROOT_USERNAME, MONGO_INITDB_ROOT_PASSWORD를 추가해주면 mongodb 컨테이너에 데이터베이스 삽입이 생성되어 이후 액세스에서 사용자 이름과 비밀번호가 필요합니다.
그렇다면 설정은 다음과 같이 됩니다.

$ docker run --name db -v data:/data/db --rm -d -e MONGO_INITDB_ROOT_USERNAME=admin -e MONGO_INITDB_ROOT_PASSWORD=secret -network test_net mongo

그리고 공식문서의 api 규정에 맞추면 다음과 같이 api를 바꿀 수 있습니다. 앞에 유저이름,비밀번호를 써주고 마지막에 변수를 추가해줍니다.
mongodb://admin:secret@db:27017/my_api?authSource=admin

이렇게 도커 네트워크를 통한 컨테이너 통신에 성공합니다!

물론 통신 성공에만 집중했고 개발 단계의 모습이기도 해서 완성도가 떨어지는 상태입니다. 다음 글에서 백엔드 컨테이너에 옵션 추가를 통해 더 좋은 형태로 바꿔보겠습니다.

profile
공부!

0개의 댓글