만쥬의 개발일기
article thumbnail

이번 포스팅에서는 엘라스틱 서치와 키바나 8.12.2 버전을 설치하고, 단일 노드와 멀티 노드 클러스터 환경을 각각 구축하는 방법에 대해 알아보겠습니다.

만약 서버(컴퓨팅 자원)이 여러 대라면 멀티 노드 클러스터 구축 시 단일 노드를 각 서버마다 구축해주면 되고, 서버가 한 대로 한정적이라면 멀티 노드 클러스터를 구축해주면 됩니다.

 

개발환경


ubuntu 20.04
java 17
docker 26.0.0
elastic search 8.12.2

 

🚨주의사항🚨

엘라스틱 서치는 일정량 이상의 메모리가 필요합니다. 노드당 최소 4GB를 할당해주는 것이 바람직하며, 만약 1GB등 매우 낮은 메모리를 할당해준다면 작동 도중 137번 error code와 함께 프로그램이 중단될 수 있습니다.

따라서 충분한 컴퓨팅 자원을 확보한 상태에서 실습을 진행하는 것을 권장합니다.

 

단일 노드 Elasticsearch + Kibana 구축하기

1.자바 설치

엘라스틱 서치는 자바 기반이기 때문에 자바를 먼저 설치해주어야 합니다.

저는 주로 사용하는 17버전을 선택하였습니다.

sudo apt install openjdk-17-jdk
sudo apt install apt-transport-https

 

2.도커 설치

엘라스틱 서치는 여러 개의 노드(서버)를 띄워서 사용하게 되는데 도커를 썼을 때의 이점이 확실합니다. 엘라스틱 서치는 yml을 수정해주어야 하는 상황이 잦은데, 이미지를 도커허브에 등록해놓음으로서 같은 설정을 반복해주지 않아도 되고, 만약 한 컴퓨팅 자원 내에 여러 개의 노드를 띄워야 하는 상황이라면 역시나 VM 보단 도커가 좋습니다.

curl -fsSL https://get.docker.com/ | sudo sh
newgrp docker
docker version

 

3.elastic 클러스터용 docker network를 만들어줍니다.

docker network create elastic

 

4.elastic 최신 버전 다운로드 (8.12.2) 

docker pull docker.elastic.co/elasticsearch/elasticsearch:8.12.2

 

5~9번 과정은 도커이미지 서명의 유효성을 검증하기 위한 과정으로, 생략하셔도 됩니다.

5. cosign 설치

sudo wget https://github.com/sigstore/cosign/releases/latest/download/cosign-linux-amd64 -O cosign

 

6. cosign 권한부여

 sudo chmod +x cosign

 

7.cosign 폴더 위치옮겨주기

sudo mv cosign /usr/local/bin/cosign 

 

8.pub 키 생성

sudo wget https://artifacts.elastic.co/cosign.pub

 

9. 도커이미지 서명의 유효성 검증

cosign verify --key cosign.pub docker.elastic.co/elasticsearch/elasticsearch:8.12.2

 

11.elastic 컨테이너 실행

docker run -d --name es01 --net elastic -p 9200:9200 -it -m 4GB docker.elastic.co/elasticsearch/elasticsearch:8.12.2

만약 멀티 노드 클러스터를 구축할거라면 이름은 그에 맞춰 수정하면 되고, 램은 최소 4GB는 할당해줍니다.(-m 4GB) 포트는 9200번 포트를 열어줍니다. (elastic search 기본 포트)

 

아마 99% 확률로 노드가 죽을텐데, 로그를 보면 위 에러가 발생한 것을 볼 수 있습니다.

🚨ERROR: Elasticsearch exited unexpectedly, with exit code 78🚨

호스트 터미널에서 다음 명령을 실행해줍니다.

$ sudo sysctl -w vm.max_map_count=262144
vm.max_map_count = 262144

 

(*vm.max_map_count는 가상 메모리 맵 영역의 최대 개수를 제어합니다.)

 

혹은 wsl을 사용 중이기 때문에 window 경로의 /c/users/user/.wslconfig 파일을 다음과 같이 설정하면 재부팅 시마다 설정해주지 않아도 됩니다.

[wsl2]
kernelCommandLine = "sysctl.vm.max_map_count=262144"

 

 

재부팅하고 설정이 잘 되었는지 확인.

$ sysctl vm.max_map_count
vm.max_map_count = 262144

이후 종료된 컨테이너를 삭제하고, 재실행합니다.


12. 실행 후 로그를 보면 다음과 같이 enrollment token과 password 주어집니다. 해당 출력은 실행 시에만 나오므로 따로 저장해놓습니다. (물론 추후 변경도 가능)

 

13.백그라운드로 실행했으므로 password 재설정을 위해 다음 명령어를 실행합니다. ( 컨테이너 이름은 본인 설정대로)

docker exec -it es01 /usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic

14.위 출력에서 password를 환경변수로 등록해놓습니다.

export ELASTIC_PASSWORD="your_password"

 

15.토큰도 똑같이 재설정 시 다음 명령어를 실행합니다.

docker exec -it es01 /usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s kibana
export ELASTIC_TOKEN="your_token"

 

16.다음 명령어로 환경변수 설정이 잘 되었는지 확인해줍니다.

echo "TOKEN = "$ELASTIC_TOKEN && echo "\nPW = "$ELASTIC_PASSWORD

 

ES 커널에서 쿼리를 쓰려면 SSL 인증서가 필요합니다.

 

17.SSL 인증서를 현재 위치에 복사합니다.

docker cp es01:/usr/share/elasticsearch/config/certs/http_ca.crt .

 

18.API로 ES 컨테이너가 정상 실행 중인지 확인합니다.

$ curl --cacert http_ca.crt -u elastic:$ELASTIC_PASSWORD https://localhost:9200
{
  "name" : "f5c53b8b7dd5",
  "cluster_name" : "docker-cluster",
  "cluster_uuid" : "bYRS4xtdT0-ccYIz_6wwPQ",
  "version" : {
    "number" : "8.12.2",
    "build_flavor" : "default",
    "build_type" : "docker",
    "build_hash" : "48a287ab9497e852de30327444b0809e55d46466",
    "build_date" : "2024-02-19T10:04:32.774273190Z",
    "build_snapshot" : false,
    "lucene_version" : "9.9.2",
    "minimum_wire_compatibility_version" : "7.17.0",
    "minimum_index_compatibility_version" : "7.0.0"
  },
  "tagline" : "You Know, for Search"
}

 

19.키바나 컨테이너를 실행합니다.

docker run -d --name kibana --net elastic -p 5601:5601 docker.elastic.co/kibana/kibana:8.12.2

그리고 localhost:5601에 접속하면 다음과 같이 코드를 입력해야 합니다.

해당 코드는 kibana의 /bin/kibana-verification-code 실행파일을 실행하면 얻을 수 있습니다.

 

20.다음 명령어로 코드를 얻을 수 있습니다.

docker exec -it kib01 ./bin/kibana-verification-code

 

21.이후 설정을 마치면 다음과 같은 페이지가 나옵니다.

초기 username은 elastic이고, password는 아까 생성 후 환경변수에 설정한 것을 넣어주면 됩니다.

멀티 노드 클러스터 구축하기

들어가기에 앞서, 해당 방법은 공식 홈페이지에 나온 방법을 다룬 것이지만 연습용 외에는 권장하지 않습니다.

그 이유는 다양하게 있는데, 다음 포스팅에서 다루겠습니다.

 

1. docker-compose와 환경파일을 넣을 폴더를 하나 만듭니다.

2.해당 폴더 하위에 .env 파일을 만들고, 내용은 다음 코드를 복사합니다.

# Password for the 'elastic' user (at least 6 characters)
ELASTIC_PASSWORD={your pw}

# Password for the 'kibana_system' user (at least 6 characters)
KIBANA_PASSWORD={your pw}

# Version of Elastic products
STACK_VERSION=8.12.2

# Set the cluster name
CLUSTER_NAME=docker-cluster

# Set to 'basic' or 'trial' to automatically start the 30-day trial
LICENSE=basic
#LICENSE=trial

# Port to expose Elasticsearch HTTP API to the host
ES_PORT=127.0.0.1:9200
#ES_PORT=127.0.0.1:9200

# Port to expose Kibana to the host
KIBANA_PORT=5601
#KIBANA_PORT=80

# Increase or decrease based on the available host memory (in bytes)
MEM_LIMIT=1073741824

# Project namespace (defaults to the current folder name if not set)
#COMPOSE_PROJECT_NAME=myproject

ELASTIC과 KIBANA의 패스워드는 이 파일에서 설정해줍니다.

스택 버전은 설치 버전을 써주면 됩니다. (여기서는 8.12.2)

기본적으로 Docker Compose 구성은 모든 네트워크 인터페이스에서 포트 9200을 노출합니다.

 

3.호스트에서만 ES에 접속하게 하려면 ES_PORT를 다음과 같이 설정해줍니다.

ES_PORT=127.0.0.1:9200

 

4.docker-compose.yml 파일을 만듭니다.
내용은 다음 코드 복사.

 

elasticsearch/docs/reference/setup/install/docker/docker-compose.yml at 8.12 · elastic/elasticsearch

Free and Open, Distributed, RESTful Search Engine. Contribute to elastic/elasticsearch development by creating an account on GitHub.

github.com

 

5.docker-compose를 백그라운드에서 실행시켜준다.

docker-compose up -d

localhost:9200 과 localhost:5601에 접속하면 아이디는 elastic, 패스워드는 .env 파일에 작성한 것을 입력해주면 초기 설정은 끝입니다.

멀티 노드 클러스터의 API 통신

실행 시킨 컨테이너들을 보면, 외부에서 접속가능한 노드는 es01_1노드 뿐인 것을 확인할 수 있습니다.

싱글 노드일 때 처럼 터미널에서 SSL 인증서과 curl을 사용해 ES에 명령을 줘보겠습니다.

$ docker volume list
DRIVER    VOLUME NAME
local     dc_elk_certs
local     dc_elk_esdata01
local     dc_elk_esdata02
local     dc_elk_esdata03
local     dc_elk_kibanadata

docker volume 리스트를 보면 인증서 볼륨 있는 것을 확인할 수 있습니다.

마운트된 경로를 확인해줍니다.

리눅스 환경이라면 경로는 동일할 것입니다.

먼저 -R 옵션으로 도커 볼륨 하위 폴더에 전부 권한 부여해줍니다.

sudo chmod -R +777 /var/lib/docker/volumes

인증서를 둘 위치로 가서 마운트된 위치에 있는 인증서를 복사해줍니다.

sudo cp /var/lib/docker/volumes/dc_elk_certs/_data/es01/es01.crt .

 

다음과 같이 API를 보내면 성공적으로 작동하는 모습입니다.

단, 외부 통신이 되는 한 노드에게만 요청을 보낼 수 있습니다.

$ curl --cacert es_01.crt -u elastic:$ELASTIC_PASSWORD https://localhost:9200
{
  "name" : "es01",
  "cluster_name" : "docker-cluster",
  "cluster_uuid" : "64iQHH6bQYOgVVnl8G05KQ",
  "version" : {
    "number" : "8.12.2",
    "build_flavor" : "default",
    "build_type" : "docker",
    "build_hash" : "48a287ab9497e852de30327444b0809e55d46466",
    "build_date" : "2024-02-19T10:04:32.774273190Z",
    "build_snapshot" : false,
    "lucene_version" : "9.9.2",
    "minimum_wire_compatibility_version" : "7.17.0",
    "minimum_index_compatibility_version" : "7.0.0"
  },
  "tagline" : "You Know, for Search"
}

 

또한 인증서와 인증 정보를 함께 넣으면, curl로 터미널에서 다양한 쿼리를 줄 수 있습니다.

$ sudo curl --cacert es01.crt -u elastic:$ELASTIC_PASSWORD -X GET "https://localhost:9200/_cat/indices?v"

 

물론 키바나가 몇 배는 더 편하므로, 위 방법은 GUI를 사용할 수 없을 때 이용합니다.

 

reference

profile

만쥬의 개발일기

@KangManJoo

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!