ELK Stack 이란?
- Elasticsearch, Kibana, Beats, Logstash으로 구성 된 오픈 소스 소프트웨어 스택
- 어떠한 소스에서나 어떠한 형식의 데이터든 안정적이고 보안이 유지되는 방식으로 가져온 다음 검색, 분석, 시각화하는 데 사용
Elsasticserach
- Elasticsearch는 Apache Lucene에 구축되어 배포된 검색 및 분석 엔진
- 다양한 언어를 지원하고 고성능에 스키마가 없는 JSON 문서로 다양한 로그 분석과 검색 사용 사례에 활용
Logstash
- Logstash는 다양한 소스로부터 데이터를 수집하고 전환하여 원하는 대상에 전송하는 오픈 소스 데이터 수집 도구
Kibana
- Kibana는 확장형 사용자 인터페이스로서, 데이터를 구체적으로 시각화 도구
ELK Stack 구성
💡 프로젝트에서 사용한 데이터 리소스는 Kafka 이다.
💡 X-Pack은 Elastic Stack(구 ELK Stack)의 확장 기능으로, Elasticsearch, Logstash, Kibana 등 Elastic Stack 구성 요소에 다양한 추가 기능을 제공한다.
프로젝트 내 ELK Stack을 위해 구성한 디렉토리 구조
ELK
├── elasticsearch
│ ├── config
│ │ └── elasticsearch.yml
│ ├── data
│ │ └── nodes
│ └── elastic.Dockerfile
├── kibana
│ ├── config
│ │ └── kibana.yml
│ └── kibana.Dockerfile
└── logstash
├── config
│ └── logstash.yml
├── logstash.Dockerfile
└── pipeline
└── logstash.conf
elasticsearch.yml
## Default Elasticsearch configuration from Elasticsearch base image.
## <https://github.com/elastic/elasticsearch/blob/master/distribution/docker/src/docker/config/elasticsearch.yml>
#
cluster.name: "docker-cluster"
network.host: 0.0.0.0
## X-Pack settings
## see <https://www.elastic.co/guide/en/elasticsearch/reference/current/setup-xpack.html>
#
xpack.license.self_generated.type: trial
xpack.security.enabled: true
xpack.monitoring.collection.enabled: true
- xpack.security.enabled: true : X-Pack의 보안 기능을 활성화. 보안 기능이 활성화되면 인증 및 권한 부여가 필요
logstash.yml
## Default Logstash configuration from Logstash base image.
## <https://github.com/elastic/logstash/blob/master/docker/data/logstash/config/logstash-full.yml>
#
http.host: "0.0.0.0"
xpack.monitoring.elasticsearch.hosts: [ "" ]
## X-Pack security credentials
#
xpack.monitoring.enabled: true
xpack.monitoring.elasticsearch.username: elastic
xpack.monitoring.elasticsearch.password: ${LOGSTASH_ELASTIC_PASSWORD}
- xpack.monitoring.enabled: true : Logstash가 X-Pack 모니터링 기능을 이용해서 데이터를 수집하고 Elasticsearch로 전송
- xpack.monitoring.elasticsearch.username: elastic : Lostash가 Elasticsearch로 데이터를 전송할 때 권한 인증을 위해 사용할 유저 네임
- xpack.monitoring.elasticsearch.password: ${LOGSTASH_ELASTIC_PASSWORD} : 마찬가지로 권한 인증을 위해 사용할 비밀번호
logstash.conf
# logstash.conf
input {
kafka {
bootstrap_servers => "kafka:29092"
topics => ["my_topic"]
}
}
filter {
json {
source => "message"
}
}
output {
elasticsearch {
hosts => "elasticsearch:9200"
index => "github-crawl-elasticsearch"
user => "elastic"
password => "${LOGSTASH_ELASTIC_PASSWORD}"
}
}
- logstash가 수집할 input resource를 kafka로 지정 (도커 네트워크에서 사용되는 DNS네임과 포트번호 사용)
- 구독할 토픽도 지정
- 전달 대상을 elasticseach로 지정 (마찬가지로 도커 네트워크에서 사용되는 DNS네임과 포트번호 사용)
- elastic search에서 지정한 user와 password를 설정하여 접근하기 위한 인증 정보 설정
Kibana.yml
## Default Kibana configuration from Kibana base image.
## <https://github.com/elastic/kibana/blob/master/src/dev/build/tasks/os_packages/docker_generator/templates/kibana_yml.template.js>
#
server.name: kibana
server.host: "0"
elasticsearch.hosts: [ "" ]
xpack.monitoring.ui.container.elasticsearch.enabled: true
## X-Pack security credentials
#
elasticsearch.username: p3-gc
elasticsearch.password: p3githubcrawl
- elasticsearch에 접근하기 위한 인증 정보 설정
Docker-compose.yml
services:
elasticsearch:
build:
context: "${PWD}/ELK/elasticsearch/"
dockerfile: elastic.Dockerfile
args:
ELK_VERSION: $ELK_VERSION
volumes:
- type: bind
source: "${PWD}/ELK/elasticsearch/config/elasticsearch.yml"
target: /usr/share/elasticsearch/config/elasticsearch.yml
read_only: true
- "${PWD}/ELK/elasticsearch/data:/usr/share/elasticsearch/data"
ports:
- "9200:9200"
- "9300:9300"
environment:
node.name: elasticsearch
ES_JAVA_OPTS: "-Xmx256m -Xms256m"
ELASTIC_PASSWORD: changeme
# Use single node discovery in order to disable production mode and avoid bootstrap checks
# see <https://www.elastic.co/guide/en/elasticsearch/reference/current/bootstrap-checks.html>
discovery.type: single-node
networks:
- elk
logstash:
build:
context: "${PWD}/ELK/logstash/"
dockerfile: logstash.Dockerfile
args:
ELK_VERSION: $ELK_VERSION
volumes:
- type: bind
source: "${PWD}/ELK/logstash/config/logstash.yml"
target: /usr/share/logstash/config/logstash.yml
read_only: true
- type: bind
source: "${PWD}/ELK/logstash/pipeline"
target: /usr/share/logstash/pipeline
read_only: true
ports:
- "5001:5001/tcp"
- "5001:5001/udp"
- "9600:9600"
environment:
LS_JAVA_OPTS: "-Xmx256m -Xms256m"
networks:
- elk
depends_on:
- elasticsearch
kibana:
build:
context: ELK/kibana/
dockerfile: kibana.Dockerfile
args:
ELK_VERSION: $ELK_VERSION
volumes:
- type: bind
source: "${PWD}/ELK/kibana/config/kibana.yml"
target: /usr/share/kibana/config/kibana.yml
read_only: true
ports:
- "5601:5601"
networks:
- elk
depends_on:
- elasticsearch
zookeeper:
image: wurstmeister/zookeeper:latest
container_name: zookeeper
ports:
- "2181:2181"
networks:
- elk
kafka:
image: wurstmeister/kafka:latest
container_name: kafka
ports:
- "9092:9092"
environment:
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:29092,PLAINTEXT_HOST://localhost:9092
KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:29092,PLAINTEXT_HOST://0.0.0.0:9092
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
volumes:
- /var/run/docker.sock:/var/run/docker.sock
networks:
- elk
networks:
elk:
driver: bridge
- KAFKA_ADVERTISED_LISTENERS
- Kafka 클러스터 내외부에 있는 클라이언트이 사용할 리스너의 목록을 정의. 클라이언트는 리스너를 통해 브로커에 연결
- PLAINTEXT://kafka:29092:
- PLAINTEXT: 보안이 없는 일반 텍스트 연결
- kafka:29092: Docker 네트워크 내 다른 컨테이너에서 사용될 호스트 이름과 포트로 설정
- PLAINTEXT_HOST://localhost:9092:
- PLAINTEXT_HOST: 호스트에서 접근할 때 사용할 리스너
- localhost:9092: 호스트 시스템에서 localhost:9092로 카프카에 접근 가능하도록 설정
- KAFKA_LISTENERS
- Kafka가 요청을 수신할 리스너의 주소와 포트를 설정
- PLAINTEXT://0.0.0.0:29092:
- 0.0.0.0:29092: 모든 네트워크 인터페이스의 29092 포트에서 수신 대기. Docker 네트워크 내에서 통신할 때 사용
- PLAINTEXT_HOST://0.0.0.0:9092:
- 0.0.0.0:9092: 호스트의 모든 네트워크 인터페이스에서 9092 포트에서 수신 대기. 외부 애플리케이션이 이 포트를 통해 Kafka에 접근
- 네트워크를 elk(bridge)로 통일 → 같은 네트워크상에선 DNS 네임 사용 가능
동작 확인
- Kafka + ELK Stack 실행
$ docker-compose up
- 실행 후 웹 브라우저로 키바나를 접속하기 위해 localhost:5601로 접속
- 왼쪽 메뉴에서 Stack Management
- Create index patter을 눌러 Index Pattern 생성
- Index의 경우 현재 프로젝트의 Input이 Kafka이기 때문에 설정한 토픽명과 동일하게 생성
- index pattern의 이름은 Index와 같아야 함
- timestamp field의 경우 필요에 따라 설정
- 다시 메뉴에서 Discover
- 시간 범위를 설정하여 현재까지 수집한 데이터를 눈으로 확인 가능
'개발 메모' 카테고리의 다른 글
멀티 스레딩에서 자원 공유하기 (0) | 2024.11.16 |
---|---|
Github Submodule 연결하기 (0) | 2024.10.18 |