EC2를 이용한 ElasticSearch Cluster 구현하기 - Logstash 설치 및 ES 기본 데이터 템플릿 설정

2021-09-26

.

Data_Engineering_TIL(20210926)

[참고자료]

“ES Cluster 구성” 최정민님 깃허브 자료

URL : https://github.com/cjungm/with-aws/tree/main/ElasticSearch/installed_ES

“Elastic Cluster 구성” 김종민(kimjmin@gmail.com)님 블로그글

URL : http://kimjmin.net/2018/01/2018-01-build-es-cluster-1/

[참고사항]

“EC2를 이용한 ElasticSearch Cluster 구현하기 - NFS 설정 및 config 공유” 에 이어서 진행하는 실습내용임

URL : https://minman2115.github.io/DE_TIL285

[실습내용]

  • Service 서버에 Logstash 설치

공식 도큐먼트 : https://www.elastic.co/guide/en/logstash/current/index.html

비디오: https://www.elastic.co/kr/webinars/getting-started-logstash

  • Logstash 설치

Logstash도 Elasticsearch와 마찬가지로 Java 에서 실행되며 1.8 버전을 권장함

아래 문서를 참고해서 설치를 진행해도됨

https://www.elastic.co/guide/en/logstash/current/installing-logstash.html#_yum

공개 서명 키를 다운로드하고 설치한다.

# 공개 서명 키를 다운로드하고 설치
[ec2-user@es-coordinater ~]$ sudo rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch
    
# Yum 설치를 위해 /etc/yum.repos.d/에 logstash.repo 파일을 만들고 아래 내용을 추가한다.
[ec2-user@es-coordinater ~]$ cd /etc/yum.repos.d/

[ec2-user@es-coordinater yum.repos.d]$ sudo vim logstash.repo
[logstash-7.x]
name=Elastic repository for 7.x packages
baseurl=https://artifacts.elastic.co/packages/7.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md

[ec2-user@es-coordinater yum.repos.d]$ sudo yum install logstash -y

...

==========================================================================================================================================================================================
 Package                                     Arch                                      Version                                        Repository                                     Size
==========================================================================================================================================================================================
Installing:
 logstash                                    x86_64                                    1:7.14.0-1                                     kibana-7.x                                    347 M

Transaction Summary
==========================================================================================================================================================================================
Install  1 Package

...                                                                                                                                    1/1

Installed:
  logstash.x86_64 1:7.14.0-1

Complete!

Logstash의 RPM 버전 설치 경로들은 아래와 같다

기본 프로그램 ($LS_HOME) : /usr/share/logstash

실행 파일 : bin/logstash

설정 : logstash.yml,jvm.options,log4j2.properties,startup.options

파이프라인 설정 (path.config) : /etc/logstash/conf.d

플러그인(path.plugins) : /usr/share/logstash/plugins

데이터 (추가 플러그인 설치 등) : /var/lib/logstash

로그 (path.logs) : /var/log/logstash

[ec2-user@es-coordinater yum.repos.d]$ sudo vim /etc/logstash/logstash.yml

...

# 아래의 내용 추가

xpack.monitoring.enabled: true
xpack.monitoring.elasticsearch.hosts: ["http://{마스터노드 또는 코디네이터 노드 프라이빗 아이피}:9200"]
xpack.monitoring.elasticsearch.username: elastic
xpack.monitoring.elasticsearch.password: xxxxxxxxxxx
    
[ec2-user@es-coordinater yum.repos.d]$ sudo systemctl start logstash.service

[ec2-user@es-coordinater yum.repos.d]$ sudo systemctl status logstash.service
● logstash.service - logstash
   Loaded: loaded (/etc/systemd/system/logstash.service; disabled; vendor preset: disabled)
   Active: active (running) since Sun 2021-09-26 20:14:35 KST; 10s ago
 Main PID: 32685 (java)
   CGroup: /system.slice/logstash.service
           └─32685 /usr/share/logstash/jdk/bin/java -Xms1g -Xmx1g -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly -Dj...

Sep 26 20:14:35 es-coordinater systemd[1]: Started logstash.
Sep 26 20:14:35 es-coordinater logstash[32685]: Using bundled JDK: /usr/share/logstash/jdk
Sep 26 20:14:35 es-coordinater logstash[32685]: OpenJDK 64-Bit Server VM warning: Option UseConcMarkSweepGC was deprecated in version 9.0 and will likely be...e release.
Sep 26 20:14:43 es-coordinater logstash[32685]: /usr/share/logstash/vendor/bundle/jruby/2.5.0/gems/bundler-1.17.3/lib/bundler/rubygems_integration.rb:200: w...deprecated
Hint: Some lines were ellipsized, use -l to show in full.
  • Logstash 관리 기능 설정

Kibana에서 Logstash 관리 기능의 사용이 가능하다. 먼저 사용자 중에 logstash_admin 권한을 가진 사용자가 필요하다. Kibana 에서 logstash-admin-user 라는 이름으로 사용자를 추가한다. 이 사용자에게는 logstash_admin 그리고 logstash_system 권한을 부여한다.

키바나에 접속해서 아래와 같이 logstash-admin-user 유저를 생성한다.

1

[ec2-user@es-coordinater yum.repos.d]$ sudo vim /etc/logstash/logstash.yml

...

# 아래의 내용 추가

xpack.management.enabled: true
xpack.management.elasticsearch.hosts: "http://{마스터노드 또는 코디네이터 노드 프라이빗 아이피}:9200/"
xpack.management.elasticsearch.username: logstash-admin-user
xpack.management.elasticsearch.password: mypasswd12!
xpack.management.logstash.poll_interval: 5s
xpack.management.pipeline.id: ["apache", "cloudwatch_logs","ls-custom"]
    
[ec2-user@es-coordinater yum.repos.d]$ sudo systemctl restart kibana.service

[ec2-user@es-coordinater yum.repos.d]$ sudo systemctl status kibana.service
● kibana.service - Kibana
   Loaded: loaded (/etc/systemd/system/kibana.service; disabled; vendor preset: disabled)
   Active: active (running) since Sun 2021-09-26 20:33:58 KST; 14s ago
     Docs: https://www.elastic.co
 Main PID: 3623 (node)
   CGroup: /system.slice/kibana.service
           ├─3623 /usr/share/kibana/bin/../node/bin/node /usr/share/kibana/bin/../src/cli/dist --logging.dest="/var/log/kibana/kibana.log" --pid.file="/run/kibana/kib...
           └─3635 /usr/share/kibana/node/bin/node --preserve-symlinks-main --preserve-symlinks /usr/share/kibana/src/cli/dist --logging.dest="/var/log/kibana/kibana.l...

Sep 26 20:33:58 es-coordinater systemd[1]: Stopped Kibana.
Sep 26 20:33:58 es-coordinater systemd[1]: Started Kibana.

그런다음에 아래와 같이 logstash 관리 화면에서 파이프라인을 추가한다.

2

input{
    tcp{
        port => 9999
    }
}

filter{
}

output{
    elasticsearch{
        hosts => ["{master 또는 코디네이트 private ip}:9200"]
        user => "elastic"
        password => "xxxxxxxxx"
    }
}

위 그림과 같이 입력은 tcp 의 9999 포트에서 입력 받아 출력은 elasticsearch 로 해보자

이제 콘솔에서 nc(NetCat) 명령을 이용해서 9999 포트로 “hello” 라는 메시지를 전송해보자

# netcat 패키지를 설치
[ec2-user@es-coordinater ~]$ sudo yum install nc -y

...

===============================================================================================================================================================
 Package                              Arch                              Version                                    Repository                             Size
===============================================================================================================================================================
Installing:
 nmap-ncat                            x86_64                            2:6.40-13.amzn2                            amzn2-core                            207 k

Transaction Summary
===============================================================================================================================================================

...                                                                                                       1/1

Installed:
  nmap-ncat.x86_64 2:6.40-13.amzn2

Complete!

# 포트 확인
[ec2-user@es-coordinater ~]$ sudo netstat -nap | grep 9999

# 9999 포트로 메시지 전송
# echo 'hello' | nc {master 또는 코디네이트 private ip} 9999 명령어를 날리면 아마 아래와 같이 에러가 날것이다.
[ec2-user@es-coordinater ~]$ echo 'hello' | nc 10.10.1.180 9999
Ncat: Connection refused.

# 현재 trial license 이므로 중앙 집중 관리 기능을 제공받지 못한다. work around도 pipeline 기능을 확인해보자.
[ec2-user@es-coordinater ~]$ sudo systemctl stop logstash.service

# -f 옵션 뒤에 파라미터로 설정 된 파일을 config로 logstash 실행
[ec2-user@es-coordinater ~]$ sudo vim /etc/logstash/conf.d/logstash.conf
input {
    tcp{
        port => 9999
        }
}

filter{
}

output{
    elasticsearch{
        hosts => ["{master 또는 코디네이트 private ip}:9200"]
                user => "elastic"
                password => "xxxxxxxxx"
        }
    stdout{}
}

[ec2-user@es-coordinater ~]$ sudo /usr/share/logstash/bin/logstash -f /etc/logstash/conf.d/logstash.conf
Using bundled JDK: /usr/share/logstash/jdk
OpenJDK 64-Bit Server VM warning: Option UseConcMarkSweepGC was deprecated in version 9.0 and will likely be removed in a future release.
/usr/share/logstash/vendor/bundle/jruby/2.5.0/gems/bundler-1.17.3/lib/bundler/rubygems_integration.rb:200: warning: constant Gem::ConfigMap is deprecated
WARNING: Could not find logstash.yml which is typically located in $LS_HOME/config or /etc/logstash. You can specify the path using --path.settings. Continuing using the defaults
Could not find log4j2 configuration at path /usr/share/logstash/config/log4j2.properties. Using default config which logs errors to the console
[INFO ] 2021-09-26 22:02:13.716 [main] runner - Starting Logstash {"logstash.version"=>"7.14.0", "jruby.version"=>"jruby 9.2.19.0 (2.5.8) 2021-06-15 55810c552b OpenJDK 64-Bit Server VM 11.0.11+9 on 11.0.11+9 +indy +jit [linux-x86_64]"}
[WARN ] 2021-09-26 22:02:14.153 [LogStash::Runner] multilocal - Ignoring the 'pipelines.yml' file because modules or command line options are specified
[INFO ] 2021-09-26 22:02:16.005 [Api Webserver] agent - Successfully started Logstash API endpoint {:port=>9600}
[INFO ] 2021-09-26 22:02:16.771 [Converge PipelineAction::Create<main>] Reflections - Reflections took 130 ms to scan 1 urls, producing 120 keys and 417 values
[WARN ] 2021-09-26 22:02:17.757 [Converge PipelineAction::Create<main>] tcp - Relying on default value of `pipeline.ecs_compatibility`, which may change in a future major release of Logstash. To avoid unexpected changes when upgrading Logstash, please explicitly declare your desired ECS Compatibility mode.
[WARN ] 2021-09-26 22:02:17.915 [Converge PipelineAction::Create<main>] elasticsearch - Relying on default value of `pipeline.ecs_compatibility`, which may change in a future major release of Logstash. To avoid unexpected changes when upgrading Logstash, please explicitly declare your desired ECS Compatibility mode.
[INFO ] 2021-09-26 22:02:18.189 [[main]-pipeline-manager] elasticsearch - New Elasticsearch output {:class=>"LogStash::Outputs::ElasticSearch", :hosts=>["//10.10.1.180:9200"]}
[INFO ] 2021-09-26 22:02:18.743 [[main]-pipeline-manager] elasticsearch - Elasticsearch pool URLs updated {:changes=>{:removed=>[], :added=>[http://elastic:xxxxxx@10.10.1.180:9200/]}}
[WARN ] 2021-09-26 22:02:19.016 [[main]-pipeline-manager] elasticsearch - Restored connection to ES instance {:url=>"http://elastic:xxxxxx@10.10.1.180:9200/"}
[INFO ] 2021-09-26 22:02:19.076 [[main]-pipeline-manager] elasticsearch - Elasticsearch version determined (7.14.1) {:es_version=>7}
[WARN ] 2021-09-26 22:02:19.079 [[main]-pipeline-manager] elasticsearch - Detected a 6.x and above cluster: the `type` event field won't be used to determine the document _type {:es_version=>7}
[WARN ] 2021-09-26 22:02:19.179 [[main]-pipeline-manager] elasticsearch - Configuration is data stream compliant but due backwards compatibility Logstash 7.x will not assume writing to a data-stream, default behavior will change on Logstash 8.0 (set `data_stream => true/false` to disable this warning)
[WARN ] 2021-09-26 22:02:19.180 [Ruby-0-Thread-10: :1] elasticsearch - Configuration is data stream compliant but due backwards compatibility Logstash 7.x will not assume writing to a data-stream, default behavior will change on Logstash 8.0 (set `data_stream => true/false` to disable this warning)
[INFO ] 2021-09-26 22:02:19.267 [Ruby-0-Thread-10: :1] elasticsearch - Using a default mapping template {:es_version=>7, :ecs_compatibility=>:disabled}
[INFO ] 2021-09-26 22:02:19.291 [[main]-pipeline-manager] javapipeline - Starting pipeline {:pipeline_id=>"main", "pipeline.workers"=>4, "pipeline.batch.size"=>125, "pipeline.batch.delay"=>50, "pipeline.max_inflight"=>500, "pipeline.sources"=>["/etc/logstash/conf.d/logstash.conf"], :thread=>"#<Thread:0x252fc3e4 run>"}
[INFO ] 2021-09-26 22:02:20.481 [[main]-pipeline-manager] javapipeline - Pipeline Java execution initialization time {"seconds"=>1.19}
[INFO ] 2021-09-26 22:02:20.624 [[main]-pipeline-manager] javapipeline - Pipeline started {"pipeline.id"=>"main"}
[INFO ] 2021-09-26 22:02:20.654 [[main]<tcp] tcp - Starting tcp input listener {:address=>"0.0.0.0:9999", :ssl_enable=>false}
[INFO ] 2021-09-26 22:02:20.726 [Agent thread] agent - Pipelines running {:count=>1, :running_pipelines=>[:main], :non_running_pipelines=>[]}

...

# 터미널을 하나 더 띄우고 아래와 같이 명령어를 실행하여 메세지를 전송해본다.
[ec2-user@es-coordinater ~]$ echo 'hello' | nc {master private ip} 9999

그리고 키바나에 접속해서 아래와 같이 logstash-* 인덱스를 확인 해 보면 "message": "hello" 인 도큐먼트가 입력된 것을 확인할 수 있다.

3

  • 기본 Template 설정

_template API를 사용하면 특정한 인덱스 이름등에 대해서 setting, mapping 등의 값들을 미리 정해줄 수 있다. GET /_cat/templates 또는 GET /_templates/ 템플릿이름을 이용해서 지금 설정되어 있는 템플릿들과 세부 내용들을 볼 수 있다.

ex) GET /_cat/templates?v&s=name

4

Elasticsearch가 가지고 있는 몇가지 기본 설정들이 있는데, 클러스터가 작고 노드가 3개밖에 없으므로 몇가지 기본 설정을 아래와 같이 변경해보자.

5

PUT _template/basic
{
  "index_patterns" : ["*"],
  "order": "0",
  "settings": {
    "number_of_shards": 1,
    "refresh_interval": "10s"
  }
}

"index_patterns" : ["*"] : 앞으로 이 클러스터에서 생성될 모든 인덱스에 적용한다.

"order": "0" : 이 값이 높을수록 템플릿의 우선순위가 높으며, 지금 만든 basic 템플릿은 우선순위가 0으로 가장 낮다. logstash-* 와 같은 인덱스 패턴에 적용되는 또다른 템플릿이 order:1 등으로 설정되게 되면 해당 이름의 인덱스들은 더 높은 우선순위의 템플릿을 적용받는다.

"settings.number_of_shards": 1 : 기본 샤드 개수를 5개 –> 1개로 변경

"settings.refresh_interval": "10s" : refresh 주기를 1초 –> 10초 로 변경

이제 Logstash 설치와 템플릿 설정도 모두 끝났다. 클러스터에 데이터를 입력하고 사용할 준비를 모두 마쳤다.

  • es에서 자주사용하는 명령어
# 서비스 시작
sudo systemctl start elasticsearch.service
sudo systemctl start kibana.service
sudo systemctl start metricbeat.service
sudo systemctl start logstash.service

# 서비스 확인
sudo systemctl status elasticsearch.service
sudo systemctl status kibana.service
sudo systemctl status metricbeat.service
sudo systemctl status logstash.service

# 서비스 재시작
sudo systemctl restart elasticsearch.service
sudo systemctl restart kibana.service
sudo systemctl restart metricbeat.service
sudo systemctl restart logstash.service

# kibana 기본 인덱스 삭제
curl -X DELETE 'http://{master private ip}:9200/.kibana*' -u {username}:{password}

# 자세한 로그 확인
journalctl -fu kibana.service
journalctl -fu elasticsearch.service