CloudNet@팀의 EKS 스터디 AEWS 2기에 작성된 자료를 토대로 작성합니다.
pod 로깅
pod로깅은 data plane 노드 로그와 노드에서 실행 중인 pod로그를 말합니다. pod로깅은 EKS설정을 지원하지 않습니다.
사용자가 도구를 선택해서 pod로그 수집과 저장을 해야 합니다.
본 포스팅에서는 Fluentbit또는 FlunetD를 사용하여 pod를 수집하고 cloudwatch에 전송하는 예제를 다룸
1. 로그수집은 누가?
who collects logs? Fluentd
2. 로그 전송은 누가?
who transfer logs? Fluentd
3. 로그 저장과 검색은 누가?
who stores and search logs? ElasticSearch Kibana
CW Agent & Fluent Bit
노드에 CW Agent 파드와 Fluent Bit 파드가 데몬셋으로 배치되어 Metrics 와 Logs 수집
CloudWatch Agent vs. Fluent Bit (로그 전송)
CloudWatch Agent VS Fluent Bit
사용 목적 | CloudWatch Logs 및 Metrics 전송 | Lightweight 로그 수집 및 전송 |
지원 로그 | 시스템 로그, 애플리케이션 로그, Prometheus 메트릭 | 컨테이너 로그 (stdout, stderr), 애플리케이션 로그 |
통합 대상 | CloudWatch Logs, CloudWatch Metrics, Prometheus | Elasticsearch, CloudWatch, S3, Kafka 등 |
즉, CloudWatch Agent는
- CloudWatch Logs와 CloudWatch Metrics로 로그 및 메트릭을 전송하는 역할
- Prometheus 메트릭을 수집하여 CloudWatch에서 모니터링할 수 있도록 지원
- Fluent Bit과 함께 사용하여 로그를 더 효과적으로 CloudWatch로 보낼 수도 있음
→ Fluent Bit을 사용하는 환경에서도, CloudWatch Logs로 보내려면 CloudWatch Agent를 함께 구성하는 경우가 많음!
- [수집] 플루언트비트 Fluent Bit 컨테이너를 데몬셋으로 동작시키고, 아래 3가지 종류의 로그를 CloudWatch Logs 에 전송
- /aws/containerinsights/*Cluster_Name*/application : 로그 소스(All log files in /var/log/containers), 각 컨테이너/파드 로그
- /aws/containerinsights/*Cluster_Name*/host : 로그 소스(Logs from /var/log/dmesg, /var/log/secure, and /var/log/messages), 노드(호스트) 로그
- /aws/containerinsights/*Cluster_Name*/dataplane : 로그 소스(/var/log/journal for kubelet.service, kubeproxy.service, and docker.service), 쿠버네티스 데이터플레인 로그
- [저장] : CloudWatch Logs 에 로그를 저장, 로그 그룹 별 로그 보존 기간 설정 가능
- [시각화] : CloudWatch 의 Logs Insights 를 사용하여 대상 로그를 분석하고, CloudWatch 의 대시보드로 시각화한다
Fluent Bit is a lightweight log processor and forwarder that allows you to collect data and logs from different sources, enrich them with filters and send them to multiple destinations like CloudWatch, Kinesis Data Firehose, Kinesis Data Streams and Amazon OpenSearch Service.
CloudWatch Container Insight ( CCI )는 컨테이너형 애플리케이션 및 마이크로 서비스에 대한 모니터링, 트러블 슈팅 및 알람을 위한 완전 관리형 관측 서비스입니다.
- CloudWatch 콘솔에서 자동화된 대시보드를 통해 container metrics, Prometeus metrics, application logs 및 performance log events를 탐색, 분석 및 시각화할 수 있습니다.
- CloudWatch Container Insight는 CPU, 메모리, 디스크 및 네트워크와 같은 인프라 메트릭을 자동으로 수집합니다.
- EKS 클러스터의 crashloop backoffs와 같은 진단 정보를 제공하여 문제를 격리하고 신속하게 해결할 수 있도록 지원합니다.
- 이러한 대시보드는 Amazon ECS, Amazon EKS, AWS ECS Fargate 그리고 EC2 위에 구동되는 k8s 클러스터에서 사용 가능합니다.
1. 로그 종류 확인
/var/log/pods/
- 어플리케이션 로그
- 로그 소스(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
for node in $N1 $N2 $N3; do echo ">>>>> $node <<<<<"; ssh ec2-user@$node sudo ls -al /var/log/containers; echo; done
# 개별 파드 로그 확인 : 아래 각자 디렉터리 경로는 다름
ssh ec2-user@$N1 sudo tail -f /var/log/pods/default_nginx-685c67bc9-pkvzd_69b28caf-7fe2-422b-aad8-f1f70a206d9e/nginx/0.log
/var/log/dmesg
/var/log/secure
/var/log/mesages
- 호스트 로그
- 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
for node in $N1 $N2 $N3; do echo ">>>>> $node <<<<<"; ssh ec2-user@$node sudo ls -la /var/log/; echo; done
# 호스트 로그 확인
#ssh ec2-user@$N1 sudo tail /var/log/dmesg
#ssh ec2-user@$N1 sudo tail /var/log/secure
#ssh ec2-user@$N1 sudo tail /var/log/messages
for log in dmesg secure messages; do echo ">>>>> Node1: /var/log/$log <<<<<"; ssh ec2-user@$N1 sudo tail /var/log/$log; echo; done
for log in dmesg secure messages; do echo ">>>>> Node2: /var/log/$log <<<<<"; ssh ec2-user@$N2 sudo tail /var/log/$log; echo; done
for log in dmesg secure messages; do echo ">>>>> Node3: /var/log/$log <<<<<"; ssh ec2-user@$N3 sudo tail /var/log/$log; echo; done
/var/log/journal
- 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
# 저널 로그 확인 - 링크
ssh ec2-user@$N3 sudo journalctl -x -n 200
ssh ec2-user@$N3 sudo journalctl -f
2. CloudWatch Container observability 설치
- Fluentbit 설정 시 호스트 패스 공유를 하는데 보안상 안전한가?
# 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
# addon 배포
aws eks create-addon --addon-name amazon-cloudwatch-observability --cluster-name $CLUSTER_NAME --service-account-role-arn arn:aws:iam::015609516422:role/$CLUSTER_NAME-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
{
"agent": {
"region": "ap-northeast-2"
},
"logs": {
"metrics_collected": {
"application_signals": {
"hosted_in": "myeks"
},
"kubernetes": {
"cluster_name": "myeks",
"enhanced_container_insights": true
}
}
},
"traces": {
"traces_collected": {
"application_signals": {}
}
}
}
#Fluent bit 파드 수집하는 방법 : Volumes에 HostPath를 살펴보자! >> / 호스트 패스 공유??? 보안상 안전한가? 좀 더 범위를 좁힐수는 없을까요?
kubectl describe -n amazon-cloudwatch ds cloudwatch-agent
...
Volumes:
...
rootfs:
Type: HostPath (bare host directory volume)
Path: /
HostPathType:
# Fluent Bit 로그 INPUT/FILTER/OUTPUT 설정 확인 - 링크
## 설정 부분 구성 : application-log.conf , dataplane-log.conf , fluent-bit.conf , host-log.conf , parsers.conf
kubectl describe cm fluent-bit-config -n amazon-cloudwatch
...
application-log.conf:
----
[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
multiline.parser docker, cri
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}
...
[FILTER]
Name kubernetes
Match application.*
Kube_URL https://kubernetes.default.svc:443
Kube_Tag_Prefix application.var.log.containers.
Merge_Log On
Merge_Log_Key log_processed
K8S-Logging.Parser On
K8S-Logging.Exclude Off
Labels Off
Annotations Off
Use_Kubelet On
Kubelet_Port 10250
Buffer_Size 0
[OUTPUT]
Name cloudwatch_logs
Match application.*
region ${AWS_REGION}
log_group_name /aws/containerinsights/${CLUSTER_NAME}/application
log_stream_prefix ${HOST_NAME}-
auto_create_group true
extra_user_agent container-insights
...
# Fluent Bit 파드가 수집하는 방법 : Volumes에 HostPath를 살펴보자!
kubectl describe -n amazon-cloudwatch ds fluent-bit
...
ssh ec2-user@$N1 sudo tree /var/log
ssh ec2-user@$N2 sudo tree /var/log
ssh ec2-user@$N3 sudo tree /var/log
- 사전확인 한대로 로그 그룹에는 application, dataplane, host의 로그등을 Cloudwatch로 전송하고 있음을 알수 있습니다.
- 메트릭 확인은 Container insight에서 확인할수 있습니다.

- nginx pod 헬름 설치
# NGINX 웹서버 배포
helm repo add bitnami https://charts.bitnami.com/bitnami
# 사용 리전의 인증서 ARN 확인
CERT_ARN=$(aws acm list-certificates --query 'CertificateSummaryList[].CertificateArn[]' --output text)
echo $CERT_ARN
# 도메인 확인
echo $MyDomain
# 파라미터 파일 생성 : 인증서 ARN 지정하지 않아도 가능! 혹시 https 리스너 설정 안 될 경우 인증서 설정 추가(주석 제거)해서 배포 할 것
cat <<EOT > nginx-values.yaml
service:
type: NodePort
networkPolicy:
enabled: false
ingress:
enabled: true
ingressClassName: alb
hostname: nginx.$MyDomain
pathType: Prefix
path: /
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
#alb.ingress.kubernetes.io/certificate-arn: $CERT_ARN
alb.ingress.kubernetes.io/success-codes: 200-399
alb.ingress.kubernetes.io/load-balancer-name: $CLUSTER_NAME-ingress-alb
alb.ingress.kubernetes.io/group.name: study
alb.ingress.kubernetes.io/ssl-redirect: '443'
EOT
cat nginx-values.yaml | yh
# 배포
helm install nginx bitnami/nginx --version 15.14.0 -f nginx-values.yaml
# 확인
kubectl get ingress,deploy,svc,ep nginx
kubectl get targetgroupbindings # ALB TG 확인
# 접속 주소 확인 및 접속
echo -e "Nginx WebServer URL = https://nginx.$MyDomain"
curl -s https://nginx.$MyDomain
kubectl logs deploy/nginx -f
## 외부에서는 접속이 잘되나, myeks EC2에서 url 접속이 잘 되지 않을 경우 : 이전 aws DNS cache 영향(추정)
dig +short nginx.$MyDomain
dig +short nginx.$MyDomain @192.168.0.2
dig +short nginx.$MyDomain @1.1.1.1
dig +short nginx.$MyDomain @8.8.8.8
cat /etc/resolv.conf
sed -i "s/^nameserver 192.168.0.2/nameserver 1.1.1.1/g" /etc/resolv.conf
cat /etc/resolv.conf
dig +short nginx.$MyDomain
dig +short nginx.$MyDomain @8.8.8.8
dig +short nginx.$MyDomain @192.168.0.2
curl -s https://nginx.$MyDomain
----
# 반복 접속
while true; do curl -s https://nginx.$MyDomain -I | head -n 1; date; sleep 1; done
# (참고) 삭제 시
helm uninstall nginx
- 컨테이너 로그 환경의 로그는 표준 출력 stdout과 표준 에러 stderr로 보내는 것을 권고
- 왜 ? 컨테이너 환경에서 로그를 표준 출력(stdout)과 표준 에러(stderr)로 보내는 것이 권장되는 이유는 다음과 같습니다.
1. 로깅 드라이버와의 통합이 용이
- Docker 및 Kubernetes와 같은 컨테이너 오케스트레이션 시스템에서는 기본적으로 표준 출력(stdout)과 표준 에러(stderr)를 통해 로그를 수집합니다.
- Docker의 docker logs 또는 Kubernetes의 kubectl logs 명령어를 사용하면 별도의 설정 없이 로그를 쉽게 확인할 수 있습니다.
- 다양한 로깅 드라이버(GCP Stackdriver, AWS CloudWatch, Elasticsearch 등)와 연계하여 중앙 집중식 로그 관리가 가능해집니다.
2. 로그 수집 및 관리의 일관성 유지
- 컨테이너 내부에서 직접 파일로 로그를 남길 경우, 컨테이너가 재시작되면 로그가 손실될 수 있습니다.
- 반면, stdout과 stderr로 로그를 출력하면, 컨테이너의 수명과 관계없이 로그 수집기가 이를 처리할 수 있어 데이터 보존이 용이합니다.
- Kubernetes에서는 fluentd, logstash와 같은 로그 수집 에이전트가 표준 출력 기반으로 동작하며, 이를 통해 클러스터 전반의 로그를 중앙화할 수 있습니다.
3. 컨테이너 불변성(Immutable Infrastructure) 유지
- 컨테이너 환경에서는 컨테이너 이미지를 변경하지 않고 배포 및 롤백하는 것이 일반적입니다.
- 로그를 파일로 저장하면 컨테이너 내부에서 상태를 유지하게 되어 불변성이 깨질 수 있습니다.
- 표준 출력으로 로그를 보내면 애플리케이션의 로그 관리 방식이 컨테이너의 수명과 무관하게 유지될 수 있습니다.
4. 리소스 효율성과 스토리지 관리
- 컨테이너 내부에 로그 파일을 저장하면 디스크 공간을 차지하며, 장기 실행되는 컨테이너의 경우 디스크가 가득 차는 문제가 발생할 수 있습니다.
- 로그를 stdout/stderr로 출력하면 로그 수집 시스템이 이를 자동으로 외부 저장소로 보내므로 컨테이너 내부의 디스크 공간이 불필요하게 사용되지 않습니다.
5. Kubernetes와의 최적화된 연동
- Kubernetes의 로그 수집 방식은 kubectl logs 명령어를 통해 stdout/stderr를 기반으로 작동합니다.
- sidecar 패턴을 사용하여 추가적인 로그 수집기를 배포할 수도 있으며, fluentd, logstash 등과의 연계를 통해 로그를 중앙화하고 분석할 수 있습니다.
- Kubernetes에서는 컨테이너가 재시작되더라도 로그를 보존하기 위해 log rotation 및 persistent storage를 활용하는 것이 일반적입니다.
6. 다양한 로깅 백엔드와의 손쉬운 연계
- stdout과 stderr를 활용하면 Docker logging driver, ELK stack (Elasticsearch, Logstash, Kibana), Promtail + Loki, AWS CloudWatch, Google Stackdriver 등 다양한 로그 관리 솔루션과 쉽게 연계할 수 있습니다.
- 만약 로그를 파일로 저장하는 경우, 추가적인 에이전트가 필요하며 설정이 복잡해질 수 있습니다.
7. 가독성과 디버깅의 편리함
- docker logs <container_id> 또는 kubectl logs <pod_name> 명령어만으로 컨테이너의 실시간 로그를 확인할 수 있어 디버깅이 편리합니다.
- 로그 파일을 따로 찾아보지 않아도 되므로 운영 및 트러블슈팅 과정에서 시간을 절약할 수 있습니다.
결론
컨테이너 환경에서는 로그를 표준 출력(stdout)과 표준 에러(stderr)로 출력하는 것이 가장 효율적인 방식입니다. 이를 통해 로깅 시스템과 쉽게 연계할 수 있으며, 컨테이너의 불변성을 유지하고, 디스크 공간을 절약하며, 디버깅을 용이하게 할 수 있습니다.
실제 운영 환경에서는 이러한 원칙을 기반으로 로깅 드라이버를 설정하고, 중앙 집중식 로그 수집 시스템과 연계하여 로그를 효과적으로 관리하는 것이 중요합니다.
# 로그 모니터링
kubectl logs deploy/nginx -f
# nginx 웹 접속 시도
# 컨테이너 로그 파일 위치 확인
kubectl exec -it deploy/nginx -- ls -l /opt/bitnami/nginx/logs/
total 0
lrwxrwxrwx 1 root root 11 Feb 18 13:35 access.log -> /dev/stdout
lrwxrwxrwx 1 root root 11 Feb 18 13:35 error.log -> /dev/stderr

'DevOps' 카테고리의 다른 글
[AWS EKS] (12) EKS 스터디 4주차 ( 프로메테우스 스택 ) (0) | 2025.02.28 |
---|---|
[AWS EKS] (10) EKS 스터디 4주차 ( Control-plane ) (0) | 2025.02.26 |
[AWS EKS] (9) EKS 스터디 3주차 ( EFS Controller/ S3 CSI driver ) (0) | 2025.02.22 |
[AWS EKS] (8) EKS 스터디 3주차 ( Storage 성능 지표 및 벤치마크 ) (0) | 2025.02.20 |
[AWS EKS] (7) EKS 스터디 3주차 ( Storage - provsioner와 CSI driver 차이점 ) (0) | 2025.02.19 |