Amazon Web Service (AWS)/EKS

FluentBit + CloudWatch logs 로 Pods Application 로그 수집하기

Ssemi-Column 2023. 4. 23. 01:40
728x90

AWS를 개인적으로 구성하면서 적다보니, 140만원이 청구되어 환경이 갖춰지기 전까진 글로만...

빨간색 부분에서 데몬셋으로 실행된 FluentBit가 각 Pods의 로그를 수집하여 CloudWatchLogs에 항목별로 쌓아주는 구성을 작성
 
참고글 : https://repost.aws/ko/knowledge-center/cloudwatch-stream-container-logs-eks
(작성하고 찾아보니 질문이 아닌 공식 문서에도 적혀있다)

Amazon EKS에서 컨테이너 로그를 CloudWatch로 스트리밍 | AWS re:Post

Amazon Elastic Kubernetes Service(Amazon EKS)에서 실행되는 컨테이너 로그를 CloudWatch Logs와 같은 로깅 시스템으로 스트리밍하고 싶습니다. 어떻게 해야 합니까?

repost.aws


위 참고 문서를 읽어보면 FluentD, FluentBit 두 개 다 구성 할 수 있으나, AWS에서는 FluentBit를 추천.
 

1. FleuntBit가 CloudWatchLogs에 알아서 쌓을 수 있도록,

CloudWatchAgentServerPoliy 권한을 가지고있는 Role를 만들기

 
 
1. IAM 역할 탭 접속후 역할 만들기 선택
 

2. 신뢰할 수 있는 엔터티 유형에서 웹 자격 증명 선택

3. EKS 지정된 클러스터에서만 동작 할 수 있도록 EKS의 자격 증명 공급자(OIDC) 선택

  • 만약 EKS OIDC를 모른다면 EKS 페이지에서 클러스터 정보에서 OpenID Connect(OIDC)의 값을 확인

4. 권한 정책에서 정책 생성 선택
 

5. JSON 편집에서 해당 내용 작성

{
  "Version" : "2012-10-17",
  "Statement" : [
    {
      "Effect" : "Allow",
      "Action" : [
        "cloudwatch:PutMetricData",
        "ec2:DescribeVolumes",
        "ec2:DescribeTags",
        "logs:PutLogEvents",
        "logs:DescribeLogStreams",
        "logs:DescribeLogGroups",
        "logs:CreateLogStream",
        "logs:CreateLogGroup"
      ],
      "Resource" : "*"
    },
    {
      "Effect" : "Allow",
      "Action" : [
        "ssm:GetParameter"
      ],
      "Resource" : "arn:aws:ssm:*:*:parameter/AmazonCloudWatch-*"
    }
  ]
}

6. 검토에서 알맞은 이름 작성 후 정책생성


2. EKS에 FluentBit를 설치하고 IAM 역할을 부여하여 로그 수집후 CloudWatch logs에 전달하기

1. kubectl 명령어로 cloudWatch 용 namespace 생성
- 별 내용 없이 amazon-cloudwatch 라는 namespace가 생성됨

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

## create amazon-cloudwatch namespace
# apiVersion: v1
# kind: Namespace
# metadata:
#   name: amazon-cloudwatch
#   labels:
#     name: amazon-cloudwatch

2. 클러스터에 지정할 configmap 작성

ClusterName=나의 클러스터 이름
RegionName=내 리전 (ap-northeast-ap2)
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

3. 해당 문서를 yaml 로 생성하고 배포함

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

4. 배포 된 fluentBit에 앞에서 생성한 role을 부여함 (위 문서에 annotation으로 붙음)

kubectl annotate serviceaccounts fluent-bit -n amazon-cloudwatch "eks.amazonaws.com/role-arn=arn:aws:iam::{AWS 계정}:role/{앞서 만든 role 이름}"


1. 위에서 적용한 문서를 살펴보면..
application-log.conf, dataplane-log.conf, host-log.conf 3가지 설정으로 cloudwatch logs 에 쌓임.
나는 application 의 로그가 필요하므로 dataplane-log.conf, host-log.conf 두개의 설정을 모두 지움.
 
2. application-log.conf 중 INPUT 부분들을 살펴보면...

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}

    [INPUT]
        Name                tail
        Tag                 application.*
        Path                /var/log/containers/fluent-bit*
        multiline.parser    docker, cri
        DB                  /var/fluent-bit/state/flb_log.db
        Mem_Buf_Limit       5MB
        Skip_Long_Lines     On
        Refresh_Interval    10
        Read_from_Head      ${READ_FROM_HEAD}

    [INPUT]
        Name                tail
        Tag                 application.*
        Path                /var/log/containers/cloudwatch-agent*
        multiline.parser    docker, cri
        DB                  /var/fluent-bit/state/flb_cwagent.db
        Mem_Buf_Limit       5MB
        Skip_Long_Lines     On
        Refresh_Interval    10
        Read_from_Head      ${READ_FROM_HEAD}
  • tail 로 새로 생성된 로그의 꽁지 부분을 계속 가져간다.
  • Excplude_Path 로 cloudwatch logs 로 올리고싶지 않은 패키지 + 파일이름을 지정 할 수 있다.
  • path 로 올리고 싶은 패키지 + 파일이름을 지정 할 수 있다.
  • 이전에 설치한 argoCd의 로그도 올라가기 때문에 Exclude_Path에 /var/log/containers/argoCd* 도 추가함
  • DB를 보면 어디쪽에 쌓이는지 알 수 있다

3. application-log.conf의 OUTPUT부분을 살펴본다면

    [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
  • Match로 cloudwatch_logs의 path가 어느정도 지정된다
  • log_group_name에서 클러스터의 이름대로 로그가 그룹핑된다.
  • prefix의 값으로 다른 Pods들과 구분지어 로그가 쌓이게 된다.
728x90
반응형
LIST