본문 바로가기
ElasticSearch

엘라스틱서치 클러스터 구성

by Salt-Fn 2024. 7. 25.

엘라스틱서치를 공부하고 클러스터를 구성해 봤다. 책을 참고하며 진행하였는데 쉽지 않았다.

1. 노드 설정과 노드 역할

클러스터 구성 전 엘라스틱서치의 노드 역할에 대해 알아보자.

  1. 마스터 후보 : 노드의 역할에 master를 지정하면 해당 노드는 마스터 후보 노드가 된다. 마스터 후보 노드 중 선거를 통해 마스터 노드가 선출된다.
    • 클러스터 상태 관리 : 클러스터의 상태(노드 추가/제거, 인덱스 생성/삭제 등)를 관리
    • 인덱스 생성 및 삭제 : 인덱스 생성 및 삭제 담당
    • 샤드 할당 :샤드를 클러스터 내 데이터 노드에 할당
  2. 데이터 노드 : 실제 데이터를 들고 있는 노드다. CRUD, 검색, 집계와 같이 데이터와 관련된 작업을 수행한다.
    • 데이터 저장 : 실제 데이터(문서)를 저장, 샤드를 보유
    • CRUD 작업 : 데이터 노드는 문서의 생성(create), 읽기(read), 업데이트(update), 삭제(delete) 작업 처리
    • 검색 및 집계 : 데이터 노드는 검색 쿼리 및 집계 실행
  3. 인제스트 노드 : 데이터가 색인되기 전 전처리를 수행하는 인제스트 파이프라인을 수행하는 노드 
    • 데이터 처리 파이프라인 관리 : 데이터가 색인되기 전 변환 및 처리(파이프라인 처리)를 수행
    • 데이터 변환 및 정제 : 데이터 정제, 필터링, 추가적인 필드 생성 등의 작업 수행
  4. 조정 노드 (클라이언트 노드/코디네이팅 노드) : 클라이언트의 요청을 받아서 다른 노드에 요청을 분배하고 클라이언트에게 최종 응답을 돌려줌
    • 요청 라우팅 : 사용자의 요청을 받아 적절한 노드에 분배
    • 쿼리 조정 : 검색 쿼리와 집계 요청을 조정하고 최정화 된 방식으로 분배
    • 결과 병합 : 여러 데이터 노드에서 온 검색 결과를 병합하여 최종 결과 반환
  5. 원격 클러스터 클라이언트 노드 : 다른 엘라스틱서치 클러스터에 클라이언트로 붙을 수 있는 노드. 노드 역할에 remote_cluster_clinet를 추가해 지정
    • 원격 클러스터 통신 : 원격 클러스터와의 통신을 최적화
    • 원격 작업 관리 : 로컬 클러스터에서 원격 클러스터로의 검색 및 인덱스 작업 관리
    • 모니터링 : 키바나의 스택 모니터링 기능을 활용해 모니터링 전용 클러스터를 구축 후 얼럿 메시지를 보내도로 구성 가능
  6. 데이터 티어 노드 : 데이터 노드를 용도 및 성능별로 hot-warm-cold-frozen 티어로 구분해 저장하는 데이터 티어 구조. data 역할 대신 data_content, data_hot, data_warm, data_cold, data_frozen 역할을 선택.
    • hot data node :
      • 최신 데이터 저장 : 자주 액세스 되는 최신 데이터 저장
      • 신속한 읽기/쓰기 처리 : 높은 성능 요구 사항 충족
    • warm data node :
      • 빈도가 낮아진 데이터 저장 : 덜 빈번하게 액세스되는 데이터 저장
      • 효율적 자원 사용 : 비교적 낮은 성능 요구 사항 충족
    • cold data node :
      • 오래된 데이터 저장 : 거의 사용하지 안흔 오래된 데이터 저장
      • 저비용 스토리지 사용 : 낮은 성능 요구 사항으로 비용 절감
    • frozen data node :
      • 아카이브 데이터 저장 : 매우 드물게 접근되는 데이터를 저비용 스토리지에 저장
      • 최소한의 성능
    • 트랜스폼 노드
      • 데이터 변환 및 집계 : 데이터를 실시간으로 변환하고 집계
      • 데이터 재구조화 : 특정 요구사항에 맞게 데이터를 요약하거나 재구조화

2.1 클러스터 구성

클러스터를 구성하며 사용했던 엘라스틱서치 버전은 8.14.3, java버전은 17이다. 보안 기능 적용까지 할 예정이다.

2.1.1 TLS 부트스트랩 체크

엘라스틱서치 클러스터는 기동 과정에서 노드간 transport 통신에 TLS를 적용하지 않았다면 기동을 거부한다. 단, discovery.tpye을 single-node로 지정해서 개발 모드로 띄우거나 xpack.security.enabled를 false로 지정했다면 TLS 부트스트랩 체크를 건너뛴다.

 

2.1.2 클러스터 최초 기동 시 자동 보안 설정

엘라스틱서치 8버전 부터는 자동 보안 설정이 가능하다. 자동 보안 설정 기능은 클러스터 최초 기동 시 다른 보안 설정이 지정되지 않았을 때 수행된다. 전용 CA(Certificate Authority)를 생성하고, 그 CA로 서명된 인증서를 자동 발급한다. 노드 간 transport 레이어와 REST API에 사용하는 HTTP 레이어에 TLS 통신을 적용한다. 이후 클러스터에 합류하는 노드에도 인증서를 복사하며 자동으로 설정을 기입한다.

키바나에도 필요한 CA 파일을 복사하고 설정을 자동으로 기입한다.

 

https://www.elastic.co/guide/en/elasticsearch/reference/current/install-elasticsearch.html 해당 링크에서 본인 os에 맞는 엘라스틱서치를 다운로드한다.

 

클러스터 구성은, 마스터 ・ 데이터 노드, 2개의 데이터 노드, 조정 노드로 구성할 계획이다. 결국은 총 4개의 엘라스틱서치 프로세스를 띄우게 된다.

 

1. 먼저 인증서를 자동 생성하기 위해 클러스터를 최초 가동할 필요가 있다. 다운로드한 폴더 안에 config/elasticsearch.yml을 수정한다. 예시는 마스터 ・ 데이터 노드의 설정이다. 초기 가동을 위해 master와 data의 역할을 주었고 추후 data 노드의 역할은 제거할 예정이다. 

node.roles: [master, data]
cluster.name: dev-es
node.name: node-master
path.data: /path/to/your/data
path.logs :/path/to/your/logs
network.host: 127.0.0.1
network.bind_host: 0.0.0.0
http.port: 9200
discovery.seed_hosts: ["127.0.0.1:9300"]
discovery.type: "single-node"

 

  • node.roles : 노드 역할을 지정하는 설정. master, data, ingest 등 0개 이상 조합해 지정. []와 같이 비워 두면 조정 전용 노드가 된다.
  • cluster.name : 클러스터 이름을 지정. 클러스터에 합류시킬 모든 노드에 같은 이름이 지정되어야 한다.
  • node.name : 노드 이름을 지정한다. 노드마다 이름이 달라야 한다.
  • discovery.seed_host : 마스터 노드로 동작할 수 있는 노드 목록을 지정한다. 클러스터 내에서는 trasnport 레이어를 이용해 통신하므로 9300번 포트(기본값, 변경가능)를 이용한다.
  • cluster.initial_master_nodes : 클러스터를 처음 기동할 때 첫 마스터 선거를 수행할 후보 노드 목록 지정. 이 값은 node.name에 기입한 값이어야 한다.
  • network.bind_host, network.pulish_host : 엘라스틱서치에 바인딩할 네트워크 지정. 클러스터의 다른 노드에게 자신을 알릴 때 쓰는 주소 지정. 두 값은 network.host에 지정한 값을 따른다. 일반적으로는 network.host 하나만 설정하면 되지만 네트워크 인터페이스가 여러 개 거나 L4 등이 배치된 구성이라면 바인딩될 호스트를 따로 지정해야 할 수 있다.
  • http.port : HTTP 통신을 위해 사용하는 포트 지정. 기본값은 9200-9300. 범위를 지정할 경우 범위 내 선점되지 않은 포트 중 가장 앞쪽 포트 사용.
  • transport.port : transport 통신을 위해 사용하는 포트 지정. 기본값은 9300-9400. 엘라스틱서치 노드 사이의 내부 통신에 사용되는 프로토콜. 일부는 HTTP 통신을 하기도 한다.

master 노드의 경우 메모리가 크지 않아도 되므로 메모리 제한을 2048m로 설정했다. 설치한 디렉터리에 config/jvm.options.d/ 디렉터리에 heap-size.options 이름으로 파일을 생성한다. 파일에 아래와 같이 작성 후 저장한다.

-Xms2048m
-Xmx2048m

힙 크기와 관련해서는 추후 따로 포스팅하겠다.

 

위와 같이 모든 설정을 끝낸 후 엘라스틱서치 서버를 기동 한다.

위와 같은 메시지가 나왔다면 자동 설정이 수행된 것이다. 위 메시지를 복사하고 프로세스를 종료한다. 여기서 발급된 enrollment 토큰을 클러스터에 새 노드를 합류시키거나 키바나를 기동 하는 데 사용한다. 프로세스 종료 후 config디렉터리를 확인해 보면 certs 디렉터리가 생성된 것을 볼 수 있다. 그리고 config/elasticsearch.yml을 확인해 보면 자동으로 추가된 부분 또한 확인할 수 있다.

xpack.security.enrollment.enabled 설정은 enrollment 토큰을 발행하고 이를 이용해 클러스터에 노드를 추가하거나 키바나를 붙이는 작업을 허용할지 지정하는 설정이다.

 

elasticsearch.yml에 discovery.type: "single-node"를 지우고 재실행한다. 이제 TLS 부트스트랩 체크에 걸리지 않는다.

 

다음으로는 데이터 노드의 설정이다. 데이터 노드로 이용할 엘라틱서치 디렉터리의 config/elasticsearch.yml의 파일을 수정한다.

node.roles: [data]
cluster.name: dev-es
node.name: node-data1
path.data: /path/to/your/data
path.logs :/path/to/your/logs
network.host: 127.0.0.1
network.bind_host: 0.0.0.0
http.port: 9201

합류시킬 노드의 경우 discovery.seed_host를 작성하지 않는다.

 

데이터 노드의 경우 문서 색인, CRUD 등 많은 데이터 처리를 하므로 메모리 크기를 크게 준다. /config/jvm.options.d 경로에 heap-size.options 파일을 생성한다

-Xms4096m
-Xmx4096m

위와 같이 설정이 끝났다면 첫 마스터 노드 실행 시 발급받았던 enrollment token을 이용하여 서버를 기동 한다

bin/elasticsearch --enrollment-token
eyJ2ZXIiOiI4LjE0LjAiLCJhZHIiOlsiMTI3LjAuMC4xOjkyMDAiXSwiZmdyIjoiMjYyNWQ0MmZiZjhjY2I4OTRhZTU0NzM3MGU2MDU1OGRmNjg2OWY2NzgzNzcyMDc2NzZiYjQ3NDc5YzJmMThjNCIsImtleSI6IlhZUm82WkFCeW85NkozcWRqajNjOjR2dEY1OHRxVEUtWXVma2tBV19CWVEifQ==

마스터 후보 노드가 추가로 있다면 마스터 후보 노드부터 먼저 합류시키는 편이 좋다.

 

만약 enrollment token을 잃어버렸다면 "bin/elasticsearch-create-enrollment-token -s node" 명령어를 이용해 재발급할 수 있다. 노드가 가동중일 때 명령어를 실행해야 한다.

 

노드 실행 후 elasticsearch.yml을 보면 보안 관련 설정이 추가된 것을 확인할 수 있고 discovery.seed_host 또한 적혀있는 것을 볼 수 있다.

 

두 번째 데이터 노드 또한 같은 방법으로 합류시킨다. 조정 전용 노드의 경우 node.roles: [], heap size 2048m으로 바꾸고 이 외에는 동일하다.

 

추가한 노드들의 config/certs가 생성된 것을 볼 수 있고 config/elasticsearch.yml에 자동으로 보안 설정이 지정된 것 또한 확인할 수 있다.

 

마지막으로 초기 생성된 최고 관리자 계정의 초기 비밀번호를 설정한다

bin/elasticsearch-reset-password --interactive -u elastic
  • enrollment 토큰으로 키바나 가동

이제 키바나를 붙여보자.

https://www.elastic.co/kr/downloads/kibana 사이트에서 본인 os에 맞는 kibana를 다운한다. 그리고 다음과 같은 명령어로 enrollment 토큰을 발급받는다.

bin/elasticsearch-create-enrollment-token -s kibana

키바나 시작 전 config/kibana.yml의 설정을 확인한다.

server.port: 5601
server.host: "127.0.0.1"
server.publicBaseUrl: "http://127.0.0.1:5601"

5601 포트는 kibana의 기본 포트이다. enrollment로 기동을 위해서는 elasticsearch.hosts를 지정하지 않아야 한다.

설정을 마쳤다면 기동 해보자.

bin/kibana

실행을 하면 다음과 같은 화면이 출력된다.

해당 링크로 접속한다.

링크로 들어가면 다음과 같은 화면이 나오는데 여기에 아까 발급받은 토큰을 넣고 Configure Elastic을 누르면 자동으로 키바나 설정이 진행된다.

여기서 Username은 elastic, Password는 아까 재설정한 비밀번호를 넣는다. 키바나 home이 나온다면 모든 자동 보안 설정이 종료되었다.

 

키바나가 설치된 곳의 data 디렉터리 밑에 복제된 CA 파일을 확인할 수 있고, kibana.yml 설정파일에도 elasticsearch.hosts 등 자동으로 추가된 설정을 확인할 수 있다.

  • 추가 작업

자동 보안 설정 후 의도한 상활에 맞게 정리를 할 필요가 있다. 마스터 노드, 데이터 노드 1 2의 elasticsearch.yml을 보면 discovery.seed_hosts 설정을 마스터 후보노드들을 정확히 가리키도록 변경한다. node.roles 또한 다르게 지정한 곳이 있다면 변경한다. kibana의 경우 조정 전용 노드와 통신을 해야 하므로 kibana.yml의 elasticsearch.hosts를 수정해 재기동한다.

 

만약 node.roles[master, data] 에서 data 제거 후 에러가 발생할 경우 bin/elasticsearch-node repurpose 를 실행 후 재기동한다.

 

최종적으로 완성된 클러스터의 모습이다.

 

키바나와 브라우저 사이에 TLS 적용 또한 가능하다. 하지만 현재 공인 CA를 가지고 있지 않아 이 부분은 추후 다시 글을 작성해 보겠다.

 

마스터 노드의 경우 보통 3대 이상으로 구성해서 고가용성을 구현해 준다. 하지만 현재 클러스터를 로컬에 직접 실행하고 있어 노드에 할당해 줄 수 있는 메모리에 제한이 있다. 그래서 마스터 노드를 하나만 하였지만 여유가 있는 사람은 마스터 노드를 3개 만들어 클러스터를 구축하고 마스터 노드를 하나 멈추어 다른 마스터 노드가 선출되는 과정을 직접 해보는 것도 좋을 것 같다.

 

다음 포스트에서는 완성된 엘라스틱서치 클러스터, 키바나와 통신하기 위해 spring boot 환경에서 설정하고 색인하는 작업을 해보겠다.