

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 可觀測性
<a name="cost-opt-observability"></a>

## 簡介
<a name="_introduction"></a>

可觀測性工具可協助您有效率地偵測、修復和調查工作負載。遙測資料的成本會隨著您使用 EKS 而自然增加。有時，平衡您的營運需求並衡量對業務重要的事項，以及控制可觀測性成本可能很困難。本指南著重於可觀測性的三個支柱的成本最佳化策略：日誌、指標和追蹤。這些最佳實務都可以獨立套用，以符合組織的最佳化目標。

## 日誌
<a name="_logging"></a>

記錄在監控和故障診斷叢集中的應用程式時扮演重要角色。有多種策略可用來最佳化記錄成本。下列最佳實務策略包括檢查您的日誌保留政策，以實作日誌資料保留的時間長度、根據重要性將日誌資料傳送至不同的儲存選項，以及使用日誌篩選來縮小儲存日誌訊息的類型。有效管理日誌遙測可為您的環境節省成本。

## EKS 控制平面
<a name="_eks_control_plane"></a>

### 最佳化您的控制平面日誌
<a name="_optimize_your_control_plane_logs"></a>

Kubernetes 控制平面是一組[管理叢集的元件](https://kubernetes.io/docs/concepts/overview/components/#control-plane-components)，這些元件會將不同類型的資訊做為日誌串流傳送至 [Amazon CloudWatch](https://aws.amazon.com/cloudwatch/) 中的日誌群組。雖然啟用所有控制平面日誌類型都有好處，但您應該了解每個日誌中的資訊，以及存放所有日誌遙測的相關費用。您需支付從叢集傳送至 Amazon [CloudWatch Logs 之日誌的標準 CloudWatch Logs 資料擷取和儲存成本](https://aws.amazon.com/cloudwatch/pricing/)。 Amazon CloudWatch 在啟用它們之前，請評估每個日誌串流是否必要。

例如，在非生產叢集中，選擇性地啟用特定日誌類型，例如 api 伺服器日誌，僅用於分析和之後停用。但是，對於生產叢集，您可能無法重現事件，並解決問題需要更多日誌資訊，則您可以啟用所有日誌類型。進一步的控制平面成本最佳化實作詳細資訊請參閱此[部落格](https://aws.amazon.com/blogs/containers/understanding-and-cost-optimizing-amazon-eks-control-plane-logs/)文章。

#### 將日誌串流至 S3
<a name="_stream_logs_to_s3"></a>

另一個成本最佳化最佳實務是透過 CloudWatch Logs 訂閱將控制平面日誌串流至 S3。利用 CloudWatch Logs [訂閱](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/Subscriptions.html)可讓您選擇性地將日誌轉送至 S3，相較於在 CloudWatch 中無限期保留日誌，它可提供更具成本效益的長期儲存。例如，對於生產叢集，您可以建立關鍵日誌群組，並在 15 天後利用訂閱將這些日誌串流到 S3。這將確保您能夠快速存取日誌以供分析，但也可以將日誌移至更具成本效益的儲存體，以節省成本。

**重要**  
自 9/5/2023 起，EKS 日誌在 Amazon CloudWatch Logs 中歸類為 Vended Logs。已終止的日誌是特定 AWS 服務日誌，由 AWS 服務代表客戶原生發佈，並可用於磁碟區折扣定價。請造訪 [Amazon CloudWatch 定價頁面](https://aws.amazon.com/cloudwatch/pricing/)，以進一步了解 Vended Logs 定價。

## EKS 資料平面
<a name="_eks_data_plane"></a>

### 日誌保留
<a name="_log_retention"></a>

Amazon CloudWatch 的預設保留政策是無限期保留日誌，永遠不會過期，因此產生適用於您 AWS 區域的儲存成本。為了降低儲存成本，您可以根據您的工作負載需求，為每個日誌群組自訂保留政策。

在開發環境中，可能不需要較長的保留期。但在生產環境中，您可以設定更長的保留政策，以滿足故障診斷、合規和容量規劃需求。例如，如果您在尖峰假日期間執行電子商務應用程式，系統負載會比較重，而且可能會出現可能無法立即注意到的問題，則建議您設定較長的日誌保留時間，以進行詳細的故障診斷和事件後分析。

您可以在 AWS CloudWatch 主控台或 [AWS API](https://docs.aws.amazon.com/cli/latest/reference/logs/put-retention-policy.html) 中[設定保留期間](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/Working-with-log-groups-and-streams.html#SettingLogRetention)，根據每個日誌群組，保留期間從 1 天到 10 年。擁有彈性的保留期間可以節省日誌儲存成本，同時維護關鍵日誌。

### 日誌儲存選項
<a name="_log_storage_options"></a>

儲存是可觀測性成本的一大驅動因素，因此最佳化日誌儲存策略至關重要。您的策略應與您的工作負載需求保持一致，同時維持效能和可擴展性。降低日誌儲存成本的一個策略是利用 AWS S3 儲存貯體及其不同的儲存層。

#### 將日誌直接轉送至 S3
<a name="_forward_logs_directly_to_s3"></a>

考慮將較不重要的日誌直接轉送至 S3，而非 Cloudwatch。這可能會對日誌儲存成本產生立即影響。其中一個選項是使用 Fluentbit 直接將日誌轉送至 S3。您可以在 `[OUTPUT]`區段中定義此項目，也就是 FluentBit 傳輸容器日誌以進行保留的目的地。[在此處](https://docs.fluentbit.io/manual/pipeline/outputs/s3#worker-support)檢閱其他組態參數。

```
[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 進行短期分析
<a name="_forward_logs_to_cloudwatch_only_for_short_term_analysis"></a>

如需更關鍵的日誌，例如您可能需要立即對資料執行分析的生產環境，請考慮將日誌轉送至 CloudWatch。您可以在 `[OUTPUT]`區段中定義此項目，也就是 FluentBit 傳輸容器日誌以進行保留的目的地。[在此處](https://docs.fluentbit.io/manual/pipeline/outputs/cloudwatch)檢閱其他組態參數。

```
[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
<a name="_export_to_amazon_s3_from_cloudwatch"></a>

若要長期存放 Amazon CloudWatch logs，建議您將 Amazon EKS CloudWatch 日誌匯出至 Amazon Simple Storage Service (Amazon S3)。您可以透過[主控台](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/S3ExportTasksConsole.html)或 API 建立匯出任務，將日誌轉送至 Amazon S3 儲存貯體。完成後，Amazon S3 會呈現許多選項，以進一步降低成本。您可以定義自己的 [Amazon S3 生命週期規則](https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lifecycle-mgmt.html)，將日誌移至符合您需求的儲存類別，或利用 [Amazon S3 Intelligent-Tiering](https://aws.amazon.com/s3/storage-classes/intelligent-tiering/) 儲存類別，讓 AWS 根據您的使用模式自動將資料移至長期儲存。如需詳細資訊，請參閱此[部落格](https://aws.amazon.com/blogs/containers/understanding-and-cost-optimizing-amazon-eks-control-plane-logs/)。例如，對於您的生產環境日誌， 會在 CloudWatch 中存放超過 30 天，然後匯出至 Amazon S3 儲存貯體。然後，如果您稍後需要參考日誌，您可以使用 Amazon Athena 查詢 Amazon S3 儲存貯體中的資料。

### 降低日誌層級
<a name="_reduce_log_levels"></a>

為您的應用程式練習選擇性記錄。根據預設，您的應用程式和節點都會輸出日誌。針對您的應用程式日誌，調整日誌層級以符合工作負載和環境的關鍵性。例如，以下 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](https://bottlerocket.dev/) 做為 EKS 節點作業系統，則有組態設定可讓您調整 kubelet 程序日誌層級。此組態設定的程式碼片段如下。請注意預設[日誌層級](https://github.com/bottlerocket-os/bottlerocket/blob/3f716bd68728f7fd825eb45621ada0972d0badbb/README.md?plain=1#L528) **2**，其會調整`kubelet`程序的記錄詳細程度。

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

對於開發環境，您可以設定大於 **2** 的日誌層級，以檢視其他事件，這非常適合偵錯。對於生產環境，您可以將關卡設定為 **0**，以便僅檢視關鍵事件。

### 利用篩選條件
<a name="_leverage_filters"></a>

使用預設的 EKS Fluentbit 組態將容器日誌傳送至 Cloudwatch 時，FluentBit 會擷取並傳送充實 Kubernetes 中繼資料**的所有**應用程式容器日誌至 Cloudwatch，如以下`[INPUT]`組態區塊所示。

```
 [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.
```

## 指標
<a name="_metrics"></a>

 [指標](https://aws-observability.github.io/observability-best-practices/signals/metrics/)提供有關系統效能的寶貴資訊。透過將所有與系統相關或可用的資源指標合併到集中位置，您可以獲得比較和分析效能資料的功能。這種集中式方法可讓您做出更明智的策略決策，例如擴展或縮減資源。此外，指標在評估資源的運作狀態方面扮演重要角色，可讓您在必要時採取主動措施。一般而言，可觀測性成本會隨著遙測資料收集和保留而擴展。您可以實作以下幾個策略來降低指標遙測的成本：僅收集重要的指標、降低遙測資料的基數，以及微調遙測資料收集的精細程度。

### 監控重要事項，並僅收集您需要的項目
<a name="_monitor_what_matters_and_collect_only_what_you_need"></a>

第一個降低成本策略是減少您正在收集的指標數量，進而降低保留成本。

1. 首先，從您和/或利益相關者的要求向後工作，以確定[最重要的指標](https://aws-observability.github.io/observability-best-practices/guides/#monitor-what-matters)。每個人的成功指標都不同！知道什麼是*好*東西，並對其進行測量。

1. 考慮深入探索您支援的工作負載，並識別其關鍵效能指標 (KPIs) a.k.a 'Golden Signals'。這些應符合業務和利益相關者要求。使用 Amazon CloudWatch 和指標數學計算 SLIs、SLOs 和 SLAs，對於管理服務可靠性至關重要。遵循[本指南](https://aws-observability.github.io/observability-best-practices/guides/operational/business/key-performance-indicators/#10-understanding-kpis-golden-signals)中概述的最佳實務，以有效監控和維護 EKS 環境的效能。

1. 然後，繼續瀏覽不同層級的基礎設施，以[連接 EKS 叢集、節點和其他基礎設施指標，並將其與工作負載 KPI 建立關聯](https://aws-observability.github.io/observability-best-practices/signals/metrics/#correlate-with-operational-metric-data)。 KPIs 將您的業務指標和操作指標存放在系統中，您可以將它們關聯在一起，並根據觀察到的對兩者的影響得出結論。

1. EKS 從控制平面、叢集 kube-state-metrics、Pod 和節點公開指標。所有這些指標的相關性取決於您的需求，但您可能不需要跨不同層的每個指標。您可以使用此 [EKS 基本指標](https://aws-observability.github.io/observability-best-practices/guides/containers/oss/eks/best-practices-metrics-collection/)指南做為基準，以監控 EKS 叢集和工作負載的整體運作狀態。

以下是 Prometheus 抓取組態的範例，其中我們使用 `relabel_config`來僅保留 kubelet 指標`metric_relabel_config`，並捨棄所有容器指標。

```
  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
```

### 如適用，減少基數
<a name="_reduce_cardinality_where_applicable"></a>

基數是指資料值的唯一性及其特定指標集的維度 （例如 Prometheus 標籤）。高基數指標有許多維度，每個維度指標組合都有更高的唯一性。較高的基數會導致較大的指標遙測資料大小和儲存需求，進而增加成本。

在下面的高基數範例中，我們看到 指標、延遲、 具有維度、RequestID、CustomerID 和 Service，而且每個維度都有許多唯一的值。Cardinality 是每個維度可能值的組合。在 Prometheus 中，每組唯一維度/標籤都視為新的指標，因此高基數表示更多的指標。

在每個指標具有許多指標和維度/標籤的 EKS 環境中 （叢集、命名空間、服務、Pod、容器等），基數通常會增加。為了最佳化成本，請仔細考慮您正在收集的指標基數。例如，如果您要彙總叢集層級視覺化的特定指標，則可以捨棄位於較低圖層的其他標籤，例如命名空間標籤。

為了識別 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 規則，以識別未使用的高基數指標。請遵循[本指南](https://grafana.com/docs/grafana-cloud/account-management/billing-and-usage/control-prometheus-metrics-usage/usage-analysis-mimirtool/?pg=blog&plcmt=body-txt#analyze-and-reduce-metrics-usage-with-grafana-mimirtool)，了解如何使用 `mimirtool analyze`和 `mimirtool analyze prometheus`命令來識別儀表板中未參考的作用中指標。

### 考慮指標精細度
<a name="_consider_metric_granularity"></a>

以更高的精細度收集指標，例如每秒與每分鐘，可能會對收集和存放多少遙測產生重大影響，進而增加成本。判斷合理的抓取或指標收集間隔，在足夠的精細程度之間取得平衡，以查看暫時性問題，並降低到足以符合成本效益的程度。減少用於容量規劃和較大時段分析的指標精細度。

以下是預設 AWS Distro for Opentelemetry (ADOT) EKS 附加元件收集器[組態](https://docs.aws.amazon.com/eks/latest/userguide/deploy-deployment.html)的程式碼片段。

**重要**  
全域 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
```

## 追蹤
<a name="_tracing"></a>

與追蹤相關的主要成本來自追蹤儲存產生。透過追蹤，目標是收集足夠的資料來診斷和了解效能層面。不過，由於 X-Ray 追蹤成本是以轉送至 X-Ray 的資料為基礎，因此在轉送之後清除追蹤不會降低您的成本。讓我們檢閱降低追蹤成本的方法，同時維護資料以執行適當的分析。

### 套用取樣規則
<a name="_apply_sampling_rules"></a>

根據預設，X-Ray 取樣率是保守的。定義抽樣規則，您可以在其中控制收集的資料量。這將提高效能效率，同時降低成本。透過[降低取樣率](https://docs.aws.amazon.com/xray/latest/devguide/xray-console-sampling.html#xray-console-custom)，您可以從請求中收集追蹤，只需工作負載所需的項目，同時維持較低的成本結構。

例如，您有 java 應用程式，您想要偵錯 1 個有問題路由之所有請求的追蹤。

 **透過 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) 套用尾部取樣
<a name="_apply_tail_sampling_with_aws_distro_for_opentelemetry_adot"></a>

ADOT Tail Sampling 可讓您控制服務中擷取的追蹤量。不過， Tail Sampling 可讓您在請求中的所有範圍都完成後定義抽樣政策，而不是從頭開始。這進一步限制了傳輸到 CloudWatch 的原始資料量，進而降低成本。

例如，如果您要取樣 1% 的流量到登陸頁面，以及 10% 的請求到付款頁面，這可能會在 30 分鐘內讓您有 300 個追蹤。使用篩選特定錯誤的 ADOT Tail 取樣規則，您可以保留 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 Storage 選項
<a name="_leverage_amazon_s3_storage_options"></a>

您應該利用 AWS S3 儲存貯體及其不同的儲存類別來存放追蹤。在保留期間到期之前，將追蹤匯出至 S3。使用 Amazon S3 生命週期規則，將追蹤資料移至符合您需求的儲存類別。

例如，如果您有 90 天的追蹤，[Amazon S3 Intelligent-Tiering ](https://aws.amazon.com/s3/storage-classes/intelligent-tiering/)可以根據您的使用模式自動將資料移至長期儲存。如果您需要稍後再參考追蹤，您可以使用 [Amazon Athena](https://aws.amazon.com/athena/) 查詢 Amazon S3 中的資料。這可以進一步降低分散式追蹤的成本。

## 其他資源：
<a name="_additional_resources"></a>
+  [可觀測性最佳實務指南](https://aws-observability.github.io/observability-best-practices/guides/) 
+  [最佳實務指標集合](https://aws-observability.github.io/observability-best-practices/guides/containers/oss/eks/) 
+  [AWS re：Invent 2022 - Amazon (COP343) 的可觀測性最佳實務](https://www.youtube.com/watch?v=zZPzXEBW4P8) 
+  [AWS re：Invent 2022 - 可觀測性：現代應用程式的最佳實務 (COP344)](https://www.youtube.com/watch?v=YiegAlC_yyc) 