컨테이너에서 외부 api를 불러온다든지 다른 컨테이너의 api를사용하는 등 컨테이너에서 통신이 필요할 때가 있다.
실제로 컨테이너를 하나만 사용할 경우는 별로 없고 프론트 컨테이너, 백엔드 컨테이너, 데이터베이스 컨테이너를 한번에 사용하는 것처럼 여러개의 컨테이너가 통신해야 하는 경우가 많다.
이러한 통신을 하는 방법에 대해서 알아보자.
유스케이스
일단 컨테이너에서 통신을 하는 경우가 크게 아래와 같을 것이다.
여기서 호스트 컴퓨터는 도커를 실행하고 있는 컴퓨터이다.
5번과 6번은 실질적으로 컨테이너간의 통신이기 때문에 하나의 경우라고 봐도 된다.
물론 1부터 6까지 모든 연결이 가능하다.
이제 어떻게 통신하는지 알아보자.
위 통신을 위해 간단한 파일 두개를 한 폴더에 만들었다.
# app.py
from flask import Flask
app = Flask(__name__)
@app.route("/")
def main():
return "Hello world"
app.run(host="0.0.0.0")
# Dockerfile
FROM python
COPY . .
RUN pip3 install flask
CMD ["python3", "app.py"]
그 후 파일을 빌드하고 사용할 것이다.
docker build -t myflask .
1번 케이스
컨테이너 -> 호스트컴퓨터로 가는 연결이다.
이를 위해 호스트에서 app.py를 실행시키자.
python app.py
그리고 컨테이너에서 호스트로 연결할 우분투 컨테이너를 하나 만들자.
docker run -it --rm ubuntu
그럼 우분투 컨테이서 쉘로 들어가게 될 것이다.
통신을 위해 curl을 설치하자
apt update
apt install curl
여기에서 localhost로 curl을 보낸다면 연결이 안될 것이다.
localhost는 도커 컨테이너를 가리키기 때문이다.
방법은 두가지가 있다.
1. ifconfig(ipconfig)를 통해 로컬 ip를 알아낸 후 그 ip에 통신한다.
2. host.docker.internal 사용
하지만 첫 번째 방법은 ip를 직접 찾아야 하고 ip가 달라질 때마다 고쳐야하는 불편함이 있다.
그래서 두 번째 방법을 사용한다.
host.docker.internal은 도커에서 호스트와 통신할 때 localhost처럼 도메인으로 사용할 수 있다.
그래서 curl host.docker.internal:5000이라 하면 결과가 나올 것이다.
2번 케이스
아까 만든 이미지를 실행시키자
docker run --rm -d -p 5050:5000 --name app myflask
로컬에서 5000번 포트를 사용하기 때문에 5050번 포트를 사용했다.
컨테이너와 통신하려면 단순히 localhost에 요청을 보내면 된다.
3번 케이스
다른 컴퓨터와 통신하기 위해서는 아무 설정을 할 것이 없다.
그냥 요청을 보내면 된다.
4번 케이스
다른컴퓨터에서 컨테이너로 접속할 때 포트가 열려있기 때문에 호스트의 IP로 접속하면 된다.
그래서 실제로 과정은 다음과 같다.
5, 6번 케이스
이제 컨테이너끼리 연결을 보자.
가장 단순한 방법으로 컨테이너 IP를 얻어서 접속하는 방법이 있다.
docker inspect app
위 명령어로 app컨테이너(flask) 정보를 얻어올 수 있다.
여기에서 NetworkSettings에 IPAddress가 있을 것이다.
그 IP를 다른 컨테이너에서 통신 요청을 보내면 된다.
다만 이때는 5050이 아닌 5000으로 보낸다.
하지만 이 방법은 1번케이스와 마찬가지로 IP를 직접 얻어야하는 불편함이 있다.
이를 해결하기 위해 도커 네트워크를 사용한다.
사용법
1. 도커 네트워크 생성
2. 컨테이너 실행시 네트워크 명시
네트워크를 통해 같은 네트워크에 넣어주면 편리하게 접속할 수 있다.
docker network create mynet
위 명령어로 네트워크를 만든다.
mynet은 네트워크 이름이다.
docker network ls
ls 명령을 통해 만든 네트워크를 볼 수 있다.
이제 컨테이너 생성할 때 추가 옵션을 통해 네트워크를 명시할 수 있다.
docker run --rm -d -p 5050:5000 --network mynet --name app myflask
docker run -it --rm --network mynet ubuntu
이제 ubuntu컨테이너에 curl을 다시 깔고 통신을 하는데 통신 대상을 대상 컨테이너 이름으로 한다.
curl app:5000
우리는 app 컨테이너이니 app을 쓰고 포트를 쓰면 된다.
그럼 결과가 잘 나올 것이다.
'프로그래밍 > 도커' 카테고리의 다른 글
[도커] 12. dockerignore (0) | 2022.08.19 |
---|---|
[도커] 11. 환경변수 (0) | 2022.08.19 |
[도커] 9. 도커 이미지 만들기 (0) | 2022.01.03 |
[도커] 8. Dockerfile 요소 (0) | 2022.01.02 |
[도커] 7. 가장 간단한 이미지 만들기 (0) | 2022.01.01 |