View a markdown version of this page

관찰성 - Amazon EKS

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

관찰성

소개

관찰성 도구를 사용하면 워크로드를 효율적으로 감지, 해결 및 조사할 수 있습니다. EKS 사용이 증가함에 따라 원격 측정 데이터 비용이 자연스럽게 증가합니다. 때로는 운영 요구 사항의 균형을 맞추고 비즈니스에 중요한 사항을 측정하며 관찰성 비용을 확인하는 것이 어려울 수 있습니다. 이 가이드는 관찰성의 세 가지 원칙인 로그, 지표 및 추적에 대한 비용 최적화 전략에 중점을 둡니다. 이러한 각 모범 사례는 조직의 최적화 목표에 맞게 독립적으로 적용할 수 있습니다.

로깅

로깅은 클러스터의 애플리케이션을 모니터링하고 문제를 해결하는 데 중요한 역할을 합니다. 로깅 비용을 최적화하는 데 사용할 수 있는 몇 가지 전략이 있습니다. 아래 나열된 모범 사례 전략은 로그 보존 정책을 검사하여 로그 데이터 보관 기간에 대한 세분화된 제어를 구현하고, 중요도에 따라 로그 데이터를 다양한 스토리지 옵션으로 전송하고, 로그 필터링을 활용하여 저장된 로그 메시지 유형을 좁히는 것입니다. 로그 원격 측정을 효율적으로 관리하면 환경 비용을 절감할 수 있습니다.

EKS 제어 플레인

컨트롤 플레인 로그 최적화

Kubernetes 컨트롤 플레인은 클러스터를 관리하는 구성 요소 세트이며 이러한 구성 요소는 다양한 유형의 정보를 Amazon CloudWatch의 로그 그룹에 로그 스트림으로 전송합니다. 모든 컨트롤 플레인 로그 유형을 활성화하면 이점이 있지만 각 로그의 정보와 모든 로그 원격 측정을 저장하는 데 드는 관련 비용을 알고 있어야 합니다. 클러스터에서 Amazon CloudWatch Logs로 전송된 로그에 대한 표준 CloudWatch Logs 데이터 수집 및 스토리지 비용에 대한 요금이 부과됩니다. Amazon CloudWatch 활성화하기 전에 각 로그 스트림이 필요한지 평가합니다.

예를 들어 비프로덕션 클러스터에서는 API 서버 로그와 같은 특정 로그 유형을 분석용으로만 선택적으로 활성화하고 나중에 비활성화합니다. 그러나 이벤트를 재현할 수 없고 문제를 해결하려면 더 많은 로그 정보가 필요한 프로덕션 클러스터의 경우 모든 로그 유형을 활성화할 수 있습니다. 추가 컨트롤 플레인 비용 최적화 구현 세부 정보는이 블로그 게시물에 있습니다.

S3로 로그 스트리밍

또 다른 비용 최적화 모범 사례는 CloudWatch Logs 구독을 통해 컨트롤 플레인 로그를 S3로 스트리밍하는 것입니다. CloudWatch Logs 구독을 활용하면 로그를 S3에 선택적으로 전달할 수 있으므로 CloudWatch에서 로그를 무기한 유지하는 것보다 더 비용 효율적인 장기 스토리지를 제공합니다. 예를 들어 프로덕션 클러스터의 경우 중요한 로그 그룹을 생성하고 구독을 활용하여 15일 후에 이러한 로그를 S3로 스트리밍할 수 있습니다. 이렇게 하면 분석을 위해 로그에 빠르게 액세스할 수 있을 뿐만 아니라 로그를 보다 비용 효율적인 스토리지로 이동하여 비용을 절감할 수 있습니다.

중요

9/5/2023부터 EKS 로그는 Amazon CloudWatch Logs에서 판매 로그로 분류됩니다. 판매 로그는 AWS 서비스가 고객을 대신하여 기본적으로 게시하는 특정 AWS 서비스 로그이며 대량 할인 요금으로 사용할 수 있습니다. 판매 로그 요금에 대해 자세히 알아보려면 Amazon CloudWatch 요금 페이지를 방문하세요.

EKS 데이터 영역

로그 보존

Amazon CloudWatch의 기본 보존 정책은 로그를 무기한으로 유지하고 만료되지 않도록 하여 AWS 리전에 적용되는 스토리지 비용을 발생시키는 것입니다. 스토리지 비용을 줄이기 위해 워크로드 요구 사항에 따라 각 로그 그룹의 보존 정책을 사용자 지정할 수 있습니다.

개발 환경에서는 긴 보존 기간이 필요하지 않을 수 있습니다. 그러나 프로덕션 환경에서는 문제 해결, 규정 준수 및 용량 계획 요구 사항을 충족하도록 더 긴 보존 정책을 설정할 수 있습니다. 예를 들어, 성수기 동안 전자 상거래 애플리케이션을 실행하는 경우 시스템이 더 많은 부하를 받고 즉시 눈에 띄지 않을 수 있는 문제가 발생할 수 있는 경우 자세한 문제 해결 및 이벤트 후 분석을 위해 더 긴 로그 보존을 설정하는 것이 좋습니다.

AWS CloudWatch 콘솔 또는 AWS API에서 보존 기간을 각 로그 그룹에 따라 1일~10년으로 구성할 수 있습니다. 보존 기간이 유연하면 중요한 로그를 유지하면서 로그 스토리지 비용을 절감할 수 있습니다.

로그 스토리지 옵션

스토리지는 관찰성 비용의 큰 동인이므로 로그 스토리지 전략을 최적화하는 것이 중요합니다. 전략은 성능과 확장성을 유지하면서 워크로드 요구 사항에 부합해야 합니다. 로그 저장 비용을 줄이기 위한 한 가지 전략은 AWS S3 버킷과 다양한 스토리지 계층을 활용하는 것입니다.

로그를 S3에 직접 전달

Cloudwatch 대신 개발 환경과 같이 덜 중요한 로그를 S3에 직접 전달하는 것이 좋습니다. 이는 로그 스토리지 비용에 즉각적인 영향을 미칠 수 있습니다. 한 가지 옵션은 Fluentbit을 사용하여 로그를 S3로 직접 전달하는 것입니다. FluentBit가 보관을 위해 컨테이너 로그를 전송하는 대상인 [OUTPUT] 섹션에서 이를 정의합니다. 여기에서 추가 구성 파라미터를 검토합니다.

[OUTPUT]
        Name eks_to_s3
        Match application.*
        bucket $S3_BUCKET name
        region us-east-2
        store_dir /var/log/fluentbit
        total_file_size 30M
        upload_timeout 3m

단기 분석을 위해서만 CloudWatch에 로그 전달

데이터에 대한 즉각적인 분석을 수행해야 할 수 있는 프로덕션 환경과 같은 더 중요한 로그의 경우 로그를 CloudWatch에 전달하는 것이 좋습니다. FluentBit가 보관을 위해 컨테이너 로그를 전송하는 대상인 [OUTPUT] 섹션에서 이를 정의합니다. 여기에서 추가 구성 파라미터를 검토합니다.

[OUTPUT]
        Name eks_to_cloudwatch_logs
        Match application.*
        region us-east-2
        log_group_name fluent-bit-cloudwatch
        log_stream_prefix from-fluent-bit-
        auto_create_group On

그러나 이는 비용 절감에 즉각적인 영향을 미치지 않습니다. 추가 비용 절감을 위해 이러한 로그를 Amazon S3로 내보내야 합니다.

CloudWatch에서 Amazon S3로 내보내기

Amazon CloudWatch logs를 장기간 저장하려면 Amazon EKS CloudWatch 로그를 Amazon Simple Storage Service(Amazon S3)로 내보내는 것이 좋습니다. 콘솔 또는 API를 통해 내보내기 작업을 생성하여 Amazon S3 버킷에 로그를 전달할 수 있습니다. 이렇게 하면 Amazon S3는 비용을 더욱 절감할 수 있는 다양한 옵션을 제공합니다. 자체 Amazon S3 수명 주기 규칙을 정의하여 필요에 맞는 스토리지 클래스로 로그를 이동하거나 Amazon S3 Intelligent-Tiering 스토리지 클래스를 활용하여 사용 패턴에 따라 AWS가 데이터를 장기 스토리지로 자동으로 이동하도록 할 수 있습니다. 자세한 내용은이 블로그를 참조하세요. 예를 들어 프로덕션 환경의 경우 로그는 30일 이상 CloudWatch에 상주한 다음 Amazon S3 버킷으로 내보냅니다. 그런 다음 나중에 로그를 다시 참조해야 하는 경우 Amazon Athena를 사용하여 Amazon S3 버킷의 데이터를 쿼리할 수 있습니다.

로그 수준 감소

애플리케이션에 대한 선택적 로깅을 연습합니다. 애플리케이션과 노드 모두 기본적으로 로그를 출력합니다. 애플리케이션 로그의 경우 워크로드 및 환경의 중요도에 맞게 로그 수준을 조정합니다. 예를 들어 아래 java 애플리케이션은 일반적인 기본 애플리케이션 구성인 INFO 로그를 출력하며, 코드에 따라 많은 양의 로그 데이터가 생성될 수 있습니다.

import org.apache.log4j.*;

public class LogClass {
   private static org.apache.log4j.Logger log = Logger.getLogger(LogClass.class);

public static void main(String[] args) {
      log.setLevel(Level.INFO);

   log.debug("This is a DEBUG message, check this out!");
   log.info("This is an INFO message, nothing to see here!");
   log.warn("This is a WARN message, investigate this!");
   log.error("This is an ERROR message, check this out!");
   log.fatal("This is a FATAL message, investigate this!");    } }

개발 환경에서는 문제를 디버깅하거나 프로덕션에 들어가기 전에 잠재적 문제를 포착하는 데 도움이 될 수 DEBUG있으므로 로그 수준을 로 변경합니다.

log.setLevel(Level.DEBUG);

프로덕션 환경에서는 로그 수준을 ERROR 또는 로 수정하는 것이 좋습니다FATAL. 이렇게 하면 애플리케이션에 오류가 있는 경우에만 로그가 출력되므로 로그 출력이 줄어들고 애플리케이션 상태에 대한 중요한 데이터에 집중할 수 있습니다.

log.setLevel(Level.ERROR);

다양한 Kubernetes 구성 요소 로그 수준을 미세 조정할 수 있습니다. 예를 들어 Bottlerocket을 EKS 노드 운영 체제로 사용하는 경우 kubelet 프로세스 로그 수준을 조정할 수 있는 구성 설정이 있습니다. 이 구성 설정의 코드 조각은 다음과 같습니다. kubelet 프로세스의 로깅 세부 정보를 조정하는 기본 로그 수준 2를 기록해 둡니다.

[settings.kubernetes]
log-level = "2"
image-gc-high-threshold-percent = "85"
image-gc-low-threshold-percent = "80"

개발 환경의 경우 로그 수준을 2보다 크게 설정하여 추가 이벤트를 볼 수 있습니다. 이는 디버깅에 적합합니다. 프로덕션 환경의 경우 중요한 이벤트만 보기 위해 레벨을 0으로 설정할 수 있습니다.

필터 활용

기본 EKS Fluentbit 구성을 사용하여 컨테이너 로그를 Cloudwatch로 전송할 때 FluentBit는 아래 [INPUT] 구성 블록과 같이 Kubernetes 메타데이터로 보강된 모든 애플리케이션 컨테이너 로그를 캡처하여 Cloudwatch로 전송합니다.

 [INPUT]
     Name                tail
     Tag                 application.*
     Exclude_Path        /var/log/containers/cloudwatch-agent*, /var/log/containers/fluent-bit*, /var/log/containers/aws-node*, /var/log/containers/kube-proxy*
     Path                /var/log/containers/*.log
     Docker_Mode         On
     Docker_Mode_Flush   5
     Docker_Mode_Parser  container_firstline
     Parser              docker
     DB                  /var/fluent-bit/state/flb_container.db
     Mem_Buf_Limit       50MB
     Skip_Long_Lines     On
     Refresh_Interval    10
     Rotate_Wait         30
     storage.type        filesystem
     Read_from_Head      ${READ_FROM_HEAD}

위의 [INPUT] 섹션은 모든 컨테이너 로그를 수집하는 것입니다. 이렇게 하면 필요 없는 대량의 데이터가 생성될 수 있습니다. 이 데이터를 필터링하면 CloudWatch로 전송되는 로그 데이터의 양을 줄일 수 있으므로 비용이 절감됩니다. CloudWatch로 출력하기 전에 로그에 필터를 적용할 수 있습니다. Fluentbit은 [FILTER] 섹션에서 이를 정의합니다. 예를 들어 Kubernetes 메타데이터가 로그 이벤트에 추가되지 않도록 필터링하면 로그 볼륨이 감소할 수 있습니다.

    [FILTER]
        Name                nest
        Match               application.*
        Operation           lift
        Nested_under        kubernetes
        Add_prefix          Kube.

    [FILTER]
        Name                modify
        Match               application.*
        Remove              Kube.<Metadata_1>
        Remove              Kube.<Metadata_2>
        Remove              Kube.<Metadata_3>

    [FILTER]
        Name                nest
        Match               application.*
        Operation           nest
        Wildcard            Kube.*
        Nested_under        kubernetes
        Remove_prefix       Kube.

Metrics

지표는 시스템 성능에 대한 중요한 정보를 제공합니다. 중앙 위치에서 모든 시스템 관련 또는 사용 가능한 리소스 지표를 통합하면 성능 데이터를 비교하고 분석할 수 있습니다. 이 중앙 집중식 접근 방식을 사용하면 리소스 확장 또는 축소와 같은 정보에 입각한 전략적 결정을 내릴 수 있습니다. 또한 지표는 리소스 상태를 평가하는 데 중요한 역할을 하므로 필요한 경우 사전 예방 조치를 취할 수 있습니다. 일반적으로 관찰성 비용은 원격 측정 데이터 수집 및 보존에 따라 조정됩니다. 다음은 지표 원격 측정 비용을 줄이기 위해 구현할 수 있는 몇 가지 전략입니다. 중요한 지표만 수집하고, 원격 측정 데이터의 카디널리티를 줄이고, 원격 측정 데이터 컬렉션의 세분성을 미세 조정하는 것입니다.

무엇이 중요한지 모니터링하고 필요한 것만 수집

첫 번째 비용 절감 전략은 수집하는 지표 수를 줄이고 결과적으로 보존 비용을 줄이는 것입니다.

  1. 먼저 사용자 및/또는 이해관계자의 요구 사항에서 거꾸로 작업하여 가장 중요한 지표를 결정합니다. 성공 지표는 모든 사람에게 다릅니다! 어떤 모습이 좋은지 알고 이를 측정합니다.

  2. 지원하는 워크로드를 자세히 살펴보고 핵심 성능 지표(KPIs) 'Golden Signals'를 식별하는 것이 좋습니다. 이는 비즈니스 및 이해관계자 요구 사항에 부합해야 합니다. Amazon CloudWatch 및 지표 수학SLIs, SLOs 및 SLAs를 계산하는 것은 서비스 신뢰성을 관리하는 데 매우 중요합니다. 이 가이드에 설명된 모범 사례를 따르면 EKS 환경의 성능을 효과적으로 모니터링하고 유지할 수 있습니다.

  3. 그런 다음 다양한 인프라 계층을 계속 진행하여 EKS 클러스터, 노드 및 추가 인프라 지표를 워크로드 KPIs에 연결하고 상호 연관시킵니다. 비즈니스 지표와 운영 지표를 함께 상호 연관시키고 관찰된 영향을 기반으로 결론을 도출할 수 있는 시스템에 저장합니다.

  4. EKS는 컨트롤 플레인, 클러스터 kube-state-metrics를 노출합니다. 이러한 모든 지표의 관련성은 요구 사항에 따라 다르지만 여러 계층에 걸쳐 모든 단일 지표가 필요한 것은 아닙니다. 이 EKS 필수 지표 가이드를 EKS 클러스터 및 워크로드의 전반적인 상태를 모니터링하기 위한 기준으로 사용할 수 있습니다.

다음은를 사용하여 kubelet 지표만 relabel_config 유지하고 모든 컨테이너 지표metric_relabel_config를 삭제하는 prometheus 스크레이프 구성의 예입니다.

kubernetes_sd_configs: - role: endpoints namespaces: names: - kube-system bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token tls_config: insecure_skip_verify: true relabel_configs: - source_labels: [__meta_kubernetes_service_label_k8s_app] regex: kubelet action: keep metric_relabel_configs: - source_labels: [__name__] regex: container_(network_tcp_usage_total|network_udp_usage_total|tasks_state|cpu_load_average_10s) action: drop

해당하는 경우 카디널리티 감소

카디널리티는 특정 지표 세트에 대한 차원(예: prometheus 레이블)과 함께 데이터 값의 고유성을 나타냅니다. 카디널리티가 높은 지표에는 여러 차원이 있으며 각 차원 지표 조합은 고유성이 더 높습니다. 카디널리티가 높을수록 지표 원격 측정 데이터 크기와 스토리지 요구 사항이 커져 비용이 증가합니다.

아래 높은 카디널리티 예제에서는 지표, 지연 시간이 차원, RequestID, CustomerID 및 서비스를 가지며 각 차원에 고유한 값이 많은 것을 볼 수 있습니다. 카디널리티는 차원당 가능한 값 수의 조합을 측정한 것입니다. Prometheus에서 각 고유 차원/레이블 세트는 새 지표로 간주되므로 카디널리티가 높으면 지표가 더 많아집니다.

지표 및 지표당 차원/레이블(클러스터, 네임스페이스, 서비스, 포드, 컨테이너 등)이 많은 EKS 환경에서 카디널리티는 증가하는 경향이 있습니다. 비용을 최적화하려면 신중하게 수집하는 지표의 카디널리티를 고려하세요. 예를 들어 클러스터 수준에서 시각화를 위해 특정 지표를 집계하는 경우 네임스페이스 레이블과 같이 하위 계층에 있는 추가 레이블을 삭제할 수 있습니다.

prometheus에서 높은 카디널리티 지표를 식별하려면 다음 PROMQL 쿼리를 실행하여 지표 수가 가장 많은 스크레이프 대상(카디널리티)을 확인할 수 있습니다.

topk_max(5, max_over_time(scrape_samples_scraped[1h]))

및 다음 PROMQL 쿼리는 지표 이탈률이 가장 높은 스크레이프 대상(특정 스크레이프에서 생성된 새 지표 시리즈 수)을 결정하는 데 도움이 될 수 있습니다.

topk_max(5, max_over_time(scrape_series_added[1h]))

grafana를 사용하는 경우 Grafana Lab의 Mimirtool을 사용하여 grafana 대시보드 및 prometheus 규칙을 분석하여 사용하지 않는 높은 카디널리티 지표를 식별할 수 있습니다. mimirtool analyzemimirtool analyze prometheus 명령을 사용하여 대시보드에서 참조되지 않는 활성 지표를 식별하는 방법에 대한 이 가이드를 따르세요.

지표 세부 수준 고려

매초 대 매분과 같이 더 세분화된 지표를 수집하면 수집 및 저장되는 원격 측정의 양에 큰 영향을 미쳐 비용이 증가할 수 있습니다. 일시적인 문제를 볼 수 있을 만큼 충분히 세분화되고 비용 효율적일 만큼 충분히 낮은 수준 사이에서 균형을 이루는 합리적인 스크레이프 또는 지표 수집 간격을 결정합니다. 용량 계획 및 더 큰 기간 분석에 사용되는 지표의 세부 수준을 줄입니다.

다음은 기본 Opentelemetry용 AWS Distro(ADOT) EKS Addon Collector 구성의 코드 조각입니다.

중요

글로벌 prometheus 스크레이프 간격은 15초로 설정됩니다. 이 스크레이프 간격을 늘리면 prometheus에서 수집된 지표 데이터의 양이 감소할 수 있습니다.

apiVersion: opentelemetry.io/v1alpha1
kind: OpenTelemetryCollector
metadata:
  name: my-collector-amp

...

config: |
    extensions:
      sigv4auth:
        region: "+++<YOUR_AWS_REGION>+++" service: "aps"+++</YOUR_AWS_REGION>+++

 receivers:
   #
   # Scrape configuration for the Prometheus Receiver
   # This is the same configuration used when Prometheus is installed using the community Helm chart
   #
   prometheus:
     config:
       global:   scrape_interval: 15s
         scrape_timeout: 10s

추적

추적과 관련된 기본 비용은 추적 스토리지 생성에서 비롯됩니다. 추적의 목표는 성능 측면을 진단하고 이해하기에 충분한 데이터를 수집하는 것입니다. 그러나 X-Ray 추적 비용은 X-Ray로 전달된 데이터를 기반으로 하므로 추적이 전달된 후 삭제해도 비용이 절감되지 않습니다. 적절한 분석을 수행할 수 있도록 데이터를 유지하면서 추적 비용을 낮추는 방법을 검토해 보겠습니다.

샘플링 규칙 적용

X-Ray 샘플링 속도는 기본적으로 보수적입니다. 수집하는 데이터의 양을 제어할 수 있는 샘플링 규칙을 정의합니다. 이렇게 하면 비용을 절감하면서 성능 효율성을 개선할 수 있습니다. 샘플링 속도를 줄이면 더 낮은 비용 구조를 유지하면서 워크로드에 필요한 것만 요청에서 트레이스를 수집할 수 있습니다.

예를 들어 1개의 문제가 있는 경로에 대한 모든 요청의 트레이스를 디버깅하려는 java 애플리케이션이 있습니다.

SDK를 통해 JSON 문서에서 샘플링 규칙을 로드하도록 구성

{ "version": 2, "rules": [ { "description": "debug-eks", "host": "*", "http_method": "PUT", "url_path": "/history/*", "fixed_target": 0, "rate": 1, "service_type": "debug-eks" } ], "default": { "fixed_target": 1, "rate": 0.1 } }

콘솔을 통해

AWS Distro for OpenTelemetry(ADOT)를 사용하여 테일 샘플링 적용

ADOT 테일 샘플링을 사용하면 서비스에 수집된 트레이스의 볼륨을 제어할 수 있습니다. 그러나 테일 샘플링을 사용하면 요청의 모든 범위가 처음부터 완료되는 대신 완료된 후 샘플링 정책을 정의할 수 있습니다. 이렇게 하면 CloudWatch로 전송되는 원시 데이터의 양이 추가로 제한되므로 비용이 절감됩니다.

예를 들어 랜딩 페이지에 대한 트래픽의 1%와 결제 페이지에 대한 요청의 10%를 샘플링하는 경우 30분 동안 300개의 추적이 남을 수 있습니다. 특정 오류를 필터링하는 ADOT 테일 샘플링 규칙을 사용하면 트레이스가 200개 남아 저장된 트레이스 수가 줄어들 수 있습니다.

processors:
  groupbytrace:
    wait_duration: 10s
    num_traces: 300
    tail_sampling:
    decision_wait: 1s # This value should be smaller than wait_duration
    policies:
      - ..... # Applicable policies**
  batch/tracesampling:
    timeout: 0s # No need to wait more since this will happen in previous processors
    send_batch_max_size: 8196 # This will still allow us to limit the size of the batches sent to subsequent exporters

service:
  pipelines:
    traces/tailsampling:
      receivers: [otlp]
      processors: [groupbytrace, tail_sampling, batch/tracesampling]
      exporters: [awsxray]

Amazon S3 스토리지 옵션 활용

AWS S3 버킷과 다른 스토리지 클래스를 활용하여 트레이스를 저장해야 합니다. 보존 기간이 만료되기 전에 추적을 S3로 내보냅니다. Amazon S3 수명 주기 규칙을 사용하여 추적 데이터를 요구 사항을 충족하는 스토리지 클래스로 이동합니다.

예를 들어 90일이 지난 트레이스가 있는 경우 Amazon S3 Intelligent-Tiering은 사용 패턴에 따라 데이터를 장기 스토리지로 자동으로 이동할 수 있습니다. 나중에 추적을 다시 참조해야 하는 경우 Amazon Athena를 사용하여 Amazon S3의 데이터를 쿼리할 수 있습니다. 이렇게 하면 분산 추적 비용을 더욱 줄일 수 있습니다.

추가 리소스: