2015년 3월 5일 목요일

rsyncd 를 이용한 로그 중앙화

로그 중앙화

플랜

  1. 로그 중앙화 비교
    • http://resoliwan.blogspot.kr/2015/02/logstash-vs-flume-vs-fluentd.html
    • 위와 같은 상황에서 rsyslog logstack 등을 고려 했으나 회사에서 정책상 rsyncd 로 로그 중앙화를 구현 하기로 했다.
    • 솔직이 로그 만이라면 rsyslog 또는 logstack 등을 추천하고 싶다
    • 필자의 경우 백업 파일도 한곳에 집중시켜야 되서…
  2. 플랜
    • 각각의 서버에서 logrotate 를 사용해서 모든 로그를 1일치씩 잘라낸다.
    • 각각의 서버에 rsyncd 데몬을 뛰우고 중앙 로그 서버에서 크론탭을 사용하여
    • 특정 시간에 동기화를 수행
  3. 조언
    • 중앙 집중화를 할려고 시도 한다면 실제 운영하는 서버의 대수 자체가 많은 경우일 것이다.
    • 중앙 집중화가 문제가 아니라. 모든 서버의 설정을 살펴봐야 하며 로그를 하루별로 분리하기 위해서 모든 프로세스의 설정을 체크해야 하는 대규모 공사가 된다.
    • 일정을 넉넉하게 잡고.. 업데이트날 최대한 사전작업을 해두자…

실행

  1. 정보수집
    • 모든 서버의 주소 프로세스 컨피그 등을 수집하여 리스트를 만든다.
      rel-lb                      ip
      프로그램 1
         실행자1 컨피그 주소1
      프로그램 2 
         실행자2 컨피그 주소2
      mongos
         ongod /usr/bin/mongos -f /opt/thirdparty/mongos.conf
      
    • 위와 같은 각각의 서버별 실행 되는 프로세스 정보를 모은다.
    • 위와 같은 상황에서 잘관리하지 않았으면 컨피그 파일과 실행하는 유저등이 서버마다 다 다를 것이다.
    • 그러므로 모든 애들을 이번기회에 규격화 한다고 맘을 편하게 먹
  2. 컨피그설정 만들기
    • 모든 서버에 대해서 컨피그 설정을 만든다.
      rel-lb
       /program1/conf
       /program2/conf
       /program3/conf
      
    • 해당 설정은 좀위에서 수집한 정보를 기준으로 각각의 서버에서 실제 돌아가고 있는 컨피그 들을 수집해 만들어야 한다.
  3. 각각의 설정 들의 정규화
    • 로그 위치를 만들고 모든 서버에 동일한 구조를 생성한다.
      /data/log/프로그램1
      /data/log/프로그램2
      /data/log/프로그램3
    • 꼭 파일 용량을 생각해서 /data 를 새로운 저장 장소로 mount 하는 방법도 고려해야한다.
    • 또한 로그 중앙 서버의 경우 넉넉한 저장장소를 최초부터 추가하는걸 추천한다.
  4. 실행되는유저와 폴더 구조 권한을 확인
    • 예전에 사용하던 로그 폴더의 권한과 실행시키는 유저를 꼭 확인하고 해당 권한과 유저는 새로운 설정에도 적용되어야한다.
    • 몽고디비 같은 경우는 로그를 적지 못하면 디비가 죽는 경우도 발생한다.
  5. 정보수집 리스트와 컨피그 설정을 만들고 모든 디렉토리를 정규화 하고 유저 권한을 확인했다면
    • 이제 rsyncd 데몬을 이용하여 중앙 집중화를 할 준비가 된것이다.

rsync?

  1. 장점
    • 디렉토리를 동기화 시키는대 좋다.
    • scp 보다 빠르다.
    • increment 된 파일만 받아온다
  2. 단점
    • 실시간 동기화를 요구하면 사용할수 없다.
    • 데몬을 뛰어야 하는경우가 많다.
    • 암호화가 안된다. (신뢰할수 있는 네트워크에서만 사용하자)
    • 찾다보니 ssl 위에서 동작하게 할수 있다고도 하는대 필자는 신뢰할수 있는 네트워크라….:)
  3. 비교
    • scp vs rsync
    • 그냥 일할때는 scp
    • 배치 잡일때는 rsync
  4. 어떻게 동작할것인가?
    • 서버에 rsyncd 데몬을 뛰운다.
    • 데몬을 뛰우는 이유는 모듈을 사용하기 위해서이다.(실 유저와 절대 같은 비밀 번호 사용 금지)
    • 모듈별 유저를 설정 할수 있어서 디렉토리 권한과 관련된 에러를 쉽게 피할수 있다.
    • 모듈화가 되서 관리가 좀더 편하다
    • 설정을 하고 rsyncd를 뛰운다.
    • logroate를 설정해서 모든 로그 들을 1일치씩 잘라낸다.

실제 설정


rsync 설정

  1. rsysncd 컨피그 예제
     # /etc/rsysncd.conf
     lock file = /var/run/rsync.lock
     log file = /data/log/rsyncd/rsyncd.log
     pid file = /var/run/rsyncd.pid
     #자기 자신도 로그를 남긴다.
     [rsyncdModule]
         path = /data/log/rsyncd
         comment = rsyncdModule
         uid = 해당 모튤에 접근시 사용할 유저
         gid = 해당 모튤에 접근시 사용할 그룹
         read only = no
         auth users = 접속할수있는 유저 rsyncd.secrets에 정의
         secrets file = /etc/rsyncd.secrets
         hosts allow = 중앙 로그서버 ip
     [모듈2]
         path = /data/log/mongo
         comment = mongodModule
         uid = ?
         gid = ?
         read only = no
         auth users = ?
         secrets file = /etc/rsyncd.secrets
         hosts allow = ?
    
  2. rsyncd.secrets 바말번호
    • 비밀번호가 그냥 적힌다… 왜 유저와 비번을 다르게 설정해야 되는 이유중 하나~!:)
      # /etc/rsyncd.secrets
      유저명:비번
      
    • 아래와 같이 권한을 바꿔주어야 동작한다.
      sudo chmod 600 /etc/rsyncd.secrets
      
  3. xinetd.d
    • 머하는 애인가? extend internet daemon 이다. 즉 인터넷 관련 데몬을 관리하는 애다.
    • 없으면 install 하자
      #rsync
      service rsync
      {
      disable         = no
      socket_type     = stream
      port            = 873
      protocol        = tcp
      wait            = no
      user            = root
      server          = /usr/bin/rsync
      server_args     = --daemon
      log_on_failure  += USERID
      }
      
    • xinetd 실행하기
      sudo /etc/init.d/xinetd restart
      
  4. 자이제 실제 잘 동작하는지 확인해 보자
    • 접속하기
      rsync rsync://id@localhost
      
      logModule log folder
    • 로그 확인하기

logrotate 설정

  1. 머하는 애인가?
    • 리눅스에서 기본적으로 제공하는 로그 로테이터다.
    • 대부분의 프로그램이ㅣ 지원하며 설정할 경우 특정 시간마다 새로운 파일에 로그를 적개 할수있다.
  2. 설정해보자
     # /etc/logroate.d/rsyncd
     /data/log/rsyncd/*.log {
         daily
         dateext
         dateformat -%Y-%m-%d
         missingok
         rotate 52
         compress
         copytruncate
         ifempty
         create 640 owner group
         sharedscripts
         postrotate
                /etc/init.d/xinetd restart > /dev/null 2>&1 || true
         endscript
       }
    
    • daily
      매일 로그 파일을 돌리겠다.
    • dateext
      로그 파일명을 날짜를 사용하겠다
    • dateformat
      -2013-01-02 포멧을 postfix 로 사용하겠다.
    • missingok
      파일이 없어도 상관없다
    • rotate 52
      52개가 넘어가면 예전 파일을 덥어 쓰겠다.
    • compress
      예전 파일을 압축하겠다.
    • ifempty
      로그가 빈 파일이라도 로테이트 시키겠다 로그가 size 0 일때도 (관리측면에서 하는게 좋음)
    • create 640 유저 그룹
      로테이된 로그 파일에 권한 유저 그룹을 주겠다
    • sharedscripts
      하나의 설정에서의 모든 로그 *.log 가 로테이트 된후 postrotate를 호출하겠다.
      대부분의 프로그램마다 설정하는 방법이 있다 구글링하자
    • postrotate
      로그로테이트 한 후 원 프로그램에 알려 변경된 파일에 로깅을 적으라고 알림
    • olddir
      로테이트된 로그를 해당 폴더로 옴김
    • copytruncate
      복사후 잘라내라 (동기화 오류등을 대비하기 위해서 늘 설정하기를 추천 한다.)
  3. postscript
    • 본인이 실제 실서버에서 사용한 애들의 설정이다.
    • 대부분의 메이저 프로그램이 logroate 를 지원함으로 구글링하
      #nginx
      [ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
      #mongs
      killall -SIGUSR1 mongos  > /dev/null 2>&1 || true
      find /data/log/mongos/ -type f -regex ".*.log\..*" -exec rm -rf {} \;        
      #mongod
      killall -SIGUSR1 mongod  > /dev/null 2>&1 || true
      find /data/log/mongo/ -type f -regex ".*.log\..*" -exec rm -rf {} \;
      #rsyncd
      /etc/init.d/xinetd restart > /dev/null 2>&1 || true
      
    • mongo나 mongos의 경우 로그 로테이트를 하면 더미 파일을 남긴다 해서 해당 파일을 삭제한다.
  4. 확인해보자
    • 아래의 방식으로 확인 할수있다
    • 확인 후 로테이트된 파일의 권한을 원래 해당 로그의 권한으로 바꾸어 놓
      logrotate -vf /etc/logrotate.d/mongos
      
  5. 주의사항
    • 원본로그 파일, 생성될 로그파일(conf.create ), 해당 디렉토리의 소유자와 그룹이 다같아야한다.
      소유자와 그릅은 다를수 있지만 3개의 모두 동일한 소유자와 동일한 그룹이가지고 있어야한다.

log 서버 설정

  1. 플랜
    • 크론에 쉡스크립트를 등록해 정해진 시간에 동기화 실행
    • 에러가 발생된 경우 이멜로 전송
  2. 구현
    • 크론등록
      #cron_rel_server.sh
      crontab -e
      0 4 * * * /폴더/cron_rel_server.sh  >> /data/log/폴더/log_file-$(date +"\%Y-\%m-\%d").log 2>&1
      
    • 크론에서 %는 \ 로 이스케이프 해주어야 한다. :)
    • 매일 새벽 4시에 돌리고 해당 결과를 log_file-날짜.log 형식으로 저장
    • 통합 파일
      #!/bin/bash
      check_errs()
      {
      # Function. Parameter 1 is the return code
      # Para. 2 is text to display host.
      if [ "${1}" -ne "0" ]; then
        echo "ERROR # ${1} : ${2}"
        mail -s "rel-log sync error" id@email.com <<< "$(date) ERROR # ${1} : ${2}"
        exit ${1}
      fi
      }
      #
      . /폴더/rel_lb_co_kr.sh
      check_errs $? $host_name
      #
      . /폴더/rel_lb_com.sh
      check_errs $? $host_name
      
    • 각각의 호스트별 파일
      #!/bin/bash
      host_name="rel_lb_com"
      host_ip="ip주소"
      #
      backup_dir="/data/log"
      #
      backup_user="유저"
      tartget_user_host="$backup_user@$host_ip"
      export RSYNC_PASSWORD="비번"
      #
      dest="$backup_dir/$host_name"
      echo $host_name
      #
      #rsyncd
      rsync --exclude-from '/폴더/exclude_list.txt' --remove-source-files -zvrh $tartget_user_host::"rsyncdModule" "$dest/rsyncd";
      #
      #web_node
      rsync --exclude "로그.log-$today" --remove-source-files -zvrh $tartget_user_host::"webNodeModule" "$dest/web_node"
      
    • remove-source-files 파일을 가져오면 지운다.
    • 동기화 제외할 파일을 exclude-from 또는 exclude 둘중 하나만 사용할수 있으며 아래와 같이 설정가능하다. (날짜별 로그를 제외하기 위해)
      #exclude_list.txt
      rsyncd.log
      

  1. 압축이 안되는 로그가 있으면 크론에 압축해주는 소스를 달자