[2SeC] 트러블슈팅: Logstash -> Opensearch 로그가 안 들어가는 이슈...
December 18, 2025
ECS 환경과 로컬 Docker 테스트의 결정적인 차이
0. 문제 상황 요약
2SeC-SIEM 프로젝트에서
Kinesis → Logstash(ECS Fargate) → OpenSearch 파이프라인을 구축하던 중,
Logstash 컨테이너는 정상적으로 실행되는데 OpenSearch에 로그가 전혀 적재되지 않는 문제가 발생했다.
겉으로 보기에는 단순 연결 문제처럼 보였지만, 실제로는 다음 요소들이 복합적으로 얽혀 있었다.
- Logstash 베이스 이미지 선택 문제
- OpenSearch output 플러그인 미설치
- 패턴 파일 권한 문제
- 환경 변수 미주입
- IAM 인증 방식에 대한 오해
- ECS 환경과 로컬 Docker 환경의 근본적인 차이
이 글에서는 하루 동안 이 문제를 어떻게 좁혀갔고, 최종적으로 무엇을 확인했는지를 정리한다.
1. 최초 증상: “Logstash는 도는데 OpenSearch에 로그가 없다”
ECS에서 Logstash 태스크는 다음 상태였다.
- 컨테이너 상태: RUNNING
- Logstash 기동 로그: 정상
- pipeline 로딩 로그: 정상
하지만 OpenSearch Dashboard에서는
- 인덱스가 생성되지 않음
_cat/indices결과 없음
즉, Logstash → OpenSearch output 단계에서 문제가 발생하고 있었다.
2. 첫 번째 원인: Logstash 기본 이미지에는 OpenSearch output이 없다
처음 사용하던 이미지는 다음이었다.
docker.elastic.co/logstash/logstash:8.11.0
이 이미지는 ElasticSearch 기준 이미지이며, opensearch {} output 플러그인이 기본 포함되어 있지 않다.
로컬 테스트 시 바로 다음 에러가 발생했다.
Couldn't find any output plugin named 'opensearch'
해결 방법
OpenSearch 공식 Logstash 이미지를 사용하도록 변경했다.
이 이미지에는 다음이 포함되어 있다.
• logstash-output-opensearch
• OpenSearch OSS 호환 설정
👉 이 단계에서 output 플러그인 미설치 문제는 해결
3. 두 번째 원인: 패턴 파일은 있는데 Permission denied
이미지를 빌드한 뒤 컨테이너 내부를 확인했을 때, 이상한 상태를 발견했다.
ls -l /usr/share/logstash/patterns
-????????? attack_patterns.yml
-????????? patterns_matcher.rb
-????????? severity_mapping.yml
파일은 존재하지만 권한을 읽을 수 없는 상태였다. 원인은 명확했다.
- COPY는 되었지만
- logstash 유저가 읽을 수 없는 권한
해결 방법
Dockerfile에서 명시적으로 권한과 소유자를 지정했다.
확인 결과
-rw-r--r-- 1 logstash logstash attack_patterns.yml
-rw-r--r-- 1 logstash logstash patterns_matcher.rb
-rw-r--r-- 1 logstash logstash severity_mapping.yml
4. 세 번째 원인: 로컬에서 opensearch output이 계속 죽는 이유
stdin → stdout 구조로 단순화해도 다음 에러가 반복 발생했다.
undefined method `credentials' for nil:NilClass
이 에러는 logstash-output-opensearch 내부에서 AWS SigV4 인증용 credentials 객체가 없을 때 발생한다.
즉, Logstash는 다음을 기대하고 있었다.
- ECS Task Role
- 또는 EC2 Instance Profile
- 또는 IRSA / Metadata 기반 IAM 자격증명 하지만 로컬 Docker 컨테이너에는 그 어떤 IAM 컨텍스트도 존재하지 않았다.
5. 결정적인 차이: ECS에서는 되지만 로컬에서는 안 되는 이유
ECS 환경에서는
- Task Role이 자동 주입됨
- AWS SDK가 metadata endpoint에서 credentials 획득
- auth_type => aws_iam 정상 동작
로컬 Docker 환경에서는
- IAM Role 없음
- Metadata endpoint 없음
- AWS SDK가 credentials를 얻지 못함
- 결과적으로 nil.credentials 에러 발생
👉 즉, 로컬에서 실패한 것은 설정 오류가 아니라, 실행 환경의 한계였다.
6. terraform.tfvars에서의 실수도 있었지만, 본질은 아니었다
중간에 terraform.tfvars에 다음과 같은 값이 남아 있었던 것도 발견했다.
이는 분명 ECS 배포 시 문제가 될 수 있는 설정이지만,
로컬 테스트에서 발생한 IAM 에러의 직접 원인은 아니었다.
7. 그래서 지금 상태는?
정리하면 현재 상태는 다음과 같다.
-
Logstash 이미지
-
OpenSearch output 포함
-
Kinesis input 포함
-
패턴 파일 정상 로딩
-
-
Logstash pipeline
-
문법 오류 없음
-
필터 단계 정상
-
-
ECS 환경 기준
-
IAM Role 기반 OpenSearch 접근 가능
-
구조적으로 로그 유입 가능
-
즉, 로컬 Docker에서는 IAM 인증 때문에 실패하지만, ECS 환경에서는 정상 동작할 가능성이 매우 높다.
8. 오늘의 교훈
- Logstash 로컬 테스트는 IAM 기반 output을 완전히 검증할 수 없다
- ECS + Task Role 환경을 기준으로 판단해야 한다
- OpenSearch를 쓸 경우 Elastic 공식 이미지가 아닌 OpenSearch OSS 이미지를 써야 한다
- Dockerfile에서 파일 권한은 항상 의심하자
- 에러 메시지보다 실행 환경 차이를 먼저 보자
9. 다음 액션
- PR 병합
- ECS에서 이미지 재배포
- OpenSearch Dashboard에서 인덱스 생성 여부 확인
- 필요 시 CloudWatch Logs로 Logstash output 확인
오늘은 “왜 안 되는지”를 이해한 날이고, 이해한 만큼 다음 단계는 훨씬 빠를 것이다.