이 문서의 목적은 AWS상에서 nGrinder를 빠르고 쉽게 설치하는 것을 안내하기 위한 문서입니다. 제 시행착오를 반영하여서 최대한 자세하게 정리 작성하려고 노력했습니다. 이 문서를 보시고 따라 해보시다가 문제가 생기시면 댓글로 남겨주시면 확인하는 대로 답변 드리도록 하겠습니다.
• Docker CE 설치 : nGrinder의 docker 이미지가 제공되고 있기 때문에 docker로 ngrinder를 설치하는 것이 가장 쉽습니다. 따라서 Docker CE를 먼저 설치해야 합니다.
• JAVA (openjdk-8-jdk) : nGrinder와 호환되는 JAVA version 설치. 최신 버전의 Java를 설치하면 nGrinder가 정상 동작하지 않습니다.
• SVN : nGrinder의 script를 관리하기 위해서 설치합니다.
Controller: Docker CE, JAVA, SVN 필요
Agent: JAVA 필요
먼저 Tips 항목을 적는 이유는 제가 해당 업무를 진행하면서 조금 더 효율적이고 효과적으로 업무를 하기 위해서 고민했던 내용을 공유하기 위함입니다.
이 내용은 이해가 안되시는 부분이 있으면 일단 넘어가시고 설치를 다 해보고 난 다음에 다시 참고하시면 됩니다.
아래 내용을 다 읽어보시고 이 내용을 읽어보시면 더 이해가 빠를 것입니다.
AWS에 nGrinder를 설치하고 사용할 때의 장점은 다음과 같습니다.
많은 분들이 알고 계시겠지만 AWS상에서 시스템을 구축하실 때에는 해당 시스템에 적용될 보안그룹(Security Group)부터 생성하시는 것을 강력하게 권장드립니다.
EC2 인스턴스를 생성할 때에 해당 보안그룹을 적용하고 보안그룹을 적용할 보안 규칙에 따라서 수정하는 것이 시스템을 관리하고 유지하는 가장 좋은 방법입니다.
보안그룹을 어떻게 설정해야 할지 모르시겠으면 일단 최소한의 Inbound Rule을 설정하고 사용하면서 필요한 규칙을 추가하시면 됩니다.
네트워크 보안은 최소한의 허용을 해주는 것이 기본입니다. (아래에 예시를 드렸습니다.)
흐름부터 정리하면 다음과 같습니다. 자세한 내용은 아래의 설치 부분을 참고하셔야 합니다.
위와 같이 하는 이유는 EC2 인스턴스를 정지했다가 재시작하면 Private IP도 변경이 됩니다.
nGrinder Agent는 Controller의 주소에 관련된 설정 내용이 있기 때문에 Controller의 IP가 변경이 되면 매번 Agent의 설정 파일을 수정해줘야 합니다. 이것을 수정하지 않고 사용하기 위해서는 Controller의 IP주소는 고정이 되어야 합니다.
이를 고정하는 방법은 가장 쉬운 것은 Elastic IP를 생성하고 이를 Controller에 할당하는 것입니다.
저는 다른 방법으로 네트워크 인터페이스를 미리 하나 만들어서 Private IP를 고정하고 해당 네트워크 인터페이스를 Controller의 EC2인스턴스에 할당하여서 Private IP를 고정하는 방법을 선택했습니다. Agent와 Controller는 모두 AWS상에 있기 때문에 서로 Private IP로 통신을 할수 있습니다. .
먼저 SSH로 AWS상의 EC2 서버에 접속합니다.
아래와 같이 설치합니다.
# Package Database를 update한다.
$ sudo apt-get update**
# docker install
$ sudo apt-get install docker.io
# 현재 접속한 ubuntu 계정을 docker 실행 그룹에 포함시켜 준다.
$ sudo usermod -aG docker $(whoami)
# docker service를 재시작한다.
$ sudo service docker restart
세부적인 Docker 설치에 대해서는 https://docs.docker.com/install/ , https://docs.docker.com/compose/install/ 를 참조 하시면 됩니다.
# 현재 설치된 JAVA가 있는지 확인.
$ java -version
Command 'java' not found, but can be installed with:
sudo apt install default-jre
sudo apt install openjdk-11-jre-headless
sudo apt install openjdk-8-jre-headless
# JAVA(JRE) 설치
$ sudo apt-get install openjdk-8-jdk
...... (생략)
$ java -version
openjdk version "1.8.0_265"
OpenJDK Runtime Environment (build 1.8.0_265-8u265-b01-0ubuntu2~18.04-b01)
OpenJDK 64-Bit Server VM (build 25.265-b01, mixed mode)
$ javac -version
javac 1.8.0_265
# javac 위치 확인
$ which javac
/usr/bin/javac
# javac의 심볼릭 링크 확인
$ readlink -f /usr/bin/javac
/usr/lib/jvm/java-8-openjdk-amd64/bin/javac
위에서 확인한 javac의 실제 위치는 /usr/lib/jvm/java-8-openjdk-amd64/bin/이다. 따라서, $JAVA_HOME은 /usr/lib/jvm/java-8-openjdk-amd64으로 설정 해야 한다.
환경변수를 위해서 profile 을 연다.
$ sudo nano /etc/profile
profile 파일 맨 아래 쪽에 아래 정리한 3줄을 입력한다.
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/bin/
export PATH=$JAVA_HOME/bin:$PATH
export CLASS_PATH=$JAVA_HOME/lib:$CLASS_PATH
다음의 명령어를 실행시켜서 profile을 reload 한다.
$ source /etc/profile
EC2 인스턴스를 AWS console에서 reboot하고 다음 명령어로 정상 설치를 확인한다.
# 환경변수를 확인
$ echo $JAVA_HOME
/usr/lib/jvm/java-11-openjdk-amd64
$ $JAVA_HOME/javac -version
javac 1.8.0_265
$
nGrinder의 Controller에는 JAVA, SVN, Docker CE등이 필요합니다.
nGrinder의 Agent에는 JAVA가 필요합니다.
매번 EC2인스턴스를 생성할 때마다 필요한 패키지를 설치하는 것은 불필요한 시간을 쓰게 됩니다. nGrinder 설치를 위해서는 공통되는 JAVA를 EC2인스턴스에서 설치하고, AMI(Amazon Machine Image)를 생성하는 것을 권장합니다. AMI를 생성해놓으면 필요할 때마다 빠르게 필요한 크기의 성능 EC2인스턴스를 생성을 할수가 있습니다.
이미지 이름을 알기 쉽도록 정하고 이미지 설명에 이미지가 생성된 운영체제명, 버전명, 설치된 패키지 이름 및 버전을 작성하여서 추후에 필요할 때에 사용하여서 필요한 EC2인스턴스를 빠르고 쉽게 생성한다.
이미지 이름: Ubuntu 18_04
이미지 설명: Ubuntu 18.04 LTS, Java 1.8.0_265
$ sudo apt-get install subversion
Reading package lists... Done
Building dependency tree
Reading state information... Done
…(중간 생략)
$
nGrinder는 Controller, Agent, Monitor로 구성되어 있습니다.
• Controller
• Agent : 성능 대상 시스템에 부하를 가하는 프로세스 및 스레드를 실행
• Monitor : 성능테스트의 대상이 되는 서버에 설치하여서 테스트가 수행하는 동안 대상 서버의 상황 정보를 Controller로 전달하여서 Controller에서 웹 인터페이스로 모니터링 할수 있도록 하여줍니다.
이 문서는 Ubuntu 18.04.1 LTS가 설치된 machine에 controller와 agent 를 설치하는 방법을 소개합니다. Montior설치는 이번 문서에서는 다루지 않을 계획입니다.
nGrinder는 일반적으로 Controller 1개에 Agent를 3~6개로 구성합니다. 이 문서에서는 4개를 구성하도록 하겠습니다.
Controller는 최소 t2.large. Agent는 개인적으로 최소 t2.2xlarge 를 권장사양으로 합니다.(테스트 하면서 필요하다면 언제든지 변경 가능)
nGrinder Controller가 설치되는 EC2 Instance의 inbound rule에서 80번 포트를 열어줘야만 합니다. 사용자가 nGrinder Controller를 웹 브라우저를 이용하여서 접속을 할수 있도록 하기 위해서입니다. 기본 보안그룹(Security Group)에서는 inbound 룰에서는 SSH를 위한 22번 포트만 열려 있습니다.
nGrinder 네트워크 통신 포트 정보를 정리하면 다음과 같습니다.
에이전트:모든 포트 ==> 컨트롤러 : 16001
에이전트:모든 포트 ==> 컨트롤러 : 12000 ~ 12000 + 동시 테스트 허용할 테스트 개수
컨트롤러:모든 포트 ==> 모니터:13243
컨트롤러 ==> 일반 유저 : 웹 서버 설정 방식에 따르나, 디폴트는 8080 입니다.
docker를 이용하여서 ngrinder를 실행하는 경우 웹서버 기본 포트는 8080에서 80으로 매핑하여서 사용하는 경우가 많습니다. 제 글을 따라서 하는 경우에는 80 포트를 오픈하고 8080를 따로 오픈할 필요는 없습니다.
위의 정보를 기반으로 보안그룹(Security Group)을 설정하시고 해당 보안그룹을 nGrinder가 설치되는 EC2들에 적용하셔야 합니다.
AWS상에서 nGrinder를 설치하고 사용할 때 사용하는 보안그룹(Security Group) 설정 정리
보안과 관련해서는 추가적인 제한이 필요하지만 네트워크 보안 지식이 필요하기 때문에 해당 내용은 이 문서에서는 다루지 않겠습니다. 테스트가 가능한 환경 구축을 위한 가이드 문서가 이 문서의 목적이기 때문입니다.
nGrinder Controller에는 Elastic IP를 하나 할당하여 주는 것이 좋다.
AWS EC2는 사용하지 않을 때에는 STOP시켰다가 다시 시작하면 비용을 절감할 수 있습니다. 주의해야 할 점은 EC2인스턴스는 Stop되었다가 재 시작되면 네트워크 주소가 바뀌게 된다. Agent가 설치된 EC2에 Controller주소를 설정하여 주는 부분이 있는데 Controller의 주소가 계속 바뀌게 되면 설정 파일을 실행할 때마다 변경해야 하기 때문에 Controller의 네트워크 주소를 고정해주는 것이 필요하다.
$ sudo docker pull ngrinder/controller
Using default tag: latest
latest: Pulling from ngrinder/controller
6c40cc604d8e: Pull complete
93e89d51b14f: Pull complete
a9db8812b63a: Pull complete
57d2deacb87b: Pull complete
32444f0913e3: Pull complete
4ea13017e9ac: Pull complete
Digest: sha256:4825c55dc100c8c1b6a38b6430695b3679096828dcf3faa6f58ee5cbb2873ecc
Status: Downloaded newer image for ngrinder/controller:latest
docker.io/ngrinder/controller:latest
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ngrinder/controller latest a8bea449efad 13 days ago 292MB
ubuntu@ip-172-31-34-108:~$
# nGrinder Controller 실행
$ sudo docker run -d -v ~/ngrinder-controller:/opt/ngrinder-controller -p 80:80 \
-p 16001:16001 -p 12000-12009:12000-12009 ngrinder/controller
f2c8cb609f3ba37f9d2163efb319a67637fac8a8ea73606b7641518ef04ce0cd
$ ls ~
ngrinder-controller
$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f2c8cb609f3b ngrinder/controller "/scripts/run.sh" 15 seconds ago Up 14 seconds 0.0.0.0:80->80/tcp, 0.0.0.0:12000-12009->12000-12009/tcp, 0.0.0.0:16001->16001/tcp inspiring_wing
$
nGrinder Controller를 실행하기 위한 명령어를 매번 실행할 때마다 직접 입력하기는 매우 깁니다. 또한 EC2인스턴스를 멈췄다가 재실행하거나 시스템을 재부팅한 경우 기존에 실행되어 있는 도커 컨테이너가 남아 있는 경우가 많아서 다음과 같은 실행 스크립트를 만들어서 사용하는 것을 권장합니다.
# 본인이 원하는 실행 스크립트 이름으로 선택
$ nano controller_run.sh
아래와 같은 내용으로 스크립트를 생성합니다.
#!/bin/bash
docker rm $(docker ps -a -q)
sudo docker run -d -v ~/ngrinder-controller:/opt/ngrinder-controller \
-p 80:80 -p 16001:16001 -p 12000-12009:12000-12009 ngrinder/controller
docker rm $(docker ps -a -q) 는 기존에 종료된 모든 도커 컨테이너를 제거하는 명령입니다. EC2 인스턴스를 정지하거나 재시작하는 경우에 기존에 실행되었던 도커 컨테이너가 Exited상태로 남아 있는 경우가 있습니다. 이것을 제거해주기 위함입니다.
생성한 스크립트를 실행 가능하도록 실행 권한을 부여합니다.
$ chmod 755 controller_run.sh
Controller가 설치된 EC2인스턴스를 STOP시켰다가 다시 시작한 경우에는 위에서 작성한 실행스크립트로 Controller를 실행하면 편리합니다.
Browser를 이용해서 Controller에 접속합니다.
Controller가 설치된 EC2인스턴스의 퍼블릭 IP주소를 웹 브라우저에 입력하면 다음과 같은 화면을 확인할 수 있다. 접속이 되지 않은 경우는 위에서 언급했지만 EC2인스턴스에 적용된 보안그룹의 Inbound rule에 TCP 80포트를 허용해줘야 합니다.
USER ID: admin / Password: admin
(초기 사용자 아이디와 암호입니다. 접속한 뒤에 자신이 아는 암호로 변경하는 것을 권장합니다.)
초기 사용자 아이디와 암호로 접속하면 아래와 같은 화면을 확인할수 있습니다. 해당 화면에서 admin을 선택하고 나타나는 팝업 메뉴에서 "Download Agent"를 선택합니다.
"ngrinder-agent-3.5.1-p1-54.180.101.195.tar" 파일이 로컬에 다운로드 됩니다. (파일명은 언제든지 변경이 될수 있습니다.)
Agent로 사용할 EC2인스턴스를 생성합니다. (위에서 만든 AMI이미지로 쉽고 빠르게 EC2 인스턴스를 만듭니다.)
위에서 다운로드 받은 agent설치 파일을 SCP를 이용하여서 EC2에 업로드합니다.
$ scp -i "keyfile" ngrinder-agent-3.5.1-p1-54.180.101.195.tar ubuntu@(ec2인스턴스주소):~/
해당 인스턴스에 SSH접속을 합니다.
scp를 이용하여 업로드한 agent 파일의 압축을 풉니다.
$ tar xvf ngrinder-agent-3.5.1-p1-54.180.101.195.tar
ngrinder-agent/
ngrinder-agent/lib/
ngrinder-agent/stop_agent.bat
ngrinder-agent/run_agent_internal.sh
ngrinder-agent/run_agent.bat
ngrinder-agent/stop_agent.sh
ngrinder-agent/run_agent_bg.sh
ngrinder-agent/run_agent.sh
ngrinder-agent/run_agent_internal.bat
ngrinder-agent/lib/ngrinder-core-3.5.1-p1.jar
ngrinder-agent/lib/jython-standalone-2.5.3.jar
ngrinder-agent/lib/jackson-databind-2.11.2.jar
ngrinder-agent/lib/jackson-annotations-2.11.2.jar
ngrinder-agent/lib/jcommander-1.32.jar
ngrinder-agent/lib/pf4j-3.0.1.jar
ngrinder-agent/lib/commons-collections-3.2.1.jar
ngrinder-agent/lib/ngrinder-groovy-3.5.1-p1.jar
ngrinder-agent/lib/oshi-core-5.2.2.jar
ngrinder-agent/lib/javax.servlet-api-4.0.1.jar
ngrinder-agent/lib/jna-platform-5.6.0.jar
ngrinder-agent/lib/jna-5.6.0.jar
ngrinder-agent/lib/commons-compress-1.4.1.jar
ngrinder-agent/lib/commons-codec-1.14.jar
ngrinder-agent/lib/ngrinder-runtime-3.5.1-p1.jar
ngrinder-agent/lib/grinder-http-3.9.1.jar
ngrinder-agent/lib/grinder-core-3.9.1.jar
ngrinder-agent/lib/logback-classic-1.2.3.jar
ngrinder-agent/lib/jcl-over-slf4j-1.7.30.jar
ngrinder-agent/lib/dnsjava-3.2.2.jar
ngrinder-agent/lib/slf4j-api-1.7.30.jar
ngrinder-agent/lib/hibernate-core-5.4.20.Final.jar
ngrinder-agent/lib/jboss-transaction-api_1.2_spec-1.1.1.Final.jar
ngrinder-agent/lib/hibernate-commons-annotations-5.1.0.Final.jar
ngrinder-agent/lib/jboss-logging-3.4.1.Final.jar
ngrinder-agent/lib/commons-io-2.6.jar
ngrinder-agent/lib/asm-3.3.1.jar
ngrinder-agent/lib/jackson-core-2.11.2.jar
ngrinder-agent/lib/java-semver-0.9.0.jar
ngrinder-agent/lib/javassist-3.24.0-GA.jar
ngrinder-agent/lib/groovy-datetime-3.0.5.jar
ngrinder-agent/lib/groovy-templates-3.0.5.jar
ngrinder-agent/lib/groovy-json-3.0.5.jar
ngrinder-agent/lib/groovy-sql-3.0.5.jar
ngrinder-agent/lib/groovy-xml-3.0.5.jar
ngrinder-agent/lib/groovy-3.0.5.jar
ngrinder-agent/lib/xz-1.0.jar
ngrinder-agent/lib/logback-core-1.2.3.jar
ngrinder-agent/lib/javax.persistence-api-2.2.jar
ngrinder-agent/lib/byte-buddy-1.10.14.jar
ngrinder-agent/lib/antlr-2.7.7.jar
ngrinder-agent/lib/jandex-2.1.3.Final.jar
ngrinder-agent/lib/classmate-1.5.1.jar
ngrinder-agent/lib/jaxb-api-2.3.1.jar
ngrinder-agent/lib/javax.activation-api-1.2.0.jar
ngrinder-agent/lib/dom4j-2.1.3.jar
ngrinder-agent/lib/jaxb-runtime-2.3.3.jar
ngrinder-agent/lib/commons-lang-2.6.jar
ngrinder-agent/lib/json-20090211.jar
ngrinder-agent/lib/hamcrest-all-1.1.jar
ngrinder-agent/lib/junit-dep-4.8.2.jar
ngrinder-agent/lib/txw2-2.3.3.jar
ngrinder-agent/lib/istack-commons-runtime-3.0.11.jar
ngrinder-agent/lib/hamcrest-core-2.2.jar
ngrinder-agent/lib/grinder-dcr-agent-3.9.1.jar
ngrinder-agent/lib/grinder-httpclient-3.9.1.jar
ngrinder-agent/lib/picocontainer-2.13.6.jar
ngrinder-agent/__agent.conf
$
__agent.conf 파일을 업데이트 합니다.
$ nano ./ngrinder-agent/__agent.conf
위의 화면 캡처에서 붉은색 상자로 표시한 agent.controller_host 값을 Controller가 설치된 주소로 변경하고 저장합니다.
$ cd ngrinder-agent/
$ ls
__agent.conf lib run_agent.bat run_agent.sh run_agent_bg.sh run_agent_internal.bat run_agent_internal.sh stop_agent.bat stop_agent.sh
$ ./run_agent.sh
2020-09-24 08:03:47,186 INFO agent config: NGRINDER_AGENT_HOME : /home/ubuntu/.ngrinder_agent
2020-09-24 08:03:47,194 INFO agent config: Overwrite the existing agent.conf with __agent.conf
2020-09-24 08:03:48,176 INFO starter: ***************************************************
2020-09-24 08:03:48,176 INFO starter: Start nGrinder Agent ...
2020-09-24 08:03:48,176 INFO starter: ***************************************************
2020-09-24 08:03:48,180 INFO starter: JVM server mode is disabled.
2020-09-24 08:03:48,194 INFO starter: connecting to controller 172.31.40.101:16001
2020-09-24 08:03:48,228 INFO agent controller daemon: The agent controller daemon is started.
2020-09-24 08:03:48,312 INFO agent controller: Connected to agent controller server at /172.31.40.101:16001
2020-09-24 08:03:48,315 INFO agent controller: Waiting for agent controller server signal
Controller의 web admin 페이지에서 다음과 같이 확인한다.
admin > Agent Management 선택
새로 생성하고 실행한 Agent가 목록에 있는지 확인
필요한 Agent 숫자 만큼 반복해서 Agent 생성하고 실행합니다.
Controller의 web admin 페이지에서 정상적으로 연결되었는지를 확인합니다.
이 글은 설치에 관련해서만 정리한 문서입니다. 실제 성능 테스트를 위해서는 이제 테스트를 위한 Script작성과 실제 수행을 하면서 테스트할 대상에 맞게 시나리오를 정하고 수행하고 결과를 정리해나가는 일이 필요합니다.
추후에 기회가 있으면 테스트를 위한 groovy script작성과 실제 테스트 수행에 관련해서 정리하도록 하겠습니다.
nGrinder 관리자의 개인 블로그: https://junoyoon.tistory.com/
nGrinder github 홈페이지 : http://naver.github.io/ngrinder/