

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

# 비용 최적화 모범 사례
<a name="cost-opt"></a>

Cost Optimization은 최저 가격대로 비즈니스 성과를 달성하는 것입니다. 이 가이드의 설명서에 따라 Amazon EKS 워크로드를 최적화합니다.

## 일반 가이드라인
<a name="general-guidelines"></a>

클라우드에는 마이크로서비스의 비용 최적화를 달성하는 데 도움이 되는 여러 가지 일반 지침이 있습니다.
+ Amazon EKS에서 실행되는 워크로드가 컨테이너를 실행하기 위한 특정 인프라 유형과 독립적이어야 합니다. 이렇게 하면 비용이 가장 적게 드는 인프라 유형에서 실행할 때 유연성이 향상됩니다. Amazon EKS를 EC2와 함께 사용하는 동안 워크로드의 특성으로 인해 [GPU](https://docs.aws.amazon.com/eks/latest/userguide/gpu-ami.html) 또는 기타 인스턴스 유형과 같이 특정 유형의 EC2 인스턴스 유형이 필요한 워크로드가 있는 경우 예외가 있을 수 있습니다.
+ 최적으로 프로파일링된 컨테이너 인스턴스 선택 - [Amazon CloudWatch Container Insights for Amazon EKS](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/deploy-container-insights-EKS.html) 또는 Kubernetes 에코시스템에서 사용할 수 있는 타사 도구와 같은 서비스를 사용하여 프로덕션 또는 사전 프로덕션 환경을 프로파일링하고 CPU 및 메모리와 같은 중요한 지표를 모니터링합니다. 이렇게 하면 적절한 양의 리소스를 할당하고 리소스 낭비를 방지할 수 있습니다.
+ 온디맨드, 스팟 및 Savings Plan과 같이 EC2로 EKS를 실행하기 위해 AWS에서 사용할 수 있는 다양한 구매 옵션을 활용합니다.

## EKS 비용 최적화 모범 사례
<a name="eks-cost-optimization-best-practices"></a>

클라우드에서 비용 최적화를 위한 세 가지 일반적인 모범 사례 영역이 있습니다.
+ 비용 효율적인 리소스(Auto Scaling, Down Scaling, 정책 및 구매 옵션)
+ 지출 인식(AWS 및 타사 도구 사용)
+ 시간 경과에 따른 최적화(오른쪽 크기 조정)

모든 지침과 마찬가지로 장단점이 있습니다. 조직과 협력하여이 워크로드의 우선 순위와 가장 중요한 모범 사례를 이해해야 합니다.

### 이 설명서의 사용법
<a name="how-to-use-this-guide"></a>

이 가이드는 EKS 클러스터와 지원하는 워크로드를 구현하고 관리하는 데 책임이 있는 팀을 위해 작성되었습니다. 이 가이드는 사용하기 쉽도록 다양한 모범 사례 영역으로 구성되어 있습니다. 각 주제에는 EKS 클러스터의 비용 최적화에 사용할 권장 사항, 도구 및 모범 사례 목록이 있습니다. 주제는 특정 순서로 읽을 필요가 없습니다.

### 주요 AWS 서비스 및 Kubernetes 기능
<a name="key-aws-services-and-kubernetes-features"></a>

비용 최적화는 다음 AWS 서비스 및 기능에서 지원됩니다.
+ EC2 인스턴스 유형, Savings Plan(및 예약 인스턴스) 및 스팟 인스턴스를 다양한 가격으로 제공합니다.
+ Kubernetes 기본 Auto Scaling 정책과 함께 Auto Scaling. 예측 가능한 워크로드Savings Plan(이전 예약 인스턴스)을 고려하세요. 애플리케이션 데이터의 탄력성과 내구성을 위해 EBS 및 EFS와 같은 관리형 데이터 스토어를 사용합니다.
+ Billing and Cost Management 콘솔 대시보드와 AWS Cost Explorer는 AWS 사용량에 대한 개요를 제공합니다. 세분화된 결제 세부 정보는 AWS Organizations를 사용합니다. 여러 타사 도구에 대한 세부 정보도 공유되었습니다.
+ Amazon CloudWatch 컨테이너 지표는 EKS 클러스터의 리소스 사용에 대한 지표를 제공합니다. Kubernetes 대시보드 외에도 Kubernetes 에코시스템에는 낭비를 줄이는 데 사용할 수 있는 여러 도구가 있습니다.

이 안내서에는 Amazon EKS 클러스터의 비용 최적화를 개선하는 데 사용할 수 있는 권장 사항 세트가 포함되어 있습니다.

## Feedback
<a name="feedback"></a>

이 가이드는 더 광범위한 EKS/Kubernetes 커뮤니티에서 직접적인 피드백과 제안을 수집하기 위해 GitHub에서 릴리스됩니다. 가이드에 포함해야 한다고 생각되는 모범 사례가 있는 경우 GitHub 리포지토리에 문제를 제기하거나 PR을 제출하십시오. 새로운 기능이 서비스에 추가되거나 새로운 모범 사례가 발전할 때 가이드를 정기적으로 업데이트하는 것이 목적입니다.

# 비용 최적화 프레임워크
<a name="cost-opt-framework"></a>

AWS Cloud Economics는 Amazon EKS와 같은 최신 컴퓨팅 기술을 채택하여 고객이 효율성을 높이고 비용을 절감할 수 있도록 지원하는 분야입니다. 이 원칙에서는 다음 4가지 원칙으로 구성된 "Cloud Financial Management(CFM) 프레임워크"라는 방법론을 따를 것을 권장합니다.

![\[CFM 프레임워크\]](http://docs.aws.amazon.com/ko_kr/eks/latest/best-practices/images/cfm_framework.png)


## See 원칙: 측정 및 책임
<a name="_the_see_pillar_measurement_and_accountability"></a>

See 원칙은 클라우드 지출에 대한 책임을 측정, 모니터링 및 생성하는 방법을 정의하는 기본 활동 및 기술 세트입니다. "관찰성", "계측" 또는 "텔레메트리"라고도 합니다. "관찰성" 인프라의 기능과 제한에 따라 최적화할 수 있는 것이 결정됩니다. 어디에서 시작하는지 알아야 하므로 비용을 명확하게 파악하는 것은 비용 최적화의 중요한 첫 단계입니다. 이러한 유형의 가시성은 환경을 추가로 최적화하기 위해 수행해야 하는 활동 유형도 안내합니다.

다음은 See 원칙의 모범 사례에 대한 간략한 개요입니다.
+ 워크로드에 대한 태그 지정 전략을 정의하고 유지 관리합니다.
  + [인스턴스 태그 지정](https://docs.aws.amazon.com/eks/latest/userguide/eks-using-tags.html#tag-resources-for-billing), EKS 클러스터 태그 지정을 사용하면 개별 클러스터 비용을 확인하고 비용 및 사용 보고서에서 할당할 수 있습니다.
+ [Kubecost](https://www.ibm.com/docs/en/kubecost/self-hosted/2.x?topic=installations-amazon-eks-integration)와 같은 기술을 사용하여 EKS 사용량에 대한 보고 및 모니터링을 설정합니다.
  +  리소스에 적절한 태그를 지정하고 시각화를 사용하여 비용을 측정하고 추정할 수 있도록 [Cloud Intelligence Dashboards를 활성화합니다](https://wellarchitectedlabs.com/cost/200_labs/200_enterprise_dashboards/).
+ 애플리케이션, LoBs of Business) 및 수익 스트림에 클라우드 비용을 할당합니다.
+ 비즈니스 이해관계자와 함께 효율성/가치 KPIs. 예를 들어 트랜잭션당 비용을 측정하는 "단위 지표" KPI를 생성합니다. 예를 들어 승차 공유 서비스는 "승차당 비용"에 대한 KPI를 가질 수 있습니다.

이 원칙과 관련된 권장 기술 및 활동에 대한 자세한 내용은이 가이드의 [비용 최적화 - 관찰성](cost-opt-observability.md) 섹션을 참조하세요.

## 절감 원칙: 비용 최적화
<a name="_the_save_pillar_cost_optimization"></a>

이 원칙은 "See" 원칙에서 개발된 기술과 기능을 기반으로 합니다. 다음 활동은 일반적으로이 원칙에 속합니다.
+ 환경에서 낭비를 식별하고 제거합니다.
+ 비용 효율성을 위한 설계 및 설계.
+ 온디맨드 인스턴스와 스팟 인스턴스 등 가장 적합한 구매 옵션을 선택합니다.
+ 서비스가 발전함에 따라 적응: AWS 서비스가 발전함에 따라 해당 서비스를 효율적으로 사용하는 방법이 변경될 수 있습니다. 이러한 변경 사항을 고려하여 조정할 의향이 있어야 합니다.

이러한 활동은 운영되므로 환경의 특성에 따라 크게 달라집니다. 비용의 주요 동인은 무엇인지 자문해 보세요. 다양한 환경이 제공하는 비즈니스 가치는 무엇입니까? 인스턴스 패밀리 유형과 같은 구매 옵션 및 인프라 선택 사항은 각 환경에 가장 적합합니까?

다음은 EKS 클러스터의 가장 일반적인 비용 동인의 우선 순위 목록입니다.

1.  **컴퓨팅 비용:** 여러 유형의 인스턴스 패밀리, 구매 옵션, 확장성과 가용성의 균형을 결합하려면 신중하게 고려해야 합니다. 자세한 내용은이 가이드의 [비용 최적화 - 컴퓨팅](cost-opt-compute.md) 섹션의 권장 사항을 참조하세요.

1.  **네트워킹 비용:** EKS 클러스터에 3AZs를 사용하면 잠재적으로 AZ 간 트래픽 비용이 증가할 수 있습니다. HA 요구 사항과 네트워크 트래픽 비용 절감의 균형을 맞추는 방법에 대한 권장 사항은이 가이드의 [비용 최적화 - 네트워킹](cost-opt-networking.md) 섹션을 참조하세요.

1.  **스토리지 비용:** EKS 클러스터에서 워크로드의 상태 저장/상태 비저장 특성과 다양한 스토리지 유형이 사용되는 방식에 따라 스토리지를 워크로드의 일부로 고려할 수 있습니다. EKS 스토리지 비용과 관련된 고려 사항은이 가이드의 [비용 최적화 - 스토리지](cost-opt-storage.md) 섹션을 참조하세요.

## 계획 원칙: 계획 및 예측
<a name="_the_plan_pillar_planning_and_forecasting"></a>

See 원칙의 권장 사항이 구현되면 클러스터가 지속적으로 최적화됩니다. 클러스터를 효율적으로 운영하면서 경험을 쌓으면 계획 및 예측 활동에 집중할 수 있습니다.
+ 클라우드 비용을 동적으로 예산 책정 및 예측합니다.
+ EKS 컨테이너 서비스에서 제공하는 비즈니스 가치 정량화.
+ EKS 클러스터 비용 관리를 IT 재무 관리 계획과 통합합니다.

## 실행 원칙
<a name="_the_run_pillar"></a>

비용 최적화는 지속적인 프로세스이며 점진적 개선의 플라이 휠을 포함합니다.

![\[비용 최적화 플라이휠\]](http://docs.aws.amazon.com/ko_kr/eks/latest/best-practices/images/flywheel.png)


이러한 유형의 활동에 대한 경영진 후원을 확보하는 것은 EKS 클러스터 최적화를 조직의 "FinOps" 노력에 통합하는 데 매우 중요합니다. 이를 통해 이해관계자는 EKS 클러스터 비용에 대한 이해를 공유하고, EKS 클러스터 비용 가드레일을 구현하고, 도구, 자동화 및 활동이 조직의 필요에 따라 발전하도록 할 수 있습니다.

## 참조
<a name="_references"></a>
+  [AWS Cloud Economics, 클라우드 재무 관리](https://aws.amazon.com/aws-cost-management/) 

# 지출 인식
<a name="cost-opt-awareness"></a>

지출 인식은 EKS 클러스터에서 누가, 어디서, 무엇이 지출을 유발하는지 이해하는 것입니다. 이 데이터를 정확하게 파악하면 지출에 대한 인식을 높이고 해결해야 할 영역을 강조하는 데 도움이 됩니다.

## 권장 사항
<a name="_recommendations"></a>

### Cost Explorer 사용
<a name="_use_cost_explorer"></a>

 [AWS Cost Explorer](https://aws.amazon.com/aws-cost-management/aws-cost-explorer/)에는 시간이 지남에 따라 AWS 비용 및 사용량을 시각화, 이해 및 관리할 수 있는 easy-to-use 인터페이스가 있습니다. Cost Explorer에서 사용할 수 있는 필터를 사용하여 다양한 수준에서 비용 및 사용량 데이터를 분석할 수 있습니다.

#### EKS 컨트롤 플레인 및 EKS Fargate 비용
<a name="_eks_control_plane_and_eks_fargate_costs"></a>

아래 다이어그램과 같이 필터를 사용하여 컨트롤 플레인 및 Fargate 포드에서 EKS 비용에 대해 발생한 비용을 쿼리할 수 있습니다.

![\[Cost Explorer - EKS 제어 플레인\]](http://docs.aws.amazon.com/ko_kr/eks/latest/best-practices/images/eks-controlplane-costexplorer.png)


필터를 사용하여 아래 다이어그램과 같이 CPU당 vCPU 시간 및 GB 시간 모두를 포함하는 EKS의 리전에서 Fargate 포드에 대해 발생한 총 비용을 쿼리할 수 있습니다.

![\[Cost Explorer - EKS Fargate\]](http://docs.aws.amazon.com/ko_kr/eks/latest/best-practices/images/eks-fargate-costexplorer.png)


#### 리소스 태그 지정
<a name="_tagging_of_resources"></a>

Amazon EKS는 Amazon EKS 클러스터에 [AWS 태그 추가](https://docs.aws.amazon.com/eks/latest/userguide/eks-using-tags.html)를 지원합니다. 이렇게 하면 클러스터 관리를 위해 EKS API에 대한 액세스를 쉽게 제어할 수 있습니다. EKS 클러스터에 추가된 태그는 AWS EKS 클러스터 리소스에 고유하며 EC2 인스턴스 또는 로드 밸런서와 같이 클러스터에서 사용하는 다른 AWS 리소스로 전파되지 않습니다. 현재 클러스터 태그 지정은 AWS API, 콘솔 및 SDKs.

AWS Fargate는 컨테이너에 적합한 크기의 온디맨드 컴퓨팅 용량을 제공하는 기술입니다. 클러스터의 Fargate에 포드를 예약하려면 먼저 포드가 시작될 때 Fargate를 사용할 포드를 지정하는 Fargate 프로필을 하나 이상 정의해야 합니다.

EKS 클러스터에 태그 추가 및 나열:

```
$ aws eks tag-resource --resource-arn arn:aws:eks:us-west-2:xxx:cluster/ekscluster1 --tags team=devops,env=staging,bu=cio,costcenter=1234
$ aws eks list-tags-for-resource --resource-arn arn:aws:eks:us-west-2:xxx:cluster/ekscluster1
{
    "tags": {
        "bu": "cio",
        "env": "staging",
        "costcenter": "1234",
        "team": "devops"
    }
}
```

[AWS Cost Explorer](https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/cost-alloc-tags.html)에서 비용 할당 태그를 활성화하면 AWS는 비용 할당 태그를 사용하여 비용 할당 보고서에 리소스 비용을 구성하므로 AWS 비용을 쉽게 분류하고 추적할 수 있습니다.

태그는 Amazon EKS에는 아무런 의미가 없으며 엄격하게 문자열로 해석됩니다. 예를 들어, Amazon EKS 클러스터에 태그 집합을 정의하면 클러스터의 소유자 및 스택 수준을 추적하는 데 도움이 됩니다.

### AWS Trusted Advisor 사용
<a name="_use_aws_trusted_advisor"></a>

AWS Trusted Advisor는 비용 최적화, 보안, 내결함성, 성능 및 서비스 제한의 5가지 범주에 걸쳐 다양한 모범 사례 확인 및 권장 사항을 제공합니다.

비용 최적화의 경우 Trusted Advisor는 미사용 및 유휴 리소스를 제거하는 데 도움이 되며 예약된 용량을 약정할 것을 권장합니다. Amazon EKS에 도움이 되는 주요 작업 항목은 사용률이 낮은 EC2 인스턴스, 연결되지 않은 탄력적 IP 주소, 유휴 로드 밸런서, 사용률이 낮은 EBS 볼륨 등입니다. 검사의 전체 목록은 https://aws.amazon.com/premiumsupport/technology/trusted-advisor/best-practice-checklist/ 제공됩니다.

또한 Trusted Advisor는 할인 요금에 대한 대가로 일관된 사용량을 약정할 수 있도록 EC2 인스턴스 및 Fargate에 대한 Savings Plans 및 예약 인스턴스 권장 사항을 제공합니다.

**참고**  
Trusted Advisor의 권장 사항은 일반적인 권장 사항이며 EKS에만 국한되지 않습니다.

### Kubernetes 대시보드 사용
<a name="_use_the_kubernetes_dashboard"></a>

 ** *Kubernetes 대시보드* ** 

Kubernetes 대시보드는 Kubernetes 클러스터용 범용 웹 기반 UI로, 클러스터, 노드 및 포드 수준의 리소스 사용량을 포함하여 Kubernetes 클러스터에 대한 정보를 제공합니다. Amazon EKS 클러스터에 Kubernetes 대시보드를 배포하는 방법은 [Amazon EKS 설명서에](https://docs.aws.amazon.com/eks/latest/userguide/dashboard-tutorial.html) 설명되어 있습니다.

대시보드는 각 노드 및 포드에 대한 리소스 사용 내역과 포드, 서비스, 배포 및 기타 Kubernetes 객체에 대한 자세한 메타데이터를 제공합니다. 이 통합 정보는 Kubernetes 환경에 대한 가시성을 제공합니다.

![\[Kubernetes 대시보드\]](http://docs.aws.amazon.com/ko_kr/eks/latest/best-practices/images/kubernetes-dashboard.png)


 ** *kubectl 상단 및 설명 명령* ** 

kubectl top 및 kubectl을 사용하여 리소스 사용량 지표를 보면 명령을 설명합니다. kubectl top은 클러스터 전체의 포드 또는 노드 또는 특정 포드 또는 노드에 대한 현재 CPU 및 메모리 사용량을 표시합니다. kubectl describe 명령은 특정 노드 또는 포드에 대한 자세한 정보를 제공합니다.

```
$ kubectl top pods
$ kubectl top nodes
$ kubectl top pod pod-name --namespace mynamespace --containers
```

출력에는 최상위 명령을 사용하여 노드가 사용하는 총 CPU(코어) 및 메모리(MiB) 양과 해당 숫자가 나타내는 노드의 할당 용량 백분율이 표시됩니다. 그런 다음 *--containers* 플래그를 추가하여 포드 내의 다음 수준인 컨테이너 수준으로 드릴다운할 수 있습니다.

```
$ kubectl describe node <node>
$ kubectl describe pod <pod>
```

 *kubectl describe*는 각 리소스 요청 또는 제한이 나타내는 총 가용 용량의 백분율을 반환합니다.

kubectl Top and describe는 kubernetes 포드, 노드 및 컨테이너에서 CPU, 메모리 및 스토리지와 같은 중요한 리소스의 사용률과 가용성을 추적합니다. 이러한 인식은 리소스 사용량을 이해하고 비용을 관리하는 데 도움이 됩니다.

### CloudWatch Container Insights 사용
<a name="_use_cloudwatch_container_insights"></a>

[CloudWatch Container Insights](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/deploy-container-insights-EKS.html)를 사용하여 컨테이너화된 애플리케이션 및 마이크로서비스에서 지표와 로그를 수집, 집계 및 요약할 수 있습니다. Container Insights는 EC2의 Amazon Elastic Kubernetes Service와 Amazon EC2의 Kubernetes 플랫폼에서 사용할 수 있습니다. 이 지표에는 CPU, 메모리, 디스크, 네트워크 같은 리소스 사용률이 포함되어 있습니다.

인사이트 설치는 [설명서에](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/deploy-container-insights-EKS.html) 나와 있습니다.

CloudWatch는 클러스터, 노드, 포드, 작업 및 서비스 수준에서 집계된 지표를 CloudWatch 지표로 생성합니다.

 **다음 쿼리는 평균 노드 CPU 사용률을 기준으로 정렬된 노드 목록을 보여줍니다.**

```
STATS avg(node_cpu_utilization) as avg_node_cpu_utilization by NodeName
| SORT avg_node_cpu_utilization DESC
```

 **컨테이너 이름별 CPU 사용량** 

```
stats pct(container_cpu_usage_total, 50) as CPUPercMedian by kubernetes.container_name
| filter Type="Container"
```

 **컨테이너 이름별 디스크 사용량** 

```
stats floor(avg(container_filesystem_usage/1024)) as container_filesystem_usage_avg_kb by InstanceId, kubernetes.container_name, device
| filter Type="ContainerFS"
| sort container_filesystem_usage_avg_kb desc
```

[Container Insights 문서에](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Container-Insights-view-metrics.html) 더 많은 샘플 쿼리가 제공됩니다.

이러한 인식은 리소스 사용량을 이해하고 비용을 관리하는 데 도움이 됩니다.

### 지출 인식 및 지침에 Kubecost 사용
<a name="_using_kubecost_for_expenditure_awareness_and_guidance"></a>

[kubecost](https://kubecost.com/)와 같은 타사 도구를 Amazon EKS에 배포하여 Kubernetes 클러스터 실행 비용을 파악할 수도 있습니다. Kubecost를 사용하여 비용을 추적하려면이 [AWS 블로그](https://aws.amazon.com/blogs/containers/how-to-track-costs-in-multi-tenant-amazon-eks-clusters-using-kubecost/)를 참조하세요.

Helm 3을 사용하여 kubecost 배포:

```
$ curl -sSL https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash
$ helm version --short
v3.2.1+gfe51cd1
$ helm repo add stable https://kubernetes-charts.storage.googleapis.com/
$ helm repo add stable https://kubernetes-charts.storage.googleapis.com/c^C
$ kubectl create namespace kubecost
namespace/kubecost created
$ helm repo add kubecost https://kubecost.github.io/cost-analyzer/
"kubecost" has been added to your repositories

$ helm install kubecost kubecost/cost-analyzer --namespace kubecost --set kubecostToken="aGRoZEBqc2pzLmNvbQ==xm343yadf98"
NAME: kubecost
LAST DEPLOYED: Mon May 18 08:49:05 2020
NAMESPACE: kubecost
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
--------------------------------------------------Kubecost has been successfully installed. When pods are Ready, you can enable port-forwarding with the following command:

    kubectl port-forward --namespace kubecost deployment/kubecost-cost-analyzer 9090

Next, navigate to http://localhost:9090 in a web browser.
$ kubectl port-forward --namespace kubecost deployment/kubecost-cost-analyzer 9090

NOTE: If you are using Cloud 9 or have a need to forward it to a different port like 8080, issue the following command
$ kubectl port-forward --namespace kubecost deployment/kubecost-cost-analyzer 8080:9090
```

Kubecost 대시보드 - ![\[Kubernetes Cluster Auto Scaler logs\]](http://docs.aws.amazon.com/ko_kr/eks/latest/best-practices/images/kube-cost.png) 

### Kubernetes 비용 할당 및 용량 계획 분석 도구 사용
<a name="_use_kubernetes_cost_allocation_and_capacity_planning_analytics_tool"></a>

 [Kubernetes Opex Analytics](https://github.com/rchakode/kube-opex-analytics)는 조직이 Kubernetes 클러스터에서 사용 중인 리소스를 추적하여 초과 지불을 방지하는 데 도움이 되는 도구입니다. 이를 위해 각 프로젝트가 시간 경과에 따라 지출하는 리소스의 양에 대한 관련 인사이트를 보여주는 단기(7일), 중기(14일) 및 장기(12개월) 사용 보고서를 생성합니다.

![\[Kubernetes Opex 분석\]](http://docs.aws.amazon.com/ko_kr/eks/latest/best-practices/images/kube-opex-analytics.png)


### 요타스케일
<a name="_yotascale"></a>

Yotascale은 Kubernetes 비용을 정확하게 할당하는 데 도움이 됩니다. Yotascale Kubernetes 비용 할당 기능은 일반 시장 요금 추정 대신 예약 인스턴스 할인 및 스팟 인스턴스 요금을 포함하는 실제 비용 데이터를 활용하여 총 Kubernetes 비용 발자국을 알립니다.

자세한 내용은 [웹 사이트에서 확인할 수 있습니다](https://www.yotascale.com/).

### Alcide Advisor
<a name="_alcide_advisor"></a>

Alcide는 AWS 파트너 네트워크(APN) 고급 기술 파트너입니다. Alcide Advisor를 사용하면 Amazon EKS 클러스터, 노드 및 포드 구성이 보안 모범 사례 및 내부 지침에 따라 실행되도록 조정할 수 있습니다. Alcide Advisor는 프로덕션으로 이동하기 전에 개발 단계를 강화하여 원활하고 안전한 DevSecOps 흐름을 보장하도록 구축된 Kubernetes 감사 및 규정 준수를 위한 에이전트 없는 서비스입니다.

자세한 내용은이 [블로그 게시물](https://aws.amazon.com/blogs/apn/driving-continuous-security-and-configuration-checks-for-amazon-eks-with-alcide-advisor/)에서 확인할 수 있습니다.

## 기타 도구
<a name="_other_tools"></a>

### Kubernetes 가비지 수집
<a name="_kubernetes_garbage_collection"></a>

[Kubernetes 가비지 수집기의](https://kubernetes.io/docs/concepts/workloads/controllers/garbage-collection/) 역할은 한 번 소유자가 있었지만 더 이상 소유자가 없는 특정 객체를 삭제하는 것입니다.

### Fargate 수
<a name="_fargate_count"></a>

 [Fargatecount](https://github.com/mreferre/fargatecount)는 AWS 고객이 사용자 지정 CloudWatch 지표를 사용하여 특정 계정의 특정 리전에서 Fargate에 배포된 총 EKS 포드 수를 추적할 수 있는 유용한 도구입니다. 이렇게 하면 EKS 클러스터에서 실행되는 모든 Fargate 포드를 추적하는 데 도움이 됩니다.

### 팝아이 - Kubernetes 클러스터 새니타이저
<a name="_popeye_a_kubernetes_cluster_sanitizer"></a>

 [Popeye - Kubernetes 클러스터 새니타이저](https://github.com/derailed/popeye)는 라이브 Kubernetes 클러스터를 스캔하고 배포된 리소스 및 구성과 관련된 잠재적 문제를 보고하는 유틸리티입니다. 디스크에 있는 것이 아니라 배포된 것을 기반으로 클러스터를 삭제합니다. 클러스터를 스캔하면 잘못된 구성을 감지하고 모범 사례가 적용되도록 하는 데 도움이 됩니다.

### 리소스
<a name="_resources"></a>

비용 최적화 모범 사례에 대해 자세히 알아보려면 다음 리소스를 참조하세요.

#### 설명서 및 블로그
<a name="_documentation_and_blogs"></a>
+  [Amazon EKS에서 태그 지정 지원](https://docs.aws.amazon.com/eks/latest/userguide/eks-using-tags.html) 

#### 도구
<a name="_tools"></a>
+  [AWS Billing and Cost Management란 무엇입니까?](https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/cost-alloc-tags.html)
+  [Amazon CloudWatch Container Insights](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/ContainerInsights.html) 
+  [Kubecost를 사용하여 멀티 테넌트 Amazon EKS 클러스터의 비용을 추적하는 방법](https://aws.amazon.com/blogs/containers/how-to-track-costs-in-multi-tenant-amazon-eks-clusters-using-kubecost/) 
+  [Kubecost](https://kubecost.com/) 
+  [Kube Opsview](https://github.com/hjacobs/kube-ops-view) 
+  [Kubernetes Opex 분석](https://github.com/rchakode/kube-opex-analytics) 

# 컴퓨팅 및 오토 스케일링
<a name="cost-opt-compute"></a>

개발자는 CPU 및 메모리와 같은 애플리케이션의 리소스 요구 사항을 추정하지만 지속적으로 조정하지 않으면 비용이 증가하고 성능과 신뢰성이 저하될 수 있습니다. 애플리케이션의 리소스 요구 사항을 지속적으로 조정하는 것이 처음부터 올바르게 조정하는 것보다 중요합니다.

아래에 언급된 모범 사례는 비용을 최소화하고 조직이 투자 수익을 극대화할 수 있도록 하면서 비즈니스 성과를 달성하는 비용 인식 워크로드를 구축하고 운영하는 데 도움이 됩니다. 클러스터 컴퓨팅 비용 최적화의 중요도는 다음과 같습니다.

1. 적절한 크기의 워크로드

1. 미사용 용량 감소

1. 컴퓨팅 용량 유형(예: 스팟) 및 액셀러레이터(예: GPUs) 최적화

## 워크로드 크기 조정
<a name="_right_size_your_workloads"></a>

대부분의 EKS 클러스터에서 대부분의 비용은 컨테이너화된 워크로드를 실행하는 데 사용되는 EC2 인스턴스에서 발생합니다. 워크로드 요구 사항을 이해하지 않으면 컴퓨팅 리소스의 크기를 조정할 수 없습니다. 따라서 적절한 요청 및 제한을 사용하고 필요에 따라 해당 설정을 조정해야 합니다. 또한 인스턴스 크기 및 스토리지 선택과 같은 종속성은 워크로드 성능에 영향을 미쳐 비용 및 신뢰성에 의도하지 않은 다양한 결과를 초래할 수 있습니다.

 *요청은* 실제 사용률과 일치해야 합니다. 컨테이너의 요청이 너무 높으면 총 클러스터 비용에서 큰 요인인 미사용 용량이 있습니다. 애플리케이션 및 사이드카와 같은 포드의 각 컨테이너에는 집계 포드 제한이 최대한 정확하도록 자체 요청 및 제한이 설정되어 있어야 합니다.

컨테이너에 대한 리소스 요청 및 제한을 추정하는 [Goldilocks](https://www.youtube.com/watch?v=DfmQWYiwFDk), [KRR](https://www.youtube.com/watch?v=uITOzpf82RY) 및 [Kubecost](https://aws.amazon.com/blogs/containers/aws-and-kubecost-collaborate-to-deliver-cost-monitoring-for-eks-customers/)와 같은 도구를 활용합니다. 애플리케이션의 특성, 성능/비용 요구 사항 및 복잡성에 따라 확장하기에 가장 적합한 지표, 애플리케이션 성능이 저하되는 시점(포화점), 그에 따라 요청 및 제한을 조정하는 방법을 평가해야 합니다. 이 주제에 대한 추가 지침은 [애플리케이션 오른쪽 크기 조정](https://docs.aws.amazon.com/eks/latest/best-practices/node_and_workload_efficiency.html)을 참조하세요.

Horizontal Pod Autoscaler(HPA)를 사용하여 실행해야 하는 애플리케이션의 복제본 수를 제어하고, Vertical Pod Autoscaler(VPA)를 사용하여 복제본당 애플리케이션 요구 사항을 조정하고 제한하며, [Karpenter](http://karpenter.sh/) 또는 [Cluster Autoscaler와 같은 노드 Autoscaler](https://github.com/kubernetes/autoscaler)를 사용하여 클러스터의 총 노드 수를 지속적으로 조정하는 것이 좋습니다. Karpenter 및 Cluster Autoscaler를 사용한 비용 최적화 기법은이 문서의 뒷부분에 설명되어 있습니다.

Vertical Pod Autoscaler는 워크로드가 최적으로 실행되도록 컨테이너에 할당된 요청 및 제한을 조정할 수 있습니다. VPA가 자동으로 변경되지 않고 포드를 다시 시작하지 않도록 감사 모드에서 VPA를 실행해야 합니다. 관찰된 지표를 기반으로 변경 사항을 제안합니다. 프로덕션 워크로드에 영향을 미치는 변경 사항이 있는 경우 먼저 비프로덕션 환경에서 변경 사항을 검토하고 테스트해야 합니다. 이러한 변경 사항은 애플리케이션의 신뢰성과 성능에 영향을 미칠 수 있기 때문입니다.

## 소비 감소
<a name="_reduce_consumption"></a>

비용을 절감하는 가장 좋은 방법은 리소스를 더 적게 프로비저닝하는 것입니다. 이를 위한 한 가지 방법은 현재 요구 사항에 따라 워크로드를 조정하는 것입니다. 워크로드가 요구 사항을 정의하고 동적으로 확장되도록 하여 비용 최적화 작업을 시작해야 합니다. 이렇게 하려면 애플리케이션에서 지표를 가져오고 [https://kubernetes.io/docs/tasks/run-application/configure-pdb/](https://kubernetes.io/docs/tasks/run-application/configure-pdb/) 및 [포드 준비 게이트](https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.5/deploy/pod_readiness_gate/)와 같은 구성을 설정하여 애플리케이션이 동적으로 안전하게 확장 및 축소될 수 있도록 해야 합니다. Cluster Autoscaler와 Karpenter는 모두 PodDisruptionBudgets를 준수하므로 제한적인 PodDisruptionBudgets. PodDisruptionBudget의 'minAvailable' 값은 항상 배포의 포드 수보다 작아야 하며 두 포드 사이에 적절한 버퍼를 유지해야 합니다. 예를 들어, 6개의 포드를 배포하여 항상 최소 4개의 포드를 실행하려면 PodDisruptionBidget의 'minAvailable'을 4로 설정합니다. 이렇게 하면 Cluster Autoscaler와 Karpenter가 노드 스케일 다운 이벤트 중에 사용률이 낮은 노드에서 포드를 안전하게 드레이닝하고 제거할 수 있습니다. [Cluster Autoscaler FAQ](https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/FAQ.md#what-types-of-pods-can-prevent-ca-from-removing-a-node) 문서를 참조하세요.

Horizontal Pod Autoscaler는 애플리케이션의 성능 및 안정성 요구 사항을 충족하는 데 필요한 복제본 수를 조정할 수 있는 유연한 워크로드 Autoscaler입니다. CPU, 메모리 또는 대기열 깊이, 포드에 대한 연결 수 등과 같은 사용자 지정 지표와 같은 다양한 지표를 기반으로 스케일 업 및 스케일 다운 시기를 정의하는 유연한 모델이 있습니다.

Kubernetes 지표 서버는 CPU 및 메모리 사용량과 같은 기본 제공 지표에 대한 응답으로 규모 조정을 활성화하지만 Amazon CloudWatch 또는 SQS 대기열 깊이와 같은 다른 지표를 기반으로 규모 조정하려는 경우 [KEDA](https://keda.sh/)와 같은 이벤트 기반 Auto Scaling 프로젝트를 고려해야 합니다. CloudWatch 지표와 함께 KEDA를 사용하는 방법은 [이 블로그 게시물](https://aws.amazon.com/blogs/mt/proactive-autoscaling-of-kubernetes-workloads-with-keda-using-metrics-ingested-into-amazon-cloudwatch/)을 참조하세요. 모니터링 및 확장 기준이 되는 지표를 잘 모르는 경우 [중요한 지표 모니터링에 대한 모범 사례를](https://aws-observability.github.io/observability-best-practices/guides/#monitor-what-matters) 확인하세요.

워크로드 소비를 줄이면 클러스터에 초과 용량이 생성되고 적절한 오토 스케일링 구성을 통해 노드를 자동으로 스케일 다운하고 총 지출을 줄일 수 있습니다. 컴퓨팅 용량을 수동으로 최적화하지 않는 것이 좋습니다. Kubernetes 스케줄러 및 노드 오토스케일러는이 프로세스를 처리하도록 설계되었습니다.

## 미사용 용량 감소
<a name="_reduce_unused_capacity"></a>

애플리케이션의 올바른 크기를 결정하여 초과 요청을 줄이면 프로비저닝된 컴퓨팅 용량을 줄일 수 있습니다. 위의 섹션에서 워크로드의 크기를 올바르게 조정하는 데 시간이 걸린 경우 동적으로이 작업을 수행할 수 있습니다. AWS의 Kubernetes에는 두 개의 프라이머리 노드 오토스케일러가 사용됩니다.

### Karpenter 및 Cluster Autoscaler
<a name="_karpenter_and_cluster_autoscaler"></a>

포드가 생성되거나 제거되고 컴퓨팅 요구 사항이 변경되면 Karpenter와 Kubernetes Cluster Autoscaler 모두 클러스터의 노드 수를 조정합니다. 두 가지 모두의 기본 목표는 동일하지만 Karpenter는 노드 관리 프로비저닝 및 프로비저닝 해제에 대해 다른 접근 방식을 취하여 비용을 절감하고 클러스터 전체 사용을 최적화하는 데 도움이 될 수 있습니다.

클러스터의 크기가 커지고 워크로드가 다양해지면 노드 그룹 및 인스턴스를 사전 구성하기가 더 어려워집니다. 워크로드 요청과 마찬가지로 초기 기준을 설정하고 필요에 따라 지속적으로 조정하는 것이 중요합니다.

Cluster Autoscaler를 사용하는 경우 각 Auto Scaling 그룹(ASG)의 "최소" 및 "최대" 값을 준수하고 "원하는" 값만 조정합니다. Cluster Autoscaler는 "최소" 수를 초과하여 ASG를 스케일 다운할 수 없으므로 기본 ASG에 대해 이러한 값을 설정하는 동안 주의해야 합니다. "원하는" 수를 정상 업무 시간에 필요한 노드 수로 설정하고 "최소"를 업무 외 시간에 필요한 노드 수로 설정합니다. [Cluster Autoscaler FAQ](https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/aws/README.md#auto-discovery-setup) 문서를 참조하세요.

### Cluster Autoscaler Priority 확장 프로그램
<a name="_cluster_autoscaler_priority_expander"></a>

Kubernetes Cluster Autoscaler는 애플리케이션이 확장 및 축소됨에 따라 노드 그룹이라고 하는 노드 그룹을 확장 및 축소하여 작동합니다. 워크로드를 동적으로 조정하지 않는 경우 Cluster Autoscaler는 비용을 절감하는 데 도움이 되지 않습니다. Cluster Autoscaler를 사용하려면 클러스터 관리자가 노드 그룹을 미리 생성해야 합니다. 노드 그룹은 "profile"이 동일한 인스턴스, 즉 대략 동일한 양의 CPU와 메모리를 사용하도록 구성해야 합니다.

여러 노드 그룹을 가질 수 있으며, 우선 순위 조정 수준을 설정하도록 Cluster Autoscaler를 구성할 수 있으며, 각 노드 그룹에는 다양한 크기의 노드가 포함될 수 있습니다. 노드 그룹은 다양한 용량 유형을 가질 수 있으며 우선 순위 확장기를 사용하여 더 저렴한 그룹을 먼저 확장할 수 있습니다.

다음은 온디맨드 인스턴스를 사용하기 전에 `ConfigMap``를 사용하여 예약 용량의 우선 순위를 지정하는 클러스터 구성 조각의 예입니다. 동일한 기술을 사용하여 다른 유형보다 Graviton 또는 스팟 인스턴스의 우선 순위를 지정할 수 있습니다.

```
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
  name: my-cluster
managedNodeGroups:
  - name: managed-ondemand
    minSize: 1
    maxSize: 7
    instanceType: m5.xlarge
  - name: managed-reserved
    minSize: 2
    maxSize: 10
    instanceType: c5.2xlarge
```

```
apiVersion: v1
kind: ConfigMap
metadata:
  name: cluster-autoscaler-priority-expander
  namespace: kube-system
data:
  priorities: |-
    10:
      - .*ondemand.*
    50:
      - .*reserved.*
```

노드 그룹을 사용하면 기본 컴퓨팅 리소스가 기본적으로 예상되는 작업을 수행하는 데 도움이 될 수 있습니다. 예를 들어 노드를 AZs에 분산하지만 모든 워크로드에 동일한 요구 사항 또는 기대치가 있는 것은 아니며 애플리케이션이 요구 사항을 명시적으로 선언하도록 하는 것이 좋습니다. Cluster Autoscaler에 대한 자세한 내용은 [모범 사례 섹션을](https://docs.aws.amazon.com/eks/latest/best-practices/cas.html) 참조하세요.

### 디스케줄러
<a name="_descheduler"></a>

Cluster Autoscaler는 예약이 필요한 새 포드 또는 사용률이 낮은 노드를 기반으로 클러스터에서 노드 용량을 추가하고 제거할 수 있습니다. 노드로 예약된 후에는 포드 배치를 전체적으로 볼 수 없습니다. Cluster Autoscaler를 사용하는 경우 클러스터의 용량이 낭비되지 않도록 [Kubernetes 스케줄러](https://github.com/kubernetes-sigs/descheduler)도 확인해야 합니다.

클러스터에 노드가 10개 있고 각 노드가 60% 사용되는 경우 클러스터에서 프로비저닝된 용량의 40%를 사용하지 않는 것입니다. Cluster Autoscaler를 사용하면 노드당 사용률 임계값을 60%로 설정할 수 있지만 사용률이 60% 미만으로 떨어진 후에만 단일 노드를 축소하려고 시도합니다.

디스케줄러를 사용하면 포드가 예약되거나 노드가 클러스터에 추가된 후 클러스터 용량과 사용률을 확인할 수 있습니다. 클러스터의 총 용량을 지정된 임계값 이상으로 유지하려고 시도합니다. 또한 노드 테인트 또는 클러스터에 조인하는 새 노드를 기반으로 포드를 제거하여 포드가 최적의 컴퓨팅 환경에서 실행되고 있는지 확인할 수 있습니다. 디스케줄러는 제거된 포드의 교체를 예약하지 않지만 이에 대한 기본 스케줄러를 사용합니다.

### Karpenter 통합
<a name="_karpenter_consolidation"></a>

Karpenter는 노드 관리에 "그룹 없는" 접근 방식을 취합니다. 이 접근 방식은 다양한 워크로드 유형에 대해 더 유연하며 클러스터 관리자의 사전 구성이 덜 필요합니다. 그룹을 사전 정의하고 워크로드에 따라 각 그룹을 조정하는 대신 Karpenter는 프로비저너와 노드 템플릿을 사용하여 생성할 수 있는 EC2 인스턴스 유형과 인스턴스가 생성될 때 인스턴스에 대한 설정을 광범위하게 정의합니다.

빈 패킹은 더 적은 수의 최적의 크기의 인스턴스에 더 많은 워크로드를 패킹하여 인스턴스의 리소스를 더 많이 활용하는 방법입니다. 이렇게 하면 워크로드가 사용하는 리소스만 프로비저닝하여 컴퓨팅 비용을 줄이는 데 도움이 되지만 장단점이 있습니다. 특히 대규모 조정 이벤트 시 용량을 클러스터에 추가해야 하므로 새 워크로드를 시작하는 데 더 오래 걸릴 수 있습니다. 빈 패킹을 설정할 때 비용 최적화, 성능 및 가용성 간의 균형을 고려하세요.

Karpenter는 지속적으로 모니터링하고 binpack하여 인스턴스 리소스 사용률을 개선하고 컴퓨팅 비용을 절감할 수 있습니다. Karpenter는 워크로드에 대해 보다 비용 효율적인 작업자 노드를 선택할 수도 있습니다. 이는 프로비저너에서 "통합" 플래그를 true로 설정하여 달성할 수 있습니다(아래 샘플 코드 조각). 아래 예제는 통합을 활성화하는 프로비저너 예제를 보여줍니다. 이 안내서를 작성할 때 Karpenter는 실행 중인 스팟 인스턴스를 더 저렴한 스팟 인스턴스로 대체하지 않습니다. Karpenter 통합에 대한 자세한 내용은 [이 블로그](https://aws.amazon.com/blogs/containers/optimizing-your-kubernetes-compute-costs-with-karpenter-consolidation/)를 참조하세요.

```
apiVersion: karpenter.sh/v1
kind: Provisioner
metadata:
  name: enable-binpacking
spec:
  consolidation:
    enabled: true
```

체크포인트가 없는 장기 실행 배치 작업과 같이 중단이 불가능할 수 있는 워크로드의 경우 포드에 `do-not-evict` 주석을 추가하는 것이 좋습니다. 포드를 제거에서 옵트아웃하면 Karpenter에이 포드가 포함된 노드를 자발적으로 제거해서는 안 된다고 알립니다. 그러나 노드가 `do-not-evict` 드레이닝되는 동안 포드가 노드에 추가되면 나머지 포드는 여전히 제거되지만 해당 포드는 제거될 때까지 종료를 차단합니다. 어느 경우든 노드에 추가 작업이 예약되지 않도록 노드가 연결됩니다. 다음은 주석을 설정하는 방법을 보여주는 예제입니다.

```
apiVersion: v1
kind: Pod
metadata:
  name: label-demo
  labels:
    environment: production
  annotations: +
    "karpenter.sh/do-not-evict": "true"
spec:
  containers:

* name: nginx
image: nginx
ports:
 ** containerPort: 80
```

### Cluster Autoscaler 파라미터를 조정하여 사용률이 낮은 노드 제거
<a name="_remove_under_utilized_nodes_by_adjusting_cluster_autoscaler_parameters"></a>

노드 사용률은 요청된 리소스의 합계를 용량으로 나눈 값으로 정의됩니다. 기본적으로 `scale-down-utilization-threshold`는 50%로 설정됩니다. 이 파라미터는 및와 함께 사용할 수 `scale-down-unneeded-time`있습니다.이 파라미터는 노드가 스케일 다운에 적합하기 전에 필요 없는 시간을 결정합니다. 기본값은 10분입니다. 축소된 노드에서 계속 실행 중인 포드는 kube-scheduler에 의해 다른 노드에서 예약됩니다. 이러한 설정을 조정하면 사용률이 낮은 노드를 제거하는 데 도움이 될 수 있지만 클러스터가 조기에 축소되지 않도록 먼저 이러한 값을 테스트하는 것이 중요합니다.

제거 비용이 많이 드는 포드가 Cluster Autoscaler에서 인식하는 레이블로 보호되도록 하여 스케일 다운이 발생하지 않도록 할 수 있습니다. 이렇게 하려면 제거 비용이 많이 드는 포드에 주석이 있어야 합니다`cluster-autoscaler.kubernetes.io/safe-to-evict=false`. 다음은 주석을 설정하는 yaml의 예입니다.

```
apiVersion: v1
kind: Pod
metadata:
  name: label-demo
  labels:
    environment: production
  annotations: +
    "cluster-autoscaler.kubernetes.io/safe-to-evict": "false"
spec:
  containers:

* name: nginx
image: nginx
ports:
 ** containerPort: 80
```

### Cluster Autoscaler 및 Karpenter를 사용하여 노드에 태그 지정
<a name="_tag_nodes_with_cluster_autoscaler_and_karpenter"></a>

AWS 리소스 [태그](https://docs.aws.amazon.com/tag-editor/latest/userguide/tagging.html)는 리소스를 구성하고 AWS 비용을 세부적으로 추적하는 데 사용됩니다. 비용 추적을 위해 Kubernetes 레이블과 직접 연관되지 않습니다. Kubernetes 리소스 레이블 지정으로 시작하고 [Kubecost](https://aws.amazon.com/blogs/containers/aws-and-kubecost-collaborate-to-deliver-cost-monitoring-for-eks-customers/)와 같은 도구를 활용하여 포드, 네임스페이스 등의 Kubernetes 레이블을 기반으로 인프라 비용 보고를 받는 것이 좋습니다.

작업자 노드에는 AWS Cost Explorer에 결제 정보를 표시하는 태그가 있어야 합니다. Cluster Autoscaler를 사용하면 [시작 템플릿을](https://docs.aws.amazon.com/eks/latest/userguide/launch-templates.html) 사용하여 관리형 노드 그룹 내의 작업자 노드에 태그를 지정합니다. 자체 관리형 노드 그룹의 경우 [EC2 Auto Scaling 그룹을](https://docs.aws.amazon.com/autoscaling/ec2/userguide/ec2-auto-scaling-tagging.html) 사용하여 인스턴스에 태그를 지정합니다. Karpenter에서 프로비저닝한 인스턴스[의 경우 노드 템플릿에서 spec.tags](https://karpenter.sh/docs/concepts/nodeclasses/#spectags)를 사용하여 태그를 지정합니다.

### 다중 테넌트 클러스터
<a name="_multi_tenant_clusters"></a>

다른 팀에서 공유하는 클러스터에서 작업하는 경우 동일한 노드에서 실행되는 다른 워크로드를 볼 수 없을 수 있습니다. 리소스 요청은 CPU 공유와 같은 일부 "시끄러운 이웃" 문제를 격리하는 데 도움이 될 수 있지만 디스크 I/O 소진과 같은 모든 리소스 경계를 격리하지는 못할 수 있습니다. 워크로드별 모든 소모성 리소스가 격리되거나 제한될 수 있는 것은 아닙니다. 다른 워크로드보다 더 높은 속도로 공유 리소스를 사용하는 워크로드는 노드 [테인트 및 허용 오차를](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) 통해 격리해야 합니다. 이러한 워크로드에 대한 또 다른 고급 기법은 컨테이너에 대한 공유 CPU 대신 배타적인 CPU를 보장하는 CPU [고정](https://kubernetes.io/docs/tasks/administer-cluster/cpu-management-policies/#static-policy)입니다.

노드 수준에서 워크로드를 격리하면 비용이 더 많이 들 수 있지만 [예약 인스턴스](https://aws.amazon.com/ec2/pricing/reserved-instances/), [Graviton 프로세서](https://aws.amazon.com/ec2/graviton/) 또는 [스팟](https://aws.amazon.com/ec2/spot/)을 사용하여 [BestEffort](https://kubernetes.io/docs/concepts/workloads/pods/pod-qos/#besteffort) 작업을 예약하거나 추가 비용 절감을 활용할 수 있습니다.

공유 클러스터에는 IP 소진, Kubernetes 서비스 제한 또는 API 조정 요청과 같은 클러스터 수준 리소스 제약이 있을 수도 있습니다. [확장성 모범 사례 가이드를](https://docs.aws.amazon.com/eks/latest/best-practices/scale-control-plane.html) 검토하여 클러스터가 이러한 제한을 피하도록 해야 합니다.

네임스페이스 또는 Karpenter 프로비저너 수준에서 리소스를 격리할 수 있습니다. [Resource Quotas](https://kubernetes.io/docs/concepts/policy/resource-quotas/)는 네임스페이스의 리소스 워크로드가 소비할 수 있는 리소스 수에 대한 제한을 설정하는 방법을 제공합니다. 이는 좋은 초기 가드레일일 수 있지만 워크로드의 규모 조정을 인위적으로 제한하지 않도록 지속적으로 평가해야 합니다.

Karpenter 프로비저너는 클러스터[의 일부 소모성 리소스(예: CPU, GPU)에 대한 제한을 설정할](https://karpenter.sh/docs/concepts/nodepools/#speclimitsresources) 수 있지만 적절한 프로비저너를 사용하도록 테넌트 애플리케이션을 구성해야 합니다. 이렇게 하면 단일 프로비저너가 클러스터에 노드를 너무 많이 생성하지 못할 수 있지만, 제한이 너무 낮게 설정되지 않았는지 확인하고 워크로드가 확장되지 않도록 지속적으로 평가해야 합니다.

### 예약된 Autoscaling
<a name="_scheduled_autoscaling"></a>

주말과 업무 시간에 클러스터를 스케일 다운해야 할 수 있습니다. 이는 사용하지 않을 때 0으로 스케일 다운하려는 테스트 및 비프로덕션 클러스터와 특히 관련이 있습니다. [클러스터 턴다운](https://github.com/kubecost/cluster-turndown)과 같은 솔루션은 cron 일정에 따라 복제본을 0으로 축소할 수 있습니다. 다음 [AWS 블로그](https://aws.amazon.com/blogs/containers/manage-scale-to-zero-scenarios-with-karpenter-and-serverless/)에 설명된 Karpenter를 사용하여이 문제를 해결할 수도 있습니다.

## 컴퓨팅 용량 유형 최적화
<a name="_optimize_compute_capacity_types"></a>

클러스터의 총 컴퓨팅 용량을 최적화하고 빈 패킹을 활용한 후에는 클러스터에서 프로비저닝한 컴퓨팅 유형과 이러한 리소스에 대한 비용을 지불하는 방법을 살펴봐야 합니다. AWS에는 [다음과 같은 용량 유형으로 분류할 컴퓨팅 비용을 줄일 수 있는 컴퓨팅 절감형 플랜](https://aws.amazon.com/savingsplans/compute-pricing/)이 있습니다.
+ 스팟
+ 절감형 플랜
+ 온디맨드
+ Fargate

각 용량 유형에는 관리 오버헤드, 가용성 및 장기 약정에 대한 장단점이 서로 다르므로 환경에 적합한 것을 결정해야 합니다. 어떤 환경도 단일 용량 유형에 의존해서는 안 되며 단일 클러스터에서 여러 실행 유형을 혼합하여 특정 워크로드 요구 사항과 비용을 최적화할 수 있습니다.

### 스팟
<a name="_spot"></a>

[스팟](https://aws.amazon.com/ec2/spot/) 용량 유형은 가용 영역의 예비 용량에서 EC2 인스턴스를 프로비저닝합니다. 스팟은 최대 90%까지 가장 큰 할인을 제공하지만 다른 곳에서 필요할 때 해당 인스턴스를 중단할 수 있습니다. 또한 새 스팟 인스턴스를 프로비저닝할 수 있는 용량이 항상 있는 것은 아니며 [2분 중단 알림](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-interruptions.html)으로 기존 스팟 인스턴스를 회수할 수 있습니다. 애플리케이션에 긴 시작 또는 종료 프로세스가 있는 경우 스팟 인스턴스가 최선의 옵션이 아닐 수 있습니다.

스팟 컴퓨팅은 스팟 용량을 사용할 수 없을 가능성을 줄이기 위해 다양한 인스턴스 유형을 사용해야 합니다. 노드를 안전하게 종료하려면 인스턴스 중단을 처리해야 합니다. Karpenter 또는 관리형 노드 그룹의 일부로 프로비저닝된 노드는 [인스턴스 중단 알림을](https://docs.aws.amazon.com/eks/latest/best-practices/karpenter.html) 자동으로 지원합니다. 자체 관리형 노드를 사용하는 경우 [노드 종료 핸들러](https://github.com/aws/aws-node-termination-handler)를 개별적으로 실행하여 스팟 인스턴스를 정상적으로 종료해야 합니다.

단일 클러스터에서 스팟 인스턴스와 온디맨드 인스턴스의 균형을 맞출 수 있습니다. Karpenter를 사용하면 [가중 프로비저너](https://karpenter.sh/docs/concepts/scheduling/#on-demandspot-ratio-split)를 생성하여 다양한 용량 유형의 균형을 맞출 수 있습니다. Cluster Autoscaler를 사용하면 [스팟 및 온디맨드 또는 예약 인스턴스를 사용하여 혼합 노드 그룹을](https://aws.amazon.com/blogs/containers/amazon-eks-now-supports-provisioning-and-managing-ec2-spot-instances-in-managed-node-groups/) 생성할 수 있습니다.

다음은 Karpenter를 사용하여 온디맨드 인스턴스보다 먼저 스팟 인스턴스의 우선순위를 지정하는 예제입니다. 프로비저너를 생성할 때 스팟, 온디맨드 또는 둘 다(아래 참조)를 지정할 수 있습니다. 둘 다 지정하고 포드가 스팟을 사용해야 하는지 온디맨드를 사용해야 하는지 명시적으로 지정하지 않으면 Karpenter는 [price-capacity-optimization 할당 전략](https://aws.amazon.com/blogs/compute/introducing-price-capacity-optimized-allocation-strategy-for-ec2-spot-instances/)으로 노드를 프로비저닝할 때 스팟의 우선 순위를 지정합니다.

```
apiVersion: karpenter.sh/v1
kind: Provisioner
metadata:
  name: spot-prioritized
spec:
  requirements:
    - key: "karpenter.sh/capacity-type"
      operator: In
        values: ["spot", "on-demand"]
```

### Savings Plans, 예약 인스턴스 및 AWS EDP
<a name="_savings_plans_reserved_instances_and_aws_edp"></a>

컴퓨팅 [절감형 플랜을 사용하여 컴퓨팅](https://aws.amazon.com/savingsplans/compute-pricing/) 지출을 줄일 수 있습니다. 절감형 플랜은 1년 또는 3년 약정의 컴퓨팅 사용량에 대해 할인된 가격을 제공합니다. 사용량은 EKS 클러스터의 EC2 인스턴스에 적용될 수 있지만 Lambda 및 Fargate와 같은 모든 컴퓨팅 사용량에도 적용됩니다. 절감형 플랜을 사용하면 비용을 절감하고 약정 기간 동안 모든 EC2 인스턴스 유형을 선택할 수 있습니다.

컴퓨팅 절감형 플랜은 사용하려는 인스턴스 유형, 패밀리 또는 리전에 대한 약정 없이 EC2 비용을 최대 66% 절감할 수 있습니다. 절감액은 인스턴스를 사용할 때 인스턴스에 자동으로 적용됩니다.

EC2 Instance Savings Plans C 패밀리의 인스턴스와 같은 특정 리전 및 EC2 패밀리에서 사용량을 약정하여 컴퓨팅 비용을 최대 72% 절감합니다. 사용량을 리전 내의 모든 AZ로 전환하고, c5 또는 c6와 같은 인스턴스 패밀리의 모든 세대를 사용하고, 패밀리 내의 모든 크기의 인스턴스를 사용할 수 있습니다. 할인은 절감형 플랜 기준과 일치하는 계정의 모든 인스턴스에 자동으로 적용됩니다.

 [예약 인스턴스](https://aws.amazon.com/ec2/pricing/reserved-instances/)는 EC2 인스턴스 Savings Plan과 유사하지만 온디맨드 인스턴스에 비해 가용 영역 또는 리전의 용량을 보장하고 비용을 최대 72% 절감합니다. 필요한 예약 용량을 계산한 후에는 예약 기간(1년 또는 3년)을 선택할 수 있습니다. 계정에서 해당 EC2 인스턴스를 실행하면 할인이 자동으로 적용됩니다.

고객은 AWS와의 엔터프라이즈 계약에 등록할 수도 있습니다. 엔터프라이즈 계약은 고객의 요구에 가장 적합한 계약을 맞춤 설정할 수 있는 옵션을 제공합니다. 고객은 AWS EDP(엔터프라이즈 할인 프로그램)에 따라 요금 할인을 받을 수 있습니다. 엔터프라이즈 계약에 대한 자세한 내용은 AWS 영업 담당자에게 문의하십시오.

### 온디맨드
<a name="_on_demand"></a>

온디맨드 EC2 인스턴스는 절감형 플랜에 비해 스팟과 장기 약정이 없는 경우 중단 없는 가용성의 이점을 누릴 수 있습니다. 클러스터에서 비용을 절감하려면 온디맨드 EC2 인스턴스의 사용량을 줄여야 합니다.

워크로드 요구 사항을 최적화한 후에는 클러스터의 최소 및 최대 용량을 계산할 수 있어야 합니다. 이 숫자는 시간이 지남에 따라 변경될 수 있지만 감소하는 경우는 거의 없습니다. 최소 미만의 모든 항목에 Savings Plan을 사용하고 애플리케이션 가용성에 영향을 주지 않는 용량을 확보하는 것이 좋습니다. 지속적으로 사용되지 않거나 가용성에 필요한 다른 모든 것은 온디맨드 방식으로 사용할 수 있습니다.

이 단원에서 언급했듯이 사용량을 줄이는 가장 좋은 방법은 리소스를 적게 사용하고 프로비저닝한 리소스를 최대한 활용하는 것입니다. Cluster Autoscaler를 사용하면 `scale-down-utilization-threshold` 설정으로 사용률이 낮은 노드를 제거할 수 있습니다. Karpenter에서는 통합을 활성화하는 것이 좋습니다.

워크로드에 사용할 수 있는 EC2 인스턴스 유형을 수동으로 식별하려면 각 리전에서 사용할 수 있는 인스턴스와 EKS와 호환되는 인스턴스를 표시할 수 있는 [ec2-instance-selector](https://github.com/aws/amazon-ec2-instance-selector)를 사용해야 합니다. x86 프로세스 아키텍처, 4Gb 메모리, vCPUs 있고 us-east-1 리전에서 사용할 수 있는 인스턴스의 사용 예입니다.

```
ec2-instance-selector --memory 4 --vcpus 2 --cpu-architecture x86_64 \
  -r us-east-1 --service eks
c5.large
c5a.large
c5ad.large
c5d.large
c6a.large
c6i.large
t2.medium
t3.medium
t3a.medium
```

비프로덕션 환경의 경우 야간 및 주말과 같은 미사용 시간에 클러스터를 자동으로 축소할 수 있습니다. kubecost 프로젝트 [클러스터 가동 중지](https://github.com/kubecost/cluster-turndown)는 설정된 일정에 따라 클러스터를 자동으로 축소할 수 있는 컨트롤러의 예입니다.

### Fargate 컴퓨팅
<a name="_fargate_compute"></a>

Fargate 컴퓨팅은 EKS 클러스터를 위한 완전 관리형 컴퓨팅 옵션입니다. Kubernetes 클러스터에서 노드당 하나의 포드를 예약하여 포드 격리를 제공합니다. 이를 통해 컴퓨팅 노드의 크기를 워크로드의 CPU 및 RAM 요구 사항에 맞게 조정하여 클러스터의 워크로드 사용량을 엄격하게 제어할 수 있습니다.

Fargate는 0.5GB 메모리가 있는 .25 vCPU만큼 작은 워크로드와 120GB 메모리가 있는 16 vCPU만큼 큰 워크로드를 확장할 수 있습니다. 사용 가능한 [포드 크기 변형](https://docs.aws.amazon.com/eks/latest/userguide/fargate-pod-configuration.html) 수에는 제한이 있으며 워크로드가 Fargate 구성에 가장 적합한 방법을 이해해야 합니다. 예를 들어 워크로드에 메모리가 0.5GB인 vCPU 1개가 필요한 경우 가장 작은 Fargate 포드는 메모리가 2GB인 vCPU 1개입니다.

Fargate는 EC2 인스턴스 또는 운영 체제 관리가 없는 등 많은 이점이 있지만 배포된 모든 포드가 클러스터에서 별도의 노드로 격리되어 있기 때문에 기존 EC2 인스턴스보다 더 많은 컴퓨팅 용량이 필요할 수 있습니다. 이렇게 하려면 일반적으로 노드에 배포하는 Kubelet, 로깅 에이전트 및 DaemonSets와 같은 사물에 대해 더 많은 중복이 필요합니다. DaemonSets는 Fargate에서 지원되지 않으므로 포드 "`sidecars"로 변환하고 애플리케이션과 함께 실행해야 합니다.

워크로드 경계가 워크로드 간에 버스트하거나 공유할 수 없는 노드이므로 Fargate는 빈 패킹 또는 CPU 오버프로비저닝의 이점을 누릴 수 없습니다. Fargate는 비용이 드는 EC2 인스턴스 관리 시간을 절약하지만 CPU 및 메모리 비용은 다른 EC2 용량 유형보다 더 높을 수 있습니다. Fargate 포드는 컴퓨팅 절감형 플랜을 활용하여 온디맨드 비용을 절감할 수 있습니다.

## 컴퓨팅 사용량 최적화
<a name="_optimize_compute_usage"></a>

컴퓨팅 인프라 비용을 절감하는 또 다른 방법은 워크로드에 보다 효율적인 컴퓨팅을 사용하는 것입니다. 이는 x86보다 최대 20% 저렴하고 60% 더 에너지 효율적인 [Graviton 프로세서](https://aws.amazon.com/ec2/graviton/)와 같은 고성능 범용 컴퓨팅 또는 GPUs 및 [FPGAs](https://aws.amazon.com/ec2/instance-types/f1/)와 같은 워크로드별 액셀러레이터에서 발생할 수 있습니다. [팔 아키텍처에서 실행할](https://aws.amazon.com/blogs/containers/how-to-build-your-containers-for-arm-and-save-with-graviton-and-spot-instances-on-amazon-ecs/) 수 있는 컨테이너를 구축하고 워크로드[에 적합한 액셀러레이터로 노드를 설정해야](https://aws.amazon.com/blogs/compute/running-gpu-accelerated-kubernetes-workloads-on-p3-and-p2-ec2-instances-with-amazon-eks/) 합니다.

EKS는 혼합 아키텍처(예: amd64 및 arm64)를 사용하여 클러스터를 실행할 수 있으며 컨테이너가 여러 아키텍처에 맞게 컴파일된 경우 프로비저너에서 두 아키텍처를 모두 허용하여 Karpenter를 사용하는 Graviton 프로세서를 활용할 수 있습니다. 그러나 일관된 성능을 유지하려면 각 워크로드를 단일 컴퓨팅 아키텍처에 유지하고 사용 가능한 추가 용량이 없는 경우에만 다른 아키텍처를 사용하는 것이 좋습니다.

프로비저너는 여러 아키텍처로 구성할 수 있으며 워크로드 사양에서 특정 아키텍처를 요청할 수도 있습니다.

```
apiVersion: karpenter.sh/v1
kind: Provisioner
metadata:
  name: default
spec:
  requirements:
  - key: "kubernetes.io/arch"
    operator: In
    values: ["arm64", "amd64"]
```

Cluster Autoscaler를 사용하면 Graviton 인스턴스에 대한 노드 그룹을 생성하고 [워크로드에서 노드 허용치를 설정](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/)하여 새 용량을 활용해야 합니다.

GPUs 및 FPGAs는 워크로드의 성능을 크게 높일 수 있지만 액셀러레이터를 사용하도록 워크로드를 최적화해야 합니다. 기계 학습 및 인공 지능을 위한 많은 워크로드 유형은 컴퓨팅에 GPUs 사용할 수 있으며, 인스턴스를 클러스터에 추가하고 리소스 요청을 사용하여 워크로드에 탑재할 수 있습니다.

```
spec:
  template:
    spec:
    - containers:
      ...
      resources:
          limits:
            nvidia.com/gpu: "1"
```

일부 GPU 하드웨어는 여러 워크로드에서 공유할 수 있으므로 단일 GPU를 프로비저닝하고 사용할 수 있습니다. 워크로드 GPU 공유를 구성하는 방법을 알아보려면 [가상 GPU 디바이스 플러그인](https://aws.amazon.com/blogs/opensource/virtual-gpu-device-plugin-for-inference-workload-in-kubernetes/)에서 자세한 내용을 참조하세요. 다음 블로그를 참조할 수도 있습니다.
+  [NVIDIA 시분할 및 가속화된 EC2 인스턴스를 사용하여 Amazon EKS에서 GPU 공유](https://aws.amazon.com/blogs/containers/gpu-sharing-on-amazon-eks-with-nvidia-time-slicing-and-accelerated-ec2-instances/) 
+  [Amazon EKS에서 NVIDIA의 다중 인스턴스 GPU(MIG)를 사용하여 GPU 사용률 극대화: 성능 향상을 위해 GPU당 더 많은 포드 실행](https://aws.amazon.com/blogs/containers/maximizing-gpu-utilization-with-nvidias-multi-instance-gpu-mig-on-amazon-eks-running-more-pods-per-gpu-for-enhanced-performance/) 

# 비용 최적화 - 네트워킹
<a name="cost-opt-networking"></a>

고가용성(HA)을 위한 아키텍처 시스템은 복원력과 내결함성을 달성하기 위한 모범 사례입니다. 실제로 이는 워크로드와 기본 인프라를 지정된 AWS 리전의 여러 가용 영역(AZs)에 분산시키는 것을 의미합니다. Amazon EKS 환경에 이러한 특성이 적용되도록 하면 시스템의 전반적인 안정성이 향상됩니다. 이와 함께 EKS 환경은 다양한 구성 요소(예: VPCs), 구성 요소(예: ELBs) 및 통합(예: ECR 및 기타 컨테이너 레지스트리)으로 구성될 수도 있습니다.

고가용성 시스템과 기타 사용 사례별 구성 요소의 조합은 데이터가 전송되고 처리되는 방식에 중요한 역할을 할 수 있습니다. 이로 인해 데이터 전송 및 처리로 인해 발생하는 비용에 영향을 미칩니다.

아래에 설명된 방법은 다양한 도메인 및 사용 사례에 대한 비용 효율성을 달성하기 위해 EKS 환경을 설계하고 최적화하는 데 도움이 됩니다.

## 포드 간 통신
<a name="_pod_to_pod_communication"></a>

설정에 따라 포드 간 네트워크 통신 및 데이터 전송은 Amazon EKS 워크로드 실행의 전체 비용에 상당한 영향을 미칠 수 있습니다. 이 섹션에서는 고가용성(HA) 아키텍처, 애플리케이션 성능 및 복원력을 고려하면서 포드 간 통신과 관련된 비용을 완화하기 위한 다양한 개념과 접근 방식을 다룹니다.

### 가용 영역으로 트래픽 제한
<a name="_restricting_traffic_to_an_availability_zone"></a>

Kubernetes 프로젝트는 초기에 노드에 할당된 kubernetes.io/hostname, topology.kubernetes.io/region 및 topology.kubernetes.io/zone 같은 레이블을 포함한 토폴로지 인식 구문을 개발하여 장애 도메인 및 토폴로지 인식 볼륨 프로비저너 간의 워크로드 분산과 같은 기능을 활성화하기 시작했습니다. Kubernetes 1.17을 졸업한 후 레이블을 활용하여 포드 간 통신을 위한 토폴로지 인식 라우팅 기능을 활성화했습니다.

다음은 비용을 절감하고 지연 시간을 최소화하기 위해 EKS 클러스터의 포드 간 AZ 간 트래픽 양을 제어하는 방법에 대한 몇 가지 전략입니다.

 *클러스터의 포드 간 AZ 간 트래픽 양(예: 바이트 단위로 전송된 데이터 양)을 세밀하게 확인하려면 [이 게시물을 참조](https://aws.amazon.com/blogs/containers/getting-visibility-into-your-amazon-eks-cross-az-pod-to-pod-network-bytes/)하세요.*

![\[토폴로지 인식 라우팅\]](http://docs.aws.amazon.com/ko_kr/eks/latest/best-practices/images/topo_aware_routing.png)


위 다이어그램에서 볼 수 있듯이 서비스는 포드로 향하는 트래픽을 수신하는 안정적인 네트워크 추상화 계층입니다. 서비스가 생성되면 여러 EndpointSlices가 생성됩니다. 각 EndpointSlice에는 실행 중인 노드와 함께 포드 주소의 하위 집합이 포함된 엔드포인트 목록과 추가 토폴로지 정보가 있습니다. Amazon VPC CNI를 사용하는 경우 모든 노드에서 실행되는 데몬 세트인 kube-proxy는 포드 통신 및 서비스 검색을 활성화하는 네트워크 규칙을 유지합니다(대체 eBPF 기반 CNIs kube-proxy를 사용하지 않지만 동등한 동작을 제공할 수 있음). 내부 라우팅의 역할을 수행하지만 생성된 EndpointSlices에서 소비하는 것에 따라 수행됩니다.

EKS에서 kube-proxy는 주로 노드 또는 AZ 배치에 관계없이 클러스터의 모든 포드에서 트래픽 분산을 위해 iptables NAT 규칙(또는 [IPVS](https://docs.aws.amazon.com/eks/latest/best-practices/ipvs.html), [NFTables](https://kubernetes.io/blog/2025/02/28/nftables-kube-proxy/)를 대안으로 사용)을 사용합니다. 이 기본 배포로 인해 AZ 간 트래픽 라우팅이 발생하여 대규모 배포에서 민감한 애플리케이션의 지연 시간이 증가하고 AZ 간 데이터 전송 요금이 증가할 수 있습니다.

 **토폴로지 인식 라우팅 사용(이전 명칭은 토폴로지 인식 힌트)** 

Kubernetes Service에서 [https://kubernetes.io/docs/concepts/services-networking/topology-aware-routing/](https://kubernetes.io/docs/concepts/services-networking/topology-aware-routing/)이 활성화되고 구현되면 EndpointSlice 컨트롤러는 클러스터가 분산된 여러 영역에 엔드포인트를 비례적으로 할당합니다. 이러한 각 엔드포인트에 대해 EndpointSlice 컨트롤러는 영역에 대한 *힌트*도 설정합니다. *힌트는* 엔드포인트가 트래픽을 처리해야 하는 영역을 설명합니다. 그러면 `kube-proxy`는 적용된 *힌*트를 기반으로 영역에서 엔드포인트로 트래픽을 라우팅합니다.

아래 다이어그램은 힌트가 있는 EndpointSlices가 영역별 오리진 지점을 기반으로 어떤 대상으로 이동해야 하는지 알 `kube-proxy` 수 있는 방식으로 구성되는 방법을 보여줍니다. 힌트가 없으면 이러한 할당이나 조직이 없으며 트래픽은 출처에 관계없이 다양한 영역 대상으로 프록시됩니다.

![\[엔드포인트 조각\]](http://docs.aws.amazon.com/ko_kr/eks/latest/best-practices/images/endpoint_slice.png)


경우에 따라 EndpointSlice 컨트롤러는 다른 영역에 *힌트*를 적용할 수 있습니다. 즉, 엔드포인트가 다른 영역에서 시작된 트래픽을 제공할 수 있습니다. 그 이유는 서로 다른 영역의 엔드포인트 간에 균등한 트래픽 분산을 시도하고 유지하기 위한 것입니다.

다음은 서비스에 대한 *토폴로지 인식 라우팅*을 활성화하는 방법에 대한 코드 조각입니다.

```
apiVersion: v1
kind: Service
metadata:
  name: orders-service
  namespace: ecommerce
  annotations:
    service.kubernetes.io/topology-mode: Auto
spec:
  selector:
    app: orders
  type: ClusterIP
  ports:

* protocol: TCP
port: 3003
targetPort: 3003
```

아래 스크린샷은 EndpointSlice 컨트롤러가 AZ에서 실행 중인 포드 복제본의 엔드포인트에 힌트를 성공적으로 적용한 결과를 보여줍니다`eu-west-1a`.

![\[조각 쉘\]](http://docs.aws.amazon.com/ko_kr/eks/latest/best-practices/images/slice_shell.png)


**참고**  
토폴로지 인식 라우팅은 여전히 베타 버전입니다. 이 기능은 컨트롤러가 영역 간에 엔드포인트를 비례적으로 할당하지만 영역의 노드 리소스가 너무 불균형하여 과도한 과부하를 피할 수 없는 경우 힌트 할당을 건너뛸 수 있으므로 클러스터 토폴로지 전체에 균등하게 분산된 워크로드에서 보다 예측 가능하게 작동합니다. 따라서 [포드 토폴로지 분산 제약 조건과 같은 애플리케이션의 가용성을 높이는 예약 제약 조건](https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/)과 함께 사용하는 것이 좋습니다. 비례 분포를 계산할 때 중단 또는 교체가 실시간으로 감지되지 않으므로 [Amazon EC2 스팟 인스턴스](https://aws.amazon.com/ec2/spot/)를 사용할 때와 같이 영역 간에 용량이 변동하는 경우에도 힌트가 할당되지 않을 수 있습니다.

 **트래픽 배포 사용** 

Kubernetes 1.30에 도입되고 1.33에 정식 출시된 [트래픽 분산](https://kubernetes.io/docs/reference/networking/virtual-ips/#traffic-distribution)은 동일한 영역 트래픽 선호도를 위해 토폴로지 인식 라우팅에 대한 더 간단한 대안을 제공합니다. 토폴로지 인식 라우팅은 엔드포인트 오버로드를 방지하기 위해 트래픽 라우팅에 대한 지능형 접근 방식을 사용하려고 시도하지만 예측할 수 없는 동작을 초래했습니다. 트래픽 분산은 대신 예측 가능성을 우선시합니다. PreferClose 옵션은 kube-proxy에 EndpointSlice Controller에서 설정한 영역 *힌트*를 기반으로 먼저 트래픽을 동일한 영역 엔드포인트로 라우팅하는 규칙을 생성하도록 지시합니다. 동일한 영역 엔드포인트를 사용할 수 없는 경우 서비스의 모든 클러스터 엔드포인트에 트래픽을 분산하는 것으로 돌아갑니다. 이 기능은 토폴로지 인식 라우팅이 제공하는 로드의 균일한 분산을 시도하는 대신 근접성을 최적화하는 절충점을 수용하는 워크로드를 위해 설계되었습니다.

다음은 서비스에 대한 *트래픽 분산*을 활성화하는 방법에 대한 코드 조각입니다.

```
apiVersion: v1
kind: Service
metadata:
  name: orders-service
  namespace: ecommerce
spec:
  trafficDistribution: PreferClose
  selector:
    app: orders
  type: ClusterIP
  ports:

* protocol: TCP
port: 3003
targetPort: 3003
```

트래픽 분산을 활성화하면 일반적인 문제가 발생합니다. 대부분의 트래픽이 동일한 영역에서 발생하는 경우 단일 AZ 내의 엔드포인트에 과부하가 걸릴 수 있습니다. 이 오버로드로 인해 다음과 같은 심각한 문제가 발생할 수 있습니다.
+ 다중 AZ 배포를 관리하는 단일 Horizontal Pod Autoscaler(HPA)는 여러 AZs. 그러나이 작업은 영향을 받는 영역의 증가된 부하를 효과적으로 해결하지 못합니다.
+ 이 상황은 결과적으로 리소스 비효율성을 초래할 수 있습니다. Karpenter와 같은 클러스터 오토스케일러가 여러 AZs에서 포드 스케일 아웃을 감지하면 영향을 받지 않는 AZs에 추가 노드를 프로비저닝하여 불필요한 리소스 할당이 발생할 수 있습니다.

이 문제를 해결하려면:
+ 영역별로 자체 HPAs가 있는 별도의 배포를 생성하여 서로 독립적으로 확장할 수 있습니다.
+ 토폴로지 분산 제약 조건을 활용하여 클러스터 전반의 워크로드 분산을 보장함으로써 트래픽이 많은 영역에서 엔드포인트 오버로드를 방지하는 데 도움이 됩니다.

 **Autoscaler 사용: 특정 AZ에 노드 프로비저닝** 

 여러 AZs에서 고가용성 환경에서 워크로드를 실행하는 *것이 좋습니다*. 이렇게 하면 특히 AZ에 문제가 발생한 경우 애플리케이션의 신뢰성이 향상됩니다. 네트워크 관련 비용을 줄이기 위해 신뢰성을 희생하려는 경우 노드를 단일 AZ로 제한할 수 있습니다.

동일한 AZ에서 모든 포드를 실행하려면 동일한 AZ에서 작업자 노드를 프로비저닝하거나 동일한 AZ에서 실행되는 작업자 노드에서 포드를 예약합니다. 단일 AZ 내에서 노드를 프로비저닝하려면 [Cluster Autoscaler(CA)](https://github.com/kubernetes/autoscaler/tree/master/cluster-autoscaler)를 사용하여 동일한 AZ에 속하는 서브넷이 있는 노드 그룹을 정의합니다. [Karpenter](https://karpenter.sh/)의 경우 `topology.kubernetes.io/zone`를 사용하고 작업자 노드를 생성할 AZ를 지정합니다. 예를 들어 아래 Karpenter 프로비저너 코드 조각은 us-west-2a AZ에 노드를 프로비저닝합니다.

 **Karpenter** 

```
apiVersion: karpenter.sh/v1
kind: Provisioner
metadata:
name: single-az
spec:
  requirements:

* key: "topology.kubernetes.io/zone"`
operator: In
values: ["us-west-2a"]
```

 **Cluster Autoscaler(CA)** 

```
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
  name: my-ca-cluster
  region: us-east-1
  version: "1.21"
availabilityZones:

* us-east-1a
managedNodeGroups:
* name: managed-nodes
labels:
  role: managed-nodes
instanceType: t3.medium
minSize: 1
maxSize: 10
desiredCapacity: 1
...
```

 **포드 할당 및 노드 선호도 사용** 

또는 여러 AZs에서 작업자 노드를 실행하는 경우 각 노드에는 AZ 값이 포함된 *[topology.kubernetes.io/zone](http://topology.kubernetes.io/zone%E2%80%9D) * 레이블이 있습니다(예: us-west-2a 또는 us-west-2b). `nodeSelector` 또는 `nodeAffinity`를 사용하여 단일 AZ의 노드에 대한 포드를 예약할 수 있습니다. 예를 들어 다음 매니페스트 파일은 AZ us-west-2a에서 실행되는 노드 내의 포드를 예약합니다.

```
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    env: test
spec:
  nodeSelector:
    topology.kubernetes.io/zone: us-west-2a
  containers:

* name: nginx
image: nginx
imagePullPolicy: IfNotPresent
```

### 노드로 트래픽 제한
<a name="_restricting_traffic_to_a_node"></a>

영역 수준에서 트래픽을 제한하는 것만으로는 충분하지 않은 경우가 있습니다. 비용 절감 외에도 상호 통신이 빈번한 특정 애플리케이션 간의 네트워크 지연 시간을 줄여야 하는 요구 사항이 추가될 수 있습니다. 최적의 네트워크 성능을 달성하고 비용을 절감하려면 트래픽을 특정 노드로 제한할 수 있는 방법이 필요합니다. 예를 들어 마이크로서비스 A는 고가용성(HA) 설정에서도 항상 노드 1의 마이크로서비스 B와 통신해야 합니다. 노드 1의 마이크로서비스 A가 노드 2의 마이크로서비스 B와 통신하면 특히 노드 2가 별도의 AZ에 있는 경우 이러한 특성의 애플리케이션에 대해 원하는 성능에 부정적인 영향을 미칠 수 있습니다.

 **서비스 내부 트래픽 정책 사용** 

포드 네트워크 트래픽을 노드로 제한하기 위해 * [서비스 내부 트래픽 정책](https://kubernetes.io/docs/concepts/services-networking/service-traffic-policy/) *를 사용할 수 있습니다. 기본적으로 워크로드의 서비스로 전송된 트래픽은 생성된 여러 엔드포인트에 무작위로 분산됩니다. 따라서 HA 아키텍처에서는 마이크로서비스 A의 트래픽이 서로 다른 AZs. 그러나 서비스의 내부 트래픽 정책을 로 설정하면 `Local`트래픽이 시작된 노드의 엔드포인트로 트래픽이 제한됩니다. 이 정책은 노드-로컬 엔드포인트의 독점적 사용을 지시합니다. 즉, 해당 워크로드에 대한 네트워크 트래픽 관련 비용은 배포가 클러스터 전체인 경우보다 저렴합니다. 또한 지연 시간이 짧아져 애플리케이션의 성능이 향상됩니다.

**참고**  
이 기능은 Kubernetes의 토폴로지 인식 라우팅과 결합할 수 없다는 점에 유의해야 합니다.

![\[로컬 내부 트래픽\]](http://docs.aws.amazon.com/ko_kr/eks/latest/best-practices/images/local_traffic.png)


다음은 서비스에 대한 *내부 트래픽 정책을* 설정하는 방법에 대한 코드 조각입니다.

```
apiVersion: v1
kind: Service
metadata:
  name: orders-service
  namespace: ecommerce
spec:
  selector:
    app: orders
  type: ClusterIP
  ports:

* protocol: TCP
port: 3003
targetPort: 3003
  internalTrafficPolicy: Local
```

트래픽 감소로 인한 애플리케이션의 예기치 않은 동작을 방지하려면 다음 접근 방식을 고려해야 합니다.
+ 각 통신 포드에 대해 충분한 복제본 실행
+ [토폴로지 분산 제약 조건을 사용하여 포드를 비교적 균등하게 분산시킵니다.](https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/)
+ 포[드 통신의 코로케이션에 포드 선호도 규칙](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity) 사용

이 예제에서는 마이크로서비스 A 복제본 2개와 마이크로서비스 B 복제본 3개가 있습니다. 마이크로서비스 A의 복제본이 노드 1과 2 사이에 분산되어 있고 마이크로서비스 B의 복제본 3개가 모두 노드 3에 있는 경우 `Local` 내부 트래픽 정책으로 인해 통신할 수 없습니다. 사용 가능한 노드-로컬 엔드포인트가 없으면 트래픽이 삭제됩니다.

![\[node-local_no_peer\]](http://docs.aws.amazon.com/ko_kr/eks/latest/best-practices/images/no_node_local_1.png)


마이크로서비스 B의 노드 1과 2에 복제본 3개 중 2개가 있는 경우 피어 애플리케이션 간에 통신이 이루어집니다. 그러나 통신할 피어 복제본이 없는 마이크로서비스 B의 격리된 복제본이 여전히 있을 것입니다.

![\[node-local_with_peer\]](http://docs.aws.amazon.com/ko_kr/eks/latest/best-practices/images/no_node_local_2.png)


**참고**  
일부 시나리오에서는 위 다이어그램에 표시된 것과 같은 격리된 복제본이 여전히 목적(예: 외부 수신 트래픽의 요청 처리)을 제공하는 경우 문제가 되지 않을 수 있습니다.

 **토폴로지 분산 제약 조건과 함께 서비스 내부 트래픽 정책 사용** 

*토폴로지 분산 제약* 조건과 함께 *내부 트래픽 정책을* 사용하면 여러 노드에서 마이크로서비스를 통신하기 위한 적절한 수의 복제본을 확보하는 데 유용할 수 있습니다.

```
apiVersion: apps/v1
kind: Deployment
metadata:
  name: express-test
spec:
  replicas: 6
  selector:
    matchLabels:
      app: express-test
  template:
    metadata:
      labels:
        app: express-test
        tier: backend
    spec:
      topologySpreadConstraints:
      - maxSkew: 1
        topologyKey: "topology.kubernetes.io/zone"
        whenUnsatisfiable: ScheduleAnyway
        labelSelector:
          matchLabels:
            app: express-test
```

 **포드 선호도 규칙과 함께 서비스 내부 트래픽 정책 사용** 

또 다른 접근 방식은 서비스 내부 트래픽 정책을 사용할 때 포드 선호도 규칙을 사용하는 것입니다. 포드 선호도를 사용하면 빈번한 통신으로 인해 스케줄러가 특정 포드를 공동 배치하도록 영향을 미칠 수 있습니다. 특정 포드에 엄격한 예약 제약 조건(`requiredDuringSchedulingIgnoredDuringExecution`)을 적용하면 스케줄러가 노드에 포드를 배치할 때 포드 코로케이션에 대한 더 나은 결과를 얻을 수 있습니다.

```
apiVersion: apps/v1
kind: Deployment
metadata:
  name: graphql
  namespace: ecommerce
  labels:
    app.kubernetes.io/version: "0.1.6"
    ...
    spec:
      serviceAccountName: graphql-service-account
      affinity:
        podAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - orders
            topologyKey: "kubernetes.io/hostname"
```

## Load Balancer서와 포드 통신
<a name="_load_balancer_to_pod_communication"></a>

EKS 워크로드는 일반적으로 EKS 클러스터의 관련 포드로 트래픽을 분산하는 로드 밸런서가 앞에 위치합니다. 아키텍처는 내부 및/또는 외부 방향 로드 밸런서를 포함할 수 있습니다. 아키텍처 및 네트워크 트래픽 구성에 따라 로드 밸런서와 포드 간의 통신이 데이터 전송 요금에 상당한 영향을 미칠 수 있습니다.

[AWS Load Balancer Controller](https://kubernetes-sigs.github.io/aws-load-balancer-controller)를 사용하여 ELB 리소스(ALB 및 NLB) 생성을 자동으로 관리할 수 있습니다. 이러한 설정에서 발생하는 데이터 전송 요금은 네트워크 트래픽이 취하는 경로에 따라 달라집니다. AWS Load Balancer 컨트롤러는 *인스턴스* 모드와 IP *모드라는 두 가지 네트워크 트래픽 모드를* 지원합니다.

*인스턴스 모드를* 사용하면 EKS 클러스터의 각 노드에서 NodePort가 열립니다. 그러면 로드 밸런서가 노드 간에 트래픽을 균등하게 프록시합니다. 노드에 대상 포드가 실행 중인 경우 데이터 전송 비용이 발생하지 않습니다. 그러나 대상 포드가 트래픽을 수신하는 NodePort와 다른 노드와 다른 AZ에 있는 경우 kube-proxy에서 대상 포드로 추가 네트워크 홉이 발생합니다. 이러한 시나리오에서는 교차 AZ 데이터 전송 요금이 발생합니다. 노드 간에 트래픽이 균등하게 분산되므로 kube 프록시에서 관련 대상 포드로의 교차 영역 네트워크 트래픽 홉과 관련된 추가 데이터 전송 요금이 발생할 가능성이 높습니다.

아래 다이어그램은 로드 밸런서에서 NodePort로, 이후에서 다른 AZ의 별도 노드에 있는 `kube-proxy` 대상 포드로 흐르는 트래픽의 네트워크 경로를 보여줍니다. 다음은 *인스턴스 모드* 설정의 예입니다.

![\[LB에서 포드로\]](http://docs.aws.amazon.com/ko_kr/eks/latest/best-practices/images/lb_2_pod.png)


*IP 모드를* 사용하는 경우 네트워크 트래픽은 로드 밸런서에서 대상 포드로 직접 프록시됩니다. 따라서이 접근 방식에는 *데이터 전송 요금이 부과되지 않습니다*.

**참고**  
데이터 전송 요금을 줄이려면 로드 밸런서를 *IP 트래픽 모드로* 설정하는 것이 좋습니다. 이 설정의 경우 로드 밸런서가 VPC의 모든 서브넷에 배포되었는지 확인하는 것도 중요합니다.

아래 다이어그램은 네트워크 *IP 모드에서* 로드 밸런서에서 포드로 흐르는 트래픽의 네트워크 경로를 보여줍니다.

![\[IP 모드\]](http://docs.aws.amazon.com/ko_kr/eks/latest/best-practices/images/ip_mode.png)


## 컨테이너 레지스트리에서 데이터 전송
<a name="_data_transfer_from_container_registry"></a>

### Amazon ECR
<a name="_amazon_ecr"></a>

Amazon ECR 프라이빗 레지스트리로의 데이터 전송은 무료입니다. *리전 내 데이터 전송에는 비용이 들지* 않지만 인터넷 및 리전 간 데이터 전송에는 전송 양쪽의 인터넷 데이터 전송 요금이 부과됩니다.

ECRs 기본 제공 [이미지 복제 기능을](https://docs.aws.amazon.com/AmazonECR/latest/userguide/replication.html) 활용하여 관련 컨테이너 이미지를 워크로드와 동일한 리전에 복제해야 합니다. 이렇게 하면 복제 비용이 한 번 청구되고 동일한 리전(리전 내) 이미지 풀은 모두 무료입니다.

*[인터페이스 VPC 엔드포인트](https://docs.aws.amazon.com/whitepapers/latest/aws-privatelink/what-are-vpc-endpoints.html)를 사용하여 리전 내 ECR 리포지토리에 연결하여 ECR(데이터 전송)에서 이미지를 가져오는 것과 관련된 데이터 전송 비용을 추가로 줄일 수 있습니다*. ECR의 퍼블릭 AWS 엔드포인트(NAT 게이트웨이 및 인터넷 게이트웨이를 통해)에 연결하는 대체 접근 방식은 데이터 처리 및 전송 비용을 높입니다. 다음 섹션에서는 워크로드와 AWS 서비스 간의 데이터 전송 비용 절감에 대해 자세히 설명합니다.

특히 큰 이미지로 워크로드를 실행하는 경우 사전 캐시된 컨테이너 이미지로 사용자 지정 Amazon Machine Image(AMIs)를 구축할 수 있습니다. 이렇게 하면 컨테이너 레지스트리에서 EKS 작업자 노드로 초기 이미지 가져오기 시간과 잠재적 데이터 전송 비용을 줄일 수 있습니다.

## 인터넷 및 AWS 서비스로 데이터 전송
<a name="_data_transfer_to_internet_aws_services"></a>

인터넷을 통해 Kubernetes 워크로드를 다른 AWS 서비스 또는 타사 도구 및 플랫폼과 통합하는 것이 일반적인 방법입니다. 관련 대상과의 트래픽을 라우팅하는 데 사용되는 기본 네트워크 인프라는 데이터 전송 프로세스에서 발생하는 비용에 영향을 미칠 수 있습니다.

### NAT 게이트웨이 사용
<a name="_using_nat_gateways"></a>

NAT 게이트웨이는 NAT(네트워크 주소 변환)를 수행하는 네트워크 구성 요소입니다. 아래 다이어그램은 다른 AWS 서비스(Amazon ECR, DynamoDB 및 S3) 및 타사 플랫폼과 통신하는 EKS 클러스터의 포드를 보여줍니다. 이 예제에서 포드는 별도의 AZs. 인터넷에서 트래픽을 보내고 받기 위해 NAT 게이트웨이가 하나의 AZ의 퍼블릭 서브넷에 배포되므로 프라이빗 IP 주소가 있는 모든 리소스가 인터넷에 액세스할 수 있도록 단일 퍼블릭 IP 주소를 공유할 수 있습니다. 이 NAT 게이트웨이는 인터넷 게이트웨이 구성 요소와 통신하므로 패킷을 최종 대상으로 전송할 수 있습니다.

![\[NAT 게이트웨이\]](http://docs.aws.amazon.com/ko_kr/eks/latest/best-practices/images/nat_gw.png)


이러한 사용 사례에 NAT 게이트웨이를 사용하는 *경우 각 AZ에 NAT 게이트웨이를 배포하여 데이터 전송 비용을 최소화할 수 있습니다*. 이렇게 하면 인터넷으로 라우팅되는 트래픽이 동일한 AZ의 NAT 게이트웨이를 통과하여 AZ 간 데이터 전송을 피할 수 있습니다. 그러나 AZ 간 데이터 전송 비용을 절감할 수 있지만이 설정의 영향은 아키텍처에서 추가 NAT 게이트웨이 비용이 발생한다는 것입니다.

이 권장 접근 방식은 아래 다이어그램에 나와 있습니다.

![\[권장 접근 방식\]](http://docs.aws.amazon.com/ko_kr/eks/latest/best-practices/images/recommended_approach.png)


### VPC 종단점 사용
<a name="_using_vpc_endpoints"></a>

이러한 아키텍처의 비용을 더욱 줄이려면 * [VPC 엔드포인트를](https://docs.aws.amazon.com/whitepapers/latest/aws-privatelink/what-are-vpc-endpoints.html) 사용하여 워크로드와 AWS 서비스 간의 연결을 설정해야 합니다*. VPC 엔드포인트를 사용하면 인터넷을 통과하는 데이터/네트워크 패킷 없이 VPC 내에서 AWS 서비스에 액세스할 수 있습니다. 모든 트래픽은 내부 트래픽이며 AWS 네트워크 내에 유지됩니다. VPC 엔드포인트에는 인터페이스 VPC 엔드포인트([많은 AWS 서비스에서 지원)](https://docs.aws.amazon.com/vpc/latest/privatelink/aws-services-privatelink-support.html)와 게이트웨이 VPC 엔드포인트(S3 및 DynamoDB에서만 지원)의 두 가지 유형이 있습니다.

 **게이트웨이 VPC 엔드포인트** 

 *게이트웨이 VPC 엔드포인트와 관련된 시간당 또는 데이터 전송 비용은 없습니다*. 게이트웨이 VPC 엔드포인트를 사용할 때는 VPC 경계를 넘어 확장할 수 없다는 점에 유의해야 합니다. VPC 피어링, VPN 네트워킹 또는 Direct Connect를 통해 사용할 수 없습니다.

 **인터페이스 VPC 엔드포인트** 

VPC 엔드포인트에는 [시간당 요금이 부과](https://aws.amazon.com/privatelink/pricing/)되며 기본 ENI를 통한 데이터 처리와 관련된 추가 요금이 부과됩니다. AZ 간 데이터 전송에는 [요금이 부과되지 않습니다](https://aws.amazon.com/about-aws/whats-new/2022/04/aws-data-transfer-price-reduction-privatelink-transit-gateway-client-vpn-services/).

아래 다이어그램은 VPC 엔드포인트를 통해 AWS 서비스와 통신하는 포드를 보여줍니다.

![\[VPC 엔드포인트\]](http://docs.aws.amazon.com/ko_kr/eks/latest/best-practices/images/vpc_endpoints.png)


## VPCs 간 데이터 전송
<a name="_data_transfer_between_vpcs"></a>

경우에 따라 서로 통신해야 하는 개별 VPCs(동일한 AWS 리전 내)에 워크로드가 있을 수 있습니다. 이는 트래픽이 각 VPCs. 이러한 통신은 퍼블릭 서브넷에 EC2 인스턴스, NAT 게이트웨이 또는 NAT 인스턴스와 같은 인프라 구성 요소를 배포하여 활성화할 수 있습니다. 그러나 이러한 구성 요소를 포함한 설정은 VPCs 안팎으로 데이터를 처리/전송하는 데 요금이 발생합니다. 별도의 VPCs와 주고받는 트래픽이 AZs 간에 이동하는 경우 데이터 전송에 추가 요금이 부과됩니다. 아래 다이어그램은 NAT 게이트웨이와 인터넷 게이트웨이를 사용하여 서로 다른 VPCs의 워크로드 간에 통신을 설정하는 설정을 보여줍니다.

![\[VPCs 간\]](http://docs.aws.amazon.com/ko_kr/eks/latest/best-practices/images/between_vpcs.png)


### VPC 피어링 연결
<a name="_vpc_peering_connections"></a>

이러한 사용 사례의 비용을 줄이기 위해 [VPC 피어링](https://docs.aws.amazon.com/vpc/latest/peering/what-is-vpc-peering.html)을 사용할 수 있습니다. VPC 피어링 연결을 사용하면 동일한 AZ 내에 유지되는 네트워크 트래픽에 대한 데이터 전송 요금이 부과되지 않습니다. 트래픽이 AZs 통과하면 비용이 발생합니다. 그러나 VPC 피어링 접근 방식은 동일한 AWS 리전 내의 개별 VPCs에 있는 워크로드 간의 비용 효율적인 통신에 권장됩니다. 그러나 VPC 피어링은 전이적 네트워킹을 허용하지 않으므로 주로 1:1 VPC 연결에 효과적입니다.

아래 다이어그램은 VPC 피어링 연결을 통한 워크로드 통신을 개괄적으로 나타낸 것입니다.

![\[피어링\]](http://docs.aws.amazon.com/ko_kr/eks/latest/best-practices/images/peering.png)


### 전이적 네트워킹 연결
<a name="_transitive_networking_connections"></a>

이전 단원에서 언급했듯이 VPC 피어링 연결은 전이적 네트워킹 연결을 허용하지 않습니다. 3VPCs를 전이적 네트워킹 요구 사항에 연결하려면 [Transit Gateway](https://docs.aws.amazon.com/vpc/latest/tgw/what-is-transit-gateway.html)(TGW)를 사용해야 합니다. 이렇게 하면 VPC 피어링의 제한이나 여러 VPC 간에 여러 VPC 피어링 연결이 있는 것과 관련된 운영 오버헤드를 극복할 수 VPCs. [시간당 및 TGW로 전송된 데이터에 대한 요금이 청구](https://aws.amazon.com/transit-gateway/pricing/)됩니다. *TGW를 통해 흐르는 AZ 간 트래픽과 관련된 대상 비용은 없습니다.*

아래 다이어그램은 서로 다른 VPCs의 워크로드 간에 동일한 AWS 리전 내에서 TGW를 통해 흐르는 AZ 간 트래픽을 보여줍니다.

![\[전이적\]](http://docs.aws.amazon.com/ko_kr/eks/latest/best-practices/images/transititive.png)


## Service Mesh 사용
<a name="_using_a_service_mesh"></a>

서비스 메시는 EKS 클러스터 환경에서 네트워크 관련 비용을 줄이는 데 사용할 수 있는 강력한 네트워킹 기능을 제공합니다. 그러나 채택할 경우 서비스 메시가 환경에 도입할 운영 작업과 복잡성을 신중하게 고려해야 합니다.

### 가용 영역으로 트래픽 제한
<a name="_restricting_traffic_to_availability_zones"></a>

 **Istio의 지리 가중 분포 사용** 

Istio를 사용하면 라우팅이 발생한 *후* 트래픽에 네트워크 정책을 적용할 수 있습니다. 이는 [지리 가중 분포](https://istio.io/latest/docs/tasks/traffic-management/locality-load-balancing/distribute/)와 같은 [대상 규칙을](https://istio.io/latest/docs/reference/config/networking/destination-rule/) 사용하여 수행됩니다. 이 기능을 사용하면 오리진에 따라 특정 대상으로 이동할 수 있는 트래픽의 가중치(백분율로 표시)를 제어할 수 있습니다. 이 트래픽의 소스는 외부(또는 퍼블릭) 로드 밸런서 또는 클러스터 자체 내의 포드에서 발생할 수 있습니다. 모든 포드 엔드포인트를 사용할 수 있게 되면 가중치 라운드 로빈 로드 밸런싱 알고리즘을 기반으로 로캘리티가 선택됩니다. 특정 엔드포인트가 비정상이거나 사용할 수 없는 경우 사용 가능한 엔드포인트의이 변경 사항을 반영하도록 [로캘 가중치가 자동으로 조정됩니다](https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/load_balancing/locality_weight.html).

**참고**  
로컬리티 가중치 기반 배포를 구현하기 전에 먼저 네트워크 트래픽 패턴과 대상 규칙 정책이 애플리케이션 동작에 미칠 수 있는 영향을 이해해야 합니다. 따라서 [AWS X-Ray](https://aws.amazon.com/xray/) 또는 [Jaeger](https://www.jaegertracing.io/)와 같은 도구를 사용하여 분산 추적 메커니즘을 마련하는 것이 중요합니다.

위에 자세히 설명된 Istio 대상 규칙을 적용하여 로드 밸런서에서 EKS 클러스터의 포드로 가는 트래픽을 관리할 수도 있습니다. 고가용성 로드 밸런서(특히 Ingress Gateway)에서 트래픽을 수신하는 서비스에 로컬리티 가중치 기반 배포 규칙을 적용할 수 있습니다. 이러한 규칙을 사용하면 영역 오리진, 즉이 경우 로드 밸런서에 따라 트래픽이 이동하는 양을 제어할 수 있습니다. 올바르게 구성하면 서로 다른 AZs의 포드 복제본에 트래픽을 균등하게 또는 무작위로 분산하는 로드 밸런서에 비해 송신 교차 영역 트래픽이 적게 발생합니다.

다음은 Istio에 있는 대상 규칙 리소스의 코드 블록 예제입니다. 아래에서 볼 수 있듯이이 리소스는 `eu-west-1` 리전에 있는 3개의 서로 다른 AZs에서 들어오는 트래픽에 대한 가중치 기반 구성을 지정합니다. 이러한 구성은 지정된 AZ에서 들어오는 트래픽의 대부분(이 경우 70%)이 시작된 동일한 AZ의 대상으로 프록시되어야 한다고 선언합니다.

```
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: express-test-dr
spec:
  host: express-test.default.svc.cluster.local
  trafficPolicy:
    loadBalancer:                      +
      localityLbSetting:
        distribute:
        - from: eu-west-1/eu-west-1a/  +
          to:
            "eu-west-1/eu-west-1a/_": 70
            "eu-west-1/eu-west-1b/_": 20
            "eu-west-1/eu-west-1c/_": 10
        - from: eu-west-1/eu-west-1b/_  +
          to:
            "eu-west-1/eu-west-1a/_": 20
            "eu-west-1/eu-west-1b/_": 70
            "eu-west-1/eu-west-1c/_": 10
        - from: eu-west-1/eu-west-1c/_  +
          to:
            "eu-west-1/eu-west-1a/_": 20
            "eu-west-1/eu-west-1b/_": 10
            "eu-west-1/eu-west-1c/*": 70**
    connectionPool:
      http:
        http2MaxRequests: 10
        maxRequestsPerConnection: 10
    outlierDetection:
      consecutiveGatewayErrors: 1
      interval: 1m
      baseEjectionTime: 30s
```

**참고**  
분산 대상일 수 있는 최소 가중치는 1%입니다. 그 이유는 기본 대상의 엔드포인트가 비정상이거나 사용할 수 없는 경우 장애 조치 리전과 영역을 유지하기 위한 것입니다.

아래 다이어그램은 *eu-west-1* 리전에 고가용성 로드 밸런서가 있고 지리 가중 분포가 적용되는 시나리오를 보여줍니다. 이 다이어그램의 대상 규칙 정책은 *eu-west-1a*에서 오는 트래픽의 60%를 동일한 AZ의 포드로 전송하도록 구성된 반면, *eu-west-1a*에서 오는 트래픽의 40%는 eu-west-1b의 포드로 이동해야 합니다.

![\[트래픽 제어 중지\]](http://docs.aws.amazon.com/ko_kr/eks/latest/best-practices/images/istio-traffic-control.png)


### 가용 영역 및 노드로 트래픽 제한
<a name="_restricting_traffic_to_availability_zones_and_nodes"></a>

 **Istio에서 서비스 내부 트래픽 정책 사용** 

*외부* 수신 트래픽 및 포드 간 *내부* 트래픽과 관련된 네트워크 비용을 완화하기 위해 Istio의 대상 규칙과 Kubernetes Service *내부 트래픽 정책을* 결합할 수 있습니다. Istio 대상 규칙을 서비스 내부 트래픽 정책과 결합하는 방법은 크게 3가지에 따라 달라집니다.
+ 마이크로서비스의 역할
+ 마이크로서비스 전반의 네트워크 트래픽 패턴
+ Kubernetes 클러스터 토폴로지에 마이크로서비스를 배포하는 방법

아래 다이어그램은 중첩된 요청의 경우 네트워크 흐름의 모습과 앞서 언급한 정책이 트래픽을 제어하는 방법을 보여줍니다.

![\[외부 및 내부 트래픽 정책\]](http://docs.aws.amazon.com/ko_kr/eks/latest/best-practices/images/external-and-internal-traffic-policy.png)


1. 최종 사용자는 **APP A에 요청을** 하고, 그러면 **APP C**에 중첩된 요청을 합니다. 이 요청은 먼저 위의 다이어그램과 같이 AZ 1 및 AZ 2에 인스턴스가 있는 가용성이 높은 로드 밸런서로 전송됩니다.

1. 그런 다음 외부 수신 요청은 Istio Virtual Service에 의해 올바른 대상으로 라우팅됩니다.

1. 요청이 라우팅된 후 Istio 대상 규칙은 요청이 시작된 위치(AZs 따라 각 AZ로 전송되는 트래픽의 양을 제어합니다.

1. 그러면 트래픽이 **APP A**용 서비스로 이동하고 해당 포드 엔드포인트로 프록시됩니다. 다이어그램에 표시된 것처럼 수신 트래픽의 80%는 AZ 1의 포드 엔드포인트로 전송되고 수신 트래픽의 20%는 AZ 2로 전송됩니다.

1.  그런 다음 **APP A**는 **APP C**에 내부 요청을 보냅니다. **APP C**의 서비스에 내부 트래픽 정책이 활성화되어 있습니다(`internalTrafficPolicy``: Local`).

1. **APP A**(**NODE 1**)에서 **APP C**로의 내부 요청은 **APP** C에 사용할 수 있는 노드-로컬 엔드포인트로 인해 성공합니다.

1. **APP A**(**NODE 3)에서** **APP C**로의 내부 요청은 **APP C**에 사용할 수 있는 *노드-로컬 엔드포인트*가 없기 때문에 실패합니다. 다이어그램에서 볼 수 있듯이 APP C에는 NODE 3에 복제본이 없습니다. **\$1**\$1

아래 스크린샷은이 접근 방식의 실제 예제에서 캡처됩니다. 첫 번째 스크린샷 세트는에 대한 성공적인 외부 요청`graphql`과에서 노드의 공동 위치 `orders` 복제본`graphql`에 대한 성공적인 중첩 요청을 보여줍니다`ip-10-0-0-151.af-south-1.compute.internal`.

![\[Before\]](http://docs.aws.amazon.com/ko_kr/eks/latest/best-practices/images/before.png)


![\[결과 이전\]](http://docs.aws.amazon.com/ko_kr/eks/latest/best-practices/images/before-results.png)


Istio를 사용하면 프록시가 인식하는 모든 [업스트림 클러스터](https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/intro/terminology) 및 엔드포인트의 통계를 확인하고 내보낼 수 있습니다. 이를 통해 네트워크 흐름과 워크로드 서비스 간의 분산 공유를 파악할 수 있습니다. 동일한 예제를 계속 진행하면서 프록시`graphql`가 인식하는 `orders` 엔드포인트는 다음 명령을 사용하여 가져올 수 있습니다.

```
kubectl exec -it deploy/graphql -n ecommerce -c istio-proxy -- curl localhost:15000/clusters | grep orders
```

```
...
orders-service.ecommerce.svc.cluster.local::10.0.1.33:3003::**rq_error::0**
orders-service.ecommerce.svc.cluster.local::10.0.1.33:3003::**rq_success::119**
orders-service.ecommerce.svc.cluster.local::10.0.1.33:3003::**rq_timeout::0**
orders-service.ecommerce.svc.cluster.local::10.0.1.33:3003::**rq_total::119**
orders-service.ecommerce.svc.cluster.local::10.0.1.33:3003::**health_flags::healthy**
orders-service.ecommerce.svc.cluster.local::10.0.1.33:3003::**region::af-south-1**
orders-service.ecommerce.svc.cluster.local::10.0.1.33:3003::**zone::af-south-1b**
...
```

이 경우 `graphql` 프록시는 노드를 공유하는 복제본의 `orders` 엔드포인트만 인식합니다. 서비스 주문에서 `internalTrafficPolicy: Local` 설정을 제거하고 위와 같은 명령을 다시 실행하면 결과가 서로 다른 노드에 분산된 복제본의 모든 엔드포인트를 반환합니다. 또한 각 엔드포인트`rq_total`의를 검사하면 네트워크 배포가 비교적 균등하게 공유됩니다. 따라서 엔드포인트가 서로 다른 AZs에서 실행되는 업스트림 서비스와 연결된 경우 영역 간이 네트워크 배포로 인해 비용이 증가합니다.

위의 이전 섹션에서 언급한 대로 포드 선호도를 사용하여 자주 통신하는 포드를 공동 배치할 수 있습니다.

```
...
spec:
...
  template:
    metadata:
      labels:
        app: graphql
        role: api
        workload: ecommerce
    spec:
      affinity:
        podAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - orders
            topologyKey: "kubernetes.io/hostname"
      nodeSelector:
        managedBy: karpenter
        billing-team: ecommerce
...
```

`graphql` 및 `orders` 복제본`graphql`이 동일한 노드(`ip-10-0-0-151.af-south-1.compute.internal`)에 공존하지 않으면 아래 Postman 스크린샷의 `200 response code`에 명시된 대로에 대한 첫 번째 요청이 성공하는 반면,에 `graphql` 대한 두 번째 중첩 요청은 로 `orders` 실패합니다`503 response code`.

 ![\[After\]](http://docs.aws.amazon.com/ko_kr/eks/latest/best-practices/images/after.png) ![\[After results\]](http://docs.aws.amazon.com/ko_kr/eks/latest/best-practices/images/after-results.png) 

## 추가 리소스
<a name="_additional_resources"></a>
+  [Istio를 사용하여 EKS의 지연 시간 및 데이터 전송 비용 해결](https://aws.amazon.com/blogs/containers/addressing-latency-and-data-transfer-costs-on-eks-using-istio/) 
+  [Amazon Elastic Kubernetes Service에서 네트워크 트래픽에 대한 토폴로지 인식 힌트의 영향 탐색](https://aws.amazon.com/blogs/containers/exploring-the-effect-of-topology-aware-hints-on-network-traffic-in-amazon-elastic-kubernetes-service/) 
+  [Amazon EKS Cross-AZ 포드에서 포드 네트워크 바이트로의 가시성 확보](https://aws.amazon.com/blogs/containers/getting-visibility-into-your-amazon-eks-cross-az-pod-to-pod-network-bytes/) 
+  [Istio를 사용하여 AZ 트래픽 최적화](https://youtu.be/EkpdKVm9kQY) 
+  [토폴로지 인식 라우팅을 사용하여 AZ 트래픽 최적화](https://youtu.be/KFgE_lNVfz4) 
+  [서비스 내부 트래픽 정책을 사용하여 Kubernetes 비용 및 성능 최적화](https://youtu.be/-uiF_zixEro) 
+  [Istio 및 서비스 내부 트래픽 정책을 사용하여 Kubernetes 비용 및 성능 최적화](https://youtu.be/edSgEe7Rihc) 
+  [Overview of Data Transfer Costs for Common Architectures](https://aws.amazon.com/blogs/architecture/overview-of-data-transfer-costs-for-common-architectures/) 
+  [AWS 컨테이너 서비스의 데이터 전송 비용 이해](https://aws.amazon.com/blogs/containers/understanding-data-transfer-costs-for-aws-container-services/) 

# 스토리지
<a name="cost-opt-storage"></a>

## 개요
<a name="_overview"></a>

단기 또는 장기적으로 데이터를 보존해야 하는 애플리케이션을 실행하려는 시나리오가 있습니다. 이러한 사용 사례의 경우 포드가 볼륨을 정의하고 탑재하여 컨테이너가 다양한 스토리지 메커니즘을 활용할 수 있도록 할 수 있습니다. Kubernetes는 임시 및 영구 스토리지를 위해 다양한 유형의 [볼륨](https://kubernetes.io/docs/concepts/storage/volumes/)을 지원합니다. 스토리지 선택은 주로 애플리케이션 요구 사항에 따라 달라집니다. 각 접근 방식에는 비용에 영향을 미치며, 아래에 설명된 관행은 EKS 환경에서 일종의 스토리지가 필요한 워크로드에 대한 비용 효율성을 달성하는 데 도움이 됩니다.

## 임시 볼륨
<a name="_ephemeral_volumes"></a>

임시 볼륨은 일시적인 로컬 볼륨이 필요하지만 재시작 후 데이터를 유지할 필요가 없는 애플리케이션을 위한 것입니다. 여기에는 스크래치 공간, 캐싱, 구성 데이터 및 보안 암호와 같은 읽기 전용 입력 데이터에 대한 요구 사항이 포함됩니다. Kubernetes 임시 볼륨에 대한 자세한 내용은 여기에서 확인할 수 [있습니다](https://kubernetes.io/docs/concepts/storage/ephemeral-volumes/). 대부분의 임시 볼륨(예: emptyDir, configMap, downwardAPI, secret, hostpath)은 로컬에 연결된 쓰기 가능한 디바이스(일반적으로 루트 디스크) 또는 RAM으로 지원되므로 가장 비용 효율적이고 성능이 뛰어난 호스트 볼륨을 선택하는 것이 중요합니다.

### EBS 볼륨 사용
<a name="_using_ebs_volumes"></a>

 *호스트 루트 볼륨으로 [gp3](https://aws.amazon.com/ebs/general-purpose/)로 시작하는 것이 좋습니다.* Amazon EBS에서 제공하는 최신 범용 SSD 볼륨이며 gp2 볼륨에 비해 GB당 더 저렴한 가격(최대 20%)을 제공합니다.

### Amazon EC2 인스턴스 스토어 사용
<a name="_using_amazon_ec2_instance_stores"></a>

 [Amazon EC2 인스턴스 스토어](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/InstanceStorage.html)는 EC2 인스턴스에 임시 블록 수준 스토리지를 제공합니다. EC2 인스턴스 스토어에서 제공하는 스토리지는 호스트에 물리적으로 연결된 디스크를 통해 액세스할 수 있습니다. Amazon EBS와 달리 인스턴스가 시작될 때만 인스턴스 스토어 볼륨을 연결할 수 있으며, 이러한 볼륨은 인스턴스 수명 동안에만 존재합니다. 분리하여 다른 인스턴스에 다시 연결할 수 없습니다. Amazon EC2 인스턴스 스토어에 대한 자세한 내용은 여기에서 확인할 수 [있습니다](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/InstanceStorage.html). *인스턴스 스토어 볼륨과 관련된 추가 요금은 없습니다.* 이렇게 하면 EBS 볼륨이 큰 일반 EC2 인스턴스보다 (인스턴스 스토어 볼륨)가 *더 비용 효율적*입니다.

Kubernetes에서 로컬 스토어 볼륨을 사용하려면 볼륨을 포드 사양에서 [HostPath](https://kubernetes.io/docs/concepts/storage/volumes/#hostpath)로 마운트할 수 있도록 [ Amazon EC2 사용자 데이터를 사용하여](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-add-user-data.html) 디스크를 분할, 구성 및 포맷해야 합니다. 또는 [Local Persistent Volume Static Provisioner](https://github.com/kubernetes-sigs/sig-storage-local-static-provisioner)를 활용하여 로컬 스토리지 관리를 간소화할 수 있습니다. 로컬 영구 볼륨 정적 프로비저너를 사용하면 표준 Kubernetes PersistentVolumeClaim(PVC) 인터페이스를 통해 로컬 인스턴스 스토어 볼륨에 액세스할 수 있습니다. 또한 노드 선호도 정보가 포함된 PersistentVolumes(PVs)을 프로비저닝하여 포드를 올바른 노드로 예약합니다. Kubernetes PersistentVolumes를 사용하지만 EC2 인스턴스 스토어 볼륨은 본질적으로 일시적입니다. 임시 디스크에 기록된 데이터는 인스턴스 수명 동안에만 사용할 수 있습니다. 인스턴스가 종료되면 데이터도 마찬가지입니다. 자세한 내용은이 [블로그](https://aws.amazon.com/blogs/containers/eks-persistent-volumes-for-instance-store/)를 참조하세요.

Amazon EC2 인스턴스 스토어 볼륨을 사용할 때 총 IOPS 한도는 호스트와 공유되며 특정 호스트에 포드를 바인딩합니다. Amazon EC2 인스턴스 스토어 볼륨을 채택하기 전에 워크로드 요구 사항을 철저히 검토해야 합니다.

## 영구 볼륨
<a name="_persistent_volumes"></a>

Kubernetes는 일반적으로 상태 비저장 애플리케이션을 실행하는 것과 관련이 있습니다. 그러나 한 요청에서 다음 요청으로 영구 데이터 또는 정보를 보존해야 하는 마이크로서비스를 실행하려는 시나리오가 있습니다. 데이터베이스는 이러한 사용 사례의 일반적인 예입니다. 그러나 포드와 포드 내의 컨테이너 또는 프로세스는 본질적으로 일시적입니다. 포드의 수명을 초과하여 데이터를 유지하려면 PVs 사용하여 포드와 독립적인 특정 위치에서 스토리지에 대한 액세스를 정의할 수 있습니다. *PVs와 관련된 비용은 사용 중인 스토리지 유형과 애플리케이션이 이를 사용하는 방식에 따라 크게 달라집니다.*

[여기에](https://docs.aws.amazon.com/eks/latest/userguide/storage.html) 나열된 Amazon EKS에서 Kubernetes PVs 지원하는 다양한 유형의 스토리지 옵션이 있습니다. 아래에서 다루는 스토리지 옵션은 Amazon EBS, Amazon EFS, Amazon FSx for Lustre, Amazon FSx for NetApp ONTAP입니다.

### Amazon Elastic Block Store(EBS) 볼륨
<a name="_amazon_elastic_block_store_ebs_volumes"></a>

Amazon EBS 볼륨을 Kubernetes PVs을 제공할 수 있습니다. 이는 임의 읽기 및 쓰기와 길고 지속적인 읽기 및 쓰기를 수행하는 처리량 집약적인 애플리케이션에 의존하는 데이터베이스에 적합합니다. [Amazon Elastic Block Store 컨테이너 스토리지 인터페이스(CSI) 드라이버를](https://docs.aws.amazon.com/eks/latest/userguide/ebs-csi.html) 사용하면 Amazon EKS 클러스터가 영구 볼륨에 대한 Amazon EBS 볼륨의 수명 주기를 관리할 수 있습니다. 컨테이너 스토리지 인터페이스는 Kubernetes와 스토리지 시스템 간의 상호 작용을 활성화하고 용이하게 합니다. CSI 드라이버가 EKS 클러스터에 배포되면 영구 볼륨(PVs), 영구 볼륨 클레임(PVCs), 스토리지 클래스(SCs. 이 [링크](https://github.com/kubernetes-sigs/aws-ebs-csi-driver/tree/master/examples/kubernetes)는 Amazon EBS CSI 드라이버를 사용하여 Amazon EBS 볼륨과 상호 작용하는 방법에 대한 실제 예제를 제공합니다.

#### 올바른 볼륨 선택
<a name="_choosing_the_right_volume"></a>

 *가격과 성능 간에 적절한 균형을 제공하므로 최신 세대의 블록 스토리지(gp3)를 사용하는 것이 좋습니다*. 또한 추가 블록 스토리지 용량을 프로비저닝할 필요 없이 볼륨 크기와 관계없이 볼륨 IOPS 및 처리량을 조정할 수 있습니다. 현재 gp2 볼륨을 사용하는 경우 gp3 볼륨으로 마이그레이션하는 것이 좋습니다. 블로그 게시물 [gp2에서 gp3 EBS 볼륨으로 Amazon EKS 클러스터 마이그레이션](https://aws.amazon.com/blogs/containers/migrating-amazon-eks-clusters-from-gp2-to-gp3-ebs-volumes/)에서는 애플리케이션 가동 중지가 필요한 CSI [볼륨 스냅샷](https://kubernetes.io/docs/concepts/storage/volume-snapshots/) 기능을 사용하여 백업 및 복원을 통해 Amazon EKS 클러스터의 gp*2*에서 *gp3*로 마이그레이션하는 방법을 설명합니다.

Amazon EBS를 사용하면 볼륨 크기, IOPS 및 처리량과 같은 볼륨 특성을 온라인으로 변경할 수 있습니다. 이 기능을 사용하면이 [블로그](https://aws.amazon.com/blogs/storage/simplifying-amazon-ebs-volume-migration-and-modification-using-the-ebs-csi-driver/)에 설명된 대로 EBS CSI 드라이버 v1.19.0\$1를 사용하거나 여기에 설명된 [VolumeAttributesClass API](https://kubernetes.io/docs/concepts/storage/volume-attributes-classes/)를 사용하여 Amazon EKS v1.31 및 EBS CSI 드라이버 1.35로 시작하는 PVC 주석을 사용하여 애플리케이션 가동 중지 없이 gp3의 *gp**2*에서 마이그레이션할 수 [있습니다](https://aws.amazon.com/blogs/containers/modify-amazon-ebs-volumes-on-kubernetes-with-volume-attributes-classes/).

더 높은 성능이 필요하고 단일 [gp3 볼륨이 지원할 수 있는 것보다 더 큰 볼륨](https://aws.amazon.com/ebs/general-purpose/)이 필요한 애플리케이션이 있는 경우 [io2 블록 익스프레스](https://aws.amazon.com/ebs/provisioned-iops/)를 사용하는 것이 좋습니다. 이러한 유형의 스토리지는 SAP HANA 또는 지연 시간이 짧은 기타 대규모 데이터베이스와 같은 가장 크고 가장 많은 I/O 집약적이며 미션 크리티컬한 배포에 적합합니다. 인스턴스의 EBS 성능은 인스턴스의 성능 제한에 따라 제한되므로 모든 인스턴스가 io2 블록 Express 볼륨을 지원하는 것은 아닙니다. 이 [문서에서 지원되는 인스턴스 유형 및 기타 고려 사항을 확인할 수 있습니다](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/provisioned-iops.html).

 *단일 gp3 볼륨은 최대 16,000 IOPS, 최대 1,000MiB/s 처리량, 최대 16TiB를 지원할 수 있습니다. 최대 256,000 IOPS, 4,000MiB/s, 처리량 및 64TiB를 제공하는 최신 세대의 프로비저닝된 IOPS SSD 볼륨입니다.*

이러한 옵션 중에서 애플리케이션의 요구 사항에 맞게 스토리지 성능과 비용을 가장 잘 조정해야 합니다.

#### 시간 경과에 따른 모니터링 및 최적화
<a name="_monitor_and_optimize_over_time"></a>

애플리케이션의 기준 성능을 이해하고 선택한 볼륨에 대해 모니터링하여 애플리케이션이 요구 사항/기대치를 충족하는지 또는 과다 프로비저닝되었는지(예: 프로비저닝된 IOPS가 완전히 활용되지 않는 시나리오) 확인하는 것이 중요합니다.

대용량 볼륨을 처음부터 할당하는 대신 데이터를 누적할 때 볼륨 크기를 점진적으로 늘릴 수 있습니다. Amazon Elastic Block Store CSI 드라이버(aws-ebs-csi-driver)의 [볼륨 크기 조정](https://github.com/kubernetes-sigs/aws-ebs-csi-driver/tree/master/examples/kubernetes/resizing) 기능을 사용하여 볼륨 크기를 동적으로 조정할 수 있습니다. *EBS 볼륨 크기만 늘릴 수 있다는 점에 유의하세요.*

매달린 EBS 볼륨을 식별하고 제거하려면 [AWS 신뢰할 수 있는 어드바이저의 비용 최적화 범주를](https://docs.aws.amazon.com/awssupport/latest/user/cost-optimization-checks.html) 사용할 수 있습니다. 이 기능을 사용하면 연결되지 않은 볼륨 또는 일정 기간 동안 쓰기 활동이 매우 적은 볼륨을 식별할 수 있습니다. 라이브 Kubernetes 클러스터를 스캔하고 배포된 리소스 및 구성과 관련된 잠재적 문제를 보고하는 [Popeye](https://github.com/derailed/popeye)라는 클라우드 네이티브 오픈 소스 읽기 전용 도구가 있습니다. 예를 들어 미사용 PVs 및 PVCs를 스캔하고 경계가 있는지 또는 볼륨 마운트 오류가 있는지 확인할 수 있습니다.

모니터링에 대한 자세한 내용은 [EKS 비용 최적화 관찰성 가이드를](https://docs.aws.amazon.com/eks/latest/best-practices/cost-opt-observability.html) 참조하세요.

고려할 수 있는 또 다른 옵션은 [AWS Compute Optimizer Amazon EBS 볼륨 권장 사항](https://docs.aws.amazon.com/compute-optimizer/latest/ug/view-ebs-recommendations.html)입니다. 이 도구는 최적의 볼륨 구성과 필요한 올바른 성능 수준을 자동으로 식별합니다. 예를 들어 지난 14일 동안의 최대 사용률을 기반으로 프로비저닝된 IOPS, 볼륨 크기 및 EBS 볼륨 유형과 관련된 최적의 설정에 사용할 수 있습니다. 또한 권장 사항에서 파생된 잠재적 월별 비용 절감액도 정량화합니다. 자세한 내용은이 [블로그](https://aws.amazon.com/blogs/storage/cost-optimizing-amazon-ebs-volumes-using-aws-compute-optimizer/)를 참조하세요.

#### 백업 보관 정책
<a name="_backup_retention_policy"></a>

point-in-time 스냅샷을 생성하여 Amazon EBS 볼륨에 데이터를 백업할 수 있습니다. Amazon EBS CSI 드라이버는 볼륨 스냅샷을 지원합니다. 여기에 설명된 단계를 사용하여 스냅샷을 생성하고 EBS PV를 복원하는 방법을 배울 수 [있습니다](https://github.com/kubernetes-sigs/aws-ebs-csi-driver/blob/master/examples/kubernetes/snapshot/README.md).

후속 스냅샷은 증분 백업입니다. 즉, 가장 최근 스냅샷 이후에 변경된 디바이스의 블록만 저장됩니다. 그러면 스냅샷을 만드는 데 필요한 시간이 최소화되며 데이터를 복제하지 않으므로 스토리지 비용이 절약됩니다. 그러나 적절한 보존 정책 없이 이전 EBS 스냅샷 수를 늘리면 대규모로 운영할 때 예상치 못한 비용이 발생할 수 있습니다. AWS API를 통해 Amazon EBS 볼륨을 직접 백업하는 경우 [Amazon Elastic Block Store(EBS) 스냅샷 및 EBS 지원 Amazon Machine Image(AMI)에 대한 자동화된 정책 기반 수명 주기 관리 솔루션을 제공하는 Amazon Data Lifecycle Manager](https://aws.amazon.com/ebs/data-lifecycle-manager/)AMIs. 콘솔을 사용하면 EBS 스냅샷 및 AMIs.

**참고**  
현재 Amazon EBS CSI 드라이버를 통해 Amazon DLM을 사용할 수 있는 방법은 없습니다.

Kubernetes 환경에서는 [Velero](https://velero.io/)라는 오픈 소스 도구를 활용하여 EBS 영구 볼륨을 백업할 수 있습니다. 백업 만료 작업을 예약할 때 TTL 플래그를 설정할 수 있습니다. 다음은 Velero의 [예제](https://velero.io/docs/v1.12/how-velero-works/#set-a-backup-to-expire) 가이드입니다.

### Amazon Elastic File System(EFS)
<a name="_amazon_elastic_file_system_efs"></a>

 [Amazon Elastic File System(EFS)](https://aws.amazon.com/efs/)은 광범위한 워크로드 및 애플리케이션에 대해 표준 파일 시스템 인터페이스 및 파일 시스템 의미 체계를 사용하여 파일 데이터를 공유할 수 있는 서버리스의 완전 탄력적 파일 시스템입니다. 워크로드 및 애플리케이션의 예로는 Wordpress 및 Drupal, JIRA 및 Git과 같은 개발자 도구, Jupyter와 같은 공유 노트북 시스템, 홈 디렉터리 등이 있습니다.

Amazon EFS의 주요 이점 중 하나는 여러 노드와 여러 가용 영역에 분산된 여러 컨테이너에서 탑재할 수 있다는 것입니다. 또 다른 이점은 사용하는 스토리지에 대해서만 비용을 지불한다는 것입니다. 파일을 추가 및 제거하면 EFS 파일 시스템이 자동으로 확장 및 축소되므로 용량 계획이 필요하지 않습니다.

Kubernetes에서 Amazon EFS를 사용하려면 Amazon Elastic File System Container Storage Interface(CSI) 드라이버인 [aws-efs-csi-driver](https://github.com/kubernetes-sigs/aws-efs-csi-driver) 사용해야 합니다. 현재 드라이버는 [액세스 포인트를](https://docs.aws.amazon.com/efs/latest/ug/efs-access-points.html) 동적으로 생성할 수 있습니다. 그러나 Amazon EFS 파일 시스템을 먼저 프로비저닝하고 Kubernetes 스토리지 클래스 파라미터에 대한 입력으로 제공해야 합니다.

#### 올바른 EFS 스토리지 클래스 선택
<a name="_choosing_the_right_efs_storage_class"></a>

Amazon EFS는 [네 가지 스토리지 클래스](https://docs.aws.amazon.com/efs/latest/ug/storage-classes.html)를 제공합니다.

두 가지 표준 스토리지 클래스:
+ Amazon EFS Standard
+  [Amazon EFS Standard-Infrequent Access](https://aws.amazon.com/blogs/aws/optimize-storage-cost-with-reduced-pricing-for-amazon-efs-infrequent-access/)(EFS Standard-IA)

두 개의 단일 영역 스토리지 클래스:
+  [Amazon EFS One Zone](https://aws.amazon.com/blogs/aws/new-lower-cost-one-zone-storage-classes-for-amazon-elastic-file-system/) 
+ Amazon EFS One Zone-Infrequent Access(EFS One Zone-IA)

Infrequent Access(IA) 스토리지 클래스는 매일 액세스하지 않는 파일에 대해 비용이 최적화됩니다. Amazon EFS 수명 주기 관리를 사용하면 수명 주기 정책 기간(7, 14, 30, 60 또는 90일) 동안 액세스하지 않은 파일을 IA 스토리지 클래스로 이동할 수 *있으므로 EFS Standard 및 EFS One Zone 스토리지 클래스에 비해 스토리지 비용을 각각 최대 92% 절감할 수* 있습니다.

EFS Intelligent-Tiering을 사용하면 수명 주기 관리가 파일 시스템의 액세스 패턴을 모니터링하고 파일을 가장 최적의 스토리지 클래스로 자동으로 이동합니다.

**참고**  
aws-efs-csi-driver는 현재 스토리지 클래스 변경, 수명 주기 관리 또는 Intelligent-Tiering을 제어할 수 없습니다. AWS 콘솔 또는 EFS APIs.

**참고**  
aws-efs-csi-driver는 창 기반 컨테이너 이미지와 호환되지 않습니다.

**참고**  
파일 시스템의 크기에 비례하는 양의 메모리를 소비하는 [DiskUsage](https://github.com/kubernetes/kubernetes/blob/ee265c92fec40cd69d1de010b477717e4c142492/pkg/volume/util/fs/fs.go#L66) 함수로 인해 *vol-metrics-opt-in*(볼륨 지표를 내보내기 위해)이 활성화된 경우 알려진 메모리 문제가 있습니다. *현재는 메모리를 너무 많이 소비하지 않도록 대용량 파일 시스템에서 `--vol-metrics-opt-in` 옵션을 비활성화하는 것이 좋습니다**.vol-metrics-opt-in 자세한 내용은 github 문제 [링크를](https://github.com/kubernetes-sigs/aws-efs-csi-driver/issues/1104) 참조하세요.*

### Amazon FSx for Lustre
<a name="_amazon_fsx_for_lustre"></a>

Lustre는 최대 수백 GB/s의 처리량과 작업당 밀리초 미만의 지연 시간이 필요한 워크로드에 일반적으로 사용되는 고성능 병렬 파일 시스템입니다. 기계 학습 훈련, 금융 모델링, HPC 및 비디오 처리와 같은 시나리오에 사용됩니다. [Amazon FSx for Lustre](https://aws.amazon.com/fsx/lustre/)는 Amazon S3와 원활하게 통합된 확장성과 성능을 갖춘 완전관리형 공유 스토리지를 제공합니다.

Amazon EKS의 FSx for Lustre [CSI 드라이버 또는 AWS의 자체 관리형 Kubernetes 클러스터를 사용하여 FSx for Lustre](https://github.com/kubernetes-sigs/aws-fsx-csi-driver)에서 지원하는 Kubernetes 영구 스토리지 볼륨을 사용할 수 있습니다. 자세한 내용과 예제는 [Amazon EKS 설명서를](https://docs.aws.amazon.com/eks/latest/userguide/fsx-csi.html) 참조하세요.

#### Amazon S3에 대한 링크
<a name="_link_to_amazon_s3"></a>

Amazon S3에 있는 내구성이 뛰어난 장기 데이터 리포지토리를 FSx for Lustre 파일 시스템과 연결하는 것이 좋습니다. 연결된 대용량 데이터 세트는 필요에 따라 Amazon S3에서 FSx for Lustre 파일 시스템으로 지연 로드됩니다. 분석 및 결과를 S3로 다시 실행한 다음 Lustre 파일 시스템을 삭제할 수도 있습니다.

#### 올바른 배포 및 스토리지 옵션 선택
<a name="_choosing_the_right_deployment_and_storage_options"></a>

FSx for Lustre는 다양한 배포 옵션을 제공합니다. 첫 번째 옵션은 *스크래치*라고 하며 데이터를 복제하지 않고, 두 번째 옵션은 *영구*적이라고 하며, 이름에서 알 수 있듯이 데이터가 유지됩니다.

첫 번째 옵션(*스크래치*)을 사용하여 *일시적인 단기 데이터 처리 비용을 줄일 수 있습니다.* 영구 배포 옵션은 AWS 가용 영역 내에서 데이터를 자동으로 복제하는 *장기 스토리지를 위해 설계되었습니다*. 또한 SSD 및 HDD 스토리지를 모두 지원합니다.

FSx for lustre 파일 시스템의 Kubernetes StorageClass의 파라미터에서 원하는 배포 유형을 구성할 수 있습니다. 다음은 샘플 템플릿을 제공하는 [링크](https://github.com/kubernetes-sigs/aws-fsx-csi-driver/tree/master/examples/kubernetes/dynamic_provisioning#edit-storageclass)입니다.

**참고**  
지연 시간에 민감한 워크로드 또는 최고 수준의 IOPS/처리량이 필요한 워크로드의 경우 SSD 스토리지를 선택해야 합니다. 지연 시간에 민감하지 않은 처리량 중심 워크로드의 경우 HDD 스토리지를 선택해야 합니다.

#### 데이터 압축 활성화
<a name="_enable_data_compression"></a>

"LZ4"를 데이터 압축 유형으로 지정하여 파일 시스템에서 데이터 압축을 활성화할 수도 있습니다. 활성화되면 새로 작성된 모든 파일은 디스크에 기록되기 전에 FSx for Lustre에서 자동으로 압축되고 읽을 때 압축되지 않습니다. LZ4 데이터 압축 알고리즘은 손실이 없으므로 압축된 데이터에서 원본 데이터를 완전히 재구성할 수 있습니다.

FSx for lustre 파일 시스템의 Kubernetes StorageClass의 파라미터에서 데이터 압축 유형을 LZ4로 구성할 수 있습니다. 값이 기본값인 NONE으로 설정되면 압축이 비활성화됩니다. 이 [링크](https://github.com/kubernetes-sigs/aws-fsx-csi-driver/tree/master/examples/kubernetes/dynamic_provisioning#edit-storageclass)는 샘플 템플릿을 제공합니다.

**참고**  
Amazon FSx for Lustre는 창 기반 컨테이너 이미지와 호환되지 않습니다.

### Amazon FSx for NetApp ONTAP
<a name="_amazon_fsx_for_netapp_ontap"></a>

 [Amazon FSx for NetApp ONTAP](https://aws.amazon.com/fsx/netapp-ontap/)은 NetApp의 ONTAP 파일 시스템에 구축된 완전 관리형 공유 스토리지입니다. FSx for ONTAP은 AWS 또는 온프레미스에서 실행되는 Linux, Windows 및 macOS 컴퓨팅 인스턴스에서 광범위하게 액세스할 수 있는 기능이 풍부하고 빠르고 유연한 공유 파일 스토리지를 제공합니다.

Amazon FSx for NetApp ONTAP은 *1/프라이머리 티어와 2/용량 풀 티어**의 두 가지 스토리지 티어를 지원합니다.*

*기본 계층*은 지연 시간에 민감한 활성 데이터를 위한 프로비저닝된 고성능 SSD 기반 계층입니다. 완전 탄력적 *용량 풀 계층*은 자주 액세스하지 않는 데이터에 대해 비용 최적화되고, 데이터가 계층화되면 자동으로 확장되며, 사실상 무제한 페타바이트의 용량을 제공합니다. 용량 풀 스토리지에서 데이터 압축 및 중복 제거를 활성화하고 데이터가 소비하는 스토리지 용량을 추가로 줄일 수 있습니다. NetApp의 기본 정책 기반 FabricPool 기능은 데이터 액세스 패턴을 지속적으로 모니터링하여 스토리지 계층 간에 양방향으로 데이터를 자동으로 전송하여 성능과 비용을 최적화합니다.

NetApp의 Astra Trident는 Amazon EKS 클러스터가 Amazon FSx for NetApp ONTAP 파일 시스템이 지원하는 영구 볼륨 PVs의 수명 주기를 관리할 수 있도록 CSI 드라이버를 사용하여 동적 스토리지 오케스트레이션을 제공합니다. 시작하려면 Astra Trident 설명서의 [Amazon FSx for NetApp ONTAP에서 Astra Trident 사용](https://docs.netapp.com/us-en/trident/trident-use/trident-fsx.html)을 참조하세요.

## 기타 고려 사항
<a name="_other_considerations"></a>

### 컨테이너 이미지 크기 최소화
<a name="_minimize_the_size_of_container_image"></a>

컨테이너가 배포되면 컨테이너 이미지가 호스트에 여러 계층으로 캐시됩니다. 이미지 크기를 줄이면 호스트에 필요한 스토리지 양을 줄일 수 있습니다.

처음부터 스크래치 이미지 또는 [무분별](https://github.com/GoogleContainerTools/distroless)한 컨테이너 이미지(애플리케이션 및 런타임 종속성만 포함)와 같은 축소된 기본 이미지를 사용하면 *공격 표면적 감소 및 이미지 풀 타임 단축과 같은 다른 보조 이점 외에도 스토리지 비용을 절감할 수 있습니다.*

또한 [Slim.ai](https://www.slim.ai/docs/quickstart) 같은 오픈 소스 도구를 사용하면 최소한의 이미지를 쉽고 안전하게 생성할 수 있습니다.

패키지, 도구, 애플리케이션 종속성, 라이브러리의 여러 계층이 컨테이너 이미지 크기를 쉽게 팽창시킬 수 있습니다. 다단계 빌드를 사용하면 최종 이미지에서 필요하지 않은 모든 것을 제외하고 한 단계에서 다른 단계로 아티팩트를 선택적으로 복사할 수 있습니다. 여기에서 더 많은 이미지 빌드 모범 사례를 확인할 수 [있습니다](https://docs.docker.com/get-started/09_image_best/).

또 다른 고려 사항은 캐시된 이미지를 얼마나 오래 유지할지입니다. 일정량의 디스크를 사용할 때 이미지 캐시에서 오래된 이미지를 정리할 수 있습니다. 이렇게 하면 호스트 작업에 충분한 공간이 있는지 확인하는 데 도움이 됩니다. 기본적으로 [kubelet](https://kubernetes.io/docs/reference/generated/kubelet)은 5분마다 미사용 이미지에 대해 가비지 수집을 수행하고 1분마다 미사용 컨테이너에 대해 가비지 수집을 수행합니다.

 *미사용 컨테이너 및 이미지 가비지 수집에 대한 옵션을 구성하려면 [구성 파일을](https://kubernetes.io/docs/tasks/administer-cluster/kubelet-config-file/) 사용하여 kubelet을 조정하고 [https://kubernetes.io/docs/reference/config-api/kubelet-config.v1beta1/](https://kubernetes.io/docs/reference/config-api/kubelet-config.v1beta1/) 리소스 유형을 사용하여 가비지 수집과 관련된 파라미터를 변경합니다.*

이에 대한 자세한 내용은 Kubernetes [설명서](https://kubernetes.io/docs/concepts/architecture/garbage-collection/#containers-images)에서 확인할 수 있습니다.

# 관찰성
<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에서 벤딩 로그로 분류됩니다. 벤딩 로그는 AWS 서비스가 고객을 대신하여 기본적으로 게시하고 볼륨 할인 요금으로 사용할 수 있는 특정 AWS 서비스 로그입니다. [Amazon CloudWatch 요금 페이지를](https://aws.amazon.com/cloudwatch/pricing/) 방문하여 벤딩 로그 요금에 대해 자세히 알아보세요.

## 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)에서 각 로그 그룹에 따라 1일에서 10년까지 보존 기간을 [구성할 수 있습니다](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/Working-with-log-groups-and-streams.html#SettingLogRetention). 유연한 보존 기간이 있으면 로그 스토리지 비용을 절감하는 동시에 중요한 로그를 유지할 수 있습니다.

### 로그 스토리지 옵션
<a name="_log_storage_options"></a>

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

#### 로그를 S3로 직접 전달
<a name="_forward_logs_directly_to_s3"></a>

Cloudwatch 대신 개발 환경과 같이 덜 중요한 로그를 S3로 직접 전달하는 것이 좋습니다. 이는 로그 스토리지 비용에 즉각적인 영향을 미칠 수 있습니다. 한 가지 옵션은 Fluentbit을 사용하여 로그를 S3로 직접 전달하는 것입니다. FluentBit가 보관을 위해 컨테이너 로그를 전송하는 대상인 `[OUTPUT]` 섹션에서 이를 정의합니다. [여기에서](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에 전달하는 것이 좋습니다. FluentBit가 보관을 위해 컨테이너 로그를 전송하는 대상인 `[OUTPUT]` 섹션에서 이를 정의합니다. [여기에서](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/)를 참조하세요. 예를 들어 프로덕션 환경의 경우 로그는 30일 이상 CloudWatch에 상주한 다음 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 프로세스 로그 수준을 조정할 수 있는 구성 설정이 있습니다. 이 구성 설정의 코드 조각은 다음과 같습니다. `kubelet` 프로세스의 로깅 세부 정보를 조정하는 기본 [로그 수준](https://github.com/bottlerocket-os/bottlerocket/blob/3f716bd68728f7fd825eb45621ada0972d0badbb/README.md?plain=1#L528) **2**를 기록해 둡니다.

```
[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는 아래 `[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
<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 *좋은* 모습이 무엇인지 파악하고 측정합니다.

1. 지원하는 워크로드에 대해 자세히 살펴보고 KPIs(Key Performance Indicator)를 식별해 보세요. 'Golden Signals'라고도 합니다. 이는 비즈니스 및 이해관계자 요구 사항에 부합해야 합니다. Amazon CloudWatch 및 지표 수학SLIs, SLOs 및 SLAs를 계산하는 것은 서비스 신뢰성을 관리하는 데 매우 중요합니다. EKS 환경의 성능을 효과적으로 모니터링하고 유지하려면이 [가이드](https://aws-observability.github.io/observability-best-practices/guides/operational/business/key-performance-indicators/#10-understanding-kpis-golden-signals)에 설명된 모범 사례를 따르세요.

1. 그런 다음 다양한 인프라 계층을 계속 진행하여 EKS 클러스터, 노드 및 추가 인프라 지표를 워크로드 KPIs에 [연결하고 상호](https://aws-observability.github.io/observability-best-practices/signals/metrics/#correlate-with-operational-metric-data) 연관시킵니다. 비즈니스 지표와 운영 지표를 함께 상호 연관시킬 수 있는 시스템에 저장하고 두 지표 모두에 대해 관찰된 영향을 기반으로 결론을 도출합니다.

1. EKS는 컨트롤 플레인, 클러스터 kube-state-metrics를 노출합니다. 이러한 모든 지표의 관련성은 요구 사항에 따라 다르지만 여러 계층에 걸쳐 모든 단일 지표가 필요한 것은 아닙니다. 이 [EKS 필수 지표](https://aws-observability.github.io/observability-best-practices/guides/containers/oss/eks/best-practices-metrics-collection/) 가이드를 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
```

### 해당하는 경우 카디널리티 감소
<a name="_reduce_cardinality_where_applicable"></a>

카디널리티는 특정 지표 세트에 대한 차원(예: 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 analyze` 및 `mimirtool analyze 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) 따르세요.

### 지표 세분화 고려
<a name="_consider_metric_granularity"></a>

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

다음은 Opentelemetry용 AWS Distro(ADOT) EKS Addon Collector [구성](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)이면 워크로드에 필요한 것만 요청에서 트레이스를 수집하는 동시에 비용 구조를 낮출 수 있습니다.

예를 들어 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)를 사용하여 테일 샘플링 적용
<a name="_apply_tail_sampling_with_aws_distro_for_opentelemetry_adot"></a>

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 스토리지 옵션 활용
<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 - Observability: 최신 애플리케이션을 위한 모범 사례(COP344)](https://www.youtube.com/watch?v=YiegAlC_yyc) 