엔지니어링

Kubernetes 통합 가시성 자습서: Elastic APM을 통한 애플리케이션 성능 모니터링

이 포스팅은 Kubernetes에서 실행되는 애플리케이션의 모든 측면을 모니터링할 수 있는 방법을 살펴보는 Kubernetes 통합 가시성 자습서 시리즈 중 세 번째로, 다음이 포함됩니다.

Elastic Observability를 사용하여 Elastic APM과 함께 애플리케이션 성능 모니터링(APM)을 수행하는 것에 대해 얘기해 보겠습니다.

시작하기 전에: 다음 자습서는 Kubernetes 환경 설정을 사용하는 것을 전제로 하고 있습니다. 나머지 활동을 실행할 수 있도록 데모 어플리케이션으로 단일 노드 Minikube 환경을 설정하는 과정을 단계별로 안내하는 보충 블로그를 만들었습니다.

애플리케이션 성능 모니터링

APM은 주요 사용자 서비스 수준 지표(SLI): 요청/응답 대기 시간 및 사용자 오류)의 자동 측정에 중점을 두고 있습니다. 이를 효과적으로 모니터링함으로써 성능 저하나 오류 증가와 같은 문제를 야기는 구성 요소(코드 블록까지)를 신속하게 찾을 수 있습니다. APM은 문제의 근본 원인을 정확히 파악할 수 있는 훌륭한 1차 단계 분류 도구를 제공하여 평균 응답 시간(MTTR)을 단축합니다.

Elastic APM을 사용한 분산 추적

Elastic APM은 분산 추적을 지원하므로 동일한 사용자 요청을 처리하는 데 참여하는 다른 분산 애플리케이션 구성 요소의 엔드 투 엔드 요청/응답 대기 시간을 측정할 수 있습니다. APM 앱은 전체 추적 기간뿐만 아니라 분산 추적에 참여하는 구성 요소 관련 대기 시간의 분석 결과도 표시합니다. Kibana에 있는 APM 앱으로 가서 추적과 트랜잭션을 확인해 봅시다. 참고: 먼저 petclinic 앱을 클릭하여 사용자 트래픽을 생성하세요!

Elastic APM의 분산 추적

로그 및 메트릭을 사용하여 컨텍스트에서 추적

Kubernetes에 애플리케이션을 배포할 때 분산 추적 및 APM은 통합 가시성 퍼즐의 다른 부분인 로그와 메트릭을 캡처하고 상호 참조하는 동시에 문제를 신속하게 추적할 수 있는 이점을 지속적으로 제공합니다. 이러한 각 부분들을 손쉽게 다루는 상태에서, 대기 시간 급증 문제 해결은 APM을 사용하여 조사 범위를 단일 구성 요소로 좁히는 것으로 시작할 수 있으며, Kibana를 떠나지 않고도 CPU 및 메모리 활용 메트릭과 특정 Kubernetes 포드의 오류 로그 항목에 쉽게 연결될 수 있습니다.

이제 Beats의 프로세서와 APM 에이전트가 수집한 메타데이터 덕분에 Kibana의 모든 통합 가시성 데이터는 상호 참조됩니다. APM 추적을 보기 시작하고, 그 추적을 처리하는 작업의 일부였던 포드의 메트릭을 확인하며, 추적이 처리될 당시 실행된 구성 요소가 남긴 로그를 모두 한 곳에서 볼 수 있습니다.

Elastic APM을 사용하면 추적 및 로그 데이터의 상관 관계를 쉽게 파악할 수 있습니다.

APM 추적에서 Kibana의 인프라 메트릭으로 신속하게 전환

Elastic APM 에이전트 배포

APM 에이전트는 모니터링하는 애플리케이션 구성 요소와 함께 배포됩니다. Kubernetes와 함께 애플리케이션 구성 요소는 포드 안에서 실행되는 코드의 일부가 됩니다. 이 자습서에서는 APM 실제 사용자 모니터링(RUM) JavaScript 에이전트와 APM Java 에이전트, 이 두 가지 에이전트를 사용하고 있습니다.

Elastic APM Java 에이전트

다음은 petclinic 포드 배포 설명자 $HOME/k8s-o11y-workshop/petclinic/petclinic.yml에서 APM Java 에이전트의 초기화 부분입니다.

          env:
          - name: ELASTIC_APM_SERVER_URLS
            valueFrom:
              secretKeyRef:
                name: apm-secret
                key: apm-url
          - name: ELASTIC_APM_SECRET_TOKEN
            valueFrom:
              secretKeyRef:
                name: apm-secret
                key: apm-token
          - name: ELASTIC_APM_SERVICE_NAME
            value: spring-petclinic-monolith
          - name: ELASTIC_APM_APPLICATION_PACKAGES
            value: org.springframework.samples

APM 에이전트는 petclinic 애플리케이션 $HOME/k8s-o11y-workshop/docker/petclinic/pom.xml의 pom.xml 파일에 종속성으로 포함됩니다.

<!-- Elastic APM dependencies -->
        <dependency>
            <groupId>co.elastic.apm</groupId>
            <artifactId>apm-agent-attach</artifactId>
            <version>${elastic-apm.version}</version>
        </dependency>
        <dependency>
            <groupId>co.elastic.apm</groupId>
            <artifactId>apm-agent-api</artifactId>
            <version>${elastic-apm.version}</version>
        </dependency>
        <dependency>
            <groupId>co.elastic.apm</groupId>
            <artifactId>elastic-apm-agent</artifactId>
            <version>${elastic-apm.version}</version>
        </dependency>
        <!-- End of Elastic APM dependencies -->

Java 에이전트를 Maven 종속성으로 배포하는 방법. APM 에이전트를 배포하는 방법에는 Java 에이전트를 통한 런타임 첨부와 같은 다른 방법도 있습니다. 자세한 내용은 Elastic APM Java 에이전트 설명서를 참조하세요.

Elastic APM 실제 사용자 모니터링(RUM) 에이전트

RUM 에이전트는 사용자 브라우저 애플리케이션의 일부로 실행되며 브라우저에서 바로 모든 사용자 메트릭을 제공합니다. 이 자습서에서는 정확히 이를 위해 사용될뿐 아니라 분산 추적의 시작점으로도 사용됩니다. 다음은 APM 에이전트가 Javascript 사용자측 코드 $HOME/k8s-o11y-workshop/docker/petclinic/src/main/resources/templates/fragments/layout.html에서 인스턴스화되는 부분입니다.

 <script th:inline="javascript">
...
    var serverUrl = [[${apmServer}]];
    elasticApm.init({
     serviceName: 'petclinic-frontend',
     serverUrl: serverUrl,
     distributedTracingOrigins: [],
     pageLoadTransactionName: pageName,
     active: true,
     pageLoadTraceId: [[${transaction.traceId}]],
     pageLoadSpanId: [[${transaction.ensureParentId()}]],
     pageLoadSampled: [[${transaction.sampled}]],
     distributedTracing: true,
    })
...
 </script>

Petclinic은 서버측 렌더링 애플리케이션으로, Thymeleaf는 Spring Boot와 함께 사용되는 템플릿 렌더링 프레임워크로서, 컨트롤러의 자바 코드에 프런트 엔드로 전송된 값의 일부를 채웁니다. 트랜잭션 모델 속성이 $HOME/k8s-o11y-workshop/docker/petclinic/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java에 채워지는 방식의 예는 다음과 같습니다.

    @ModelAttribute("transaction")
    public Transaction transaction() {
        return ElasticApm.currentTransaction();
    }

모니터링 오류

APM 에이전트는 처리되지 않은 예외도 포착합니다. "ERROR" 메뉴를 클릭하고 Kibana의 APM 앱에서 발생한 예외 세부 정보를 확인하세요.

샘플 애플리케이션

Elastic APM을 통해 클릭 한 번으로 모든 애플리케이션 오류를 표시할 수 있음

다음은 APM 에이전트가 애플리케이션에서 발생하는 처리되지 않은 예외를 포착하는 방식을 담당하는 자바 코드입니다. $HOME/k8s-o11y-workshop/docker/petclinic/src/main/java/org/springframework/samples/petclinic/system/CrashController.java:

    @GetMapping("/oups")
    public String triggerException() {
        throw new RuntimeException("Expected: controller used to showcase what "
                + "happens when an exception is thrown");
    }

런타임 메트릭 모니터링

에이전트는 런타임에 애플리케이션 구성 요소와 함께 배치되고 런타임 메트릭을 수집합니다. 예를 들어, Java 에이전트는 메트릭 수집 활성화와는 별개로 어떤 코드나 구성도 제공할 필요 없이 이를 즉시 수집합니다.

Elastic APM의 런타임 메트릭

서비스 지도

Elastic APM 7.7은 APM 추적에서 표현된 관계를 그래픽으로 나타내는 서비스 지도의 베타 버전을 선보였습니다. 이 보기는 APM 앱에 표시된 추적에 어떤 구성 요소가 관여하는지를 보여줍니다. 우리의 애플리케이션은 Java와 MySQL 백엔드를 가진 브라우저 클라이언트일 뿐이므로 결과 지도는 매우 간단할 것입니다.

Elastic APM의 서비스 지도

Elastic APM 에이전트를 사용하여 JMX 메트릭 수집

Java 에이전트는 애플리케이션에 의해 노출된 JMX 메트릭을 수집하도록 구성할 수 있습니다. 이 자습서의 Petclinic 구성 요소는 다음 메트릭 $HOME/k8s-o11y-workshop/petclinic/petclinic.yml을 수집하도록 구성됩니다.

- name: ELASTIC_APM_CAPTURE_JMX_METRICS
  value: >-
   object_name[java.lang:type=GarbageCollector,name=*]    
     attribute[CollectionCount:metric_name=collection_count] 
     attribute[CollectionTime:metric_name=collection_time],
   object_name[java.lang:type=Memory] attribute[HeapMemoryUsage:metric_name=heap]

Lens를 통한 사용자 정의 메트릭 시각화

모든 메트릭이 APM 앱에 표시되는 것은 아닙니다. 위의 예에서와 같이 JMX 메트릭스는 애플리케이션에 매우 특화되어 있으므로 APM 앱 내에서 시각화할 수 없습니다. 또한 메트릭이 가치 있게 되기 위해서는 다른 시각화의 일부가 되거나 다른 방식으로 시각화되어야 합니다. Kibana 시각화 및 대시보드는 기본적으로 이러한 메트릭을 시각화하는 데 사용될 수 있지만, 보다 빠르게 수행할 수 있는 새롭고 흥미로운 방법을 보여드리려고 합니다.

최근에 Lens가 보다 직관적인 분석가 중심의 시각화 도구로 Kibana에 도입되었습니다. 이 예는 에이전트가 수집한 사용자 정의 JMX 메트릭을 시각화하는 데 Lens를 사용하는 방법을 보여줍니다.

Lens 예

흥미롭게 만들기 위해, 스케일 아웃 명령을 실행하여 petclinic 구성 요소의 포드 수를 증가시켜 실행 중인 JVM당 여러 개의 라인을 얻도록 합시다.

$ kubectl scale --replicas=3 deployment petclinic-deployment
# 스케일 아웃이 원래 의도했던 대로 이루어졌는지 확인
$ kubectl get pods

다음과 같이 볼 수 있어야 합니다.

NAME                                    READY   STATUS    RESTARTS   AGE
mysql-deployment-7ffc9c5897-grnft       1/1     Running   0          37m
nginx-7ff654f859-xjqgn                  1/1     Running   0          28m
petclinic-deployment-86b666567c-5m9xb   1/1     Running   0          9s
petclinic-deployment-86b666567c-76pv7   1/1     Running   0          9s
petclinic-deployment-86b666567c-gncsw   1/1     Running   0          30m
theia-86d9888954-867kk                  1/1     Running   0          43m

이제 Lens의 성능을 볼 수 있습니다.

Lens 작업 시작!

검색 창. 모두가 아는 Search!

물론 Elastic APM 앱에는 검색 창이 있습니다. 그리고 엄청나게 많은 것들 중에 어떤 특정한 항목을 검색하려면 평가하고자 하는 문제의 범위를 좁히는 것이 좋은 방법입니다. 예를 들어, 다음은 APM UI 보기를 특정 브라우저 유형으로 좁힐 수 있는 방법입니다.

Elastic APM은 Elasticsearch를 기반으로 구축되었기 때문에 강력한 검색 기능을 갖추고 있습니다.

APM 추적 및 로그 상관 관계

전체는 그 구성 요소의 합보다 더 크다는 것의 또 다른 유용한 예로 추적된 코드에 의해 생성된 로그 항목과 APM 추적을 연관시키는 것을 들 수 있습니다. APM 추적은 trace.id<code> 필드로 로그 항목에 연결될 수 있습니다. 그리고 이 모든 것은 큰 노력 없이 단지 몇 가지 간단한 구성을 통해 가능합니다. 먼저 그러한 상관 관계의 예를 보겠습니다.

다음과 같이 추적을 살펴봅시다.

클릭 한 번으로 추적과 로그 상관 관계 분석

이 추적은 어떻게 다른 코드 조각들이 실행되었는지에 대한 타임라인을 보여줍니다. 이제 우리가 방금 추적한 코드에 의해 어떤 로그가 생성되었는지 봅시다. 작업 메뉴에서 로그 추적을 선택합니다. 추적 데이터가 캡처된 시간을 미리 선택하여 Logs UI로 이동하며, trace.id를 사용하여 동일한 trace.id로 주석을 단 로그 데이터를 필터링할 것입니다.

추적에 대한 로그 스트림

추적 ID로 드릴다운

분명히, trace.id는 APM 추적에 내재되어 있지만, 어떻게 우리는 이를 통해 로그 데이터를 보강했을까요? 첫째, 우리는 Elastic APM Java 에이전트를 사용하고 있기 때문에, 그것이 구현하는 로그 상관 관계 기능을 사용했습니다. 본질적으로 이것은 자바 로깅 프레임워크의 (Spring Boot의 경우 로그백) MDC 컨텍스트 맵에서 trace.idtransaction.id 필드를 채웁니다. 필요한 것은 petclinic ConfigMap petclinic/petclinic.yml에서 이 환경 변수를 설정하는 것 뿐입니다.

          - name: ELASTIC_APM_ENABLE_LOG_CORRELATION
            value: "true"

그런 다음, log.level, transaction.idElastic Common Schema에 해당하는 추가 필드로 Elastic 스택에 전송되는 로그 항목을 보강하는 ECS 로깅으로 petclinic 앱 로깅을 구성합니다. 이를 위해 petclinic 애플리케이션의 pom.xml에서 다음과 같은 종속성을 포함시켰습니다.

        <dependency>
            <groupId>co.elastic.logging</groupId>
            <artifactId>logback-ecs-encoder</artifactId>
            <version>${ecs-logging-java.version}</version>
        </dependency>

또한 다음과 같이 JSON으로 stdout에 작성하도록 구성된 ECS 로깅이 있는 docker/petclinic/src/main/resources/logback-spring.xml 파일도 있습니다.

    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
      <encoder class="co.elastic.logging.logback.EcsEncoder">
        <serviceName>petclinic</serviceName>
      </encoder>
    </appender>
    <root level="INFO">
        <appender-ref ref="console"/>
    </root>

마지막으로 petclinic ConfigMap(petclinic/petclinic.yml)에 대한 주석이 있는데, 이는 다음과 같이 beats 자동 검색을 활용해 filebeat가 petclinic에서 나온 결과 JSON을 구문 분석하도록 지시합니다.

container:
      annotations:
...
        co.elastic.logs/type: "log"
        co.elastic.logs/json.keys_under_root: "true"
        co.elastic.logs/json.overwrite_keys: "true"

따라서 이러한 상관 관계가 작동하려면 Java 에이전트와 로깅 프레임워크가 추적 상관 관계를 기록할 수 있도록 해야 하며, 통합 가시성 데이터의 두 부분을 함께 연결할 수 있습니다.

시리즈를 마치며

로그, 메트릭스, APM... 끝났습니다! 이 블로그 시리즈에서는 Filebeat, Metricbeat, APM을 사용하여 Elastic Stack으로 로그, 메트릭, APM 추적을 수집하는 애플리케이션을 계측하는 방법을 살펴보았습니다. 자습서는 또한 동일한 구성 요소를 사용하여 Kubernetes 로그와 메트릭을 수집하는 방법을 보여줍니다. Elastic 에코시스템에는 Kubernetes 환경의 통합 가시성 그림을 완성할 수 있는 더 자세한 세부 내용을 추가할 수 있는 추가 구성 요소가 있습니다.

  • Heartbeat - 애플리케이션 및 전체 Kubernetes 환경의 가동 시간과 응답성을 측정하는 좋은 방법입니다. 사용자가 있는 곳에 더 가깝게 클러스터 외부에 배포할 수 있습니다. Heartbeat는 사용자가 애플리케이션을 보는 방식, 관찰 중인 네트워크 및 응답 대기 시간의 종류, 노출되는 오류 수를 나타낼 수 있습니다.
  • Packetbeat - 내부 Kubernetes 클러스터 네트워크 트래픽, TLS 인증서 핸드셰이크, DNS 조회 등을 확인합니다.
  • 여러분이 마음대로 데이터 사이언스 작업을 해보실 수 있도록 다음과 같이 Jupyter 노트북의 샘플 배포를 포함시켰고 Elasticsearch에 저장된 원시 통합 가시성 데이터에 어떻게 접근할 수 있는지 보여주는 샘플 노트북을 추가했습니다.
    k8s-o11y-workshop/jupyter/scripts/example.ipynb
        

언제든지 Github 리포지토리에 기여하시거나, 문제가 발생할 경우 Github에 문제를 제기해 주세요.

지금 바로 시스템 및 인프라 모니터링을 시작할 수 있습니다. Elastic Cloud의 Elasticsearch Service 무료 체험판에 등록하거나 Elastic Stack을 다운로드하고 직접 호스팅하세요. 일단 실행되면, Elastic Uptime으로 호스트의 가용성을 모니터링하고 Elastic APM으로 호스트에서 실행 중인 애플리케이션을 계측하세요. 시스템에서 새 메트릭 클러스터와 완벽하게 통합된, 완전한 통합 가시성을 갖추는 작업을 계속 진행하세요. 어려운 상황에 부딪히거나 질문이 있으시면, 토론 포럼으로 오세요. 저희는 언제나 도와드리기 위해 기다리고 있습니다.