docker

[docker] 컨테이너간 통신 이해

99duuk 2024. 8. 12. 18:26

|  단일 컨테이너간 통신

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 파일로 정의하고 관리

 

확장성과 유지보수성: 이런 구성은 쉽게 확장하고 수정할 수 있음. 예를 들어, 새로운 서비스를 추가하거나 기존 서비스의 설정을 변경하는 것이 매우 간단