docker pull ngrinder/controller
docker run -d -v ~/ngrinder-controller:/opt/ngrinder-controller --name controller -p 80:80 -p 16001:16001 -p 12000-12009:12000-12009 ngrinder/controller
-d : 백그라운드로 컨테이너 실행-v ~/ngrinder-controller:/opt/ngrinder-controller : 호스트와 컨테이너 간의 볼륨을 마운트한다. 호스트의 ~ngrinder-controller 경로와 컨테이너 내부의 /opt/ngrinder-controller 경로를 연결한다.-p : 호스트의 포트와 컨테이너의 포트를 바인딩한다.ngrinder/controller : 해당 도커 이미지를 사용한다.--name controller : 컨테이너의 이름을 controller로 설정한다.(중요!!)docker pull ngrinder/agent
docker run -d --name agent --link controller:controller ngrinder/agent
--link controller:controller : 컨테이너 간에 네트워크를 설정하는 단계로 컨테이너 이름이 controller인 컨테이너와 네트워크를 연결한다. :controller 로 인해 agent 컨테이너 내부에서 controller라는 이름으로 controller 컨테이너에 접근할 수 있다.TMI : --link
테스트 할 서버는 인텔리제이를 통해서 로컬에서 실행했고, 현재 상황은 아래와 같다.

도커로 nGrinder를 성공적으로 실행됐다면, localhost:80으로 nGrinder에 접속할 수 있다. 초기 ID, PW는 admin, admin으로 로그인할 수 있다.
nGrinder에 접속해 '127.0.0.1:8080/actuator/health'로 요청을 보내는 스크립트를 작성하고 실행한 결과, Connection refused 에러가 발생했다.
에러 원인을 알기 전에 nGrinder의 동작 방식은 간단하게 다음과 같다.
사용자가 스크립트를 작성해서 테스트 시나리오를 controller에게 전달한다.
controller는 여러 대의 agent를 가지고 있으며, 해당 스크립트를 agent에게 실행하도록 한다.
agent는 타켓 서버에 요청을 보낸다.
원인
agent에서 로컬 서버로 요청을 보낸다.
agent는 컨테이너로 실행 중이다.
agent 컨테이너를 실행할 때 8080 포트는 아무런 연결을 하지 않았다.
nGrinder의 동작 방식에서 agent에서 타켓 서버로 요청을 보낸다. 를 주목하자. 현재 agent는 컨테이너로 실행되고 있다. 그리고, 컨테이너에서 127.0.0.1을 요청하면 agent 컨테이너 내부의 localhost:8080으로 통신을 요청한다.
하지만, 서버는 agent 컨테이너 외부에 있고, agent 컨테이너 내부의 8080포트에는 서버가 실행되고 있지 않기 때문에 Connection refused 에러가 발생한다.
ngrok은 로컬에 실행된 서버를 터널링을 통해 외부에서 접속할 수 있도록 도와주는 플랫폼이다.
ngrok 또한 Docker image가 있기 때문에 다음과 같이 실행할 수 있다. - 공식문서 참고
docker run -it -e NGROK_AUTHTOKEN=xyz ngrok/ngrok:alpine http host.docker.internal:8080
-e NGROK_AUTHTOKEN: 환경 변수를 설정한다. ngrok의 토큰으로 NGROK 회원 가입 이후에 받을 수 있다.ngrok/ngrok:alpine: alpine 버전의 ngrok 이미지를 사용한다.host.docker.internal:8080: 문서에 나온 것 같이 윈도우, 맥 환경으로 실행할 때, host.docker.internal:[포트번호] 형식으로 실행해야 한다. 현재 8080 포트로 서버를 실행하기 때문에 8080으로 실행한다. 
--log stdout: 컨테이너에서 발생하는 것을 로그로 표현하는 명령어로 이를 통해서 url을 확인한다. 하지만 ngrok 홈페이지에 들어가서 확인할 수 있어서 해당 명령어는 선택이다. 
이제 테스트 스크립트를 127.0.0.1 대신 ngrok에서 제공해주는 url로 바꾸면 성공적으로 부하 테스트를 성공할 수 있다.
하지만 다음과 같은 이유로 ngrok을 추천하지 않는다.

nGrinder에서는 수많은 요청을 ngrok에게 보내면, 대부분의 요청을 429:too many request 에러로 반환해서 20초 내로 부하테스트가 종료된다.
![]() | ![]() |
문제의 원인은 agent 컨테이너가 Host의 로컬 서버를 접근하지 못하는 것이다. Docker 문서에서 host.docker.internal명령어를 통해서 Host에 접근할 수 있는 것을 알았다.
host.docker.internal: 컨테이너 내부에서 Host의 접근이 가능하도록 만드는 DNS이다.
부하 테스트 스크립트를 127.0.0.1:8080 → host.docker.internal:8080 으로 변경했고, 그 결과 agent가 Host의 서버로 요청을 잘 보내는 것을 볼 수 있다.
HTTPResponse response = request.GET("http://host.docker.internal:8080/actuator/health", params)

도커의 동작을 잘 몰랐기 때문에 많이 해맸다고 생각한다. 이 과정을 통해서 도커의 호스트와 컨테이너 관계에 대해 이해할 수 있었고, 역시 기본부터 잘 알아야 된다는 것을 다시금 깨달았다.