본문 바로가기
Kubernetes

Kubernetes환경에서 Filebeat + ELK를 활용한 Log Pipeline 구축 #1 Elasticsearch편

by beann 2025. 3. 10.

ELK란 Elastic Search + Logstash + Kibana를 합친 용어로, 각각의 도구별로 용도가 달라 조합하여 사용하기 때문에 합쳐서 부르는 경우가 많다.

 

"Logstash의 경우에도 file플러그인을 통해 직접 로그파일을 읽어서 수집할 수 있지만, 무겁고 리소스를 많이 사용하기 때문에 비효율적이다.

따라서 위와 같이 Filebeat같은 경량형 로그수집 도구를 이용해 로그를 수집하고 Logstash로 전달한 다음, Logstash에서 filter를 이용해 변환 및 재가공을 진행하고 Elasticsearch에 로그를 저장한다음 인덱싱하여 Kibana를 통해 대쉬보드로 로그를 검색 및 가시화한다"라고 일반적으로 알려져 있다.

 

다 무슨말인지 이해 했지만 Elasticsearch에서 로그를 저장하는 것 까지는 알겠는데 인덱싱 한다는건 무슨말일까? 어떻게 인덱싱을 한다는건지?

 

일반적으로 Elasticsearch의 경우 Json형식으로 변환된 Log를 전달받아 Elasticsearch가 데이터를 색인하기에 최적화 할 수 있도록 자신만의 방식으로 형식을 변환하는데 그게 Document방식이라고 한다.

 

그럼 JSON과 Document 방식의 차이는 뭘까?

 

Elasticsearch에 대해 알아보자

 

 

# Elasticsearch의 데이터 저장 방식


 

## 아래는 JSON 방식이다

JSON은 우리가 흔히 아는 Key:Value형태로 따로 검색기능은 없으며, 만약 특정 데이터를 조회하려면 전체 데이터를 불러와서 필터링 해야한다

 

# JSON 데이터에서 특정 값 찾기 (Python 예제)
data = [
    {"name": "Alice", "age": 25},
    {"name": "Bob", "age": 30}
]

# name이 "Alice"인 데이터 찾기
result = [item for item in data if item["name"] == "Alice"]
print(result)

 

 

## 아래는 Elasticsearch에서 사용하는 Document방식이다.

Elasticsearch의 경우 아래와 같이 JSON과는 다르게 _index, _type, _id 등의 메타데이터가 추가된다

아래 Document 예시처럼 _source 메타데이터에는 JSON과 유사하게 Key:Value형태로 실제 사용자가 저장한 데이터가 저장되며,

_search 쿼리를 통해 전체 인덱스를 검색해 원하고자 하는 데이터를 조회할 수 있다.

 

물론 예시엔 없지만 _source 쿼리를 통해 특정 필드만 검색할 수도 있다.

# Elasticsearch Document 예시
{
  "_index": "users",
  "_type": "_doc",
  "_id": "123",
  "_version": 1,
  "_source": {
    "name": "Alice",
    "age": 25,
    "email": "alice@example.com"
  }
}


# Elasticsearch의 전체 Index 중에서 "name"이 "Alice"인 문서를 검색(_search 메타데이터를 활용하면 전체 인덱스를 검색)
GET users/_search
{
  "query": {
    "match": { "name": "Alice" }
  }
}

# 실행결과 예시
{
  "hits": {
    "total": 1,
    "hits": [
      {
        "_index": "users",
        "_id": "123",
        "_source": { "name": "Alice", "age": 25, "email": "alice@example.com" }
      }
    ]
  }
}

 

즉, 쉽게 생각하면 Elasticsearch는 검색 가능한 JSON이며, Rest API를 통해 데이터 조회가 가능한 데이터베이스라고 봐도 될 것 같다.

 

# Elasticsearch의 구성요소


역할(Role)  설명
Master 클러스터 관리, 노드 추가/제거, 샤드 할당 관리
Data 실제 데이터를 저장하고 검색 요청을 처리
Ingest Document로 저장되기 전에 데이터를 추가적인 변환 및 전처리 (Ingest Pipeline기능 이라고도 함)
Coordinator 클라이언트한테서 검색 및 인덱싱 요청을 받아 Data 노드로 라우팅 , API Gateway 비슷한 역할을

구성요소별로 각각의 역할이 있으나, 필수는 아니며 Master Node 단일 노드로 구축도 할 수 있다.

다만, Master Node가 모든 역할을 담당하기 때문에 많은 검색 요청이 발생할 시 부하로 인해 느려질 수 있는 단점이 있다.

 

 

# Kubernetes환경에서 Elasticsearch 설치 전 고려사항


먼저, Kubernetes환경에서 Elasticsearch를 설치하기 전 아래와 같은 사항들이 고려 되어야 한다.

 

1. 배포 방식

배포 방식은 아래와 같이 3가지로 추릴수 있을 것 같다.

  1. Helm Chart를 통한 배포
  2. ECK(Elastic Cloud on Cloud Kubernetes)
    1. Elastic에서 제공하는 Kubernets Operator를 통한 배포(관리형이라 보면 된다.) 
  3. Yaml 직접배포 
    1. Statefulset 또는 Deployment를 통한 배포

Helm, ECK모두 배포하기엔 편하고 관리가 쉽겠지만 세부적인 수정 및 제어가 어려운 반면, yaml을 통한 직접 배포 방식의 경우 세부적인 설정이 가능하긴 하지만, Manifest관리가 어려울 수 있을 것 같다.

 

 

2. 배포 방식에 따른 데이터 저장 방식

Deployment, Statefulset에 따라 PV활용 방식이 달라질 수 있다.

일단 Elasticsearch의 경우 볼륨은 높은 I/O에대한 요구사항 때문에 Blockstorage를 사용하도록 권장 되는데 BlockStorage를 통해 PV를 생성 한다면 해당 노드에만 Pod가 반드시 배치되어야 한다는 단점이 있고, 해당 단점을 보완하고자 한다면 각 노드별로 Blocstorage를 할당 해놓아야 하는데 이렇게 되면 Pod가 만약 다른 노드로 재배치 된다면 기존 스토리지는 사용하지 못하게 된다.

 

 

그래서, Deployment로 배포하게 될 경우 각 Pod별로 자신의 노드에 Blockstorage Pod별로 PV를 공유하여 사용하게 될텐데, 이렇게 될경우 데이터 중복에 대한 우려가 있고, 기본적으로 Elasticsearch는 동시쓰기가 불가능해 Pod간 같은 볼륨을 공유하지 못하도록 되어있다.

 

즉, Elasticsearch는 DB처럼 Statefulset + RWO로 배포하여 Pod별로 독립적인 PV를 가지고 stateful하게 운영하는 것을 공식적으로 추천한다고 한다.

 

 

3. Mster 단일노드로 갈지, 컴포넌트들 별로 노드를 구성하여 클러스터 형태로 구축할지

Elasticsearch의 경우 위 구성요소에서 나열한 것처럼 Master, Ingester, Data, Coordinator 노드들을 구성할 수가 있다.

모두다 반드시 구성이 필요한 것들은 아니고, Master 단일노드로도 구성할 수는 있다.

 

다만, 각 요소별 역할들이 있는것 처럼 모든 역할을 Master Node가 하게 되면 부하를 혼자 감당해야 하기에 순간적으로 검색이 많아지는

경우 시스템 다운 또는 노드 다운이 발생할 수 있고, 이렇게 되면 운영환경의 경우 큰 장애로 확대될 수 있다.

 

개발/테스트환경 또는 데이터 저장이 중요하지 않은 환경이라면 단일노드로 구축하여 빠르고 쉽게 설치하는 것이 좋겠고,

운영환경이라면 데이터에 대한 추가전인 변환 및 전처리가 필요하지 않은 경우 Ingester는 제외하더라도, Master, Data, Coordinator 정도는 구축하는 것이 좋겠다.