OpenShift Logging

애플리케이션 로그는 애플리케이션 내부에서 발생하는 상황을 이해하는 데 도움이 된다. 로그는 문제를 디버깅하고 클러스터 활동을 모니터링하는 데 특히 유용하다. 대부분의 최신 애플리케이션에는 일종의 로깅 메커니즘이 있다. 마찬가지로, 컨테이너 엔진들도 로깅을 지원하도록 설계되었다. 컨테이너화된 애플리케이션에 가장 쉽고 가장 널리 사용되는 로깅 방법은 표준 출력과 표준 에러 스트림에 작성하는 것이다.

그러나, 일반적으로 컨테이너 엔진이나 런타임에서 제공하는 기본 기능은 완전한 로깅 솔루션으로 충분하지 않다.예를 들어, 컨테이너가 크래시되거나, 파드가 축출되거나, 노드가 종료된 경우에도 애플리케이션의 로그에 접근하고 싶을 것이다.

클러스터에서 로그는 노드, 파드 또는 컨테이너와는 독립적으로 별도의 스토리지와 라이프사이클을 가져야 한다. 이 개념을 클러스터-레벨-로깅 이라고 한다. 클러스터-레벨 로깅은 로그를 저장, 분석, 쿼리하기 위해서는 별도의 백엔드가 필요하다. 쿠버네티스가 로그 데이터를 위한 네이티브 스토리지 솔루션을 제공하지는 않지만, 쿠버네티스에 통합될 수 있는 기존의 로깅 솔루션이 많이 있다.

노드 레벨에서의 로깅

애플리케이션 로깅
노드 레벨 로깅

컨테이너화된 애플리케이션의 stdout(표준 출력) 및 stderr(표준 에러) 스트림에 의해 생성된 모든 출력은 컨테이너 엔진이 처리 및 리디렉션 한다. pod에 실행된 애플리케이션의 로그는 ‘kubectl log’ 명령어로 로그를 볼 수 있다.

kubectl logs my-pod
시스템 컴포넌트 로그

systemd를 사용하는 리눅스에서는 기본적으로 kubelet 및 컨테이너 런타임은 journald 에 로그를 쓴다. journalct 명령어는 시스템 저널을 읽는데 사용된다.

journalctl -u kubelet

클러스터 수준의 로깅 아키텍처

쿠버네티스는 클러스터 수준 로깅을 위한 기본 솔루션을 제공하고 있지 않지만 고려할 수 있는 방안이 몇가지가 있다. 그 중 OpenShift는 모든 노드에서 실행되는 노드 수준 로깅 에이전트를 사용한다.

노드 수준 로깅 에이전트 사용

각 노드에서 노드 수준 로깅 에이전트를 포함하여 클러스터 수준 로깅을 구현할 수가 있다. 로깅 에이전트는 로그를 노출하거나 백엔드로 로그를 푸시하는 전용 도구이다. 일반적으로 로깅 에이전트는 해당 노드에 있는 모든 애플리케이션 컨테이너의 로그 파일이 있는 디렉토리에 액세스할 수 있는 컨테이너이다.

오픈시프트 로깅

기본적으로 오픈시프트의 로깅은 Cluster Logging 으로 관리되고 있다.
Cluster Logging은 다음의 영역을 포함한다.

application인프라 컨테이너 애플리케이션을 제외하고 클러스터에서 실행 중인 사용자 애플리케이션에 의해 생성된 컨테이너 로그.
infrastructure저널 로그와 같이 클러스터 및 OpenShift Container Platform 노드에서 실행되는 인프라 구성 요소에 의해 생성된 로그. openshift-* 와 kube-* , 그리고 default 프로젝트에서 실행되는 Pod의 로그
audit/var/log/audit/audit.log 파일 에 저장된 노드 감사 시스템인 auditd에 의해 생성된 로그와 Kubernetes apiserver 및 OpenShift apiserver의 감사 로그.

오픈시프트 로깅 아키텍처

OpenShift는 여러가지 모듈에 대해서 Operator로 관리가 된다. Logging역시 Operator로 관리가 되며 다음과 같은 아키텍처를 가진다. OpenShift 클러스터 관리자가 cli 명령이나 웹 콘솔을 사용하여 Cluster Logging을 배포하여 Cluster Logging Operator 와 Elasticsearch Operator를 설치할 수 있다.

Cluster Logger가 배포되고 나면 설치되는 항목은 Fluentd, Elasticsearch, Kibana 이다. 흔히들 말하는 컨테이너를 위한 로그처리 형태인 EFK 스텍이다.

Fluentd로그를 주입하는 주체이다. DaemonSet으로 동작을 하며 노드나 컨테이너에서 발생하는 로그들을 elasticsearch로 보내는 역할을 한다.
Elasticsearch로그를 저장하는 저장소이다. elasticseach cluste를 이루는 노드들에게 설치가 되며 fluentd에서 보내온 로그들을 분산된 형식으로 저장한다. 노드는 최소 3개 이상이다.
Kibana로그를 분석하는 대시보드이다. elasticsearch에 저장된 데이터를 사용자의 요구사항에 따라 보여주는 대시보드이다.

EFK 스텍은 아래와 같이 동작한다. 각 노드의 Pod에서 발생되는 로그들은 fluentd를 통해서 elasticsearch로 저장이 된다. 저장이 된 로그들은 kibana를 통해서 사용자에게 보여지게 된다.

fluentd는 DeamonSet으로 동작을 하고 node 마다 1개씩 운영된다. fluentd에서는 음 3가지의 로그를 수집한다.

  • Journald : 시스템에서 발생되는 로그 메시지 및 컨테이너 런타임, 오픈시프트에서 발생하는 로그들
  • CRI-O : 애플리케이션에서 발생되는 로그들
  • Event Router : stdout 으로 출력되는 모든 로그들

아래 표과 같이 각 항목의 로그를 추출한다.

로그 타입목적접근 방법
Journal log마스터 또는 작업자 노드에서 시작된 서비스의 상태 확인– journalctl 명령어
– /var/log/messages
Audit Log마스터 대시보드 또는 CLI에서 사용자가 수행하는 감사 작업(API 요청)– configure CR APIServer/cluster.
– oc adm node-logs 명령어.
Event Log노드에서 PV 또는 포드 생성 실패와 같은 노드 이벤트(장애)를 검사– oc get event 명령어
Container Log특정 Pod 또는 컨테이너 장애 검사– oc logs 명령어
Logs by troubleshooting OpenShift SDN 통신과 같은 NW 관련 문제 검사– ovs-ofctl, iptables, tcpdump, oc adm diagnostics 명령어 등.

오픈시프트 로깅 배포하기

Logging을 배포하기 위해서 두개의 Elasticsearch Operator 와 Cluster Logging Operator를 설치해야 한다.

Elasticsearch Operator 설치

OperatorHub에서 Elasticsearch Operator를 찾아서 설치한다.

설치될 namespace를 openshift-operators-redhat 을 선택한다.

Cluster Logging Operator 설치

먼저 OperatorHub에서 Cluster Logging을 검색하여 설치한다.

설치한 후 Custom Resource Definitions 에서 ClusterLogging을 선택한다.

Instances를 선택 후, ClusterLogging을 생성한다.

기본으로 주어지는 설정을 리뷰하고 생성한다

apiVersion: "logging.openshift.io/v1"
kind: "ClusterLogging"
metadata:
  name: "instance" 
  namespace: "openshift-logging"
spec:
  managementState: "Managed"  
  logStore:
    type: "elasticsearch"  
    retentionPolicy: 
      application:
        maxAge: 1d
      infra:
        maxAge: 7d
      audit:
        maxAge: 7d
    elasticsearch:
      nodeCount: 3 
      storage:
        storageClassName: "<storage_class_name>" 
        size: 200G
      resources: 
          limits:
            memory: "16Gi"
          requests:
            memory: "16Gi"
      proxy: 
        resources:
          limits:
            memory: 256Mi
          requests:
            memory: 256Mi
      redundancyPolicy: "SingleRedundancy"
  visualization:
    type: "kibana"  
    kibana:
      replicas: 1
  collection:
    logs:
      type: "fluentd"  
      fluentd: {}

위의 항목에서 elasticsearch의 노드 수, 로그의 저장기간, 스토리지의 용량 등을 검토한 후 생성한다.

배포후의 전체 오픈시프트 로깅

설치 및 설정이 끝나고 나면 아래와 같은 아키텍처로 OpenShift Logging이 수행하게 된다. 각 노드에는 Fluentd가 DaemonSet으로 동작하고 있고 3개의 노드에 Elasticsearch가 운영되고 있다.

각 노드에서 발생하는 로그들은 fluentd에 의해서 추출되고 elasticsearch에 저장이 된다. 추출된 로그의 분석이 중요한데 다음으로 로그를 분석하는 방법에 대해서 알아본다.

오픈시프트 로그 분석

Fluentd에서 Elasticsearch로 전송된 로그는 인덱싱되고 로그 파일은 인덱스로 유지된다. Elasticsearch의 로그 데이터는 사용자 애플리케이션(app-), 클러스터 관리자 작업(infra-) 및 감사 목적(audit-*)으로 분류된다.

분류된 인덱스를 사용하여 로그를 검색할 수 있다.

필드설명
kubernetes.namespace_name: namespace프로젝트(Namespace)의 명
kubernetes.flat_labels: key=valueDeployment 또는 DeploymentConfig에서 레이블 집합 지정
message:”STRING컨테이너 STDOUT/STDERR에서 검색할 문자열 지정

아래는 몇가지 항목에 대해 조건에 맞는 로그를 검색한 화면이다.

이렇게 오픈시프트의 로깅을 구성하고, 필요한 로그들을 검색하여 조사할 수가 있다.

운영에서 로깅은 중요한 부분이다. 그래서 기존 로그 관리 시스템과의 통합이 필요한지 여부가 필요한데, 기존 인프라(Splunk 등)에서 로그 관리 시스템 및 제품의 가용성과 로그 관리 및 기존 애플리케이션(Syslog, Fluentd 등)에 대한 로그 전송 방법을 살펴봐야 할 것이다.

인프라(OCP)와 애플리케이션의 로깅 플랫폼을 분리해야 하는지 여부에 관해서는 OpenShift 인프라 로그(내부 관리자용)은 클러스터 내 OpenShift 로깅(EFK 스택) 사용하고, 애플리케이션 로그는 OpenShift Logging(Fluentd)을 사용하여 외부 로그 관리 시스템으로 전송하는 방안들이 많이 사용되고 있다. 그리고 로그를 중/장기적으로 관리하기 위해서는 외부 Object Storage를 사용하여 로그를 외부로 저장하는 방법이 널리 사용된다.

감사합니다.

참고

https://kubernetes.io/ko/docs/concepts/cluster-administration/logging/

https://docs.openshift.com/container-platform/4.10/logging/cluster-logging-exported-fields.html

답글 남기기

이메일 주소는 공개되지 않습니다.