본문 바로가기

Programming/Infra

[Kubernetes] JVM Heap 메모리 모니터링 (With. Visual VM, jstat)

JVM 힙 메모리를 모니터링 해야할 일이 생겼다.

로컬이나 물리장비에 떠있는 서버를 Visual VM 연동을 통해 모니터링 해본 경험은 있지만, Kubernets 환경에서의 Visual VM 연동은 낯설었다.

 

# Visual VM ?

- https://visualvm.github.io/

 

VisualVM: Home

News: July 19, 2022: VisualVM 2.1.4 Released This release introduces several heapviewer improvements. From now, VisualVM is available as an optional GraalVM component. See the Release Notes for all changes. The tool can be downloaded from the Download page

visualvm.github.io

JVM으로 구동되는 Application의 Thread 및 GC 사용량을 모니터링할 수 있는 JDK 도구이다.

개발한 모듈의 성능을 시각적으로 확인할 수 있다.

 

Oracle JDK에는 기본적으로 내장되어있지만, Open JDK에는 내장되어 있지 않다.

로컬에서는 Intellij 플러그인이 지원되므로, 쉽게 연동이 가능하다.

 

Kubernets 환경에서 Visual VM을 연동하는 과정을 정리해본다.

 

## Visual VM 다운로드

위 사이트를 통해 로컬에 Visual VM을 다운받는다.

 

## 원격 서버 셋팅

Visual VM 연동을 위해 다음과 같은 JVM 옵션을 추가한다.

java \
   -Dcom.sun.management.jmxremote=true \
   -Dcom.sun.management.jmxremote.local.only=false \
   -Dcom.sun.management.jmxremote.port=[JMX PORT 설정] \
   -Dcom.sun.management.jmxremote.ssl=false \
   -Dcom.sun.management.jmxremote.authenticate=false \
   -Djava.rmi.server.hostname=[붙을 서버 IP] \
   -Dcom.sun.management.jmxremote.rmi.port=[JMX PORT 설정]

 

다만, 여기서 Kubernets 환경이기 때문에 -Djava.rmi.server.hostname 설정이 애매하다.

왜냐하면 Pod IP가 계속 유동적으로 변하기 때문이다.

 

이를 해결하기 위해 2가지 방법이 존재한다.

첫번째 방법은 Port forward를 활용하는 방법이다. 이 방법은 직접 해보진 않았다.

(참고: https://stackoverflow.com/questions/35184558/multiple-app-nodes-how-to-expose-jmx-in-kubernetes)

 

두번째 방법은 해당 옵션을 아예 빼버리는 것이다.

IP 설정을 따로 하지 않으면, 범위적으로 설정되는듯 하다. 이 방법은 편리할 수 있지만 보안 상 위험하다.

 

또한, Kubernets 환경이므로 Dockerfile 작성 시 위에서 설정한 JMX Port를 열어줘야한다.

...
EXPOSE [JMX PORT]
...

 

## Visual VM 연동

로컬의 Visual VM에서 원격 서버로 접근해본다.

Add Remote Host에서 원격서버 IP 주소를 입력한다.

 

그 이후, 등록된 원격 서버 우클릭 > Add JMX Connection 클릭

위와 같이 설정한 JMX Port로 연결하면 연동이 완료된다.

 

# jstat

사실 그런데 Visual VM으로 연동해서 봐도 시각적으로 보기에는 편할 뿐, 확인할 수 있는 정보는 jstat 명령어를 직접 사용하는 것과 별반 다르지 않은듯 했다.

 

그래서 Visual VM의 연동이 귀찮다면 그냥 직접 Pod에 접근해서 아래와 같이 jstat 명령어를 통해 JVM의 Heap Memory 상태를 확인하는 방법도 있다.

jstat -gcutil -h3 [PID] 3000

- `gcutil` : GC 통계요약 옵션 (그 외 gc, gcnew, gcold 등이 존재)

- `h3` : 3줄마다 헤드를 출력

- `3000` : 3초마다 출력