[docker] 컨테이너간 통신 이해
| 단일 컨테이너간 통신
1. 'study'라는 이름의 커스텀 네트워크를 생성
docker network create study
2. 두 개의 컨테이너를 생성하고 'study' 네트워크에 연결.
docker run -d --name container1 --network study nginx
docker run -d --name container2 --network study nginx
3. 하나의 컨테이너는 기본 네트워크에 연결
docker run -d --name container3 nginx
4. 같은 네트워크에 있는 컨테이너 간 통신을 테스트
docker exec -it container1 curl container2
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
다른 네트워크에 있는 컨테이너와의 통신을 시도
docker exec -it container1 curl container3
curl: (6) Could not resolve host: container3
5. container3'를 'study' 네트워크에 추가 연결
docker network connect study container3
다시 통신을 시도
docker exec -it container1 curl container3
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
| 결론
→ 같은 Docker 네트워크에 있는 컨테이너들은 서로 통신이 가능
→ 다른 네트워크에 있는 컨테이너와는 기본적으로 통신이 불가능
→ 컨테이너를 새로운 네트워크에 연결하면 해당 네트워크의 다른 컨테이너들과 통신이 가능해짐
| 여러 네트워크에 걸쳐있는 컨테이너 구성
1. 두 개의 네트워크 생성
docker network create network1
docker network create network2
2. 각 네트워크에 컨테이너 생성 및 연결
docker run -d --name container_a --network network1 nginx
docker run -d --name container_b --network network2 nginx
docker run -d --name container_c --network network1 --network network2 nginx
3. 통신 테스트
docker exec -it container_a curl container_b
curl: (6) Could not resolve host: container_b
docker exec -it container_a curl container_c
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
docker exec -it container_b curl container_c
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
| 결론
→ container_c는 두 네트워크에 모두 연결되어 있어 양쪽 네트워크의 컨테이너와 통신이 가능함
네트워크 격리:
container_a와 container_b는 서로 다른 네트워크(network1과 network2)에 속해 있어 서로 통신할 수 없음. (Docker의 네트워크 격리)
다중 네트워크 연결: container_c는 network1과 network2 모두에 연결되어 있어, 양쪽 네트워크의 컨테이너들과 모두 통신이 가능. (Docker가 단일 컨테이너를 여러 네트워크에 연결할 수 있는 유연성을 제공)
브리지 역할: container_c는 사실상 network1과 network2 사이의 브리지 역할을 수행. (직접적인 통신이 불가능한 container_a와 container_b 사이의 중개자 역할)
네트워크 설계의 유연성: Docker를 사용하여 복잡한 네트워크 토폴로지를 쉽게 구성할 수 있음. 필요에 따라 컨테이너를 여러 네트워크에 연결하거나 분리 가능
| Docker Compose를 사용한 복잡한 네트워크 설정
1. docker-compose.yml 파일 작성
version: '3'
services:
web:
image: nginx
networks:
- frontend
app:
build: .
networks:
- frontend
- backend
db:
image: mysql
networks:
- backend
environment:
MYSQL_ROOT_PASSWORD: example
networks:
frontend:
backend:
2. Docker Compose 실행
docker-compose up -d
생성된 네트워크 확인
docker-compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
test-app-1 test-app "/docker-entrypoint.…" app 2 minutes ago Up 2 minutes 80/tcp
test-db-1 mysql "docker-entrypoint.s…" db 2 minutes ago Up 2 minutes 3306/tcp, 33060/tcp
test-web-1 nginx "/docker-entrypoint.…" web 2 minutes ago Up 2 minutes 80/tcp
네트워크 확인
docker network ls
NETWORK ID NAME DRIVER SCOPE
d4636765c73d test_backend bridge local
03b1d742e82d test_frontend bridge local
| 결론
web 서비스:
nginx 이미지를 사용
frontend 네트워크에만 연결
app 서비스:
현재 디렉토리의 Dockerfile을 사용하여 빌드
frontend와 backend 네트워크 모두에 연결
db 서비스:
MySQL 이미지를 사용
backend 네트워크에만 연결
root 비밀번호가 환경변수로 설정
네트워크:
frontend와 backend 두 개의 네트워크가 정의
→ web과 db는 직접 통신할 수 없어 보안이 향상
→ app은 양쪽 네트워크에 모두 연결되어 중개 역할
→ 각 서비스는 필요한 네트워크에만 연결되어 있어 네트워크 격리
네트워크 분리와 보안:
frontend와 backend 네트워크를 분리함으로써, 웹 서버(web)와 데이터베이스(db)가 직접 통신할 수 없게 됨 (보안 강화)
중개 역할의 애플리케이션:
app 서비스가 두 네트워크에 모두 연결되어 있어, 필요한 경우 web과 db 사이의 통신을 중개할 수 있음.
선언적 구성의 편리성:
Docker Compose를 사용함으로써, 복잡한 네트워크 구성을 간단한 YAML 파일로 정의하고 관리
확장성과 유지보수성: 이런 구성은 쉽게 확장하고 수정할 수 있음. 예를 들어, 새로운 서비스를 추가하거나 기존 서비스의 설정을 변경하는 것이 매우 간단