Search
Duplicate

서비스 환경에 클러스터 구성

목차

서비스 환경에 클러스터 구성

노드의 역할

ES에서 각 노드에는 역할이 존재한다.
마스터 후보(master-eligible) 노드
마스터 후보 중에서 선거를 통해 마스터 노드가 선출된다.
클러스터를 관리하는 역할
인덱스 생성, 삭제, 어떤 샤드를 어떤 노드에 할당할지 결정
데이터 노드
실제 데이터를 가지고 있는 노드로 데이터 처리를 담당한다
인제스트(ingest) 노드
데이터가 색인되기 전 전처리를 수행하는 인제스트 파이프라인을 수행한다.
조정 노드
요청을 받아 다른노드에 분배하고 응답을 돌려주는 노드
기본적으로 모든 노드가 조정 역할을 하며, 마스터나 데이터 등 역할없이 조정만 수행하는 겨우 조정 전용 노드라 부른다.
원격 클러스터 클라이언트 노드
다른 ES 클러스터에 클라이너트로 붙을 수 있는 노드
키바나의 스택 모니터링 기능을 활용해 모니터링 전용 클러스터를 구축한 뒤 얼럿 메시지를 보내도록 구성
데이터 티어 노드
데이터 노드를 용도 및 성능별로 hot-warm-cold-frozen 티어로 구분해 저장하는 데이터 티어 구조를 선택한 경우 사용하는 역할
data 역할대신 data_content, data_hot, data_warm, data_cold, data_frozen 역할을 수행한다.

config/elasticsearch.yml 수정

클러스터를 구성할때는 설정정보를 기존 수정해줘야 한다.
이전에 개발모드로 설정했다면 더더욱 수정해야 한다.
node.roles: - master - data cluster.name: test-es node.name: test-es-node01 path.data: toPath/data path.logs: toPath/logs network.host: 127.0.0.1 network.bind_host: 0.0.0.0 http.port: 9200 transport.port: 9300-9400 xpack.security.enabled: false discovery.seed_hosts: - 10.0.0.1 - 10.0.0.2 - some-host-name.net cluster.initial_master_nodes: - test-es-node01 - test-es-node02 - test-es-node03
YAML
복사
node.roles: 노드 역할 지정. master, data, ingest 등을 0개 이상 조합해 지정한다. [] 으로 비워두면 조정 전용 노드
network.bind_host: ES에 바인딩할 네트워크 주소
transport.port: transport 통신을 위해 사용하는 포트 지정(default: 9300-9400)
transport 프로토콜은 ES 노드간 통신 프로토콜이다.
discovery.seed_hosts: 마스터 노드로 동작할 수 있는 노드 목록
cluster.initial_master_nodes: 클러스터 처음 기동시 첫 마스터 선거를 수행할 후보 노드 목록

힙 크기 설정

# JVM 이 Compressed OOPs를 사용할 수 있는지 확인하는 명령어 $ java -Xmx22528m -XX:+PrintFlagsFinal 2> /dev/null | grep UseCompressedOops # Zero-based Compressed OOPs를 적용할 수 있는 경계값 확인 명령어 $ java -XX:+UnlockDiagnosticVMOptions -Xlog:gc+heap+coops=debug -Xmx22528m -version
Bash
복사
힙 크기는 기본적으로는 시스템 메모리의 절반 이하로 지정해야 한다.
32GB 이상 지정하지 않도록 해야 한다.
JVM이 힙 영역에 생성된 객체에 접근하는 포인터(Ordinary Object Pointer, OOP)는 메모리 주소를 직접 가르킨다.
32 비트 환경에선 포인트 한개를 1개를 32비트로 표현하는데 4GB 까지의 힙 영역 사용이 가능하다.
32 GB 이내의 힙 영역에만 접근할 경우 Compressed OOPs(Ordinary Object Pointers)라는 기능으로 포인터를 32비트로 유지할 수 있다.
자바는 힙 영역에 저장하는 객체를 8바이트 단위로 정렬해 할당하기에 객체 간 주소는 항상 8바이트의 배수만큼 차이가 난다. 그래서 포인터가 메모리의 주소를 직접 가르키도록 하는게 아니라 객체의 상대적인 위치 차이를 나타내도록 하면 포인터의 1비트가 1바이트 단위의 메모리 주소가 아니라 8바이트 단위의 메모리 주소를 가르키도록 할 수 있다. 그래서 포인터는 4gb가 아닌 8배인 32gb까지 힙 메모리 사용이 가능하다.

참고: Zero-based Compressed OOPs

: Compressed OOPs로 인코딩된 주소를 실제 주소로 디코딩하려면 3비트 시프트 연산 후 힙 영역이 시작되는 기본 주소를 더하는 작업이 필요하다. 여기서 기본 주소를 0으로바꿔줄 수 있다면 시프트 연산을 제외한 과정을 없앨 수 있는데, 이런 기능을 Zero-based Compressed OOPs라 한다.

스와핑은 사용하지 말아라.

ES에선 스와핑을 사용하지 말라고 강력하게 말한다.
스와핑은 성능과 노드 안정성을 많이 떨어트리고, ms단위로 끝날 GC도 분 단위로 걸리게 만든다.
# 스와핑 완전히 끄기 - OS 재부팅시 효과가 사라진다. $ sudo swapoff -a # 스와핑 완전히 끄기위해 설정 파일 열기 - OS 재부팅 이후에도 효과 유지 $ sudo vim /etc/fstab # 스와핑 설정 주석 처리 스크립트 $ sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
Bash
복사

클러스터 구성 전략

1. 마스터 후보 노드와 데이터 노드 분리

클러스터 환경에서 마스터 후보노드와 데이터 노드는 분리되어야 한다.
데이터 노드가 죽는건 마스터 노드에 의해 복구될 수 있는 작은 문제지만 마스터 노드가 죽는건 큰 문제다.
마스터 후보 노드는 성능이 낮은 서버를 사용해도 괜찮다.
데이터 노드는 좋은 장비에 할당하는게 좋다.

2. 마스터 후보 노드와 투표 구성원

마스터 노드는 투표에 의해 선출된다.
투표 구성원(voting configuration)은 마스터 후보 노드중 일부 혹은 전체로 구성된 부분 집합으로 마스터 선출이나 클러스터 상태 저장 등의 의사 결정에 참여한다.
ES는 마스터 후보 노드가 클러스터에 참여 혹은 떠날 경우 투표 구성원을 자동 조정한다.
마스터 후보 노드는 짝수가 아닌 홀수대를 준비하는게 비용 대비 효용성이 좋다.
어짜피 짝수로준비해도 ES에서 투표 구성원을 홀수로 유지하기 위해 후보 노드를 하나 빼 둔다.

3. 서버 자원이 많지 않은 경우

마스터 후보 노드 3대, 데이터 노드 3대 정도는 있어야 기본적인 고가용성을 제공할 수 있다.
하지만 서버 자원이 많지 않아 이런 구성이 힘들 경우 겸임을 시킬 수 밖에 없다.
최소한의 서버 자원으로 ES Cluster를 구성한다면 3대의 노드가 모두 마스터 후보 및 데이터 역할을 겸임하는 구성이된다.
즉 최소 3대의 장비는 지원되야 한다.
만약 저사양의 4~5대의 장비가 있는 경우에는
3대: 마스터 후보 + 데이터 역할 겸임
1~2대: 데이터 노드 전용
만약 고사양의 4~5대의 장비가 있는 경우에는
같은 비용으로 사양이 낮은 장비 3대 + 사양이 높은 장비 3~4대 구성으로 변경가능한지 확인
변경이 가능하다면 3 / 3 으로 분리하고 불가능하다면 저사양 4~5대와 동일하게 지정한다.

4. 조정 전용 노드

안정적인 클러스터 운영을 위해서는 조정 전용 노드를 두는 것이 좋다.
보통 키바나를 연동하며 문제가 발생하게 되는데 키바나가 조정 전용 노드만을 바라보게 설정해서 문제를 최소화 하자.
서버 자원에 더 여유가 있따면 읽기전용/쓰기전용 조정 노드를 분리하는것도 좋다.

5. 한 서버에 여러 프로세스 띄우기

마스터 후보 노드는 다중 프로세스 대상으로 고려하지 말아야한다. 클러스터 안정성이 크게 떨어진다.
데이터 노드가 다중 프로세스 대상이 될 수 있다.
각 프로세스가 독립적인 http, transport, path.logs, path.data를 가져야 한다.
프로세스 기동을 위해 반드시 cluster.routing.allocation.same_shard.host: true 설정을 지정해야 한다.
샤드 할당 시 같은 샤드의 주 샤드와 복제본 샤드가 한 서버에 몰리지 않게 조정해주는 설정
같은 서버 확인 기준은 호스트 이름과 주소다
CPU 자원이 충분한지 확인해야 한다.
node.processors 설정을 통해 수동으로 값을 지정할 필요 있음.
file descriptor, mmap max_map_count, 네트워크 대역폭 자원도 공유된다.

보안 기능 적용

별도의 설정을 하지 않을 경우 Client <-> ES Cluaster <-> ES Node간의 통신은 암호화되지 않는다.
xpack.security.enabled 설정으로 보안 정책들을 ES Cluaster에 적용할 수 있다.
true로 설정하며 클러스터 최초 기동시 ES가 자동으로 보안 설정을 지정해줄 수도 있다.

1. 보안 기능 적용 하지 않은 상태

xpack.security.enabled 설정을 false로 할 경우 ES 보안 기능이 적용되지 않는다.
다음과 같은 조건 하에 보안 기능 적용이 되지 않은 상태로도 서비스가 가능하다.
인터넷과 인트라넷이 명확하게 분리되어 있다.
서비스와 데이터가 외부에 노출될 수 없다.
법적인 이슈가 없는 데이터만을 다룬다.
접근하는 사용자와 클라이언트를 명확하게 제어할 수 있따.

2. TLS 부트스트랩 체크

ES Cluaster는 기동 과정에서 노드 간 transport 통신에 TLS 적용이 되지 않았다면 기동이 되지 않는다.
discovery.type을 single-node로 지정하거나 xpack.security.enabled 설정을 false로 할 경우 TLS 부트스트랩 체크를 하지 않는다.
노드간 TLS 통신을 먼저 적용하고 클러스터를 가동한 뒤 내부 계정 초기화 작업을 수행해야 한다.

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

현재 책 및 공식문서에서 제공하는 자동 보안설정 모두 인증키가 제대로생성되지 않아서 생략
별도의 보안 설정이 되지 않았을 경우 수행된다.
전용 CA(Certificate Authority)를 생성하고, CA로 서명된 인증서를 자동 발급한다.
HTTP 레이어에 TLS 통신을 적용한다.
ES 계정의 비밀번호를 초기화한다.
클러스터에 합류하는 노드에도 인증서를 복사하며 자동으로 설정을 넣는다.
키바나에도 필요한 CA 파일을 복사하고 설정을 자동으로 기입한다.
수동설정보단 편하지만 그래도 과정은 길고 복잡하다.

3-1 TLS 부트스트랩 체크를 피해 최초 기동

node.roles: - master - data cluster.name: test-es node.name: test-es-node01 path.data: toPath/data path.logs: toPath/logs network.host: 127.0.0.1 network.bind_host: 0.0.0.0 discovery.seed_hosts: - 10.0.0.1 - 10.0.0.2 - some-host-name.net discovery.type: single-node
YAML
복사
TLS 부트스트랩 체크를 회피하기 위해 개발 모드처럼 설정하고, 보안 설정이나 클러스터 설정들은 주석처리해야 한다.

4. 수동으로 ES Node간 통신에 TLS 적용

1.
CA와 self-signed 인증서 생성
YAML
복사

당장 직접 클러스터 구성을하고 설정파일등을 건드려 설치할 일은 없기에 당장은 생략

Docker-Compose를 이용한 ES Cluster 구성하기

Docker가 설치되어있지 않다면 도커 사이트에서 도커 설치를 해준다.
ES 8.0 이상 기준 스크립트로 8.x 이하이거나 차후 9.x 대에서는 적용되지 않을 확률이 높다.
.env
elastic-docker-tls.yml