AWSInfra

Beanstalk docker 사용시 발생하는 컨테이너 로그를 제거하기 삽질

AWS beanstalk 의 docker 를 이용해서 서버를 구동할 때 /var/lib/docker 하위에 발생하는 docker 컨테이너 로그로 인하여 디스크 용량이 가득차는 문제가 발생하였다. 주기적으로 배포 또는 인스턴스 교체를 통해서 해당로그를 삭제 할 수 있지만, 잦은 업데이트가 발생하지 않을 경우 결국 desk full 로 이어져 장애에 빠지곤 하였다. 이를 해결 하기 위해 /var/lib/docker 하위에 발생하는 로그를 로테이트 하는 방법에 대한 삽질과 그 결과를 공유한다.

Elastic Beanstalk 이 로그를 저장하고 Cloud Watch Logs 로 전달 하는 방식

  • docker logs -f {contrainerId}를 이용해서 /var/log/eb-docker/containers/eb-current-app/ 경로에 로그를 저장함

      ## /opt/elasticbeanstalk/containerfiles/support/eb-docker.conf
      ## EB_CONFIG_DOCKER_CURRENT_APP 는 도커 컨테이너 ID
      ## 28번라인
      docker logs -f $EB_CONFIG_DOCKER_CURRENT_APP >> /var/log/eb-docker/containers/eb-current-app/$EB_CONFIG_DOCKER_CURRENT_APP-stdouterr.log 2>&1
    
    • 앱 배포시마다 명령이 수행되며 docker logs 명령을 kill 할 경우 docker runtime 을 관리하는 runc 에서 컨테이너 전체를 재시작 하게 됨(즉 도커로 작동하고 있는 어플리케이션 서버가 다시 실행됨)
  • 도커는 자체적으로 로그를 /var/lib/docker/containers/{containerId}/ 경로에 로그를 저장함
  • Cloud Watch Logs로 로그를 전달 하는 것은 awslogs서비스의 역활
    • awslogs/var/log/eb-docker/containers/eb-current-app/의 로그파일들을 감시하고 로그를 전송함
    • awslogs는 로그 파일을 전공하고 end postion을 기록함 (자신이 보낸 로그의 마지막을 기록 하는거 같음)
    • 만약 감시 하고 있는 로그 파일의 변화가 생기면 파일의 start position 을 첫줄로 변경
      • 변경이 생긴것을 감지 하거나 새로운 파일로 인식해야 하는 것 같음

Docker 의 기본 로그를 rotate 하고 awslogs를 이용하여 cloud watch logs 로 로그를 전송하는 방법

  • 2가지 방법으로 적용이 가능 할 것으로 예상
    1. docker의 기본 로그 옵션을 이용하여 파일 용량과 저장 갯수를 제한 하는 방법
      • —log-opt max-size=10M —log-opt max-file=5형식으로 사용
      • docker 에서 자동으로 로그를 관리 하고 docker logs -f 명령을 통해 로그를 전송하는데 문제가 없음
      • docker run 수행시 옵션을 추가로 넣어줘야 한다.
        • beanstalk 이 docker run 명령을 수행하기 때문에 명령을 수행하는 beanstalk 스크립트를 변경해야 함
    2. logroate를 이용하여 로그 파일의 용량과 저장 갯수를 제한 하는 방법
      • linux 에 설치 된 logrotate 를 이용하기 때문에 beanstalk 스크립트를 수정 할 필요가 없음
      • logrotate를 통해 도커 로그를 잘라낼 경우 docker logs -f 명령으로 로그를 출력하던 명령이 멈춤
        • /var/log/eb-docker 내에 저장 되던 로그 파일에 더이상 기록이 안됨
      • docker logs 명령을 다시 실행 할 경우 로그를 자른 위치부터 로그가 출력됨
      • 기존에 beanstalk 이 실행한 docker logs -f 명령을 삭제 할 경우 runc 에 의해 다시 실행이 됨(docker 전체의 재시작이 됨)
  • awslogs의 문제점
    • 로그 파일의 현재 위치를 저장하고 있기 때문에 로그파일이 변경점이 생겼을 경우 자동으로 감지하여 시작위치를 0으로 변경하지 않으면 로그를 정상적으로 전달 할 수 없음
    • /var/log/eb-docker의 로그파일을 logrotate를 이용하여 강제로 잘라낼 경우 간혹 파일 변경을 감지하고 시작을 0으로 설정하여 다시 로그를 전공하기 도함

결론

  • /var/lib/docker 하위에 생성되는 로그 파일의 rotate를 설정 할 수는 있지만 그럴 경우 awslogs 로 cloud watch 에 파일을 전송 하는 것에 문제가 발생함
  • 결국 /var/lib/docker 하위에 발생하는 로그를 로테이트 하기 위한 방법을 찾지 못하였다. 빈즈톡의 로그를 클라우드 와치에 전송하지 않을 것이라면 logrotate 설정을 추가 하는 것 만으로도 해결이 가능하다.
    • 단, /var/log/eb-docker/ 하위에 생성되는 콘솔 로그에 로그가 기록되지 않는다.
    • docker 자체의 log-opt 옵션을 통해서 설정하는 것이 가장 좋다.
  • 나중에 시간이 된다면 docker 의 자체 옵션을 이용해서 하는 방법을 이용해봐야 겠다.