

# Amazon EKS 및 Kubernetes에서 Java/JMX 샘플 워크로드 설정
<a name="ContainerInsights-Prometheus-Sample-Workloads-javajmx"></a>

JMX Exporter는 JMX mBeans를 스크레이프하여 노출할 수 있는 공식 Prometheus 익스포터입니다. 자세한 내용은 [prometheus/jmx\_exporter](https://github.com/prometheus/jmx_exporter)를 참조하세요.

Container Insights는 JMX Exporter를 사용하여 Java Virtual Machine(JVM), Java 및 Tomcat(Catalina)에서 사전 정의된 Prometheus 지표를 수집할 수 있습니다.

## 기본 Prometheus 스크레이프 구성
<a name="ContainerInsights-Prometheus-Sample-Workloads-javajmx-default"></a>

기본적으로 Prometheus가 지원되는 CloudWatch 에이전트는 Amazon EKS 또는 Kubernetes 클러스터에 있는 각 포드의 `http://CLUSTER_IP:9404/metrics`에서 Java/JMX Prometheus 지표를 스크레이프합니다. 이는 Prometheus `kubernetes_sd_config`의 `role: pod` 검색에 의해 수행됩니다. 9404는 Prometheus에서 JMX Exporter에 할당한 기본 포트입니다. `role: pod` 검색에 대한 자세한 내용은 [포드](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#pod)를 참조하세요. 지표를 다른 포트 또는 metrics\_path에 노출하도록 JMX Exporter를 구성할 수 있습니다. 포트 또는 경로를 변경하는 경우 CloudWatch 에이전트 config 맵의 기본 jmx scrape\_config를 업데이트하세요. 다음 명령을 실행하여 현재 CloudWatch 에이전트 Prometheus 구성을 가져옵니다.

```
kubectl describe cm prometheus-config -n amazon-cloudwatch
```

변경할 필드는 다음 예제에서 강조 표시된 대로 `/metrics` 및 `regex: '.*:9404$'` 필드입니다.

```
job_name: 'kubernetes-jmx-pod'
sample_limit: 10000
metrics_path: {{/metrics}}
kubernetes_sd_configs:
- role: pod
relabel_configs:
- source_labels: [__address__]
  action: keep
  {{regex: '.*:9404$'}}
- action: replace
  regex: (.+)
  source_labels:
```

## 기타 Prometheus 스크레이프 구성
<a name="ContainerInsights-Prometheus-Sample-Workloads-javajmx-other"></a>

Kubernetes Service의 Java/JMX Prometheus Exporter가 있는 포드 세트에서 실행 중인 애플리케이션을 노출하는 경우 Prometheus `kubernetes_sd_config`의 `role: service` 검색 또는 `role: endpoint` 검색을 사용하도록 전환할 수도 있습니다. 이러한 검색 방법에 대한 자세한 내용은 [서비스](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#service), [엔드포인트](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#endpoints), [<kubernetes\_sd\_config>](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#kubernetes_sd_config)를 참조하세요.

이러한 두 가지 서비스 검색 모드는 더 많은 메타 레이블을 제공하므로 CloudWatch 지표 측정기준을 구축하는 데 유용할 수 있습니다. 예를 들어 `__meta_kubernetes_service_name`의 레이블을 `Service`로 다시 지정하고 이를 지표의 측정기준에 포함할 수 있습니다. CloudWatch 지표 및 해당 측정기준의 사용자 지정에 대한 자세한 내용은 [Prometheus에 대한 CloudWatch 에이전트 구성](ContainerInsights-Prometheus-Setup-configure-ECS.md#ContainerInsights-Prometheus-Setup-cw-agent-config) 단원을 참조하세요.

## JMX Exporter가 포함된 Docker 이미지
<a name="ContainerInsights-Prometheus-Sample-Workloads-javajmx-docker"></a>

다음으로, Docker 이미지를 구축합니다. 다음 단원에서는 두 가지 Dockerfile 예를 제공합니다.

이미지를 구축한 경우 Amazon EKS 또는 Kubernetes에 로드한 후 다음 명령을 실행하여 Prometheus 지표가 포트 9404에서 `JMX_EXPORTER`에 의해 노출되는지 확인합니다. {{$JAR\_SAMPLE\_TRAFFIC\_POD}}를 실행 중인 포드 이름으로 바꾸고 {{$JAR\_SAMPLE\_TRAFFIC\_NAMESPACE}}를 애플리케이션 네임스페이스로 바꿉니다.

Fargate 시작 유형의 클러스터에서 JMX Exporter를 실행할 경우 이 절차의 단계를 수행하기 전에 먼저, Fargate 프로파일도 설정해야 합니다. 프로파일을 설정하려면 다음 명령을 입력합니다. {{MyCluster}}를 클러스터 이름으로 바꿉니다.

```
eksctl create fargateprofile --cluster {{MyCluster}} \
--namespace $JAR_SAMPLE_TRAFFIC_NAMESPACE\
 --name $JAR_SAMPLE_TRAFFIC_NAMESPACE
```

```
kubectl exec $JAR_SAMPLE_TRAFFIC_POD -n $JARCAT_SAMPLE_TRAFFIC_NAMESPACE -- curl http://localhost:9404
```

## 예: Prometheus 지표가 있는 Apache Tomcat Docker 이미지
<a name="ContainerInsights-Prometheus-Sample-Workloads-javajmx-tomcat"></a>

Apache Tomcat 서버는 기본적으로 JMX mBeans를 노출합니다. JMX Exporter를 Tomcat과 통합하여 JMX mBeans를 Prometheus 지표로 노출할 수 있습니다. 다음 Dockerfile 예는 테스트 이미지를 구축하는 단계를 보여 줍니다.

```
# From Tomcat 9.0 JDK8 OpenJDK 
FROM tomcat:9.0-jdk8-openjdk 

RUN mkdir -p /opt/jmx_exporter

COPY ./jmx_prometheus_javaagent-0.12.0.jar /opt/jmx_exporter
COPY ./config.yaml /opt/jmx_exporter
COPY ./setenv.sh /usr/local/tomcat/bin 
COPY {{your web application.war}} /usr/local/tomcat/webapps/

RUN chmod  o+x /usr/local/tomcat/bin/setenv.sh

ENTRYPOINT ["catalina.sh", "run"]
```

다음 목록은 이 Dockerfile에 있는 4개의 `COPY` 줄을 설명합니다.
+ [https://github.com/prometheus/jmx\_exporter](https://github.com/prometheus/jmx_exporter)에서 최신 JMX Exporter jar 파일을 다운로드합니다.
+ `config.yaml`은 JMX Exporter 구성 파일입니다. 자세한 내용은 [https://github.com/prometheus/jmx\_exporter\#Configuration](https://github.com/prometheus/jmx_exporter#Configuration )을 참조하세요.

  다음은 Java 및 Tomcat의 샘플 구성 파일입니다.

  ```
  lowercaseOutputName: true
  lowercaseOutputLabelNames: true
  
  rules:
  - pattern: 'java.lang<type=OperatingSystem><>(FreePhysicalMemorySize|TotalPhysicalMemorySize|FreeSwapSpaceSize|TotalSwapSpaceSize|SystemCpuLoad|ProcessCpuLoad|OpenFileDescriptorCount|AvailableProcessors)'
    name: java_lang_OperatingSystem_$1
    type: GAUGE
  
  - pattern: 'java.lang<type=Threading><>(TotalStartedThreadCount|ThreadCount)'
    name: java_lang_threading_$1
    type: GAUGE
  
  - pattern: 'Catalina<type=GlobalRequestProcessor, name=\"(\w+-\w+)-(\d+)\"><>(\w+)'
    name: catalina_globalrequestprocessor_$3_total
    labels:
      port: "$2"
      protocol: "$1"
    help: Catalina global $3
    type: COUNTER
  
  - pattern: 'Catalina<j2eeType=Servlet, WebModule=//([-a-zA-Z0-9+&@#/%?=~_|!:.,;]*[-a-zA-Z0-9+&@#/%=~_|]), name=([-a-zA-Z0-9+/$%~_-|!.]*), J2EEApplication=none, J2EEServer=none><>(requestCount|maxTime|processingTime|errorCount)'
    name: catalina_servlet_$3_total
    labels:
      module: "$1"
      servlet: "$2"
    help: Catalina servlet $3 total
    type: COUNTER
  
  - pattern: 'Catalina<type=ThreadPool, name="(\w+-\w+)-(\d+)"><>(currentThreadCount|currentThreadsBusy|keepAliveCount|pollerThreadCount|connectionCount)'
    name: catalina_threadpool_$3
    labels:
      port: "$2"
      protocol: "$1"
    help: Catalina threadpool $3
    type: GAUGE
  
  - pattern: 'Catalina<type=Manager, host=([-a-zA-Z0-9+&@#/%?=~_|!:.,;]*[-a-zA-Z0-9+&@#/%=~_|]), context=([-a-zA-Z0-9+/$%~_-|!.]*)><>(processingTime|sessionCounter|rejectedSessions|expiredSessions)'
    name: catalina_session_$3_total
    labels:
      context: "$2"
      host: "$1"
    help: Catalina session $3 total
    type: COUNTER
  
  - pattern: ".*"
  ```
+ `setenv.sh`는 Tomcat과 함께 JMX Exporter를 시작하고 localhost의 포트 9404에 Prometheus 지표를 노출하는 Tomcat 시작 스크립트입니다. 또한 JMX Exporter에 `config.yaml` 파일 경로를 제공합니다.

  ```
  $ cat setenv.sh 
  export JAVA_OPTS="-javaagent:/opt/jmx_exporter/jmx_prometheus_javaagent-0.12.0.jar=9404:/opt/jmx_exporter/config.yaml $JAVA_OPTS"
  ```
+ web application.war는 Tomcat에 의해 로드될 웹 애플리케이션 `war` 파일입니다.

이 구성으로 Docker 이미지를 구축하고 이미지 리포지토리에 업로드합니다.

## 예: Prometheus 지표가 있는 Java Jar 애플리케이션 Docker 이미지
<a name="ContainerInsights-Prometheus-Sample-Workloads-javajmx-jar"></a>

다음 Dockerfile 예는 테스트 이미지를 구축하는 단계를 보여 줍니다.

```
# Alpine Linux with OpenJDK JRE
FROM openjdk:8-jre-alpine

RUN mkdir -p /opt/jmx_exporter

COPY ./jmx_prometheus_javaagent-0.12.0.jar /opt/jmx_exporter
COPY ./SampleJavaApplication-1.0-SNAPSHOT.jar /opt/jmx_exporter
COPY ./start_exporter_example.sh /opt/jmx_exporter
COPY ./config.yaml /opt/jmx_exporter

RUN chmod -R o+x /opt/jmx_exporter
RUN apk add curl

ENTRYPOINT exec /opt/jmx_exporter/start_exporter_example.sh
```

다음 목록은 이 Dockerfile에 있는 4개의 `COPY` 줄을 설명합니다.
+ [https://github.com/prometheus/jmx\_exporter](https://github.com/prometheus/jmx_exporter)에서 최신 JMX Exporter jar 파일을 다운로드합니다.
+ `config.yaml`은 JMX Exporter 구성 파일입니다. 자세한 내용은 [https://github.com/prometheus/jmx\_exporter\#Configuration](https://github.com/prometheus/jmx_exporter#Configuration )을 참조하세요.

  다음은 Java 및 Tomcat의 샘플 구성 파일입니다.

  ```
  lowercaseOutputName: true
  lowercaseOutputLabelNames: true
  
  rules:
  - pattern: 'java.lang<type=OperatingSystem><>(FreePhysicalMemorySize|TotalPhysicalMemorySize|FreeSwapSpaceSize|TotalSwapSpaceSize|SystemCpuLoad|ProcessCpuLoad|OpenFileDescriptorCount|AvailableProcessors)'
    name: java_lang_OperatingSystem_$1
    type: GAUGE
  
  - pattern: 'java.lang<type=Threading><>(TotalStartedThreadCount|ThreadCount)'
    name: java_lang_threading_$1
    type: GAUGE
  
  - pattern: 'Catalina<type=GlobalRequestProcessor, name=\"(\w+-\w+)-(\d+)\"><>(\w+)'
    name: catalina_globalrequestprocessor_$3_total
    labels:
      port: "$2"
      protocol: "$1"
    help: Catalina global $3
    type: COUNTER
  
  - pattern: 'Catalina<j2eeType=Servlet, WebModule=//([-a-zA-Z0-9+&@#/%?=~_|!:.,;]*[-a-zA-Z0-9+&@#/%=~_|]), name=([-a-zA-Z0-9+/$%~_-|!.]*), J2EEApplication=none, J2EEServer=none><>(requestCount|maxTime|processingTime|errorCount)'
    name: catalina_servlet_$3_total
    labels:
      module: "$1"
      servlet: "$2"
    help: Catalina servlet $3 total
    type: COUNTER
  
  - pattern: 'Catalina<type=ThreadPool, name="(\w+-\w+)-(\d+)"><>(currentThreadCount|currentThreadsBusy|keepAliveCount|pollerThreadCount|connectionCount)'
    name: catalina_threadpool_$3
    labels:
      port: "$2"
      protocol: "$1"
    help: Catalina threadpool $3
    type: GAUGE
  
  - pattern: 'Catalina<type=Manager, host=([-a-zA-Z0-9+&@#/%?=~_|!:.,;]*[-a-zA-Z0-9+&@#/%=~_|]), context=([-a-zA-Z0-9+/$%~_-|!.]*)><>(processingTime|sessionCounter|rejectedSessions|expiredSessions)'
    name: catalina_session_$3_total
    labels:
      context: "$2"
      host: "$1"
    help: Catalina session $3 total
    type: COUNTER
  
  - pattern: ".*"
  ```
+ `start_exporter_example.sh`는 Prometheus 지표를 내보낸 JAR 애플리케이션을 시작하는 스크립트입니다. 또한 JMX Exporter에 `config.yaml` 파일 경로를 제공합니다.

  ```
  $ cat start_exporter_example.sh 
  java -javaagent:/opt/jmx_exporter/jmx_prometheus_javaagent-0.12.0.jar=9404:/opt/jmx_exporter/config.yaml -cp  /opt/jmx_exporter/SampleJavaApplication-1.0-SNAPSHOT.jar com.gubupt.sample.app.App
  ```
+ SampleJavaApplication-1.0-SNAPSHOT.jar은 샘플 Java 애플리케이션 jar 파일입니다. 이 파일을 모니터링할 Java 애플리케이션으로 바꿉니다.

이 구성으로 Docker 이미지를 구축하고 이미지 리포지토리에 업로드합니다.