nGrinder 환경을 AWS상에서 구축하기

이동한·2020년 9월 24일
4

HOWTO

목록 보기
1/1

이 문서의 목적은 AWS상에서 nGrinder를 빠르고 쉽게 설치하는 것을 안내하기 위한 문서입니다. 제 시행착오를 반영하여서 최대한 자세하게 정리 작성하려고 노력했습니다. 이 문서를 보시고 따라 해보시다가 문제가 생기시면 댓글로 남겨주시면 확인하는 대로 답변 드리도록 하겠습니다.

Prerequisites

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 필요

nGrinder Setup Tips

먼저 Tips 항목을 적는 이유는 제가 해당 업무를 진행하면서 조금 더 효율적이고 효과적으로 업무를 하기 위해서 고민했던 내용을 공유하기 위함입니다.

이 내용은 이해가 안되시는 부분이 있으면 일단 넘어가시고 설치를 다 해보고 난 다음에 다시 참고하시면 됩니다.
아래 내용을 다 읽어보시고 이 내용을 읽어보시면 더 이해가 빠를 것입니다.

AWS에 nGrinder를 설치하고 사용할 때의 장점은 다음과 같습니다.

  • 빠르고 간편하게 필요한 성능의 nGrinder를 구성할 수 있습니다. AMI를 적절하게 이용하면 바로 필요한 성능의 EC2 인스턴스를 생성하고 환경설정 파일만 수정하면 바로 테스트가 가능합니다.
  • 구성된 EC2를 언제든지 중지시켜서 비용을 절감하고 필요할 때마다 시작하여서 빠르게 부하 테스트를 진행할수 있습니다.

보안그룹(Security Group)부터 생성

많은 분들이 알고 계시겠지만 AWS상에서 시스템을 구축하실 때에는 해당 시스템에 적용될 보안그룹(Security Group)부터 생성하시는 것을 강력하게 권장드립니다.
EC2 인스턴스를 생성할 때에 해당 보안그룹을 적용하고 보안그룹을 적용할 보안 규칙에 따라서 수정하는 것이 시스템을 관리하고 유지하는 가장 좋은 방법입니다.

보안그룹을 어떻게 설정해야 할지 모르시겠으면 일단 최소한의 Inbound Rule을 설정하고 사용하면서 필요한 규칙을 추가하시면 됩니다.

네트워크 보안은 최소한의 허용을 해주는 것이 기본입니다. (아래에 예시를 드렸습니다.)

  • 인바운드 규칙 / SSH / TCP 22 : SSH 접속을 위해서는 최소한 필요합니다.
  • 인바운드 규칙 / HTTP / TCP 80 : 대부분의 서비스가 웹 접속을 허용하는 경우가 많아서 HTTP를 허용하는 경우가 많습니다.

nGrinder Controller IP 고정하기

흐름부터 정리하면 다음과 같습니다. 자세한 내용은 아래의 설치 부분을 참고하셔야 합니다.

  1. 보안그룹을 먼저 생성합니다. 해당 보안그룹은 nGrinder를 사용할 때 필요한 포트들에 대해서 Inbound 규칙을 추가해야 합니다. 자세한 내용은 아래에 정리해 놓았습니다.
  2. 네트워크 인터페이스를 하나 생성합니다. 네트워크 인터페이스 생성할 때 1번에서 생성한 보안 그룹을 설정합니다. - 서브넷 선택을 하고 해당 서브넷을 기억합니다.


  3. Controller가 설치될 EC2를 생성할 때 미리 생성해놓은 네트워크 인터페이스를 선택합니다. EC2를 생성할때에 단계3에서 "네트워크 인터페이스"항목에서 생성해놓은 네트워크 인터페이스를 선택하시면 됩니다.(아래 화면 참고) - 서브넷항목을 선택해야지 "네트워크 인터페이스"를 설정할 수가 있습니다. "네트워크 인터페이스"를 생성할때 선택한 서브넷항목과 동일한 항목을 먼저 선택하십시오.

위와 같이 하는 이유는 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로 통신을 할수 있습니다. .

Docker 설치

먼저 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가 있는지 확인. 
$ 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
$

AMI 만들기

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

SVN 설치

$ sudo apt-get install subversion
Reading package lists... Done
Building dependency tree
Reading state information... Done
…(중간 생략)

$

nGrinder

nGrinder는 Controller, Agent, Monitor로 구성되어 있습니다.

Controller

  • 성능테스트를 위한 웹 인터페이스를 제공합니다.
  • 테스트 프로세스를 조정합니다.
  • 테스트 통계를 수집하고 표시하여 줍니다. 테스트 결과를 저장하고 보여줍니다.
  • 사용자가 테스트를 위한 Script를 작성하고 수정할 수가 있습니다.

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 설치 및 실행

nGrinder 네트워크 통신 포트 정보를 정리하면 다음과 같습니다.

에이전트:모든 포트 ==> 컨트롤러 : 16001
에이전트:모든 포트 ==> 컨트롤러 : 12000 ~ 12000 + 동시 테스트 허용할 테스트 개수
컨트롤러:모든 포트 ==> 모니터:13243
컨트롤러 ==> 일반 유저 : 웹 서버 설정 방식에 따르나, 디폴트는 8080 입니다.

docker를 이용하여서 ngrinder를 실행하는 경우 웹서버 기본 포트는 8080에서 80으로 매핑하여서 사용하는 경우가 많습니다. 제 글을 따라서 하는 경우에는 80 포트를 오픈하고 8080를 따로 오픈할 필요는 없습니다.

위의 정보를 기반으로 보안그룹(Security Group)을 설정하시고 해당 보안그룹을 nGrinder가 설치되는 EC2들에 적용하셔야 합니다.

AWS상에서 nGrinder를 설치하고 사용할 때 사용하는 보안그룹(Security Group) 설정 정리

  • 기본 Security Group의 Inbound rule은 SSH접속을 위한 TCP 22번 포트만 오픈되어 있음.
  • 기본 Security Group의 Outbound rule은 모든 트래픽이 오픈되어 있음.
  • (추가 설정) Inbound Rule에 Controller 웹 접속을 위한 TCP 80 포트 오픈 추가
  • (추가 설정) Inbound Rule에 위에 정리된 포트들을 모두 오픈한다. 보안을 높이기 위해서는 Source 항목을 이용해서 제한을 걸어주는 것이 필요하다. 성능 테스트를 수행할 때 외에는 EC2 인스턴스를 모두 STOP 한다면 꼭 필요한 것은 아니다.

보안과 관련해서는 추가적인 제한이 필요하지만 네트워크 보안 지식이 필요하기 때문에 해당 내용은 이 문서에서는 다루지 않겠습니다. 테스트가 가능한 환경 구축을 위한 가이드 문서가 이 문서의 목적이기 때문입니다.

nGrinder Controller 설치

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 실행

# 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를 실행하면 편리합니다.

nGrinder Agent 설치 및 실행

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/

profile
Software Quality Assurance Engineer

0개의 댓글