최근에 Elasticsearch를 사용해야 할 일이 있어서 도커로 간단하게 설치해서 사용법을 학습하고 있었다. 최신버전이 좋겠거니 생각하고 오늘 기준으로 가장 최신 버전인 8.2.0 버전을 도커 이미지로 다운받아서 실행하고 curl 명령어를 날려보았더니 이게 왠걸!! curl: (52) Empty reply from server
가 발생하면서 아무것도 나오지 않는다.
다른 블로그와 책을 찾아봤지만 설치 후 바로 curl 명령을 날리면 아무 문제없이 응답이 오고 있었다. 그래서 7.12 버전으로 낮춰서 실행해보니 curl 명령이 잘 먹히는걸 확인할 수 있었다. 그렇게 끙끙 앓다가 우연찮게 elastic 커뮤니티에서 한 유저가 사용한 curl 명령을 보고 해결할 수 있었다.
우선 가장 최신 버전인 8.2.0을 로컬에 실행시켜보기 위해 다음 명령을 터미널에 입력합니다.
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:8.2.0
그 후에 curl 명령을 날리면 다음과 같이 에러가 발생한다.
$ curl localhost:9200
curl: (52) Empty reply from server
원인은 아직 잘 모르지만 Elasticsearch는 https 통신으로 주고 받도록 설정이 되어있는 것 같다. 그래서 찾다보면 xpack.security.enabled
값을 false
로 하라는 글들을 볼 수 있는데 보안 설정 값을 함부로 건드려서는 안될 것 같아서 원론적인 해결 방법이라고 생각하지 않았다. (xpack이 플러그인으로 제공되다가 디폴트로 탑재가 되었는데 다 이유가 있어서 한거라고 생각했다.)
그럼 curl 명령을 어떻게 날려야지 정상적으로 응답을 받을 수 있을까? 먼저 도커 컨테이너 내부로 접속해야 된다. 그러기 위해서는 컨테이너 아이디를 먼저 조회해야 하는데 다음 명령어로 조회할 수 있다.
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0fc2c0bd8454 elasticsearch:8.2.0 "/bin/tini -- /usr/l…" About an hour ago Up 41 minutes 0.0.0.0:9200->9200/tcp, 0.0.0.0:9300->9300/tcp elasticsearch
그리고 해당 컨테이너 내부를 루트 권한이 있는 계정(root)로 접속한다.
$ docker exec -it --user root 0fc2 /bin/bash
접속한 뒤에 다음 경로로 들어가서 인증서 하나를 살펴볼 수 있도록 한다.
$ cat /config/certs/http_ca.crt
-----BEGIN CERTIFICATE-----
MIIFWjCCA0KgAwIBAgIVANbY7UwEMnridEDNqkp08iwRurKlMA0GCSqGSIb3DQEB
CwUAMDwxOjA4BgNVBAMTMUVsYXN0aWNzZWFyY2ggc2VjdXJpdHkgYXV0by1jb25m
aWd1cmF0aW9uIEhUVFAgQ0EwHhcNMjIwNTExMDc0MjU5WhcNMjUwNTEwMDc0MjU5
WjA8MTowOAYDVQQDEzFFbGFzdGljc2VhcmNoIHNlY3VyaXR5IGF1dG8tY29uZmln
...생략
yERrZjNJ16xrtCL/145vCUuuRJrs/Zqu0yy3jyeWeiC/Jhf/gycIia1KuxfpAde2
XyRto6N/zZ62lWP60KBeWfZaQ5y1809A9fXdn8hcrL1jbtgdKrRemugXZ+zZT6hA
WzEKCtVqqfSqIcLe6gtXLGdz7Hp1G1lsFNjT5sPrSPYsN8lQtwik71Gb9zr6+sds
/l+3QfPYwrPzSrJBm+gyFH+m0v60VaopIkG1ZbgF
-----END CERTIFICATE-----
해당 내용을 복사해서 로컬 컴퓨터에 파일을 하나 만들 수 있도록 한다.
그 다음 curl 명령을 다음과 같이 입력한다.
$ curl --cacert <인증서 경류>/http_ca.crt https://localhost:9200
ex) curl --cacert /Users/junsugi/Desktop/http_ca.crt https://localhost:9200
{"error":{"root_cause":[{"type":"security_exception","reason":"missing authentication credentials for REST request [/]","header":{"WWW-Authenticate":["Basic realm=\"security\" charset=\"UTF-8\"","Bearer realm=\"security\"","ApiKey"]}}],"type":"security_exception","reason":"missing authentication credentials for REST request [/]","header":{"WWW-Authenticate":["Basic realm=\"security\" charset=\"UTF-8\"","Bearer realm=\"security\"","ApiKey"]}},"status":401}%
입력하면 401 에러가 발생하는데 이는 아이디 패스워드를 입력하지 않아서 발생한 문제이다.
일단 여기까지 봤을때 아까는 Empty reply from server가 발생했는데 우선 통신은 되었다는걸 확인할 수 있다.
기본적으로 Elastic 서비스에는 elastic
이라는 아이디가 존재한다. 그리고 비밀번호는 재발급 받는게 편한거 같아서 재발급해서 인증하는 방식으로 해보겠다.
다시 elasticsearch 컨테이너 내부로 접속한 뒤 bin 폴더로 접속한다. 접속하면 다음 배치 파일 리스트를 볼 수 있다.
$ docker exec -it --user root 0fc2 /bin/bash
$ root@0fc2c0bd8454:/usr/share/elasticsearch# cd bin
$ root@0fc2c0bd8454:/usr/share/elasticsearch# ls -al
total 2964
drwxrwxr-x 1 elasticsearch root 4096 May 11 07:52 .
drwxrwxr-x 1 root root 4096 May 11 07:59 ..
-r-xr-xr-x 1 root root 5398 Apr 20 10:34 elasticsearch
-r-xr-xr-x 1 root root 501 Apr 20 10:37 elasticsearch-certgen
-r-xr-xr-x 1 root root 493 Apr 20 10:37 elasticsearch-certutil
-r-xr-xr-x 1 root root 996 Apr 20 10:34 elasticsearch-cli
-r-xr-xr-x 1 root root 452 Apr 20 10:37 elasticsearch-create-enrollment-token
-r-xr-xr-x 1 root root 443 Apr 20 10:37 elasticsearch-croneval
-r-xr-xr-x 1 root root 5897 Apr 20 13:36 elasticsearch-env
-r-xr-xr-x 1 root root 2595 Apr 20 10:34 elasticsearch-env-from-file
-r-xr-xr-x 1 root root 168 Apr 20 10:34 elasticsearch-geoip
-r-xr-xr-x 1 root root 181 Apr 20 10:34 elasticsearch-keystore
-r-xr-xr-x 1 root root 126 Apr 20 10:34 elasticsearch-node
-r-xr-xr-x 1 root root 265 Apr 20 10:34 elasticsearch-plugin
-r-xr-xr-x 1 root root 509 Apr 20 10:37 elasticsearch-reconfigure-node
-r-xr-xr-x 1 root root 448 Apr 20 10:37 elasticsearch-reset-password
-r-xr-xr-x 1 root root 441 Apr 20 10:37 elasticsearch-saml-metadata
-r-xr-xr-x 1 root root 439 Apr 20 10:37 elasticsearch-service-tokens
-r-xr-xr-x 1 root root 448 Apr 20 10:37 elasticsearch-setup-passwords
-r-xr-xr-x 1 root root 118 Apr 20 10:34 elasticsearch-shard
-r-xr-xr-x 1 root root 483 Apr 20 10:37 elasticsearch-sql-cli
-r-xr-xr-x 1 root root 2915354 Apr 20 10:37 elasticsearch-sql-cli-8.2.0.jar
-r-xr-xr-x 1 root root 436 Apr 20 10:37 elasticsearch-syskeygen
-r-xr-xr-x 1 root root 436 Apr 20 10:37 elasticsearch-users
-r-xr-xr-x 1 root root 356 Apr 20 10:37 x-pack-env
-r-xr-xr-x 1 root root 364 Apr 20 10:37 x-pack-security-env
-r-xr-xr-x 1 root root 363 Apr 20 10:37 x-pack-watcher-env
여기서 reset-password 배치 파일을 사용할 건데 다음과 같이 입력할 수 있도록 한다.
# bin 폴더까지 접속한 경우
elasticsearch-reset-password -u elastic
# 그 외의 상황
./bin/elasticsearch-reset-password -u elastic
This tool will reset the password of the [elastic] user to an autogenerated value.
The password will be printed in the console.
Please confirm that you would like to continue [y/N]y
Password for the [elastic] user successfully reset.
New value: eUp1Lde3Y*rWa0t9crEN << 비밀번호
따라서 출력된 비밀번호를 복사해놓고 curl을 다음과 같이 입력할 수 있도록 한다.
$ curl --cacert /Users/junsugi/Desktop/http_ca.crt -u elastic https://localhost:9200
Enter host password for user 'elastic': eUp1Lde3Y*rWa0t9crEN (실제로는 안보임, 복붙하고 엔터치면됨)
{
"name" : "0fc2c0bd8454",
"cluster_name" : "docker-cluster",
"cluster_uuid" : "DMLiHQ_NSNGIgPusg4Apyg",
"version" : {
"number" : "8.2.0",
"build_flavor" : "default",
"build_type" : "docker",
"build_hash" : "b174af62e8dd9f4ac4d25875e9381ffe2b9282c5",
"build_date" : "2022-04-20T10:35:10.180408517Z",
"build_snapshot" : false,
"lucene_version" : "9.1.0",
"minimum_wire_compatibility_version" : "7.17.0",
"minimum_index_compatibility_version" : "7.0.0"
},
"tagline" : "You Know, for Search"
}
이렇게하면 8.2.0 버전에서도 curl을 이용해서 Elasticsearch 상태를 확인할 수 있다.
어떻게보면 중요하지 않은 부분일수도 있는데 다른 사람은 다 되는데 나만 안되니까 괜히 찝찝해서 찾아보았고 나같은 사람들도 있을꺼 같아서 적어보았습니다. 앞으로 Elastic 관련 글들을 많이 적을꺼 같아서 한번 짧게 운을 띄워보았습니다.
그럼 이만 총총.
이야 잘 보고갑니당