
Elasticsearch는 "검색 엔진" 역할을 하는 외부 서버이다.
따라서 내 애플리케이션이 Elasticsearch 서버의 네트워크로 접속해서 데이터를 주고받아야 하므로 Elasticsearch 사용하려면 설치가 필요하다.
dependencies {
...
implementation 'org.springframework.boot:spring-boot-starter-data-elasticsearch'
}
일단 build.gradle의 dependencies에 Spring Boot 버전에 맞는 Elasticsearch 라이브러리를 가져오는 코드를 추가해보았다.

버전 확인 결과 Spring Boot v3.3.1은 elasticsearch 8.13.4를 가져오고 있었다. 따라서 이에 맞춰 Elasticsearch 8.13.4 버전을 설치하였다.
참고(Spring Data와 호환되는 Elasticsearch 버전)
els.yml 을 작성하여 Elasticsearch만이 아니라, Elasticsearch + Kibana + Logstash까지 포함한 전체 ELK 스택을 한번에 실행하기 위한 구성을 해준다. 이를 통해 각각의 서비스를 따로 실행하고 연결 설정하는 번거로움을 줄일 수 있다.
즉, docker-compose를 만든 후 yml 파일을 읽어서 거기에 정의된 서비스들을 하나의 앱처럼 실행한다. 그렇게 된다면 docker-compose up 같은 명령어로 여러 컨테이너를 동시에 띄우는 게 가능해진다.
version: '3.7'
services:
es:
#image: docker.elastic.co/elasticsearch/elasticsearch:8.13.4
build:
context: .
args:
VERSION: 8.13.4
container_name: es
environment:
- node.name=single-node
- cluster.name=backtony
- discovery.type=single-node
- xpack.security.enabled=false
ports:
- 9200:9200
- 9300:9300
networks:
- es-bridge
kibana:
container_name: kibana
image: docker.elastic.co/kibana/kibana:8.13.4
environment:
SERVER_NAME: kibana
ELASTICSEARCH_HOSTS: http://es:9200
ELASTICSEARCH_SSL_VERIFICATIONMODE: none
ports:
- 5601:5601
# Elasticsearch Start Dependency
depends_on:
- es
networks:
- es-bridge
logstash:
image: docker.elastic.co/logstash/logstash:8.13.4
container_name: logstash
environment:
- ELASTICSEARCH_HOSTS=http://es:9200
- MYSQL_USER=${MYSQL_USER}
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
volumes:
- ./logstash/config/logstash.conf:/usr/share/logstash/pipeline/logstash.conf
- ./logstash/config/logstash.yml:/usr/share/logstash/config/logstash.yml
- ./logstash/mysql-connector-j-8.3.0.jar:/usr/share/logstash/mysql-connector-j-8.3.0.jar
depends_on:
- es
networks:
- es-bridge
networks:
es-bridge:
driver: bridge
# Dockerfile
ARG VERSION
FROM docker.elastic.co/elasticsearch/elasticsearch:${VERSION}
RUN elasticsearch-plugin install analysis-nori
한국어는 nori 형태소 분석기를 사용해 검색할 것이므로 이를 함께 설치한다.
es:
#image: docker.elastic.co/elasticsearch/elasticsearch:8.13.4
build:
context: .
args:
VERSION: 8.13.4
es 서비스는 위와 같이 구성되어 있다. 즉, image:를 직접 사용하는 대신 build 지시어로 현재 디렉토리에 있는 Dockerfile을 빌드해서 컨테이너를 생성하겠다는 의미이므로 Dockerfile이 필요해진다.
docker compose -f els.yml up -d
els.yml이 있는 경로에서 cmd 창을 열고 위의 명령어를 실행한다. 이 명령어의 의미는 els.yml이라는 설정 파일을 사용하여 이 안에 정의된 컨테이너들을 빌드하고 실행하라는 의미가된다.
-d는 백그라운드에서 실행하라는 뜻.
http://localhost:5601/에 접속하여 Kibana 환경으로 들어가본다.

이러한 화면이 뜬다면 elasticsearch와 kibana가 잘 뜬 것!
- xpack.security.enabled=false
현재 els.yml의 es에는 위와 같은 설정이 들어가 있다.
이는 Elasticsearch 보안 기능 전체를 비활성화하는 것으로, Elasticsearch의 인증, 권한, 암호화(SSL) 같은 보안 기능들을 전부 꺼버리는 설정이다.
이렇게 하게 되면 kibana에 접속할 때 로그인을 하지 않아도 되고, Docker에서 띄울 때 토큰같은 걸 안 줘도 되서 개발 환경에서는 편하지만 배포 단계에서는 보안때문에 이 설정을 주어선 안 된다.
근데 배포도 고민을 해야 하므로... 저 설정이 없는 경우 실행을 시켜보고 싶어서 방법을 찾아보다가 아래와 같은 방법으로 해결했다.
먼저 els.yml은 아래와 같이 작성해야 한다.
version: '3.7'
services:
es:
#image: docker.elastic.co/elasticsearch/elasticsearch:8.13.4
build:
context: .
args:
VERSION: 8.13.4
container_name: es
environment:
- node.name=single-node
- cluster.name=backtony
- discovery.type=single-node
#- xpack.security.enabled=false
ports:
- 9200:9200
- 9300:9300
networks:
- es-bridge
kibana:
container_name: kibana
image: docker.elastic.co/kibana/kibana:8.13.4
environment:
SERVER_NAME: kibana
ELASTICSEARCH_HOSTS: https://es:9200 # 배포 시 서버 주소로 바꿔줘야 함.
ELASTICSEARCH_SERVICEACCOUNTTOKEN: AAEAAWVsYX....
ELASTICSEARCH_SSL_VERIFICATIONMODE: none # 배포 시 삭제해야함.
ports:
- 5601:5601
# Elasticsearch Start Dependency
depends_on:
- es
networks:
- es-bridge
....(중략)
networks:
es-bridge:
driver: bridge
docker compose -f els.yml up -d es
일단 이 명령어로는 kibana 접속에 문제가 생기게 된다.
즉, http://localhost:5601/ 로 접속 시 “Kibana server is not ready yet." 라는 오류가 뜬다.

Elasticsearch는 처음 실행할 때 보안 기능이 켜져 있으면, 자동으로 .security 인덱스를 한 번만 생성한다. (여기에 사용자 계정, 비밀번호, 역할, 토큰 같은 보안 정보 저장)
하지만 ES가 완전히 부팅되기 전에 Kibana가 먼저 접속을 시도하면, Kibana가 "보안 정보"를 쓰려는 순간 .security 인덱스가 아직 없어서 예외가 발생한다.
그리고 그 순간부터
.security 인덱스 생성 실패server is not ready yet.security 인덱스는 정확히 뭐지?Elasticsearch 내부에서 사용자 인증, 권한, 보안 설정 등을 저장하는 특별한 시스템 인덱스이다.
elastic 사용자 비밀번호 해시kibana_system 역할 정보이 모든 정보가 .security 인덱스에 저장된다.
depends_on:
- es
이건 단지 Kibana 컨테이너가 Elasticsearch 컨테이너보다 먼저 실행되지 않도록 순서를 지정해주는 역할일 뿐이다. "Elasticsearch가 완전히 준비될 때까지 기다려준다"는 의미는 아님!
즉,
xpack.security.enabled=false 설정을 없애면, Elasticsearch는 보안 기능이 기본값인 true로 작동하게 되고,
그때부터는 Kibana가 Elasticsearch에 접근하려면 “토큰 또는 사용자 인증 정보”를 꼭 주어야 한다.
따라서 elastic 계정의 비밀번호와 kibana 전용 서비스 계정 토큰을 먼저 만들어 주어야 한다.
이 토큰 정보를 els.yml의 kibana 설정에 넣어주면 된다!
$ docker exec -it es bash
$ bin/elasticsearch-reset-password -u elastic #elastic 계정 비밀번호 재설정

New value: Fr8uGbRxg2p=b7F3_ntL
$ docker exec -it es bash # Elasticsearch 컨테이너에 들어가기
$ bin/elasticsearch-service-tokens create elastic/kibana kibana_token
# Kibana에서 사용할 서비스 계정 토큰 생성
# elastic/kibana : Kibana용 기본 서비스 계정 경로
# kibana_token: 생성할 토큰의 이름 (아무거나 가능)

앞서 말했듯이 "ES가 완전히 부팅되기 전에 Kibana가 먼저 접속을 시도하면, Kibana가 "보안 정보"를 쓰려는 순간 .security 인덱스가 아직 없어서 예외가 발생"하게 된다.
따라서 elasticsearch를 먼저 docker에 띄운 후 kibana를 띄우도록 한다.
docker compose -f els.yml up -d es
docker compose -f els.yml up -d kibana
이와 같은 순서대로 실행한다면, localhost:5601 접속 시에도 문제없이 kibana에 접속할 수 있게 된다!
시간표 아이콘 제작자: Onesadya.Std - Flaticon
썸네일 생성: Thumbnail Maker
엘라스틱서치 참 좋네요. 다음 프로젝트에 활용해볼게요. 영단없는자율프로젝트는 너무 슬플거예요.