Cloud Tech

Terraform AWS Observability Accelerator와 멀티클러스터 Observability 구성하기

Hanhorang31 2024. 3. 31. 00:35
 

Overview

EKS 멀티클러스터 옵저버빌리티 구성을 위해 AWS Observability Accelerator을 학습하고 테스트한 내용을 공유합니다.

 

AWS Observability Accelerator

AWS Observability Accelerator는 AWS 관리형 관측 가능성 서비스를 사용하여 모니터링, 로깅, 트레이싱를 손 쉽게 구성할 수 있는 모듈입니다. 모듈에서 사용하는 AWS 관리형 관측 가능성 서비스는 다음과 같습니다.

  • Amazon Managed Service for Prometheus: 프로메테우스를 AWS에서 관리형으로 제공하는 서비스입니다. 모듈에서는 metrics 수집에 사용됩니다.
  • AWS Distro for OpenTelemetry: AWS 환경에서 애플리케이션 데이터를 수집, 전송, 관리하기 위한 OpenTelemetry의 AWS 배포판입니다. 모듈에서는 메트릭 수집 및 트레이싱에 활용됩니다. 트레이싱된 데이터는 AWS X-ray에 표시됩니다.
  • Amazon CloudWatch logs : 모듈에서는 컨테이너 로깅을 위해 사용됩니다. 로깅 데이터는 fluentBits을 통해 가져오며 Cloudwatch Container log에서 확인이 가능합니다.
  • Amazon Managed Grafana: AWS에서 제공하는 Grafana 관리형 서비스로, 데이터 시각화와 대시보드 생성을 지원합니다. 위 게시되는 서비스(X-ray, Cloudwatch Container)에 대한 정보를 쿼리를 통해 그라파나로 가져와서 통합 대시보드를 제공합니다.

 

옵버저빌리티 기능 요소별 AWS 관리형서비스를 사용하여 비용이 발생합니다. 그럼에도 불구하고 필자가 본 모듈을 테스트하는 이유는 2가지인데요. 멀티 클러스터에 대한 확장성EKS addon에 대한 확장 모듈로 호환성이 높기 때문입니다.

 

  • 멀티 클러스터에 대한 확장성 지원 : 그라파나, 프로메테우스 등의 모니터링 서비스가 AWS에 의해 별도로 호스팅되어 다른 클러스터와 쉽게 통합이 가능합니다. 해당 모듈 예제에서도 동일 계정에 대한 멀티클러스터와 다중 계정에 대한 멀티클러스터 옵저버빌리티 구성 예제가 제공되는데요. 본 글의 마지막 세션에서 다루도록 하겠습니다.
  • 테라폼 EKS 호환성 제공 : 기존 생성된 EKS 클러스터에 대해 쉽게 통합하여 옵저버빌리티를 제공할 수 있도록 되어있습니다. 그리고 EKS addon를 통해 구성된 인프라에 대해서도 옵버저빌리티를 구성할 수 있습니다. 쉽게 생각하자면, 필자가 전 블로그 글에서 다룬 istio 배포 클러스터나 kafka 클러스터, gitops bridge로 배포한 모듈에 대해 간단한 변수 설정만으로 옵저버빌리티를 구성할 수 있습니다.

 

배포

모듈 호환성 확인과 옵저버빌리티 서비스 확인을 위해 EKS 클러스터를 배포하고, AWS Observability Accelerator을 배포하겠습니다.

본 모듈은 IAM SSO 활성화가 필요합니다. 루트 계정에서 SSO 활성화을 생성하여 진행해주세요.

 

EKS 배포

git clone https://github.com/aws-observability/terraform-aws-observability-accelerator.git
cd examples/eks-cluster-with-vpc
terraform init 

export TF_VAR_aws_region=ap-northeast-2
export TF_VAR_cluster_name=horang1

terraform apply

설치에 약 15분정도 소요됩니다.

 

AWS Observability Accelerator 배포

앞서 배포한 EKS 클러스터에 옵저버빌리티를 구성하겠습니다.

먼저 AWS managed grafana를 배포하겠습니다.

# Managed Grafana 
cd examples/managed-grafana-workspace 
terraform init
export TF_VAR_aws_region=ap-northeast-2
terraform apply
  • 구성 후 출력되는 그라파나 워크스페이스ID는 Observability Accelerator 배포의 변수로 사용됩니다. 꼭 메모해주세요.
  • 배포 변수로 그라파나 API 키 발급이 필요합니다. AWS SSO에서 사용자를 추가하여 그라파나에 접근한 뒤 왼쪽 admin 관리 메뉴에서 API Keys를 발급하세요

 

# Observability Accelerator 모듈 배포
cd examples/existing-cluster-with-base-and-infra
terraform init

export TF_VAR_aws_region=ap-northeast-2
export TF_VAR_eks_cluster_id=horang1 

terraform apply
# grafana workspace ID 및 API Key 입력

 

앞서 설치한 클러스터 이름만 설정하면 클러스터에 옵저버빌리티를 위한 파드가 배포되며 AWS 관리형 서비스가 설치됩니다. 모듈에 대한 테라폼 코드를 보면 다음과 같습니다.

  • eks_cluster_id 에 클러스터를 입력하면 해당 클러스터 안에 정의한 옵저버빌리티 옵션에 맞게 서비스가 배포됩니다.
  • 그라파나 API Key와 프로메테우스 워크스페이스 ID에 대한 정보 입력받아 AWS 관리형 서비스에 수집 데이터를 전달해줍니다.
 

모듈 안을 확인하면 클러스터 구성 환경에 따라 설치되는 addon이 구분되어 있습니다. 설치 addon을 요약하면 다음과 같습니다.

tree .
-------
.
├── ecs-monitoring # ECS 모니터링 설정 
├── eks-container-insight # EKS container 설정 addon
├── eks-monitoring
│   ├── add-ons
│   │   ├── adot-operator # AWS Distro for OpenTelemetry 구성  
│   │   ├── aws-for-fluentbit # 로그 수집 및 처리를 위한 Fluent Bit 구성
│   │   └── external-secrets # 클러스터 외부 비밀 정보(AWS Secret Manager) 구성 
│   ├── alerts.tf # 경보 설정 
│   ├── dashboards.tf # 대시보드 설정 
│   ├── otel-config # OpenTelemetry 설정을 포함하여 데이터 수집 및 전송을 위한 구성 
└── managed-prometheus-monitoring # managed grafana, prometheus 서비스 구성

 

서비스 확인

클러스터 배포 파드와 AWS 관리형 서비스를 확인하겠습니다.

aws eks update-kubeconfig --region ap-northeast-2 --name horang1
kubectl get pods -A 

 

 

모니터링

모니터링 요소부터 확인하겠습니다. 프로메테우스를 사용하지만, 메트릭 수집을 통해 프로메테우스까지의 전달은 AWS Distro for OpenTelemetry (ADOT) Collector 을 통해 수집됩니다. 아키텍처를 확인하면 다음과 같습니다.

중점은 프로메테우스와 ADOT과의 차이점인데요. 사용 환경, 요구 사항, 그리고 특정 클라우드 서비스와의 통합 정도에 따라 나눠질 수 있습니다.

  • 범위 및 기능: ADOT는 로깅, 메트릭, 트레이싱 데이터를 모두 지원하는 반면, 프로메테우스는 주로 메트릭스 수집 및 알람에 중점을 둡니다.
  • 통합과 최적화: ADOT는 AWS 서비스와의 통합 및 최적화에 초점을 맞추어 AWS 환경에서의 사용을 간편하게 합니다. 반면, 프로메테우스는 다양한 환경에서 범용적으로 사용될 수 있는 도구로, 특정 클라우드 제공 업체에 최적화되지 않았습니다.
  • 관리 형태: 프로메테우스는 사용자가 자체적으로 설정하고 관리해야 하는 반면, ADOT는 AWS 서비스와의 긴밀한 통합을 통해 관리의 복잡성을 줄일 수 있습니다.

 

모듈 테라폼에서도 managed AWS 서비스를 사용함에 따라 ADOT를 적용한 것으로 보이네요. 수집된 지표들은 그라파나 대시보드를 통해 확인이 가능합니다. 모듈에서 설치하는 경우 기본 대시보드가 제공됩니다. 특히 컨트롤 플레인쪽 데이터도 확인이 가능합니다.

 

로깅

로깅의 경우 각 노드 fluentbit 파드를 통해 수집되며 Cloudwatch log에 전달됩니다. 본 실습의 경우에는 managed grafana에서 데이터를 확인할 수 있습니다. Grafana 데이터소스를 Cloudwatch log로 설정하였기 때문입니다. 그라파나에서 Explore에서 Cloudwatch 그룹을 설정하고 로그 행을 실행하면 로그 값을 확인할 수 있습니다. 로깅 쿼리는 cloudwatch 로 실행해야 합니다.

fields @timestamp, log
| order @timestamp desc
| limit 100

 

트레이싱

트레이싱은 Distro를 통해 Cloudwatch X-ray로 전달됩니다. 로깅과 마찬가지로 그라파나에서도 데이터를 확인할 수 있는데요. 모듈에서 그라파나 데이터소스를 cloudwatch x-ray로 자동으로 연동해주기 때문입니다.

본 예제에서는 모듈 문서 제공하는 예제를 통해 이미지를 빌드하고 테스트하겠습니다. 주의할 점은 아래 도커 이미지 빌드시 Linux 환경에서 빌드해야 합니다. Mac에서 이미지를 빌드하는 경우 포맷이 맞지 않아 에러(exec /bin/main: exec format error ) 가 발생합니다.

git clone https://github.com/aws-observability/aws-otel-community.git
cd aws-otel-community/sample-apps/go-sample-app

# 이미지 빌드 
docker build -t go-sample-app .

# ECR 게시 
export ECR_REPOSITORY_URI=$(aws ecr create-repository --repository go-sample-app --query repository.repositoryUri --output text)
aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin $ECR_REPOSITORY_URI
docker tag go-sample-app:latest "${ECR_REPOSITORY_URI}:latest"
docker push "${ECR_REPOSITORY_URI}:latest" 

# eksctl 배포
# eks.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: go-sample-app
  namespace: default
spec:
  replicas: 2
  selector:
    matchLabels:
      app: go-sample-app
  template:
    metadata:
      labels:
        app: go-sample-app
    spec:
      containers:
        - name: go-sample-app
          image: "${ECR_REPOSITORY_URI}:latest" # 여기 변수를 위 ECR 링크로 수정해주세요.  
          imagePullPolicy: Always
          env:
          - name: OTEL_EXPORTER_OTLP_TRACES_ENDPOINT
            value: adot-collector.adot-collector-kubeprometheus.svc.cluster.local:4317
          resources:
            limits:
              cpu:  300m
              memory: 300Mi
            requests:
              cpu: 100m
              memory: 180Mi
          ports:
            - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: go-sample-app
  namespace: default
  labels:
    app: go-sample-app
spec:
  ports:
    - protocol: TCP
      port: 8080
      targetPort: 8080
  selector:
    app: go-sample-app
---
apiVersion: v1
kind: Service
metadata:
  name: go-sample-app
  namespace: default
spec:
  type: ClusterIP
  selector:
    app: go-sample-app
  ports:
    - protocol: TCP
      port: 8080
      targetPort: 8080
      
      
kubectl apply -f eks.yaml 

예제 애플리케이션을 배포하고 포트포워딩을 통해 애플리케이션에 트래픽을 보내 트레이싱을 확인하겠습니다.

# 포트포워딩 
kubectl port-forward deployment/go-sample-app 8080:8080 

# 애플리케이션 테스트
curl http://localhost:8080/
curl http://localhost:8080/outgoing-http-call
curl http://localhost:8080/aws-sdk-call
curl http://localhost:8080/outgoing-sampleapp 

트레이싱 데이터는 그라파나에서 확인이 가능합니다. 그라파나 exploer 에서 cloudwatch x-ray 그룹을 설정해주세요.

 

 

멀티클러스터 옵저버빌리티 구성 실습

옵저버빌리티 모듈 예제에서는 멀티클러스터에 대한 2가지 시나리오가 제공됩니다.

  • 단일 AWS 계정 내 멀티클러스터 옵저버빌리티 구성
  • 다중 AWS 계정간 멀티클러스터 옵저버빌리티 구성

 

구성 예제 중 단일 AWS 계정 내 멀티클러스터 옵저버빌리티에 대해 다뤄보겠습니다.

정확히는 EKS 클러스터 eks-cluster-with-vpc 을 추가 생성하고, 옵저버빌리티에 구성하여 하나의 그라파나에서 다중 클러스터를 관제할 수 있도록 구성하겠습니다.

 

클러스터 생성을 위해 클러스터 생성 폴더를 복사하고 두번째 클러스터를 생성하겠습니다.

cp -r eks-cluster-with-vpc eks-cluster-with-vpc_second
cp -r existing-cluster-with-base-and-infra existing-cluster-with-base-and-infra-second

cd eks-cluster-with-vpc eks-cluster-with-vpc_second
terraform init 

export TF_VAR_aws_region=ap-northeast-2

terraform apply

aws eks update-kubeconfig --region ap-northeast-2 --name eks-cluster-with-vpc
kubectl get pods -A 

 

 

옵저버빌리티 구성

멀티클러스터 옵저버빌리티 구성를 위해 클러스터 이름과 그라파나 API키, 워크스페이스 ID, 프로메테우스 워크스페이스 ID 입력이 필요합니다. AWS 콘솔에서 각 변수를 확인하여 클러스터 변수 파일에 정의해주세요. 그리고 앞서 배포한 단일클러스터 옵저버빌리티 모듈(existing-cluster-with-base-and-infra) 을 삭제해야 합니다.

cd example/eks-multicluster
vi variables.tf 
# 클러스터 및 grafana 변수 입력 

 

terraform apply 
  • 배포 중 external-secrets 모듈에서 에러가 발생할 수 있습니다. 클러스터 kube config를 클러스터 1번으로 맞춘다음 다시 apply 해주세요. (aws eks update-kubeconfig --region ap-northeast-2 --name eks-cluster-with-vpc )

 

옵저버빌리티 모듈이 배포되고 그라파나를 확인하면 타켓 클러스터에 새로 생성된 클러스터가 추가된 것을 확인할 수 있습니다.

 

추가 생성한 옵저버빌리티 모듈을 확인하면 다음과 같이 확인할 수 있는데요. 데이터 수집 파드만 활성화하고 AWS 관리형 서비스를 위한 연동 부분은 전부 비활성화한 것을 확인할 수 있습니다.

module "eks_cluster_2_monitoring" {
  source                 = "../../modules/eks-monitoring"
  eks_cluster_id         = var.eks_cluster_2_id
  enable_amazon_eks_adot = true
  enable_cert_manager    = true

  # Since the following were enabled in conjunction with the set up of the
  # eks_cluster_1 EKS cluster, we will skip them with the eks_cluster_2 EKS cluster
  enable_dashboards       = false
  enable_external_secrets = false 
  enable_fluxcd           = false 
  enable_alerting_rules   = false
  enable_recording_rules  = false

  # Disable additional dashboards
  enable_apiserver_monitoring  = false
  enable_adotcollector_metrics = false 

  # prevents the module to create a workspace
  enable_managed_prometheus = false 

  managed_prometheus_workspace_id       = var.managed_prometheus_workspace_id
  managed_prometheus_workspace_endpoint = data.aws_prometheus_workspace.this.prometheus_endpoint
  managed_prometheus_workspace_region   = var.eks_cluster_1_region

  prometheus_config = {
    global_scrape_interval = "60s"
    global_scrape_timeout  = "15s"
    scrape_sample_limit    = 2000
  }

  providers = {
    aws        = aws.eks_cluster_2
    kubernetes = kubernetes.eks_cluster_2
    helm       = helm.eks_cluster_2
  }
}

 

모듈 및 인프라 삭제

다뤘던 예제 모듈과 인프라를 순서대로 삭제해야 합니다.

cd example/eks-multicluster
terraform destroy -approve 

cd example/managed-grafana-workspace
terraform destroy -approve 

cd example/eks-cluster-with-vpc
terraform destroy -approve 

cd example/eks-cluster-with-vpc-secode
terraform destroy -approve