

# CloudWatch Logs에 로그 전송
<a name="Container-Insights-EKS-logs"></a>

컨테이너에서 Amazon CloudWatch Logs로 로그를 전송하려면 Fluent Bit를 사용하면 됩니다. 자세한 내용은 [Fluent Bit](https://fluentbit.io/)를 참조하세요.

**참고**  
AWS는 2025년 2월 10일에 CloudWatch Logs에 대한 로그 전달자인 FluentD에 대한 지원을 중단했습니다. 간편하고 리소스 효율이 우수한 대안인 Fluent Bit를 사용하는 것이 좋습니다. 기존 FluentD 배포는 계속 작동합니다. 로깅 파이프라인을 Fluent Bit로 마이그레이션하여 지속적인 지원과 최적 성능을 확보하세요.  
Container Insights는 이전에 FluentD를 사용하여 컨테이너에서 로그를 전송하는 것도 지원했습니다. FluentD는 사용 중지되었으며 이제 Container Insights에서 지원되지 않습니다. 그 대신에 Fluent Bit를 사용합니다.

**Topics**
+ [Fluent Bit를 DaemonSet로 설정하여 CloudWatch Logs에 로그 전송](Container-Insights-setup-logs-FluentBit.md)
+ [(선택 사항) Amazon EKS 제어 영역 로깅 설정](Container-Insights-setup-control-plane-logging.md)
+ [(선택 사항) 대규모 클러스터에 Use\$1Kubelet 기능 활성화](ContainerInsights-use-kubelet.md)

# Fluent Bit를 DaemonSet로 설정하여 CloudWatch Logs에 로그 전송
<a name="Container-Insights-setup-logs-FluentBit"></a>

다음 단원을 통해 Fluent Bit를 배포하여 컨테이너에서 CloudWatch Logs로 로그를 전송할 수 있습니다.

**Topics**
+ [Fluent Bit 설정](#Container-Insights-FluentBit-setup)
+ [여러 줄 로그 지원](#ContainerInsights-fluentbit-multiline)
+ [(선택 사항) Fluent Bit의 로그 볼륨 축소](#ContainerInsights-fluentbit-volume)
+ [문제 해결](#Container-Insights-FluentBit-troubleshoot)
+ [대시보드](#Container-Insights-FluentBit-dashboard)

## Fluent Bit 설정
<a name="Container-Insights-FluentBit-setup"></a>

Fluent Bit를 설정하여 컨테이너에서 로그를 수집하려면 [Amazon EKS 및 Kubernetes에서 Container Insights의 빠른 시작 설정](Container-Insights-setup-EKS-quickstart.md)의 절차를 따르거나 이 단원의 절차를 따르면 됩니다.

어느 방법이든 클러스터 노드에 첨부된 IAM 역할에 충분한 권한이 있어야 합니다. Amazon EKS 클러스터를 실행하는 데 필요한 권한에 대한 자세한 내용은 *Amazon EKS 사용 설명서*의 [Amazon EKS IAM 정책, 역할 및 권한](https://docs.aws.amazon.com/eks/latest/userguide/IAM_policies.html) 단원을 참조하세요.

다음 단계에서는 Fluent Bit를 daemonSet로 설정하여 CloudWatch Logs에 로그를 전송합니다. 이 단계를 완료하면 Fluent Bit가 다음 로그 그룹을 생성합니다(아직 없는 경우).

**중요**  
Container Insights에 이미 FluentD가 구성되어 있고 FluentD DaemonSet가 예상대로 실행되지 않는 경우(`containerd` 런타임을 사용하는 경우 발생할 수 있음), Fluent Bit를 설치하기 전에 Fluent Bit를 제거해야 Fluent Bit가 FluentD 오류 로그 메시지를 처리하지 않습니다. 그러지 않으면 Fluent Bit를 성공적으로 설치한 후 즉시 FluentD를 제거해야 합니다. Fluent Bit를 설치한 후 Fluentd를 제거해도 이 마이그레이션 과정에서 로깅을 계속 유지할 수 있습니다. CloudWatch Logs로 로그를 전송하는 데 Fluent Bit 또는 FluentD 중 하나만 필요합니다.


| 로그 그룹 이름 | 로그 소스 | 
| --- | --- | 
|  `/aws/containerinsights/Cluster_Name/application`  |  `/var/log/containers`의 모든 로그 파일  | 
|  `/aws/containerinsights/Cluster_Name/host`  |  `/var/log/dmesg`, `/var/log/secure` 및 `/var/log/messages`에서의 로그  | 
|  `/aws/containerinsights/Cluster_Name/dataplane`  |  `kubelet.service`, `kubeproxy.service` 및 `docker.service`에 대한 `/var/log/journal`에서의 로그.  | 

**Fluent Bit를 설치하여 컨테이너에서 CloudWatch Logs로 로그를 전송하려면**

1. `amazon-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
   ```

1. 다음 명령을 실행하여 로그를 전송할 클러스터 이름 및 리전이 포함된 `cluster-info`라는 ConfigMap을 생성합니다. *cluster-name* 및 *cluster-region*을 클러스터의 이름 및 리전으로 바꿉니다.

   ```
   ClusterName=cluster-name
   RegionName=cluster-region
   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
   ```

   이 명령에서 플러그 인 지표 모니터링을 위한 `FluentBitHttpServer`는 기본적으로 활성화되어 있습니다. 명령에서 이를 비활성화하려면 명령의 세 번째 줄을 `FluentBitHttpPort=''`(빈 문자열)로 변경합니다.

   또한 기본적으로 Fluent Bit는 테일에서 로그 파일을 읽으며 배포된 후 새 로그만 캡처합니다. 반대를 원하는 경우 `FluentBitReadFromHead='On'`으로 설정하면 파일 시스템의 모든 로그를 수집합니다.

1. 다음 명령 중 하나를 실행하여 Fluent Bit 데몬 세트를 다운로드한 후 클러스터에 배포합니다.
   + Linux 컴퓨터에 대한 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
     ```
   + Windows 컴퓨터에 대한 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-windows.yaml
     ```
   + Linux 컴퓨터를 사용 중이고 Fluentd와 더 유사한 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-compatible.yaml
     ```
**중요**  
Fluent Bit DaemonSet 구성은 기본적으로 로그 수준을 INFO로 설정하므로 CloudWatch Logs 수집 비용이 높아질 수 있습니다. 로그 수집 볼륨과 비용을 줄이려면 로그 수준을 오류로 변경하면 됩니다.  
로그 볼륨을 줄이는 방법에 대한 자세한 내용은 [(선택 사항) Fluent Bit의 로그 볼륨 축소](#ContainerInsights-fluentbit-volume) 섹션을 참조하세요.

1. 다음 명령을 입력하여 배포를 검증합니다. 각 노드에는 **fluent-bit-\$1**라는 포드가 하나 있어야 합니다.

   ```
   kubectl get pods -n amazon-cloudwatch
   ```

위 단계는 클러스터에 다음 리소스를 생성합니다.
+ `amazon-cloudwatch` 네임스페이스의 `Fluent-Bit`이라는 서비스 계정. 이 서비스 계정은 Fluent Bit daemonSet를 실행하는 데 사용됩니다. 자세한 내용은 Kubernetes 참조 문서의 [서비스 계정 관리](https://kubernetes.io/docs/reference/access-authn-authz/service-accounts-admin/)를 참조하세요.
+ `amazon-cloudwatch` 네임스페이스의 `Fluent-Bit-role`이라는 클러스터 역할. 이 클러스터 역할은 `Fluent-Bit` 서비스 계정에 대해 Pod 로그에서 `get`, `list` 및 `watch` 권한을 부여합니다. 자세한 내용은 Kubernetes 참조 문서의 [API 개요](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#api-overview/)를 참조하세요.
+ `amazon-cloudwatch` 네임스페이스의 `Fluent-Bit-config`이라는 ConfigMap. 이 ConfigMap에는 Fluent Bit에서 사용할 구성이 포함되어 있습니다. 자세한 내용은 Kubernetes 작업 설명서의 [ConfigMap을 사용하도록 Pod 구성](https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/)을 참조하세요.

Fluent Bit 설정을 확인하려면 다음 단계를 따르세요.

**Fluent Bit 설정 확인**

1. [https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/)에서 CloudWatch 콘솔을 엽니다.

1. 탐색 창에서 **로그 그룹**을 선택합니다.

1. Fluent Bit를 배포한 리전에 있는지 확인합니다.

1. 리전의 로그 그룹 목록을 확인합니다. 다음과 같은 모양이어야 합니다.
   + `/aws/containerinsights/Cluster_Name/application`
   + `/aws/containerinsights/Cluster_Name/host`
   + `/aws/containerinsights/Cluster_Name/dataplane`

1. 이러한 로그 그룹 중 하나로 이동하여 로그 스트림의 **마지막 이벤트 시간**을 확인합니다. 해당 시간이 Fluent Bit를 배포한 시점을 기준으로 최근인 경우 설정이 확인됩니다.

   `/dataplane` 로그 그룹을 생성하는 데 약간의 지연이 있을 수 있습니다. 이러한 로그 그룹은 Fluent Bit가 해당 로그 그룹에 대한 로그 전송을 시작할 때만 생성되기 때문에 약간의 지연 현상은 정상입니다.

## 여러 줄 로그 지원
<a name="ContainerInsights-fluentbit-multiline"></a>

여러 줄 로그와 함께 Fluent Bit를 사용하는 방법에 대한 자세한 내용은 Fluent Bit 설명서의 다음 섹션을 참조하세요.
+ [여러 줄 구문 분석](https://docs.fluentbit.io/manual/administration/configuring-fluent-bit/multiline-parsing)
+ [여러 줄 및 컨테이너(v1.8)](https://docs.fluentbit.io/manual/pipeline/inputs/tail#multiline-and-containers-v1.8)
+ [여러 줄 코어(v1.8)](https://docs.fluentbit.io/manual/pipeline/inputs/tail#multiline-core-v1.8)
+ [테일 입력에는 항상 여러 줄 사용](https://github.com/aws/aws-for-fluent-bit/blob/mainline/troubleshooting/debugging.md#always-use-multiline-the-tail-input)

## (선택 사항) Fluent Bit의 로그 볼륨 축소
<a name="ContainerInsights-fluentbit-volume"></a>

기본적으로 CloudWatch에 Fluent Bit 애플리케이션 로그와 Kubernetes 메타데이터가 전송됩니다. CloudWatch에 전송되는 데이터의 볼륨을 줄이려면 이러한 데이터 원본 중 하나 또는 둘 모두가 CloudWatch에 전송되지 못하게 막으면 됩니다. 이 페이지의 단계에 따라 Fluent Bit를 설정했다면, 이전에 실행한 kubectl `apply` 명령에서 Kubernetes 매니페스트 YAML 파일을 다운로드하고 변경 사항으로 수정한 다음 클러스터에 다시 적용할 수 있습니다. 또는 Amazon CloudWatch Observability EKS 추가 기능 또는 차트 Helm을 사용하는 경우, 추가 기능의 고급 구성 또는 차트 Helm을 사용하여 Fluent Bit 구성을 관리하는 방법에 대한 자세한 내용은 [(선택 사항) 추가 구성](install-CloudWatch-Observability-EKS-addon.md#install-CloudWatch-Observability-EKS-addon-configuration) 섹션을 참조하세요.

Fluent Bit 애플리케이션 로그를 중지하려면 `Fluent Bit configuration` 파일에서 다음 섹션을 제거합니다.

```
[INPUT]
        Name                tail
        Tag                 application.*
        Path                /var/log/containers/fluent-bit*
        Parser              docker
        DB                  /fluent-bit/state/flb_log.db
        Mem_Buf_Limit       5MB
        Skip_Long_Lines     On
        Refresh_Interval    10
```

Kubernetes 메타데이터를 제거하여 CloudWatch로 전송되는 로그 이벤트에 추가되지 못하게 하려면 Fluent Bit 구성의 `application-log.conf` 섹션에 다음 필터를 추가합니다. *<Metadata\$11>* 및 유사한 필드를 실제 메타데이터 식별자로 바꾸세요.

```
application-log.conf: |
    [FILTER]
        Name                nest
        Match               application.*
        Operation           lift
        Nested_under        kubernetes
        Add_prefix          Kube.

    [FILTER]
        Name                modify
        Match               application.*
        Remove              Kube.<Metadata_1>
        Remove              Kube.<Metadata_2>
        Remove              Kube.<Metadata_3>
    
    [FILTER]
        Name                nest
        Match               application.*
        Operation           nest
        Wildcard            Kube.*
        Nested_under        kubernetes
        Remove_prefix       Kube.
```

## 문제 해결
<a name="Container-Insights-FluentBit-troubleshoot"></a>

이러한 로그 그룹이 표시되지 않으며 리전이 올바른지 살펴보고 있는 경우 Fluent Bit daemonSet 포드의 로그를 확인하여 오류를 찾습니다.

다음 명령을 실행하여 상태가 `Running`인지 확인합니다.

```
kubectl get pods -n amazon-cloudwatch
```

로그에 IAM 권한과 관련된 오류가 있다면 클러스터 노드에 연결된 IAM 역할을 확인합니다. Amazon EKS 클러스터를 실행하는 데 필요한 권한에 대한 자세한 내용은 *Amazon EKS 사용 설명서*의 [Amazon EKS IAM 정책, 역할 및 권한](https://docs.aws.amazon.com/eks/latest/userguide/IAM_policies.html) 단원을 참조하세요.

Pod 상태가 `CreateContainerConfigError`이면 다음 명령을 실행하여 정확한 오류를 가져옵니다.

```
kubectl describe pod pod_name -n amazon-cloudwatch
```

## 대시보드
<a name="Container-Insights-FluentBit-dashboard"></a>

대시보드를 생성하여 실행 중인 각 플러그 인의 지표를 모니터링할 수 있습니다. 출력 오류 및 재시도/실패 비율 관련 데이터뿐만 아니라 입력 및 출력 바이트 관련 데이터, 레코드 처리 속도 관련 데이터를 확인할 수 있습니다. 이러한 지표를 보려면 Amazon EKS 및 Kubernetes 클러스터용 Prometheus 지표 수집과 함께 CloudWatch 에이전트를 설치해야 합니다. 대시보드 설정 방법에 대한 자세한 내용은 [Amazon EKS 및 Kubernetes 클러스터에 Prometheus 지표 수집과 함께 CloudWatch 에이전트 설치Amazon EKS 및 Kubernetes 클러스터에 Prometheus 지표 수집과 함께 CloudWatch 에이전트 설치](ContainerInsights-Prometheus-Setup.md) 단원을 참조하세요.

**참고**  
이 대시보드를 설정하려면 먼저, Prometheus 지표에 대한 Container Insights를 설정해야 합니다. 자세한 내용은 [Container Insights Prometheus 지표 모니터링](ContainerInsights-Prometheus.md) 섹션을 참조하세요.

**Fluent Bit Prometheus 지표에 대한 대시보드를 생성하려면**

1. 환경 변수를 만들어서 다음 줄의 오른쪽에 있는 값을 배포와 일치하도록 바꿉니다.

   ```
   DASHBOARD_NAME=your_cw_dashboard_name
   REGION_NAME=your_metric_region_such_as_us-west-1
   CLUSTER_NAME=your_kubernetes_cluster_name
   ```

1. 다음 명령을 실행하여 대시보드를 생성합니다.

   ```
   curl https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/service/cwagent-prometheus/sample_cloudwatch_dashboards/fluent-bit/cw_dashboard_fluent_bit.json \
   | sed "s/{{YOUR_AWS_REGION}}/${REGION_NAME}/g" \
   | sed "s/{{YOUR_CLUSTER_NAME}}/${CLUSTER_NAME}/g" \
   | xargs -0 aws cloudwatch put-dashboard --dashboard-name ${DASHBOARD_NAME} --dashboard-body
   ```

# (선택 사항) Amazon EKS 제어 영역 로깅 설정
<a name="Container-Insights-setup-control-plane-logging"></a>

Amazon EKS를 사용하는 경우 선택적으로 Amazon EKS 제어 영역 로깅을 사용 설정하여 Amazon EKS 제어 영역에서 CloudWatch Logs로 직접 감사 및 진단 로그를 제공할 수 있습니다. 자세한 내용은 [Amazon EKS 제어 영역 로깅](https://docs.aws.amazon.com/eks/latest/userguide/control-plane-logs.html) 단원을 참조하세요.

# (선택 사항) 대규모 클러스터에 Use\$1Kubelet 기능 활성화
<a name="ContainerInsights-use-kubelet"></a>

기본적으로 Use\$1Kubelet 기능은 FluentBit Kubernetes 플러그 인에서 비활성화되어 있습니다. 이 기능을 활성화하면 API 서버에 대한 트래픽이 줄어들고 API 서버에 병목 현상이 발생하는 문제를 완화할 수 있습니다. 대규모 클러스터에 해당 기능을 활성화하는 것이 좋습니다.

Use\$1Kubelet을 활성화하려면 먼저 노드와 노드 및 프록시 권한을 ClusterRole 구성에 추가합니다.

```
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: fluent-bit-role
rules:
  - nonResourceURLs:
      - /metrics
    verbs:
      - get
  - apiGroups: [""]
    resources:
      - namespaces
      - pods
      - pods/logs
      - nodes
      - nodes/proxy
    verbs: ["get", "list", "watch"]
```

DaemonSet 구성에서 이 기능을 사용하려면 호스트 네트워크 액세스 권한이 필요합니다. `amazon/aws-for-fluent-bit`의 이미지 버전이 2.12.0 이상이거나 fluent bit 이미지 버전이 1.7.2 이상이어야 합니다.

```
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluent-bit
  namespace: amazon-cloudwatch
  labels:
    k8s-app: fluent-bit
    version: v1
    kubernetes.io/cluster-service: "true"
spec:
  selector:
    matchLabels:
      k8s-app: fluent-bit
  template:
    metadata:
      labels:
        k8s-app: fluent-bit
        version: v1
        kubernetes.io/cluster-service: "true"
    spec:
      containers:
      - name: fluent-bit
        image: amazon/aws-for-fluent-bit:2.19.0
        imagePullPolicy: Always
        env:
            - name: AWS_REGION
              valueFrom:
                configMapKeyRef:
                  name: fluent-bit-cluster-info
                  key: logs.region
            - name: CLUSTER_NAME
              valueFrom:
                configMapKeyRef:
                  name: fluent-bit-cluster-info
                  key: cluster.name
            - name: HTTP_SERVER
              valueFrom:
                configMapKeyRef:
                  name: fluent-bit-cluster-info
                  key: http.server
            - name: HTTP_PORT
              valueFrom:
                configMapKeyRef:
                  name: fluent-bit-cluster-info
                  key: http.port
            - name: READ_FROM_HEAD
              valueFrom:
                configMapKeyRef:
                  name: fluent-bit-cluster-info
                  key: read.head
            - name: READ_FROM_TAIL
              valueFrom:
                configMapKeyRef:
                  name: fluent-bit-cluster-info
                  key: read.tail
            - name: HOST_NAME
              valueFrom:
                fieldRef:
                  fieldPath: spec.nodeName
            - name: HOSTNAME
              valueFrom:
                fieldRef:
                  apiVersion: v1
                  fieldPath: metadata.name      
            - name: CI_VERSION
              value: "k8s/1.3.8"
        resources:
            limits:
              memory: 200Mi
            requests:
              cpu: 500m
              memory: 100Mi
        volumeMounts:
        # Please don't change below read-only permissions
        - name: fluentbitstate
          mountPath: /var/fluent-bit/state
        - name: varlog
          mountPath: /var/log
          readOnly: true
        - name: varlibdockercontainers
          mountPath: /var/lib/docker/containers
          readOnly: true
        - name: fluent-bit-config
          mountPath: /fluent-bit/etc/
        - name: runlogjournal
          mountPath: /run/log/journal
          readOnly: true
        - name: dmesg
          mountPath: /var/log/dmesg
          readOnly: true
      terminationGracePeriodSeconds: 10
      hostNetwork: true
      dnsPolicy: ClusterFirstWithHostNet
      volumes:
      - name: fluentbitstate
        hostPath:
          path: /var/fluent-bit/state
      - name: varlog
        hostPath:
          path: /var/log
      - name: varlibdockercontainers
        hostPath:
          path: /var/lib/docker/containers
      - name: fluent-bit-config
        configMap:
          name: fluent-bit-config
      - name: runlogjournal
        hostPath:
          path: /run/log/journal
      - name: dmesg
        hostPath:
          path: /var/log/dmesg
      serviceAccountName: fluent-bit
      tolerations:
      - key: node-role.kubernetes.io/master
        operator: Exists
        effect: NoSchedule
      - operator: "Exists"
        effect: "NoExecute"
      - operator: "Exists"
        effect: "NoSchedule"
```

쿠버네티스 플러그 인 구성은 다음과 유사합니다.

```
[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
```