Tool/Docker

도커(Docker) 컨테이너 연결 - 링크, 네트워크, 앰배서더

재은초 2024. 1. 19. 20:38
반응형

도커 컨테이너란?

  • Docker 컨테이너는 이미지를 실행한 상태다. 이미지로 여러 개의 컨테이너를 만들 수 있다.
  • 운영체제로 보면 이미지는 실행 파일이고 컨테이너는 프로세스다. 이미 실행된 컨테이너에서 변경된 부분을 이미지로 생성할 수도 있다.

 

같은 서버의 컨테이너끼리 연결하기

link 옵션으로 도커 컨테이너 연결하기

  • Docker로 이미지를 생성할 때 웹 서버, DB 등 필요한 프로그램을 모두 설치할 수도 있지만 보통 프로그램별로 이미지를 생성한다. 이렇게 프로그램별로 이미지를 생성하고, 컨테이너를 생성했을 때 옆에 있는 컨테이너에 접속할 일이 많아 컨테이너끼리 연결하기도 한다.
  • Docker 컨테이너끼리 연결할 때는 docker run 명령에서 --link 옵션을 사용한다.
$ docker run <옵션> <이미지 이름/아이디> <실행할 파일>
$ docker run --name db -d mongo                 # 컨테이너 이름이 db인 mongo를 백그라운드에서 실행되도록 설정
$ docker run <옵션> <이미지 이름/아이디> <실행할 파일> --link <컨테이너 이름>:<별칭>
$ docker run --name web -d -p 80:80 --link db:db nginx
# nginx 이미지로 web이라는 이름의 컨테이너를 백그라운드에 80포트에 생성하면서 db 컨테이너와 연결

네트워크로 도커 컨테이너 연결하기

  • 같은 네트워크에 속한 컨테이너끼리는 컨테이너 이름으로 접속할 수 있다.
$ docker network create <이름>
$ docker network create hello-network               # 네트워크 생성
$ docker run <옵션> <이미지 이름/아이디> <실행할 파일>
$ docker run --name db -d --network hello-network mongo
# 이름이 db이고 네트워크가 hello-network인 mongodb 생성
$ docker run --name web -d -p 80:80 --network hello-network nginx
# nginx 이미지로 이름이 web인 컨테이너를 80포트에 생성하면서 hello-network에 연결
$ docker exec -it web bash
root@e3b1c984baa7:/# apt update && apt install iputils-ping -y
root@e3b1c984baa7:/# ping db
PING db (172.19.0.2) 56(84) bytes of data.
64 bytes from db.hello-network (172.19.0.2): icmp_seq=1 ttl=64 time=0.125 ms
64 bytes from db.hello-network (172.19.0.2): icmp_seq=2 ttl=64 time=0.097 ms

 

다른 서버의 컨테이너끼리 연결하기

  • 앰배서더 컨테이너(Ambassador Container)라는 것을 이용하여 다른 서버에 있는 컨테이너에 연결할 수 있는데, 앰배서더 컨테이너는 특별한 컨테이너가 아닌 그냥 일반적인 Docker 컨테이너다. 앰배서더 컨테이너는 socat이라는 프로그램을 이용하여 TCP 연결을 다른 곳으로 전달하도록 구성되어 있다.
socat이란?
SOcket CAT을 뜻하며 소켓 통신을 다른 채널로 전달하는 프로그램이다. 채널은 파일, 파이프, 장치(시리얼, pseudo 터미널 등), 소켓(유닉스 소켓, TCP, UDP 등)이 있다.

https://pyrasis.com/jHLsAlwaysUpToDateDocker/Unit06/03

  • 앰배서더 컨테이너의 Dockerfile에 docker run 명령을 실행할 때 전달한 환경 변수를 이용하여 socat을 실행하는 셸 스크립트를 적어준다.
CMD env | grep _TCP= | \
    sed 's/.*_PORT_\([0-9]*\)_TCP=tcp:\/\/\(.*\):\(.*\)/socat \
    TCP4-LISTEN:\1,fork,reuseaddr TCP4:\2:\3 \&/'  \
    | sh && top
    
# env 명령으로 환경 변수를 출력
# grep 명령으로 _TCP=를 포함하는 문자열 찾기
# sed 명령으로 정규표현식을 사용하여 문자열에서 포트 번호와 IP 주소를 추출
# 그 뒤 추출한 포트 번호와 IP 주소 이용하여 socat 명령 실행
  • 앰배서더 컨테이너를 이용해 연결할 다른 서버 컨테이너, 여기서는 Redis, 를 생성한다.
$ docker pull redis:latest                     # 이미지 받기
$ docker run -d --name redis redis:latest      # 이미지 실행 = 컨테이너 생성
  • 위의 서버 컨테이너, Redis, 를 위한 앰배서더 컨테이너를 생성한다.
  • 참고로 svendowideit는 앰배서더 패턴을 만든 사람 이름이다.
$ docker run -d \                         # 컨테이너를 백그라운드에서 실행
  --link redis:redis \                    # redis 컨테이너를 redis 별칭으로 연결
  --name redis_ambassador \               # redis_ambassador로 컨테이너 이름 지정
  -p 6379:6379 \                          # 컨테이너의 6379 포트와 호스트의 6379 연결하고 외부 노출
  svendowideit/ambassador                 # svendowideit/ambassador 이미지를 받은 뒤 컨테이너로 생성
  • Redis 클라이언트를 사용할 컴퓨터에서 앰배서더 컨테이너를 생성한다.
$ docker run -d \                  # 컨테이너 백그라운드에서 실행
  --name redis_ambassador \        # redis_ambassador로 이름 지정
  --expose 6379 \                  # 다른 컨테이너에서 redis_ambassador가 6379포트로 연결할 수 있게 포트 설정
  -e REDIS_PORT_6379_TCP=tcp://192.168.0.10:6379 \   # 다른 서버의 IP주소와 포트 설정
  svendowideit/ambassador          # 이미지 받기
  • Redis 클라이언트를 이용해 redis_ambassador 컨테이너에 접속
$ sudo docker run -i -t \           # -i -t 옵션으로 콘솔에서 입출력을 할 수 있도록 설정 
  --rm \                            # 컨테이너를 실행만 하고 컨테이너 자체는 삭제
  --link redis_ambassador \         # redis_ambassador 컨테이너 연결
  -- redis:latest \                 # redis:latest 이미지를 받은 뒤
  redis-cli -h redis_ambassador     # redis-cli로 redis_ambassador 컨테이너에 연결
  • Redis 클라이언트가 실행되면 ping 명령을 입력한다. 결과로 PONG이 출력되면 다른 서버의 Redis 컨테이너에 정상적으로 연결된 것 이다.
redis_ambassador:6379> ping
PONG

 

 

반응형