본문 바로가기
K8S

Vector + Scalable Loki

by HH_g 2024. 12. 22.

reference

https://grafana.com/docs/loki/latest/setup/install/helm/install-scalable/

 

 

Vector는 Loki 에 로그르 전송하고, 로키는 데이터를 수집, 저장, 쿼리할 수 있는 분산 환경을 쿠버네티스에 올리려고 합니다.

 

벡터는 쿠버네티스 파드의 로그를 수집하고, 수집된 로그는 로키로 전송됩니다.

로키는 로그를 저장소에 저장하고, 그라파나를 통해 시각화합니다.

 

 

헬름 차트를 활용하여 각각의 설정을 해줍니다.

 

1. 로키 설정 (Simple Scalable Mode)

replicaCount: 3

auth_enabled: false

loki:
  config:
    auth_enabled: true
    schema_config:
      configs:
      - from: 2024-01-01
        store: tsdb
        object_store: s3
        schema: v13
        index:
          prefix: loki_index_
          period: 24h
    storage_config:
      aws:
        s3: s3://your-bucket-name
        region: ap-northeast-2
      boltdb_shipper:
        shared_store: s3
        active_index_directory: /loki/index
    limits_config:
      max_streams_per_user: 1000
      max_global_streams_per_user: 5000
      ingestion_rate_mb: 10
      ingestion_burst_size_mb: 20

ingester:
  replicas: 2
  lifecycler:
    ring:
      kvstore:
        store: memberlist
      replication_factor: 3

distributor:
  replicas: 2

queryFrontend:
  replicas: 2

compactor:
  replicas: 1

gateway:
  enabled: true
  replicas: 1

resources:
  limits:
    cpu: "1"
    memory: "1Gi"
  requests:
    cpu: "0.5"
    memory: "512Mi"

 

 

2. Vector 설정

 

벡터는 로키에 로그를 전송하기 위한 구성 파일이 필요합니다.

Configmap으로 구성할 수 있습니다.

apiVersion: v1
kind: ConfigMap
metadata:
  name: vector-config
  namespace: logging
data:
  vector.toml: |
    [sources.kubernetes_logs]
    type = "kubernetes_logs"

    [transforms.filter]
    inputs = ["kubernetes_logs"]
    type = "filter"
    condition = "true"

    [sinks.loki]
    inputs = ["filter"]
    type = "loki"
    endpoint = "http://loki-gateway.loki.svc.cluster.local:3100"
    labels = { job = "kubernetes_logs", namespace = "{{ namespace }}" }

엔드포인트가 loki-gateway 서비스 인 점을 주목해주세요.

 

 

.loki scalable 버전을 헬름으로 설치해보면 read, write, backend, gateway 등등 다양한 컴포넌트들이 생기는 것을 확인할 수 있습니다.

이 중 loki gateway는 단순한 엔드포인트 역할을 합니다.

단일 진입점을 제공하여 외부 클라이언트(vector, grafana 등)이 Distributor, Querier, Ingester 와 직접 통신하지 않도록 보호합니다.

이를 통해 클라이언트는 로키의 내부 구조를 알 필요 없이 게이트웨이로 요청을 보냅니다.

게이트웨이는 요청을 올바른 백엔드 컴포넌트로 라우팅합니다.

 

Gateway는 요청(read/write)를 로키의 내부 구성 요소로 적절히 라우팅합니다.

- write -> Distributor

- read -> Querier

 

이 외에 

- loki-chunks-cache

로키는 쿼리 성능을 최적화하기 위해 로그 데이터를 Chunk(압축된 로그 블록) 단위로 캐싱합니다.

Chunk Cache 는 읽기 요청(Querier)을 처리할 때 사용됩니다.

 

- loki-gateway

- loki-results-cache

LogQL 쿼리 결과를 캐싱하여 동일한 쿼리 요청이 반복될 경우, 속도를 높이고 비용을 절감

 

- loki-backend(ingester)

로그 데이터를 받아서 처리하고, s3에 압축해서 저장.

 

- loki-canary

로키 클러스터의 상태를 주기적으로 테스트.

쓰기 및 읽기 경로가 제대로 작동하는지 확인하기 위해 샘플 데이터를 보내고, 이를 읽어봄.

카나리는 주로 상태 확인용

 

- loki-read (Querier)

클라이언트로부터 읽기 요청을 처리함

인덱스 데이터를 조회하고, 필요하면 ingester 에서 데이터를 읽어옴

 

- loki-write (Distributor)

로그 데이터를 수신하고 적절한 Ingester 로 데이터를 분배

데이터가 특정 Ingester 에 저장되도록 보장

 

 

컴포넌트 역할

Distributor loki-write 로그 데이터를 수신하고 Ingester로 분배 (Consistent Hashing 사용).
Ingester loki-backend 로그 데이터를 메모리에 임시 저장하고, 청크 단위로 Object Storage에 플러시.
Query Frontend   읽기 요청을 최적화 (병렬 처리 및 캐싱).
Querier loki-read 저장된 로그 데이터를 Ingester 또는 Object Storage에서 조회.
Object Storage   영구 저장소. 청크(로그 데이터)와 인덱스(메타데이터)를 저장.
Memcache   쿼리 성능을 최적화하기 위해 결과, 인덱스, 청크를 캐싱.

 

로키 동작 흐름

쓰기 요청

클라이언트 → Distributor → Ingester → Object Storage

1. 클라이언트(벡터) 가 로그 데이터를 loki-gateway로 보냄

2. Gateway 는 데이터를 Distributor(loki-write) 로 전달

3. Distributor 는 데이터를 적절한 Ingester(loki-backend) 로 분배

4. Ingester 는 데이터를 처리하고 저장소에 저장

 

읽기 요청

클라이언트 → Query Frontend → Querier → Ingester/Object Storage

1. 클라이언트(Grafana) 가 LogQL 쿼리를 loki-gateway 로 보냄

2. 게이트웨이는 요청을 querier (loki-read) 로 전달

3. Querier 는 데이터를 Chunk Cache (loki-chunks-cache) 에서 조회하거나 Ingester 및 저장소에서 가져옴

4. Query Frontend(loki-results-cache) 가 결과를 캐싱

'K8S' 카테고리의 다른 글

Headless Service  (0) 2024.12.08
쿠버네티스 내부에서는 어떻게 DNS 질의를 할까?  (1) 2024.10.10