[EKS] AWS EKS 로깅 직접 확인 (Control Plane, Application)

vinca·2024년 2월 19일
0

🦓 EKS

목록 보기
19/23
post-thumbnail
post-custom-banner

Control Plane 로깅

AWS EKS 환경의 Control Plane의 로깅을 활성화 해보자.

Control Plane의 로깅 기능을 활성화✅ 하면 자동으로 CloudWatch가 생성된다고 이전 글에서 설명한 바가 있다.

Control Plane의 로깅 대상은 API서버, Authenticator, 스케쥴러, 감사, 컨트롤러 관리가 있다.

Control Plane 로깅 구성

이제 본격적으로 Control Plane 로깅을 구성(활성화)해 보자.

Amazon EKS Control Plane 로깅 활성화

// Amazon EKS Control Plane 로깅 활성화 설정
aws eks update-cluster-config --region $AWS_DEFAULT_REGION --name $CLUSTER_NAME \
  --logging '{"clusterLogging":[{"types":["api","audit","authenticator","controllerManager","scheduler"],"enabled":true}]}'

물론 이렇게 aws 명령어를 사용하지 않고, aws 콘솔 화면에서 조작하는 것도 가능하다.

로그 그룹 및 로그 스트림 확인

// CloudWatch의 로그 그룹 생성 확인
aws logs describe-log-groups | jq

// 로그 그룹에 구성된 로그 스트림 확인
aws logs describe-log-streams \
  --log-group-name /aws/eks/${CLUSTER_NAME}/cluster | grep logStreamName

CloudWatch에 로그그룹 및 로그스트림이 생성된 것을 확인할 수 있다.

awscli로 Control Plane 로그 확인

// 10분 동안 Control Plane 로그 확인(more 옵션)
aws logs tail /aws/eks/$CLUSTER_NAME/cluster | more
// 신규 로그 바로 출력
aws logs tail /aws/eks/$CLUSTER_NAME/cluster --follow

//로그 스트림 대상 지정 (kube-controller-mananger)
aws logs tail /aws/eks/$CLUSTER_NAME/cluster --log-stream-name-prefix kube-controller-manager --follow

// 신규 터미널 생성 후 coreDNS 수량 조정
kubectl scale deployment -n kube-system coredns --replicas=1
kubectl scale deployment -n kube-system coredns --replicas=2

kube-controller-mananger의 로그를 확인해보자. controller-manager는 replicaset controller를 관리하므로 파드 수량을 변경시키면 수량 변경에 대한 로그가 찍힐 것이다.

다음과 같이 2 ➡️ 1로 CoreDNS 파드 수량이 감소함에 있어, kube-controller-mananger의 로그가 출력되는 것을 확인할 수 있다.

CloudWatch 로그 인사이트에서 쿼리하기

관리 콘솔에서 CloudWatch 서비스에 로그 영역에서 Logs Insights📊 메뉴로 진입 후, 생성한 로그 그룹을 선택 후 다음 작업을 수행한다.

쿼리문을 살펴볼 것은 아니므로 참고만 하면 된다.

// kube-apiserver-audit 로그에서 UserAgent 정렬 후 카운트 값
fields userAgent, requestURI, @timestamp, @message
| filter @logStream ~= "kube-apiserver-audit"
| stats count(userAgent) as count by userAgent
| sort count desc

// kube-apiserver 로그에서 timestamp로 정렬
fields @timestamp, @message
| filter @logStream ~= "kube-apiserver"
| sort @timestamp desc

// authenticator 로그에서 timestamp로 정렬
fields @timestamp, @message
| filter @logStream ~= "authenticator"
| sort @timestamp desc

다음과 같이 로그를 Logs Insights📊를 통해서 원하는 로그만을 검색하고, 지표화하여 확인할 수 있다.

Control Plane 로깅 비활성화

실습이 끝났다면 로깅을 비활성화하고, CloudWatch에서 로그 그룹을 삭제하자.

// EKS Control Plane 로깅 비활성화
eksctl utils update-cluster-logging \
  --cluster $CLUSTER_NAME \
  --region $AWS_DEFAULT_REGION \
  --disable-types all \
  --approve

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

Application 로깅

Apllication 로깅이란 EKS에서 파드에서 동작하는 실제 컨테이너(애플리케이션)📦을 로깅하는 것을 의미한다.

테스트를 위해 NGINX 웹 서버를 배포하고, 실제 접근할 수 있도록 NodePortIngress 형식으로 외부로 노출한다.

Application 로깅 직접 확인

Helm으로 bitnami nginx 설치

// helm repository 추가
helm repo add bitnami https://charts.bitnami.com/bitnami

// 도메인 변수 선언
MyDomain=<자신의 도메인>
// ARN 변수 선언
CERT_ARN=`aws acm list-certificates --query 'CertificateSummaryList[].CertificateArn[]' --output text`; echo $CERT_ARN

// nginx 파라미터 파일 생성
cat <<EOT > nginx-values.yaml
service:
    type: NodePort

ingress:
  enabled: true
  ingressClassName: alb
  hostname: nginx.$MyDomain
  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

// nginx 배포
helm install nginx bitnami/nginx --version 14.1.0 -f nginx-values.yaml

다음과 같이 Helm 차트를 작성하고 배포해 주도록 하자.

hostname을 보면 Route53 ➡️ ALB로의 A 레코드 또한 생성해서 Route53의 주소로 접속할 수 있도록 했다.

이렇게 노출된 Ingress(ALB) LoadBalancer에는 Route53에서 발급받은 ACM 인증서를 부착하여 HTTPS로의 접근이 가능하도록 구성했다.

또한 SSL-Redirectio : 443 구성을 통해서 HTTP로 접속 시, 자동으로 HTTPS로 리다이렉션하도록 설정하였다.

TroubleShoothing🔫

  • HTTPS이나 인증서가 붙지 않는 문제가 발생 -> 인증서가 2개 발급되어 있어서 2개의 값이 변수로 한번에 들어감 하나만을 명시적으로 써서 해결
  • route53 경로가 한번 설치 시, ALB를 날려도 같이 삭제되지 않음. 따라서 기존(없는 인그레스 ALB)에 라우팅 대상이 물려있는 경우 트래픽을 전송할 수 없음 -> route53에 생성된 레코드를 명시적으로 삭제 후 다시 helm install 수행
  • 리스너 규칙이 없는 오류(트래픽이 나갈 대상 그룹이 없는 상황 발생) -> helm으로 Ingress를 배포했으나 helm uninstall nginx 명령어 대해서 ingress는 삭제되지 않아 명시적으로 지워줘야 했음.

생성 정보 확인

// ingress, deployment, service, endpoint nginx 확인
kubectl get ingress,deploy,svc,ep nginx

// alb targetgroupbinding 확인
kubectl get targetgroupbindings

  • HTTP:80 리스너
    HTTPS(443 포트)로 리다이렉션을 수행하도록 설정됨

  • HTTPS:443 리스너
    HTTPS의 접속 허용 (ACM 부착하여 리스너 규칙 생성)

HTTP, HTTPS 접속 확인

// HTTPS로 접속 (정상 출력)
curl -s https://nginx.$MyDomain

// HTTP로 접속할 때 상세 로그 설정 (리다이렉션 되었습니다 출력)
curl -vs http://nginx.$MyDomain

// HTTP로 접속할 때 리다이렉션해서 출력 (정상 출력)
curl -L http://nginx.$MyDomain

// 신규 터미널 모니터링 - 반복 접속
MyDomain = <자신의 도메인>

while true; do curl -s https://nginx.$MyDomain -I | head -n 1; date; sleep 1; done

HTTP로 접속하는 경우 301응답으로 https로 리다이렉션 되는 것을 확인할 수 있다. (301은 리다이렉션을 의미)

컨테이너 로그 확인

// 컨테이너 로그 확인
kubectl logs deploy/nginx -c nginx -f

다음과 같이 내 컴퓨터에서 접속한 뒤 로그를 확인해보자.

🗯️ Response 200 / 304

처음에는 200 응답이 되었다가 이후부터는 304로 응답되는 것을 확인할 수있다. 이는 Not Modified로 클라이언트가 조건부 GET 요청을 했을 때, 클라이언트가 마지막으로 받은 이후로 리소스에 변경사항이 없으면 서버가 리소스의 본문을 다시 보내지 않는 것이다.
🍪 이는 crtl-shift+R로 쿠키를 지우고 다시 요청보내면 마지막으로 받은 리소스가 지워지므로 200 응답이 들어온다.

컨테이너 내에 로그가 저장되는 형태

컨테이너에 들어가 로그가 어떻게 저장되는지 확인해보자.

kubectl exec -it deploy/nginx -c nginx -- ls -l /opt/bitnami/nginx/logs/

bitnami nginx의 경우에는 로그정보를 다음과 같이 심볼릭 링크⤴️표준 스트림으로 지정해서 로그를 노드에서 볼 수 있도록 저장하고 있다.

이처럼 컨테이너 내부에서 로그를 확인하는 것 보다, 컨테이너 외부의 노드의 /var/log/* 경로에 심볼릭 링크로 저장한다면 kubectl logs 명령어로 노드에서 명령어를 일괄적으로 뽑아오는 게 가능하다.

⚠️하지만! 결국 심볼릭 링크⤴️를 통해서 포인터 형식으로 참조하고 있는 것이므로 파드가 종료되면 해당 로그는 사라진다.

노드에서 컨테이너 로그 확인

// /var/log/containers tree 확인 (nginx 파드가 생성된 노드 지정)
ssh ec2-user@$N1 sudo tree -C /var/log/containers

// /var/log/pods tree 확인 (nginx 파드가 생성된 노드 지정)
ssh ec2-user@$N1 sudo tree -C /var/log/pods

// /var/log/pods에서 로그 직접 확인 (nginx 로그 뒤에 삽입)
ssh ec2-user@$N1 sudo tail -f <XXXXXXXXX>

ssh ec2-user@$N1 sudo head <XXXXXXXXX>

노드에 존재하는 모든 컨테이너의 로그를 수집해서 /var/log/containers에 저장하고, 이후 심볼릭 링크➡️를 통해서 /var/log/pods 경로에 해당 로그들을 파드/컨테이너의 디렉토리 형식으로 저장된다.

결론

이렇게 Application의 로깅을 직접 확인하는 것은 컨테이너 개별적인 로그 확인의 불편함컨테이너 용량의 한계, 파드가 죽으면 로그가 사라지는 위험성이 있다.

🌟따라서, fluentbit🐦와 같은 중앙집중형 로깅 방식이 나오게 되었다.

다음글 : fluentbit🐦이란?

profile
붉은 배 오색 딱다구리 개발자 🦃Cloud & DevOps
post-custom-banner

0개의 댓글