Home Elasticsearch + Kibana Docker 설치 가이드 (with 인증 활성화)
Post
Cancel

Elasticsearch + Kibana Docker 설치 가이드 (with 인증 활성화)

개요

커뮤니티 기능에 해시태그 검색을 구현하면서 Elasticsearch를 도입했습니다. MySQL의 LIKE 검색은 인덱스를 타지 못해 대규모 데이터에서 느리지만, Elasticsearch는 역색인(Inverted Index) 구조로 구글처럼 빠른 검색이 가능합니다.

이 글에서는 Docker Compose로 Elasticsearch와 Kibana를 설치하고, 인증까지 활성화하는 전 과정을 정리합니다.


Elasticsearch란?

검색 엔진 데이터베이스입니다.

데이터를 저장할 때 미리 역색인 구조로 인덱싱해두기 때문에 검색 시 전체 테이블을 스캔하지 않습니다.

1
2
MySQL:  "강아지 산책" 검색 → 전체 테이블 풀스캔 → 느림
ES:     "강아지 산책" 검색 → 역색인 조회        → 매우 빠름

역색인 원리

1
2
3
4
5
6
7
8
문서1: "강아지 산책 좋아요"
문서2: "강아지 목욕 힘들어"
문서3: "고양이 산책"

역색인 테이블:
  강아지 → [문서1, 문서2]
  산책   → [문서1, 문서3]
  좋아요 → [문서1]

“강아지” 검색 시 역색인에서 바로 문서1, 문서2를 찾아냅니다.


Kibana란?

Elasticsearch 데이터를 브라우저에서 시각화하는 대시보드 툴입니다.

기능설명
Dev ToolsES에 쿼리를 직접 날려보는 콘솔
Discover저장된 문서 데이터 탐색
Dashboard차트/그래프로 데이터 시각화
Index Management인덱스 생성/삭제/설정 관리

Docker Compose 설치

docker-compose.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:8.12.0
    container_name: elasticsearch
    environment:
      - node.name=es-node
      - cluster.name=puppynote-cluster
      - discovery.type=single-node
      - xpack.security.enabled=true
      - xpack.security.http.ssl.enabled=false
      - xpack.security.transport.ssl.enabled=false
      - ELASTIC_PASSWORD=Puppynote1234!
      - ES_JAVA_OPTS=-Xms512m -Xmx512m
    ports:
      - "9200:9200"
    volumes:
      - esdata:/usr/share/elasticsearch/data
    networks:
      - elastic-net
    healthcheck:
      test: ["CMD-SHELL", "curl -s -u elastic:Puppynote1234! http://localhost:9200/_cluster/health | grep -q 'status'"]
      interval: 30s
      timeout: 10s
      retries: 5

  setup:
    image: curlimages/curl:latest
    container_name: es-setup
    depends_on:
      elasticsearch:
        condition: service_healthy
    networks:
      - elastic-net
    restart: "no"
    entrypoint:
      - curl
      - -s
      - -X
      - POST
      - http://elasticsearch:9200/_security/user/kibana_system/_password
      - -H
      - "Content-Type: application/json"
      - -u
      - elastic:Puppynote1234!
      - -d
      - "{\"password\":\"원하는비밀번호\"}"

  kibana:
    image: docker.elastic.co/kibana/kibana:8.12.0
    container_name: kibana
    environment:
      - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
      - ELASTICSEARCH_USERNAME=kibana_system
      - ELASTICSEARCH_PASSWORD=원하는비밀번호
      - SERVER_BASEPATH=/kibana
      - SERVER_REWRITEBASEPATH=true
    ports:
      - "5601:5601"
    depends_on:
      setup:
        condition: service_completed_successfully
    networks:
      - elastic-net

volumes:
  esdata:

networks:
  elastic-net:
    driver: bridge

인증 관련 환경변수 설명

변수설명
xpack.security.enabled=true인증 활성화
xpack.security.http.ssl.enabled=falseHTTP SSL 비활성화 (내부망용)
ELASTIC_PASSWORDelastic 슈퍼유저 비밀번호 설정

kibana_system 비밀번호 문제

여기서 주의해야 할 함정이 있습니다.

ELASTIC_PASSWORDelastic 유저의 비밀번호만 설정합니다. Kibana가 ES에 접속할 때 사용하는 kibana_system 유저는 별도로 비밀번호를 설정해야 합니다.

설정하지 않으면 아래와 같은 인증 실패 로그가 발생합니다.

1
2
Authentication of [kibana_system] was terminated by realm [reserved]
- failed to authenticate user [kibana_system]

해결 방법

ES가 완전히 기동된 후 아래 명령어로 kibana_system 비밀번호를 설정합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 1. ES만 먼저 실행
docker-compose up -d elasticsearch

# 2. ES 정상 동작 확인
docker exec elasticsearch curl -s -u elastic:비밀번호 http://localhost:9200

# 3. kibana_system 비밀번호 설정 (딱 한 번만)
docker exec elasticsearch curl -s \
  -X POST http://localhost:9200/_security/user/kibana_system/_password \
  -H "Content-Type: application/json" \
  -u elastic:비밀번호 \
  -d '{"password":"비밀번호"}'

# 응답: {} → 성공

# 4. Kibana 실행
docker-compose up -d kibana

Kibana 접속

브라우저에서 접속합니다.

1
http://서버IP:5601

로그인 정보:

1
2
Username: elastic
Password: 설정한 비밀번호

Dev Tools에서 쿼리 테스트

접속 후 좌측 메뉴 → Management → Dev Tools

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 인덱스 목록 확인
GET /_cat/indices?v

# 전체 문서 조회
GET /posts/_search

# 해시태그 검색
GET /posts/_search
{
  "query": {
    "term": { "hashtags": "강아지산책" }
  }
}

# 인기 해시태그 Top 10 집계
GET /posts/_search
{
  "size": 0,
  "aggs": {
    "top_hashtags": {
      "terms": { "field": "hashtags", "size": 10 }
    }
  }
}

Spring Boot 연동 설정

application.yml

1
2
3
4
5
elasticsearch:
  host: ${ES_HOST:localhost}
  port: ${ES_PORT:9200}
  username: ${ES_USERNAME:elastic}
  password: ${ES_PASSWORD}

ElasticsearchConfig.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Configuration
@ConfigurationProperties(prefix = "elasticsearch")
@Getter @Setter
public class ElasticsearchConfig extends ElasticsearchConfiguration {

    private String host;
    private int port;
    private String username;
    private String password;

    @Override
    public ClientConfiguration clientConfiguration() {
        return ClientConfiguration.builder()
                .connectedTo(host + ":" + port)
                .withBasicAuth(username, password)
                .withConnectTimeout(Duration.ofSeconds(3))
                .withSocketTimeout(Duration.ofSeconds(30))
                .build();
    }
}

환경변수 역할 정리

변수사용 위치설명
ELASTIC_PASSWORDdocker-composeelastic 유저 초기 비밀번호
KIBANA_PASSWORDkibana_system 설정 APIKibana → ES 접속 비밀번호
ES_PASSWORDSpring Boot앱 → ES API 요청 비밀번호

세 값은 동일하게 맞춰야 합니다.


트러블슈팅

docker-compose.yml YAML 파싱 오류

복사/붙여넣기 시 들여쓰기나 특수문자가 깨지는 경우가 많습니다. 파일을 직접 heredoc으로 작성하면 안전합니다.

1
2
3
cat > ~/elasticsearch/docker-compose.yml << 'EOF'
# 내용 붙여넣기
EOF

kibana_system 인증 실패

ELASTIC_PASSWORD만 설정하고 kibana_system 비밀번호를 따로 설정하지 않은 경우입니다. 위의 kibana_system 비밀번호 문제 섹션을 참고하세요.

AWS EC2에서 Kibana 접속 안 될 때

보안그룹 인바운드 규칙에 5601 포트가 열려있는지 확인합니다.

1
2
포트: 5601
소스: 내 IP (전체 오픈은 보안상 비권장)
This post is licensed under CC BY 4.0 by the author.