DevOps

EKS 클러스터에서 nGrinder 사용하기

Zayson 2025. 1. 12. 10:24

개요


쿠버네티스(EKS Cluster) 환경에 nGrinder를 설치하고 API 서버에 부하를 넣어보는 방법에 대해서 알아본다.

 

nGrinder


nGrinder는 오픈 소스 기반의 분산 성능 테스트 도구이다.

nGrinderControllerAgent로 구성된다.

  • Controller: 테스트 계획 설정, Agent 관리, 모니터링, 테스트 결과 및 분석과 같이 관리자의 역할을 담당하는 컴포넌트
  • Agent: 테스트 스크립트 실행, 분산 처리, 실시간 데이터 전송을 담당하는 실제 명령을 수행하는 컴포넌트

따라서, nGrinder를 이용해 API 서버에 부하를 넣기 위해선 Controller, Agent를 모두 설치해야한다.

 

nGrinder Controller


nGrinder Controller를 배포하기 위한 Deployment를 작성해보자.

# ngrinder-controller-deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ngrinder-controller
  namespace: ngrinder
spec:
  replicas: 1
  selector:
    matchLabels:
      app: ngrinder-controller
  template:
    metadata:
      labels:
        app: ngrinder-controller
    spec:
      containers:
        - name: ngrinder-controller
          image: ngrinder/controller:3.5.9-p1
          ports:
            # Web Port
            - containerPort: 8080
            # Agent와 Controller간 통신을 위해 사용하는 포트
            - containerPort: 16001
            # Agent 내부 프로세스가 사용하는 포트 
            # 예제에선 2개의 Agent만 사용하지만 아래와 같이 더많이 지정가능
            - containerPort: 12000
            - containerPort: 12001
          resources:
            requests:
              cpu: "1000m"
              memory: "1Gi"
            limits:
              cpu: "1000m"
              memory: "1Gi"

기본적으로 컨테이너에서 사용하는 포트는 모두 방화벽이 뚫려있어야 한다.
만약 커넥션 관련한 문제가 생기면 포트가 막혀있을 가능성이 있다. 이 경우 Worker Node의 보안 그룹(Security Group)을 확인해보자.

  • 8080: Controller의 Web에 접근하기 위해 사용하는 포트 (다른 포트 사용해도 상관없음)
  • 16001: AgentController간 통신을 위해 사용
  • 12000 ~ (12000+): Agent 내부 프로세스가 사용하는 포트

 

Pod 배포만으로는 클러스터 내 다른 서비스와 통신을 할 수 없다.

따라서 Pod간 통신을 위해 Service를 추가해줘야한다.

# ngrinder-controller-svc.yml
apiVersion: v1
kind: Service
metadata:
  name: ngrinder-controller-svc
  namespace: ngrinder
spec:
  type: ClusterIP # 클러스터 내에서 통신하기 때문에 ClusterIP 사용
  ports:
    - port: 8080
      targetPort: 8080
      name: http
    - port: 16001
      targetPort: 16001
      name: agent-communication
    - port: 12000
      targetPort: 12000
      name: agent-1
    - port: 12001
      targetPort: 12001
      name: agent-2
  selector:
    app: ngrinder-controller

 

이번 포스팅에서는 API 서버와 nGrinder Controller, Agent가 동일한 EKS 클러스터에 위치한다고 가정했기 때문에 Service 타입으로 ClusterIP를 사용했다.

 

만약, 서비스가 EKS 클러스터 외부에 있다면 통신을 위해 Service 타입을 LoadBalancer로 설정해야 한다.

그리고 필요에 따라 Ingress까지 추가해야한다.

 

DeploymentService를 배포하자.

kubectl apply -f ngrinder-controller-deployment.yml -n ngrinder
kubectl apply -f ngrinder-controller-svc.yml -n ngrinder

 

정상적으로 Pod이 배포되었다면 포트포워딩을 통해서 localhost에서 붙어보자.

kubectl port-forward pod/ngrinder-controller 8080:8080 -n ngrinder

 

localhost:8080으로 접속하면 다음과 같은 화면이 나온다.

 

초기 아이디/패스워드는 admin/admin 이다.

 

nGrinder Agent


이번에는 실제 테스트 스크립트를 실행하는 AgentDeployment를 작성해보자.

# ngrinder-agent
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ngrinder-agent
  namespace: ngrinder
spec:
  replicas: 2 # 2개의 Agent 사용
  selector:
    matchLabels:
      app: ngrinder-agent
  template:
    metadata:
      labels:
        app: ngrinder-agent
    spec:
      containers:
        - name: agent
          image: ngrinder/agent:3.5.9-p1
          # args에 nGrinder Controller svc 주소를 입
          args: ["ngrinder-controller-svc.ngrinder.svc.cluster.local:8080"]

 

Agent에서 nGrinder Controller에 연결하기 위한 주소를 입력한다.

kubectl apply -f ngrinder-agent.yml -n ngrinder

 

nGrinder 콘솔 우측 상단의 admin → Agent Management로 들어가보자.

방금 배포한 2대의 Agent가 활성화된 것을 확인할 수 있다.

 

테스트 


상단의 Script → Create → Create a script를 통해서 테스트 스크립트를 생성한다.

 

스크립트를 생성하면 우측의 Add를 통해서 타겟 도메인 및 IP 주소를 설정해 로컬 DNS를 등록해준다.

만약 타겟 서비스가 ALB 주소인 경우 LoadBalancer의 주소와 IP 주소를 설정한다.

필자는 해당 부분 설정을 누락해 계속해서 타겟 호스트를 룩업하지 못해 UnknonwHostException이 발생했다.
(아마, Pod 내부에서 nslookup, curl이 잘 동작한 것으로 보아 EKS에서 사용하는 DNS와 nGrinder에서 사용하는 DNS가 달라서 발생한 이슈로 판단됨. )

2025-01-07 06:16:04,132 ERROR java.util.concurrent.ExecutionException: java.net.UnknownHostException: http://test-service.com
java.net.UnknownHostException: http://test-service.com
    at org.apache.hc.core5.reactor.SingleCoreIOReactor.validateAddress(SingleCoreIOReactor.java:285)
    at org.apache.hc.core5.reactor.SingleCoreIOReactor.processConnectionRequest(SingleCoreIOReactor.java:313)
    at org.apache.hc.core5.reactor.SingleCoreIOReactor.processPendingConnectionRequests(SingleCoreIOReactor.java:302)
    at org.apache.hc.core5.reactor.SingleCoreIOReactor.doExecute(SingleCoreIOReactor.java:139)
    at org.apache.hc.core5.reactor.AbstractSingleCoreIOReactor.execute(AbstractSingleCoreIOReactor.java:85)
    at org.apache.hc.core5.reactor.IOReactorWorker.run(IOReactorWorker.java:44)
 

How to change dns

enterprise level performance testing solution. Contribute to naver/ngrinder development by creating an account on GitHub.

github.com

 

 

DNS 등록 이후 Validate를 통해서 실제로 타겟 호스트까지 요청이 잘 전달되는지 확인해본다.

마지막으로 실제 부하를 넣기 위한 테스트를 생성한다. Performance Test → Create Test로 들어가면 테스트를 생성할 수 있다.

 

위의 테스트 스크립트와 동일하게 Target Host에 타겟 도메인 주소 및 IP를 등록해준다.

그리고 테스트를 시작하면 성공적으로 타겟 호스트 부하가 들어간다.

Reference

 

Installation Guide

enterprise level performance testing solution. Contribute to naver/ngrinder development by creating an account on GitHub.

github.com

 

반응형