관찰성 - 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(Key Performance Indicator)를 식별해 보세요. 'Golden Signals'라고도 합니다. 이는 비즈니스 및 이해관계자 요구 사항에 부합해야 합니다. Amazon CloudWatch 및 지표 수학SLIs, SLOs 및 SLAs를 계산하는 것은 서비스 신뢰성을 관리하는 데 매우 중요합니다. EKS 환경의 성능을 효과적으로 모니터링하고 유지하려면이 가이드에 설명된 모범 사례를 따르세요.

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

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

다음은를 사용하여 kubelet 지표만 유지하고 모든 컨테이너 지표relabel_configmetric_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 } }

콘솔을 통해

OpenTelemetry용 AWS Distro(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의 데이터를 쿼리할 수 있습니다. 이렇게 하면 분산 추적 비용을 더욱 줄일 수 있습니다.

추가 리소스: