EKS 스터디 4주차 입니다. 해당 주차에는 개인 도메인 및 ACM 인증서가 필요한 점 참고하시기 바랍니다.
Cloudwatch logs를 통한 로깅부터, 프로메테우스, 그라파나, OpenTelemetry까지 알아보도록 하겠습니다.
AWS Youtube - OpenTelemetry를 활용한 Amazon EKS Observability 구성하기
위 유튜브에서는 Observability란 무엇인가에 대해서 설명하며, AWS Distro for OpenTelemetry(ADOT) 서비스를 통해 EKS 서비스를 관측 하는 방법에 대해서 설명하고 있어 좋은 인사이트를 얻을 수 있었습니다.
Monitoring과 Observability(관측 가능성)은 어떤 부분에서 차이점이 있을까요?
각각 정의를 알아보도록 하겠습니다.
모니터링은 시스템의 상태를 확인하고, 문제가 발생하는지를 감지하는 것에 중점이 있습니다.
관측 가능성은 문제의 원인을 진단하고, 시스템 동작을 이해하는 것에 중점이 있습니다.
Observability 작금의 트렌드인 분산 아키텍처(MSA)에 필수적으로 필요한 요소입니다.
Why? 분산 시스템은 수 많은 API, 컴포넌트 등등이 유기적으로 연결되어 있는 구조로, 애플리케이션, 서버(시스템), 데이터베이스 등까지 많은 서비스들 통신, 데이터 흐름 등의 상태를 진단하고, 판단할 수 있어야 합니다.
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 웹 서버를 배포합니다.
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를 통해 내보내는 것을 권장합니다.
kubectl logs 명령을 통해 조회가 가능합니다.# 로그 모니터링
kubectl stern deploy/nginx
혹은
kubectl logs deploy/nginx -f
컨테이너의 로그 파일 위치를 확인해보니 access log는 stdout으로, error log는 stderr로 보내지고 있는 것을 확인 가능합니다.

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

#로그 위치 확인
#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 내의 로그 확인이 가능합니다.

# 로그 위치 확인
#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 명령어 등으로 확인이 가능합니다.

# 로그 위치 확인
#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가 기본적으로 모두 활성화됩니다. 두 기능 모두 클러스터에서 인프라, 메트릭, 애플리케이션 성능 원격 측정 및 컨테이너 로그를 수집하는 데 도움이 됩니다.
그 중, 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초의 간격을 통해 메트릭을 수집하게 됩니다.
