[AEKS2] 4주차 - EKS Observability (1)
기본 세팅은 마치고 Observability 관련하여 시작할 것이다.
EKS에서 로깅은 애플리케이션과 Node도 있지만 각종 컴포넌트가 있는 Control Plane 로깅도 필요하다.
이 글에서는 Control Plane 로깅, 컨테이너 로깅, Fluent Bit 구성에 대한 내용을 말할 것이다.
Control Plane 로깅
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**}]}'
이 명령어로 모든 로깅을 다 켰다. 그럼 클러스터 업데이트 중이라고 뜨고 잠시 후에 모든 로깅이 켜진다.
Cloud Watch에 들어가면 /aws/eks/myeks/cluster 라는 로그 그룹이 생성되고 아래와 같은 로그 스트림도 생성된다.
Amazon EKS 컨트롤 플레인 로깅 - Amazon EKS
각 스트림에 들어가서 error 를 필터링해서 로그를 확인할 수도 있다!
awscli로도 확인할 수 있는데 로그가 너무 길어 불편했다. grep으로 필터링하면 좀 낫긴한거 같기도 하다…
Logs Insights에서 쿼리를 실행하여 내가 원하는 값을 추출해 낼 수도 있다.
예를 들어 authenticator로 시작하는 로그스트림을 뽑아냈다.
fields @timestamp, @message
| filter @logStream ~= "authenticator"
| sort @timestamp desc
또는 error 레벨에 해당되는 로그만 뽑아내 볼 수 있다.
fields @timestamp, @message
| filter @logStream ~= "authenticator"
| filter @message like /level=error/
| sort @timestamp desc
이건 사용해 보면서 쿼리를 좀 알아야 잘 사용할 수 있을 것 같다.
마무리로 control plane 로깅은 비활성화하고 로그 그룹도 삭제한다.
eksctl utils **update-cluster-logging** --cluster $CLUSTER_NAME --region $AWS_DEFAULT_REGION **--disable-types all** --approve
aws logs **delete-log-group** --log-group-name /aws/eks/$CLUSTER_NAME/cluster
컨테이너 로깅
컨테이너를 로깅하기 위해 nginx를 설치하였다.
(지금 클러스터에 external dns랑 alb controller를 설치해 놔서 자동으로 ALB와 Route53에 생성된다.)
컨테이너 로그는 표준 출력 STDOUT과 표준 에러 STDERR로 보내는 것을 권고한다.
그래서 kubectl logs 명령어를 입력하여 표준 입력 STDIN 으로 보내면 즉각적으로 로그를 볼 수 있다.
logs 옵션에는 여러 가지가 있는데 나는 아래 세 가지가 가장 유용하다고 생각한다.
-f
는 로그를 실시간으로 볼 수 있게 해 준다. tail
은 지정한 라인 수만큼 보여주고 since
는 최근 시간을 보여 준다.
kubectl logs를 사용하면 아래와 같이 터미널에 출력된다.
직접 컨테이너에 들어 가서 확인하면 각각 STDOUT과 STDERR의 파일 위치도 확인 가능하다. 이 도커이미지는 심볼릭 링크를 걸어놨다..!
파드가 종료되고 나면 더 이상의 로그는 확인할 수 없다. 그래서 로그를 보존하기 위해 pvc를 붙여서 따로 저장해 둘 수 있다. 또는 로깅 아키텍처를 고려해야 한다.
기본적으로 컨테이너가 재시작하는 경우, kubelet은 종료된 컨테이너 하나를 로그와 함께 유지한다. 그러나 파드가 노드에서 축출되면 로그도 같이 축출된다.
사용자가 kubectl logs를 실행하면 → kubelet이 해당 요청을 받고 → 로그 파일에서 직접 읽는다 → kubelet이 로그 내용을 사용자에게 반환한다
이 때 kubelet 설정 파일에서 kubelet 파라미터인 containerLogMaxSize
와 containerLogMaxFiles
의 기본 값인 10Mi와 5개까지 반환할 수 있다. 각 노드에서 journalctl -u kubelet
로 확인 가능하다
kubelet은 항상 컨테이너 런타임으로 하여금 /var/log/pods
아래에 로그를 기록하도록 지시한다.
[ec2-user@ip-192-168-3-228 default_nginx-6c65c594db-9rp89_c57dbf7f-a360-46d8-b9d3-2b4942d561ec]$ ls
nginx preserve-logs-symlinks
ns_nginx파드_블라블라 디렉토리로 들어가면 nginx와 preserve-logs-symlinks 디렉토리가 있다. preserve-logs-symlinks는 kubectl logs -p
했을 때 보여지는 로그 파일이다. (이전 인스턴스에 대한 로그를 검색할 수 있어서 트러블슈팅에 유용하다)
nginx 디렉토리로 들어가면 현재 찍히는 로그 파일을 확인할 수 있다.
Fluent Bit 데몬셋 구성
또는 로그 에이전트를 데몬셋 형식 또는 애플리케이션의 사이드카 형식으로 구현해서 로그를 수집할 수 있다
여기서는 fluent bit을 데몬셋으로 구성하여 각 애플리케이션에 대한 logging을 수집하고 cloudwatch에 전달할 것이다.
우선 네임스페이스 먼저 생성한다
kubectl apply -f https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/daemonset/container-insights-monitoring/cloudwatch-namespace.yaml
그 다음은 cm을 생성할 건데 ClusterName과 RegionName은 각 사용자에 맞게 정의한다.
ClusterName=myeks
RegionName=ap-northeast-2
FluentBitHttpPort='2020'
FluentBitReadFromHead='Off'
[[ ${FluentBitReadFromHead} = 'On' ]] && FluentBitReadFromTail='Off'|| FluentBitReadFromTail='On'
[[ -z ${FluentBitHttpPort} ]] && FluentBitHttpServer='Off' || FluentBitHttpServer='On'
kubectl create configmap fluent-bit-cluster-info \
--from-literal=cluster.name=${ClusterName} \
--from-literal=http.server=${FluentBitHttpServer} \
--from-literal=http.port=${FluentBitHttpPort} \
--from-literal=read.head=${FluentBitReadFromHead} \
--from-literal=read.tail=${FluentBitReadFromTail} \
--from-literal=logs.region=${RegionName} -n amazon-cloudwatch
생성하고 나서 확인해 보면 위에서 넣어준 값이 잘 들어가 있는 것을 확인할 수 있다.
-
fluent-bit-cluster-info
-
fluent-bit-config 라는 컨피그맵은 각 노드에서 어떤 로그(INPUT_Path)를 어느 로그 그룹(OUTPUT_log_group_name)에 보낼건지 정의되어 있다.
- /aws/containerinsights/Cluster_Name/application :
/var/log/containers/*.log
,/var/log/containers/fluent-bit*
,/var/log/containers/cloudwatch-agent*
- /aws/containerinsights/Cluster_Name/host :
/var/log/dmesg
,/var/log/messages
,/var/log/secure
- /aws/containerinsights/Cluster_Name/dataplane :
/var/log/journal
,/var/log/containers/aws-node*
,/var/log/containers/kube-proxy*
- /aws/containerinsights/Cluster_Name/application :
이제 Fluent Bit 데몬셋을 생성한다.
kubectl apply -f https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/daemonset/container-insights-monitoring/fluent-bit/fluent-bit.yaml
이제 fluent bit 구성은 끝났다.
aws cloudwatch로 넘어가 로그 그룹을 확인해 보면 아래와 같이 생성된 것을 볼 수 있다.
애플리케이션에 대한 로그를 보기 위해 /aws/containerinsights/myeks/application 에 들어가서 해당하는 로그스트림을 눌러 보면 로그 확인이 가능하다.
Fluent Bit를 DaemonSet로 설정하여 CloudWatch Logs에 로그 전송 - Amazon CloudWatch
Leave a comment