AWES 4주차 - EKS Observability - amazon-cloudwatch-observability Add-On (1)

박민준·2025년 2월 28일

EKS 스터디 4주차 입니다. 해당 주차에는 개인 도메인 및 ACM 인증서가 필요한 점 참고하시기 바랍니다.
Cloudwatch logs를 통한 로깅부터, 프로메테우스, 그라파나, OpenTelemetry까지 알아보도록 하겠습니다.

시작하기 앞서...

AWS Youtube - OpenTelemetry를 활용한 Amazon EKS Observability 구성하기
위 유튜브에서는 Observability란 무엇인가에 대해서 설명하며, AWS Distro for OpenTelemetry(ADOT) 서비스를 통해 EKS 서비스를 관측 하는 방법에 대해서 설명하고 있어 좋은 인사이트를 얻을 수 있었습니다.


Monitoring vs Observability

Monitoring과 Observability(관측 가능성)은 어떤 부분에서 차이점이 있을까요?
각각 정의를 알아보도록 하겠습니다.

Monitoring

  • Google의 SRE 책(What’s IT Monitoring? IT Systems Monitoring Explained | Splunk)에서는 모니터링을 "시스템에 대한 실시간 정량 데이터 수집, 처리, 집계, 표시"로 정의하며, 쿼리 수, 오류 수, 처리 시간 등을 포함한다고 설명합니다.

Observability

  • Observability (software) - Wikipedia에 따르면, 관측 가능성은 소프트웨어 엔지니어링에서 프로그램 실행, 모듈 내부 상태, 컴포넌트 간 통신 데이터를 수집하고 분석하는 능력을 말합니다.

모니터링은 시스템의 상태를 확인하고, 문제가 발생하는지를 감지하는 것에 중점이 있습니다.
관측 가능성은 문제의 원인을 진단하고, 시스템 동작을 이해하는 것에 중점이 있습니다.

Observability 작금의 트렌드인 분산 아키텍처(MSA)에 필수적으로 필요한 요소입니다.

Why? 분산 시스템은 수 많은 API, 컴포넌트 등등이 유기적으로 연결되어 있는 구조로, 애플리케이션, 서버(시스템), 데이터베이스 등까지 많은 서비스들 통신, 데이터 흐름 등의 상태를 진단하고, 판단할 수 있어야 합니다.

Logging in EKS

EKS에서 활성화 할 수 있는 모든 로그를 Cloudwatchs에서 볼 수 있도록 로깅 활성화를 합니다.

aws eks update-cluster-config --region ap-northeast-2 --name $CLUSTER_NAME \
    --logging '{"clusterLogging":[{"types":["api","audit","authenticator","controllerManager","scheduler"],"enabled":true}]}'

Log Group을 확인 시, /aws/eks/<cluster-name>/cluster Path로 생성이 되었습니다.

minjun@PMJ-corp:~/awes$ aws logs describe-log-groups | jq
{
  "logGroups": [
    {
      "logGroupName": "/aws/eks/myeks/cluster",
      "creationTime": 1740635862370,
      "metricFilterCount": 0,
      "arn": "arn:aws:logs:ap-northeast-2:253490769853:log-group:/aws/eks/myeks/cluster:*",
      "storedBytes": 0,
      "logGroupClass": "STANDARD"
    }
  ]
}

AWS Console 확인 시에도, 생성된 Log Group으로 활성화한 로그들이 로깅되고 있습니다.

로깅 비활성화 및 Log Group 삭제

# EKS Control Plane 로깅(CloudWatch Logs) 비활성화
eksctl utils update-cluster-logging --cluster $CLUSTER_NAME --region ap-northeast-2 --disable-types all --approve

# 로그 그룹 삭제
aws logs delete-log-group --log-group-name /aws/eks/$CLUSTER_NAME/cluster

Nginx Container Logging with Ingress(ALB)

Nginx 웹 서버를 배포합니다.

helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update


cat <<EOT > nginx-values.yaml
service:
  type: NodePort
  
networkPolicy:
  enabled: false
  
resourcesPreset: "nano"

ingress:
  enabled: true
  ingressClassName: alb
  hostname: nginx.$MyDomain
  pathType: Prefix
  path: /
  annotations: 
    alb.ingress.kubernetes.io/certificate-arn: $CERT_ARN
    alb.ingress.kubernetes.io/group.name: study
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
    alb.ingress.kubernetes.io/load-balancer-name: $CLUSTER_NAME-ingress-alb
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/ssl-redirect: "443"
    alb.ingress.kubernetes.io/success-codes: 200-399
    alb.ingress.kubernetes.io/target-type: ip
EOT

helm install nginx bitnami/nginx --version 19.0.0 -f nginx-values.yaml

배포 이후 ingress, service 등을 확인합니다.

kubectl get ingress,deploy,svc,ep nginx

nginx 웹사이트로 접속이 되는지도 확인합니다.

echo -e "Nginx WebServer URL = https://nginx.$MyDomain"

컨테이너 로그 환경의 로그는 stdout / stderr를 통해 내보내는 것을 권장합니다.

  • stdout, stderr를 통한 로그는 직접 파드 내부로 접속하지 않고도 kubectl logs 명령을 통해 조회가 가능합니다.
# 로그 모니터링
kubectl stern deploy/nginx
혹은
kubectl logs deploy/nginx -f

컨테이너의 로그 파일 위치를 확인해보니 access log는 stdout으로, error log는 stderr로 보내지고 있는 것을 확인 가능합니다.

Container Insights metrics in Amazon CloudWatch & Fluent Bit (Logs) - Link

해당 목차에서 진행될 내용의 아키텍처는 다음과 같습니다.
fluent bit를 daemonset으로 동작시켜 Cloudwatchs Log로 수집하는 방식입니다.

사전 확인

  • 노드의 로그 확인
  1. application 로그 소스(All log files in /var/log/containers → 심볼릭 링크 /var/log/pods/<컨테이너>, 각 컨테이너/파드 로그
#로그 위치 확인

#ssh ec2-user@$N1 sudo tree /var/log/containers
#ssh ec2-user@$N1 sudo ls -al /var/log/containers
for node in $N1 $N2 $N3; do echo ">>>>> $node <<<<<"; ssh ec2-user@$node sudo tree /var/log/containers; echo; done

아래와 같이 /var/log/containers 내의 로그 확인이 가능합니다.

  1. host 로그 소스(Logs from /var/log/dmesg, /var/log/secure, and /var/log/messages), 노드(호스트) 로그
# 로그 위치 확인
#ssh ec2-user@$N1 sudo tree /var/log/ -L 1
#ssh ec2-user@$N1 sudo ls -la /var/log/
for node in $N1 $N2 $N3; do echo ">>>>> $node <<<<<"; ssh ec2-user@$node sudo tree /var/log/ -L 1; echo; done

host 로그를 tree 명령어 등으로 확인이 가능합니다.

  1. dataplane 로그 소스(/var/log/journal for kubelet.service, kubeproxy.service, and docker.service), 쿠버네티스 데이터플레인 로그
# 로그 위치 확인
#ssh ec2-user@$N1 sudo tree /var/log/journal -L 1
#ssh ec2-user@$N1 sudo ls -la /var/log/journal
for node in $N1 $N2 $N3; do echo ">>>>> $node <<<<<"; ssh ec2-user@$node sudo tree /var/log/journal -L 1; echo; done

dataplane 로그도 마찬가지로, tree 명령어 등으로 확인이 가능합니다.

Amazon CloudWatch Observability EKS Add-On 또는 Amazon CloudWatch Observability Helm Chart를 사용하여 Amazon EKS 클러스터에 CloudWatch Agent와 Fluent-bit Agent를 설치할 수 있습니다.

Amazon EKS 클러스터에서 두 가지 방법을 사용하면 Container Insights와 CloudWatch Application Signals가 기본적으로 모두 활성화됩니다. 두 기능 모두 클러스터에서 인프라, 메트릭, 애플리케이션 성능 원격 측정 및 컨테이너 로그를 수집하는 데 도움이 됩니다.

AWS EKS에서는 리소스에 접근할 수 있는 여러 방식을 제공합니다.

  • EKS Pod Identity
  • IAM 권한
  • IAM Service Account role(IRSA)

그 중, IRSA 방식으로 구성을 진행하겠습니다.

# IRSA 설정
eksctl create iamserviceaccount \
  --name cloudwatch-agent \
  --namespace amazon-cloudwatch --cluster $CLUSTER_NAME \
  --role-name $CLUSTER_NAME-cloudwatch-agent-role \
  --attach-policy-arn arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy \
  --role-only \
  --approve

IRSA가 정상적으로 생성되었는지 아래와 CLI/콘솔 모두에서 확인이 가능합니다.

aws iam get-role --role-name $CLUSTER_NAME-cloudwatch-agent-role

amazon-cloudwatch-observability Add-On을 배포합니다.

aws eks create-addon --addon-name amazon-cloudwatch-observability --cluster-name myeks --service-account-role-arn arn:aws:iam::<IAM User Account ID직접 입력>:role/myeks-cloudwatch-agent-role
# addon 확인
aws eks list-addons --cluster-name myeks --output table

# 설치 확인
kubectl get crd | grep -i cloudwatch
kubectl get-all -n amazon-cloudwatch
kubectl get ds,pod,cm,sa,amazoncloudwatchagent -n amazon-cloudwatch
kubectl describe clusterrole cloudwatch-agent-role amazon-cloudwatch-observability-manager-role    # 클러스터롤 확인
kubectl describe clusterrolebindings cloudwatch-agent-role-binding amazon-cloudwatch-observability-manager-rolebinding  # 클러스터롤 바인딩 확인
kubectl -n amazon-cloudwatch logs -l app.kubernetes.io/component=amazon-cloudwatch-agent -f # 파드 로그 확인
kubectl -n amazon-cloudwatch logs -l k8s-app=fluent-bit -f    # 파드 로그 확인
# cloudwatch-agent 설정 확인
kubectl describe cm cloudwatch-agent -n amazon-cloudwatch
kubectl get cm cloudwatch-agent -n amazon-cloudwatch -o jsonpath="{.data.cwagentconfig\.json}" | jq

Fluentbit는 아래와 같이 Pod의 FileSystem(FS)에 HostPath를 통해 접근하여 Log를 수집합니다.

#Fluent bit 파드 수집하는 방법 : Volumes에 HostPath를 살펴보자!
kubectl describe -n amazon-cloudwatch ds cloudwatch-agent
...
  Volumes:
   ...
   rootfs:
    Type:          HostPath (bare host directory volume)
    Path:          /
    HostPathType:  

HostPath 공유? 보안상 안전할까요? 안전하지 않다면 좀 더 범위를 좁힐수는 없을까요?
❗위와 같은 상황에서 보안상으로 위험한 점은 / 볼륨을 공유하고 있기 때문에, 악의적 사용자가 접근하여 코드를 작동시킬 수 있습니다.

How? 아래 HostPath를 살펴보면, docker.sock 볼륨이 Mount되어 있습니다.
이런 상황에서 Pod만 설치가 가능하다면, Mount된 docker.sock을 통해서 Host에 설치된 Docker로 명령을 보낼 수 있게 됩니다.

  • Docker가 Client-server 구조이기 때문에 가능한 것!!! -> Container Escape라고도 불립니다.

로그 뿐만 아니라, 메트릭도 아래와 같이 Container Insights를 통해 확인이 가능합니다.
앞에서 언급했듯이, CloudWatch Agent를 통해 Container Insights가 기본적으로 활성화된 상태입니다.

Kubernetes Metrics Server는 클러스터의 리소스 사용 데이터 집계기이며 Amazon EKS 클러스터에 기본적으로 배포되지 않습니다.

Metric-server는 amazon-cloudwatch-observability를 통해 설치한 Cloudwatch agent와는 조금 다릅니다.

cAdvisor를 통해 수집된 메트릭은 아래와 같이 확인이 가능하며, 15초의 간격을 통해 메트릭을 수집하게 됩니다.

profile
바교망

0개의 댓글