Logging & Monitoring

로그 관리 시스템

로그 관리 파이프라인

  • 각 파드의 컨테이너들로부터 발생한 로그 파일들을 중앙화된 시스템 형태로 관리하기 위해 아래와 같은 파이프라인을 구성할 수 있다.

  • 컨테이너 로그는 컨테이너가 실행중인 노드에 파일 형태로 저장된다. 로그 파일의 이름에는 네임스페이스, 파드, 컨테이너 이름이 포함된다.

  • 컨테이너가 저장한 로그 파일을 로그 수집기(ex. fluentd)가 수집하여 중앙화된 로그 저장소(ex. elastic search)에 전달하면, 운영자는 로그 저장소의 여러 확장 프로그램(ex. kibana)을 이용해 로그 검색 및 필터링 기능을 이용할 수 있다.

  • 로그 파일은 파드 컨테이너가 재시작되더라도 그대로 유지된다. 로그 로테이션으로 인해 오래된 로그 파일이 덮어쓰여질 수 있으니 노드에서 로그 파일을 중앙 저장소로 전달하면 더 장기적으로 저장할 수 있다.

  • 쿠버네티스 코어 컴포넌트에서 생성된 로그도 동일한 방식으로 수집된다.

로그 파일 수집

  • fluentd를 이용해 각 노드에서 발생한 로그 파일들을 하나의 저장소로 수집할 수 있다.

  • 모든 노드에서 fluentd의 경량화 프로세스인 fluent-bit 파드를 데몬셋 형태로 실행시키고, 파드가 로그 파일에 접근할 수 있도록 호스트경로 마운트를 추가해주어야 한다.

  • 아래는 fluentd 데몬셋 정의이다.

  • 다음 명령을 이용하면 fluentd가 각각의 컨테이너로부터 읽어들인 로그를 확인할 수 있다.

  • ConfigMap의 경우 아래와 같이 작성할 수 있다. 여기서 설정하는 값들을 통해 로그에 다양한 메타데이터를 추가하고 원하는 기준에 따라 서로 다른 대상으로 로그를 출력할 수 있다.

    • fluentd의 데이터 처리는 로그 파일을 읽어들이는 입력 단계, JSON 포맷으로 된 원시 로그를 전처리하는 파싱 단계, 하나의 엔트리를 fluentd 컨테이너 로그로 출력하는 단계로 나뉜다.

  • 다음 Deployment 정의를 통해 Elastic Search 파드를 구동한 후, fluentd의 ConfigMap을 수정해 Elastic Search에 로그를 출력하도록 한다.

  • ConfigMap을 변경하더라도 파드는 재시작되지 않으므로, 직접 재시작해주어야 한다.

  • fluentd와 elastic search를 사용하면 로그 데이터 처리 파이프라인을 애플리케이션과 분리하여 처리할 수 있기 때문에 좋다.

  • 예를 들어 특정 로그 레벨만 로깅하도록 변경하고 싶을 때, 애플리케이션 자체에서 로그 출력을 조절할 수도 있지만 애플리케이션 재시작이 필요하다. fluentd에서 로그를 필터링해 중앙 저장소에 저장한다면, 애플리케이션 재시작 없이 로그를 필터링할 수 있다.

  • 다음은 필터링 설정의 예시이다. 이를 통해 priority 필드값이 2, 3, 4인 경우에만 로그를 중앙 저장소에 저장하게 된다.

다양한 로그 모델

  • fluentd는 다양한 기능을 제공하고 효율적으로 동작하지만 복잡한 로그 처리 파이프라인에는 연산 시간이 소요되어 입출력 사이에 지연이 발생할 수 있다.

  • 애플리케이션에서 중앙 로그 저장소로 곧바로 로그를 기록하거나 사이드카 컨테이너를 이용해 중앙 로그 저장소에 기록하도록 직접 구현할 수 있다.

모니터링

  • 중앙화된 시스템에서 측정값을 수집하여 전체 애플리케이션 컴포넌트의 상태를 파악할 수 있다.

  • 모니터링 시 측정되어야 할 주요 정보로는 latency, traffic, error, saturation들이 있다. 하지만 가장 중요한 것은 사용자 경험 관점에서의 애플리케이션 성능에 영향을 미치는 원인에 지표를 찾는 것이다.

  • 쿠버네티스에서는 프로메테우스와 연동해 클러스터의 측정값을 수집하고 저장할 수 있다.

  • 프로메테우스에서는 서비스의 로드밸런싱을 통해 메트릭 정보를 얻는 것보다 각 파드의 IP 주소를 알아내 메트릭 정보를 알아내어야 한다. 이러한 과정 속에서 사용자에게 노출하는 API와 쿠버네티스 내부에서만 사용하는 API를 제어할 수도 있을 것이다.

  • 프로메테우스 deployment에서 사용되는 ConfigMap에는 스크래핑 대상을 정의해야 한다.

  • 여기서 스크래핑 대상이 된 애플리케이션은 스스로 메트릭 값을 구해 이 정보를 HTTP로 가져갈 수 있도록 해야 한다.

  • 메트릭을 제공하는 주소가 /metrics 와 다르다면 직접 HTTP 주소를 아래와 같이 어노테이션을 통해 정의해주어야 한다.

  • 이후 프로메테우스 정의에서 어노테이션에 해당하는 API를 사용할 수 있도록 아래와 같이 정의한다.

    • 프로메테우스의 모든 규칙은 레이블 형태로 처리되어 meta_kubernetes_pod_annotation_<어노테이션 이름> 레이블로 변환된다.

    • meta_kubernetes_pod_annotationpresent_<어노테이션 이름> 레이블을 통해서 해당 어노테이션이 존재하는 지 확인할 수 있다.

  • 만약 프로메테우스 스크래핑 대상에서 제외하려면 아래와 같이 파드 정의를 하면 된다.

  • 프로메테우스의 지표들을 시각화하기 위해서는 그라파나를 파드로 띄워야 한다.

  • 모니터링을 위해서는 1. 시스템 상태를 파악하는 데에 필요한 정보 목록을 작성하고, 2. 개발 및 운영 팀에서 해당 정보를 추출하는 모니터링 시스템을 구축해야 한다.

사이드카 컨테이너로 측정값을 추출하기

  • 프로메테우스가 인식할 수 있는 형태의 측정값을 제공하지 못하는 애플리케이션들은 프로메테우스가 인식할 수 있는 형태의 측정값을 제공하는 사이드카 컨테이너와 함께 사용될 수 있다.

  • Nginx용 프로메테우스 지표 추출기를 사용하면, 같은 파드 내에 존재하는 Nginx 서버에 localhost로 접근해 지표를 수집하고 HTTP 엔드포인트로 추출한 측정값을 내보낸다.

  • 아래는 Nginx용 프로메테우스 지표 추출을 위한 사이드카 컨테이너 정의이다.

  • 애플리케이션 자체에서 측정값을 제공하지 않으며 쿠버네티스의 자기수복 기능을 사용할 수 없는 경우, 프로메테우스에서 제공하는 블랙박스 exporter를 사이드카 컨테이너로 등록해 TCP/HTTP 요청으로 애플리케이션의 정상 여부를 확인할 수 있다.

쿠버네티스 객체와 컨테이너 모니터링

  • 쿠버네티스 객체와 컨테이너 상태 정보는 쿠버네티스 API를 통해 직접 수집할 수 없다.

  • 데몬셋 형태로 각 노드에 배치되어 노드의 컨테이너 런타임에서 정보를 수집하는 cAdvisor와 쿠버네티스 API에서 정보를 수집하는 kube-state-metrics 도구를 이용해야 한다.

  • 다음은 데몬셋 타입의 cAdvisor의 정의이다.

  • 다음은 디플로이먼트 타입의 kube-state-metrics 정의이다.

  • cAdvisor, kube-state-metrics의 지표들을 스크래핑하기 위한 prometheus ConfigMap 정의이다. ConfigMap이 변경되더라도 파드가 자동으로 반영하지 않으므로 curl -X POST $(kubectl get svc prometheus -o jsonpath='http://{.status.loadBalancer.ingress[0].*}:9090/-/reload' -n kiamol-ch14-monitoring) 명령을 이용해 갱신된 설정값을 사용하도록 해야 한다.

Last updated