개요
Opensearch는 AWS에서 기존의 ElasticSearch 버전을 포크(fork
)하여 개발된 프로젝트입니다.
Opensearch가 개발된 배경을 자세하게 알아보고 싶다면 링크를 참고해보세요.
이번 포스팅에서는 Opensearch + Logstash + Filebeat 조합을 활용하여 로그를 수집하는 방법에 대해서 기록해보려고 합니다.
사전 준비
디렉토리 구조
이러한 구조로 따라 만드시면 설정 파일들이 깔끔하게 나뉘어서 관리하기 좋습니다.
log-stack/
├── docker-compose.yml
├── config/
│ ├── logstash/
│ │ ├── logstash.yml
│ │ └── pipeline/
│ │ └── beats.conf
Opensearch 설치
logstash-output-opensearch
Elastic에서는 다음과 같은 logstash 이미지를 제공하고 있습니다.
docker.elastic.co/logstash/logstash
그러나 현재 위 logstash
이미지로는 Opensearch로 데이터를 정상적으로 전송할 수 없어요!
아마 위 이미지를 기반으로 opensearch로 output
을 지정하면 다음과 같은 에러가 발생할겁니다.
Couldn't find any output plugin named 'opensearch'
...
The plugin is not installed.
이를 해결하기 위해서는 logstash-output-opensearch 라는 플러그인이 필요해요.
공식 문서를 보면 해당 플러그인이 포함된 logstash-oss-with-opensearch-plugin이라는 도커 이미지를 소개해주고 있는데요!
해당 이미지는 현재 지원이 중단된 상태입니다.
그렇기 때문에 해당 플러그인이 포함된 이미지를 직접 빌드해야해요.
logstash 이미지 빌드하기
다음과 같은 Dockerfile
을 작성해주시면 됩니다.
FROM docker.elastic.co/logstash/logstash:8.13.2
# OpenSearch Output Plugin 설치
RUN bin/logstash-plugin install logstash-output-opensearch
📢 TIP
버전 정보(8.13.2)는 최신 버전에 맞게 수정해주시면 됩니다.
설정 파일 살펴보기
1. config/logstash/logstash.yml
해당 파일은 여러 파이프라인을 구성하고 설정하기 위한 파일입니다.
http.host: "0.0.0.0"
path.config: /usr/share/logstash/pipeline
2. config/logstash/pipeline/beats.yml
이제 파이프라인을 정의하는 파일을 작성해볼거에요.
input {
beats {
port => 5044
}
}
output {
opensearch {
hosts => "http://opensearch-node1:9200"
user => "admin"
password => "StrongPassword123!@#"
index => "logstash-logs-%{+YYYY.MM.dd}"
ecs_compatibility => disabled
ssl_certificate_verification => false
}
Opensearch의 보안 설정을 꺼두었다면 output.opensearch
에서 ssl_certifacate_verfication
은 false
로 해주시면 됩니다.
Docker Compose로 스택 띄우기
자세한 설치 방법은 위 링크를 참고하시면 됩니다.
아래 .yaml
파일은 한글 주석으로 변경하여 작성한 파일이니 참고해주세요.
services:
opensearch-node1:
image: opensearchproject/opensearch:latest # 최신 버전 사용 (특정 버전 명시 가능)
container_name: opensearch-node1
environment:
- cluster.name=opensearch-cluster
- node.name=opensearch-node1
- discovery.seed_hosts=opensearch-node1 # 단일 노드 설정 시 자기 자신
- cluster.initial_master_nodes=opensearch-node1 # 단일 노드 설정 시 자기 자신
- plugins.security.disabled=true # 보안 플러그인 해제
- bootstrap.memory_lock=true # Disable JVM heap memory swapping
- "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m" # JVM heap size (운영 환경에서는 시스템 메모리의 50% 이하로 설정 권장)
- OPENSEARCH_INITIAL_ADMIN_PASSWORD=StrongPassword123!@#
ulimits:
memlock:
soft: -1
hard: -1
nofile:
soft: 65536 # Max number of open files
hard: 65536
volumes:
- opensearch-data1:/usr/share/opensearch/data # 데이터 영속성을 위한 볼륨 매핑
ports:
- 9200:9200 # REST API
- 9600:9600 # Performance Analyzer
networks:
- opensearch-net
logstash:
build:
context: ./logstash
dockerfile: Dockerfile
container_name: opensearch-logstash
depends_on: [ "opensearch-node1" ]
volumes:
- ./logstash/config/logstash.yml:/usr/share/logstash/config/logstash.yml:ro
- ./logstash/pipeline:/usr/share/logstash/pipeline:ro
ports: [ "5044:5044" ]
networks: [ "opensearch-net" ]
opensearch-dashboards:
image: opensearchproject/opensearch-dashboards:latest # 최신 버전 사용
container_name: opensearch-dashboards
ports:
- 5601:5601 # OpenSearch Dashboards UI
expose:
- "5601"
environment:
# OPENSEARCH_HOSTS: '["https://opensearch-node1:9200"]' # HTTPS로 OpenSearch 노드 지정
OPENSEARCH_HOSTS: '["http://opensearch-node1:9200"]' # SSL 비활성화 시 (개발/테스트용, 보안상 권장하지 않음)
DISABLE_SECURITY_DASHBOARDS_PLUGIN: true # 브라우저로 접속 시 로그인 제거
plugins.security.enabled: "false" # 개발용으로 보안 플러그인 비활성화 시
OPENSEARCH_USERNAME: admin # OpenSearch 초기 관리자 계정 (위에서 설정한 비밀번호와 함께 사용)
OPENSEARCH_PASSWORD: StrongPassword123!@#
depends_on:
- opensearch-node1
networks:
- opensearch-net
volumes:
opensearch-data1: {}
networks:
opensearch-net:
driver: bridge
external: false
일단 저는 로그 관리를 PLG Stack 기반으로 운영 중입니다.
오픈서치는 단순히 호기심의 영역으로 구축하고자 함이라서 보안 처리는 모두 비활성화하였습니다.
만약 오픈서치를 외부로 노출할 목적으로 배포하실 예정이라면 주석된 보안 속성들은 모두 활성화하는 걸 잊지마세요!
OPENSEARCH_HOSTS
: OpenSearch Dashboards가 연결할 OpenSearch 노드의 주소를 지정.- 기본적으로 OpenSearch는 HTTPS를 사용하므로
https://
로 시작해요. - 필자의 경우 테스트용이기 때문에
http://
로 변경하였습니다.
- 기본적으로 OpenSearch는 HTTPS를 사용하므로
ulimits
: OpenSearch 성능을 위해 메모리 잠금 및 파일 디스크립터 수를 조정하는 속성입니다.
Docker Compose 실행
docker-compose.yaml
파일이 있는 경로에서 아래 명령을 실행해주세요.
docker-compose up -d --build
Opensearch 상태 확인
몇 분 정도 기다린 후에 아래 명령을 실행해 정상적으로 실행되었는지 확인해봐요.
curl -k -u admin:YourStrongAdminPassword! https://localhost:9200
# 보안 플러그인 비활성화 및 HTTP 설정 시
curl http://localhost:9200
이 때 JSON
형태의 응답이 오면 정상 실행되고 있다는 뜻입니다. cluster_name
이나 name
등이 포함된 정보가 나와요.
Opensearch 대시보드 접속하기
웹 브라우저에서 http://서버_ip:5601
로 접속해주세요.
로그인 화면이 나타나면 docker-compose.yaml
에서 설정한 admin
계정과 비밀번호로 로그인해주시면 됩니다.
클라이언트 측 에이전트 설치 및 구성
로그를 수집하여 logstash
에 전송할 에이전트를 클라이언트쪽에 설치해봅시다.
Filebeat 설치 및 구성
1. Filebeat 설치
Elasticsearch의 GPG 키를 추가하고 apt 레포지토리를 설정해주세요.
(Filebeat는 Elastic stack의 일부이지만 opensearch와 호환됩니다.)
# Elastic GPG 키 가져오기 및 저장
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo gpg --dearmor -o /usr/share/keyrings/elastic-archive-keyring.gpg
# Elastic 리포지토리 추가
echo "deb [signed-by=/usr/share/keyrings/elastic-archive-keyring.gpg] https://artifacts.elastic.co/packages/8.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-8.x.list
sudo apt update
sudo apt install filebeat -y
2. Filebeat 설정
/etc/filebeat/filebeat.yml
파일을 수정해봅시다.
sudo vim /etc/filebeat/filebeat.yml
2-1. input 설정: 어떤 로그를 수집할지 정의해줘야 해요.
filebeat.inputs:
- type: log # 또는 filestream (최신 버전 권장)
enabled: true
paths:
- /var/log/syslog # 시스템 로그 예시
- /var/log/auth.log # 인증 로그 예시
# - /var/log/nginx/*.log # Nginx 로그 예시
# - /path/to/your/application.log # 애플리케이션 로그 경로
# multiline.pattern: '^\s' # 여러 줄 로그 처리 예시 (필요시)
# multiline.negate: false
# multiline.match: after
2-2. output 설정: 수집한 로그를 어디로 내보낼지 정의해줘야 해요.
저희는 당연히 logstash
로 내보내줘야겠죠?
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/*.log
filebeat.config.modules: path: ${path.config}/modules.d/*.yml
reload.enabled: false
setup.ilm.enabled: false
setup.ilm.check_exists: false
setup.template.settings:
index.number_of_shards: 1
output.logstash:
hosts: ["localhost:5044"]
3. Filebeat 서비스 시작 및 활성화를 해줍시다.
sudo systemctl enable filebeat
sudo systemctl start filebeat
sudo systemctl status filebeat
로그 파이프라인 테스트
1. 로그 생성
클라이언트 서버에서 Filebeat가 모니터링하는 파일에 로그를 생성해봅시다.
예를 들어서, syslog
를 모니터링하도록 설정했다면
logger "테스트 로그 메시지 from Filebeat to OpenSearch"
logger "에러 발생! OpenSearch 테스트 에러 로그"
2. Opensearch dashboards에서 로그 확인해보기.
- OpenSearch Dashboards (
http://<서버_IP_또는_localhost>:5601
)에 접속합니다. - 왼쪽 메뉴에서
Management
->Stack Management
->Index Patterns
(또는 상단 검색창에 "Index Patterns" 검색)으로 이동합니다. Create index pattern
버튼을 클릭합니다.Index pattern
이름으로 Filebeat 설정에서 지정한 인덱스 패턴(예:filebeat-*
또는logstash-*
)을 입력하고 Next step을 클릭합니다.- Time field로
@timestamp
를 선택하고 Create index pattern 버튼을 클릭합니다. - 이제 왼쪽 메뉴에서 Discover를 클릭하면 수집된 로그를 확인할 수 있습니다. 오른쪽 상단의 시간 범위를 조절하여 최근 로그를 확인하세요.
트러블슈팅
Filebeat - Opensearch 호환성 문제
저는 Opensearch 구축 초기에 중간에 logstash
를 두지 않고 Filebeat -> Opensearch 직결로 로그를 전송하려고 했었는데요!
그 때 filebeat와 opensearch 연동 간에 다음과 같은 에러를 마주하였습니다.
# 클라이언트측에서 filebeat 에러 로그 조회
sudo journalctl -u filebeat -f --no-pager | grep -i 'error'
ERROR Filebeat requires the default distribution of Elasticsearch. Please update to the default distribution of Elasticsearch for full access to all free features, or switch to the OSS distribution of Filebeat.
Filebeat는 기본적으로 Elastic의 공식 Elasticsearch와 연동되도록 되어 있으며,
Opensearch는 Elasticsearch OSS(Open Source Software) 버전에서 분리된 포크 프로젝트입니다.
따라서 Elastic의 기본 Filebeat를 사용하면 OpenSearch와의 연동 시 위와 같은 에러가 발생합니다.
해결 방법 (1): logstash를 통해 Opensearch로
Elastic 사의 Filebeat는 OpenSearch로 직접 데이터를 전송하지 못하지만,
Logstash를 중간에 둬서 Filebeat → Logstash → OpenSearch 형태로 전송하는 것은 가능합니다.
그래서 현재 작성된 포스팅도 초기에는 filebeat -> opensearch 구조로 작성을 했었으나,
중간에 logstash를 두는 것으로 게시글을 다시 업데이트하였습니다.