DevOps/Docker

[Docker] 컨테이너 통신

샤아이인 2022. 9. 18.

 

컨테이너의 통신은 어떤 대상과 통신을 하는지 기준으로 3가지 방식이 있다.

1. 컨테이너 <-> web(WWW)

2. 컨테이너 <-> host machine

3. 컨테이너 <-> 컨테이너

 

각각의 방식에서 어떻게 해야 통신을 할 수 있는지 알아보자!

 

1. 컨테이너와 Web의 통신

사실 이 방식은 너무 간단해서 정리할 점이 적다.

 

예를 들어 다음과 같이 컨테이너 내부의 애플리케이션에서 인터넷으로 요청을 보내는 코드가 있다고 해보자.

get('https://some-api.com/shine-info').then(...)

이 경우 특별한 조치 없이도 Web과 소통이 가능하다.

아무런 문제없이 실행 중인 컨테이너 내부의 애플리케이션에서 외부의 WWW으로 request를 보내고, response를 반환받을 수 있다.

 

2. 컨테이너와 Host의 통신

컨테이너와 Host간의 통신을 할 때도 크게 다른 옵션을 설정해줄 필요는 없다.

 

예를 들어 컨테이너 내부의 SpringBoot 애플리케이션에서 Host에 설치된 MySQL과 소통을 해야 하는 경우가 있을 수 있다.

이때 일반적으로 애플리케이션에서 설정을 다음과 같이 localhost를 사용하려 할 것 이다.

datasource=jdbc:mysql://localhost:3306/issue

왜냐하면 위 방식이 일반적인 url 설정 방식이기 때문이다.

 

하지만, 컨테이너 상에서 위와 같이 localhost를 지정하면 인식할 수가 없다.

잘 생각해보면 컨테이너 내부에서 localhost란, 컨테이너 내부의 주소를 의미하게 된다.

하지만 컨테이너 내부에는 MySQL이 없다. 우리의 Host 상에 있다.

 

따라서 다음과 같이 설정해주면 된다.

datasource=jdbc:mysql://host.docker.internal:3306/issue

host.docker.internal은 특수 주소 or 식별자로 컨테이너를 호스팅 하는 시스템의 IP 주소로 변환됩니다.

 

3. 컨테이너와 컨테이너의 통신

도커에서는 컨테이너 네트워크를 형성할 수 있습니다.

이는 다중 컨테이너를 가지고 있을 때 컨테이너 간에 연결을 만드는 것입니다.

 

"docker run"을 수행하면서 옵션으로 "--network"를 추가하면 모든 컨테이너를 하나의 네트워크 안에 담을 수 있습니다.

다음과 같이 "--network favorites-net"을 추가 옵션으로 설정하고 run 하면 해당 네트워크를 찾을 수 없다고 나옵니다.

network는 volume과 달리 자동으로 생성되지 않기 때문입니다.

 

따라서 우선 네트워크부터 생성해 봅시다!

docker network create favorites-net

실행 결과는 다음과 같습니다.

네트워크 목록을 살펴보면 우리가 만든 "favorites-net"이 생성된 것을 확인할 수 있습니다.

 

이후 다음과 같이 mongodb 컨테이너를 실행시켜 봅시다!

docker run -d --name mongodb --network favorites-net mongo

정상적으로 실행이 됩니다.

 

(참고로 -p를 통해 포트 설정을 하지 않는데, 이는 네트워크를 형성하여 소통할 것이기 때문입니다. 포트 설정은 local host나 컨테이너 네트워크 외부와 소통할 때만 필요합니다.

즉, 동일한 네트워크 상에서 소통하는 컨테이너들 간에 연결이 있다면, 포트를 설정할 필요가 없습니다. 같은 네트워크 상의 컨테이너들은 자유롭게 통신할 수 있기 때문입니다.)

 

남은 과제는 우리의 애플리케이션 상에서 db의 url을 어떻게 설정해주는지입니다.

사실 생각보다 간단한데, 컨테이너의 이름을 다음과 같이 지정해주면 됩니다.

'mongodb://mongodb:27017/swfavorites'

도메인 부분이 mongodb라는 컨테이너의 이름으로 변경되었습니다!

 

두 컨테이너가 같은 네트워크상에 있는 경우, 이렇게 이름만 적어줘도 Docker에 의해 자동으로 해당 컨테이너의 ip로 변환됩니다.

 

이제 애플리케이션 컨테이너의 코드를 위와 같이 수정한 후, 다시 빌드하여 실행시켜 봅시다.

docker run --name favorites --network favorites-net -d --rm -p 3000:3000 favorites-node

정상적으로 수행됩니다!

댓글