보통 elasticsearch의 클러스터의 노드들을 같은 LAN 안에서 (하나의 AWS 계정에서) 구성하는 예제들이 많았는데, 나는 개발 환경 상 세 노드를 각기 다른 LAN에서 구동해 클러스터를 구성해보았다.
elasticsearch-8.8.1 기준이며, 설치 과정은 생략. + 운영 환경에서의 리눅스 설정(file descriptor / number of threads / virtual memory) 생략
elasticsearch를 학습하기 위해 클러스터를 구성하였다. 구성 컴퓨팅 환경은 다음과 같다.
클러스터 1 - 노드 3
WSL2
한 대와 AWS EC2
두 대 (세 인스턴스 모두 다른 public IP)
- name : es-cluster-1
- port
- http : 9200
- transport : 9300
Node 1
- WSL2 환경
- public IP : 58.x.x.x
- name : node-1
- port
- http : 9200
- transport : 9300
Node 2
- AWS EC2 환경
- public IP : 3.x.x.x
- name : node-2
- port
- http : 9200
- transport : 9300
Node 3
- AWS EC2 환경
- public IP : 4.x.x.x
- name : node-3
- port
- http : 9200
- transport : 9300
이를 구성하기 위한 환경 설정을 알아보자. 먼저 사전 작업부터!
필자는 공유기 네트워크 환경이기에 192.168.0.1
에 접속해 tcp:9200 & tcp:9300 포트포워딩을 해두었다.
{public IP}:{port}
-> {WSL2의 private IP}:{port}
로 연결되도록 파워쉘에서 아래와 같은 설정을 해둔다.
※ 관리자 권한 필수
# ipconfig로 private IP 확인하고 설정
netsh interface portproxy add v4tov4 listenport=9200 listenaddress=0.0.0.0 connectport=9200 connectaddress=172.x.x.x
netsh interface portproxy add v4tov4 listenport=9300 listenaddress=0.0.0.0 connectport=9300 connectaddress=172.x.x.x
# 매핑된 정보가 나오게 된다.
netsh interface portproxy show v4tov4
AWS EC2 환경에서 보안 그룹에 두 포트에 대한 인바운드 규칙을 추가한다.
세 인스턴스 모두 sudo vi /etc/hosts
를 통해 아래 매핑 추가
58.x.x.x 60jong
3.x.x.x elastic-2
43.x.x.x elastic-3
cluster.name: "es-cluster-1"
node.name: "node-1" ---- 각 node name에 맞게 설정
network.bind_host: "0.0.0.0" ---- 클라이언트의 요청을 처리하기 위한 주소
network.publish_host: "60jong" ---- 다른 노드들에게 노출할 주소
discovery.seed_hosts: ["60jong", "elastic-2", "elastic-3"]
cluster.initial_master_nodes: ["node-1", "node-2", "node-3"] ---- 세 노드 중 마스터 노드 선별
# http.port: 9200 - default
# transport.port: 9300 - default
# Security
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.keystore.path: certs/es-cluster-1.p12
xpack.security.transport.ssl.truststore.path: certs/es-cluster-1.p12
elasticsearch.yml에 Network 설정이 network.host
가 아닌 network.bind_host
와 network.publish_host
로 나뉘어있다.
노드가 자신의 프로세스에 접근하는 경우에 localhost:9200
도 사용을 가능케 하기 위해 bind_host
는 "0.0.0.0"으로 설정한다. 그리고 publish_host
는 public IP로 설정한다.
※ EC2의 경우에는 인바운드 규칙에서 tcp:9200 & tcp:9300을 모든 IPv4에 대해 허용 추가.
WSL2의 경우에는 필자의 네트워크는 공유기 환경이기에 192.168.0.1
에 접속해 포트포워딩을 해두었다.
사실 이정도 설정이면 문제 없이 클러스터 구성이 돌아간다. 단 elasticsearch.yml에서 security 설정을 xpack.security.enabled: false
만 해둔다면 말이다.
정상적으로 설정이 됐다면 모든 인스턴스에서 ~~~~/bin/elasticsearch
를 실행해주면 된다. 잘 구동이 됐는지 확인하는 방법은
{any public IP of Node}:9200/_cat/nodes
+ ?v
추가하면 더 디테일
을 통해서 클러스터에 올바른 갯수의 노드가 존재하는지 확인하면 된다.
3개로 정상적으로 구동됐다!!
임의의 요청으로부터 데이터를 보호하기 위해 보안 설정은 필수다.
보안 설정을 하는 과정은 다음과 같다.
- 공개키 생성
./config/certs
디렉토리 생성 .... 이미 존재한다면 그냥 certs폴더 비우고 시작하는 걸 추천- 대칭키 생성
- elasticsearch.keystore 생성
- elasticsearch.yml 설정
- 유저 설정
생성할 것들이 많지만, 친절하게도 다운 받은 elasticsearch/bin
폴더에 존재하는 tool들로 생성이 가능하다.
./bin/elasticsearch-certutil ca
후 공개키의 비밀번호 입력으로 공개키 생성
-> elastic-stack-ca.p12
가 생성됨.
./config
디렉토리 내부에 mkdir certs
./bin/elasticsearch-certutil cert \
--ca elastic-stack-ca.p12 \
--dns 60jong,elastic-2,elastic-3 \
--ip {public IP 1},{public IP 2},{public IP 3} \
--out config/certs/{cluster name}.p12
./bin/elasticsearch-keystore create
-- 이미 존재한다고 뜨면 overwrite
./bin/elasticsearch-keystore add xpack.security.transport.ssl.keystore.secure_password
비밀번호 입력
./bin/elasticsearch-keystore add xpack.security.transport.ssl.truststore.secure_password
비밀번호 입력
이렇게 설정하면
cofig
디렉토리에 elasticsearch.keystore
가 생성되고
./bin/elasticsearch-keystore list
를 통해 등록된 키들을 확인할 수 있다.
이제 elasticsearch.yml에 보안 관련 설정을 추가하면 설정은 끝이 난다.
# Security
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.keystore.path: certs/es-cluster-1.p12
xpack.security.transport.ssl.truststore.path: certs/es-cluster-1.p12
./bin/elasticsearch-setup-passwords auto/interactive
!! 이제 elastic
이라는 유저와 설정을 통한 비밀번호를 이용해 접근이 가능하다.
이제 클러스터 구성 설정과 보안 설정 모두 마쳤다. 보안 설정으로 인해 클러스터로의 요청 시에
-u elastic:password
를 붙여 요청하면 된다.