블로그 ELK 스택 도입 -1-

프로필

2025년 02월 15일

96 0

왜 로그 관리를 고민하게 됐는가?

가끔씩 인스턴스에 접속해 로그를 한번씩 확인하는데, 봇넷들의 악의적인 요청이 계속 들어오고 있었다.
문제는 내가 그 로그를 확인하려면 ssh로 직접 인스턴스에 접속해서 docker-compose logs 로 확인해야 했는데, 내가 매일마다 로그를 확인할 수도 없을 뿐더러, 최근에는 취업 준비때문에 기능 개발을 하지 않아서 더더욱 인스턴스에 접속할 일이 없었다.

또한 현재 CD 파이프라인을 보면
1. 변경사항 커밋
2. Github Actions가 Docker 이미지 빌드 및 Docker Hub에 Push
3. OCI Instance에서 최신 이미지 Pull
4. 서버 Down & Up

이런 식으로 진행되는데 이 흐름은 컨테이너 재시작 시 stdout 로그가 사라진다는 치명적인 문제가 있었다.
Docker 자체적으로 /var/lib/docker/containers 경로에 로그가 남긴 하지만, docker-compose logs 로는 재시작 이후 확인할 수 없었다.

첫 번째 시도 : GitHub Actions로 로그 수집

처음부터 ELK 같은 대규모 수정을 할 생각은 없었다. 그냥 간단히 로그를 Cron으로 매일 0시에 따로 저장해서 그걸 GitHub Actions Artifacts로 저장하는 비교적 간단한 방식을 시도했다.

 - name: Collect logs

 uses: appleboy/ssh-action@v1.0.0

 with:

 host: ${{ secrets.OCI_HOST }}

 username: ${{ secrets.OCI_USERNAME }}

 key: ${{ secrets.OCI_SSH_KEY }}

 script: |

 cd /home/ubuntu/ && \

 mkdir -p logs && \

 docker-compose logs --no-color > logs/app-$(date +%Y%m%d).log



 - name: Create temporary SSH key file

 run: |

 echo "${{ secrets.OCI_SSH_KEY }}" > /tmp/oci_key

 chmod 600 /tmp/oci_key



 - name: Download logs to GitHub Actions

 run: |

 mkdir -p ~/.ssh

 ssh-keyscan -H ${{ secrets.OCI_HOST }} >> ~/.ssh/known_hosts

 scp -i /tmp/oci_key -r ${{ secrets.OCI_USERNAME }}@${{ secrets.OCI_HOST }}:/home/ubuntu/logs ./logs/



 - name: Upload logs as artifact

 uses: actions/upload-artifact@v4

 with:

 name: app-logs

 path: ./logs/



 - name: Clean up temporary SSH key file

 run: |

 rm /tmp/oci_key

이런 식으로 수정을 하고 직접 실행을 시켜봤는데 직접 테스트를 해보니 예상치 못한 문제가 있었다.

위에서 언급했듯 이 workflow가 실행되는 순간 서버는 잠시 다운되고 다시 켜지는데, 그 타이밍에 저장된 로그라곤 놀랍게도 이게 전부였다.

또한 이 workflow는 기존 workflow에 로그 수집 과정을 추가해놓은 거라 결국엔 내가 하루에 한번은 workflow를 실행시켜야 할 필요가 있었고, 이건 너무 비효율적이라는 생각이 들었다.

두 번째 시도 : ELK 스택 도입으로 전환

그러다 불현듯 든 생각이 최근에 면접을 진행하면서 포트폴리오를 정리했었는데, MusicLab 프로젝트에서 DB에 저장된 데이터를 검색할 때 상세 검색 기능 구현을 위해서 Full-Text Search Index, Elasticsearch 등의 키워드를 검색해보고, 실제로 면접관 중 한 분이 검색 파트를 담당하시는 분이어서 질문을 드렸던 걸 떠올려서, 어차피 로그 관리도 해야하고 현재 블로그의 검색 기능도 한국어 상세 검색을 지원하지 못한다는 걸 확인했기에

ELK 스택을 도입하면 단순히 로그 유실 문제를 해결할 뿐만 아니라, 실시간 로그 시각화, 검색 가능한 로그 데이터, 향후 시스템 모니터링 기능 확장까지 가능하다. 이런 강점들을 생각해보니 "이왕 하는 거 끝을 보자"는 결론이 나왔다.

실제로 내 이력서의 포트폴리오 설명에도 적혀 있지만, 이 블로그는 처음부터 단순한 포트폴리오 용이 아니라 내가 실제로 앞으로 습득할 기술 스택들을 직접 적용해볼 수 있는 나만의 스케치북을 목표로 제작된 블로그다.

나는 바로 기존 docker-compose.yml을 수정해 Elasticsearch, Logstash, Kibana를 각각 컨테이너로 띄우고, 기존 FastAPI의 uvicorn 기본 로그는 ELK에서 바로 파싱하기 어렵기 때문에, python-json-logger를 이용해서 ELK에 적합한 JSON 형태로 수정했다.

그 후에 NGINX 설정을 진행하고, 설정된 경로로 Kibana 접속을 시도해 봤는데 나를 반겨주는 건

"404 Not Found."

여기서부터 NGINX + Kibana와의 끝없는 싸움이 시작됐다. 이 삽질의 기록은 다음 포스팅에서 풀어보려고 한다.

#ELK #Elasticsearch #Logstash #Kibana

댓글 개

댓글을 작성하려면 로그인이 필요합니다