Information Security Study

failover 동작 원리와 실습하기 본문

네트워크 캠퍼스/3차 프로젝트

failover 동작 원리와 실습하기

gayeon_ 2024. 8. 26. 16:01

failover 동작 원리와 실습하기

 

failover

 

  • IT 시스템에서 장애가 발생했을 때 서비스 중단을 최소화하기 위해 예비 시스템으로 자동으로 전환하는 메커니즘
  • 고가용성(High Availability)을 보장하기 위한 중요한 기술
  • 시스템이 장애를 겪을 때 서비스가 지속적으로 운영되도록 함

 

 

작동 원리

  • 주(primary) 시스템과 대기(standby) 시스템의 구성
  • 주 시스템이 정상적으로 작동하는 동안 대기 시스템은 준비 상태로 유지
  • 주 시스템에 장애가 발생하면 대기 시스템으로 자동으로 전환
  • 시스템 중단 시간 최소화

 

 

failover 테스트

  • 시스템이 예상치 못한 장애를 겪었을 때 예비 시스템(대기 시스템)이 정상적으로 작동하여 주 시스템을 대체할 수 있는지를 확인하는 절차
  • 시스템의 고가용성을 보장하기 위해 정기적으로 수행됨
  • 시스템이 장애를 처리하고 다른 예비 시스템으로 서비스가 정상적으로 전환되는지 확인하는 프로세스

 

 

failover 테스트 과정

 

1) 목표 설정 및 계획

  • 주 시스템에 장애가 발생했을 때 대기 시스템이 원활히 주 시스템의 역할을 이어받는지 확인
  • 테스트할 시나리오와 성공 기준 설정
  • 중요한 구성 요소(데이터베이스, 웹 서버, 네트워크 장비, 애플리케이션 서버 등)
  • 각각의 장비나 서비스를 테스트하는 계획 수립 필요

 

2) 환경 준비

  • 프라이머리(Primary) 시스템과 스탠바이(Standby) 시스템 또는 클러스터의 설정 필요
  • 각 시스템 간에 데이터 동기화 및 네트워크 설정 구성 확인

 

3) 장애 시뮬레이션

  • 주 시스템 장애 유발: 다양한 방법으로 장애를 시뮬레이션할 수 있다. 주 시스템의 특정 구성 요소를 비활성화하거나, 네트워크 연결을 차단하는 방식 등이 일반적이다.
    • 서버 장애: 물리적으로 주 서버를 종료하거나 네트워크 연결을 차단
    • 애플리케이션 장애: 주 애플리케이션이 다운되도록 의도적인 오류 발생
    • 네트워크 장애: 라우터 또는 스위치와의 연결을 끊어 네트워크 장애를 유발

 

4) failover 발생 확인

  • 장애가 발생하면 자동으로 대기 시스템(또는 다른 클러스터 노드)이 주 시스템의 역할을 인계받는지 확인
  • 전환 과정에서 서비스 중단 X, 데이터 무손실

 

5) failback 테스트

  • 주 시스템이 복구된 후 서비스가 원래의 주 시스템으로 돌아가는 과정(failback)이 정상적으로 이루어지는지 확인
  • 복구된 주 시스템이 다시 안정적으로 운영되는지 검증

 

6) 결과 분석 및 보고

  • 성공/실패 여부를 평가
  • 주 시스템이 전환되는 동안 예비 시스템이 빠르게 정상적으로 작동했는지 데이터 손실이나 지연이 없었는지 확인
  • 테스트 후 문제점이나 개선점이 발견되면 이를 문서화하고 수정

 

 

failover 테스트에서 고려해야 할 사항

  • 서비스 연속성
  • 데이터 무결성
    • Failover 과정에서 데이터 손실이나 일관성 문제가 발생 X
  • 시간 측정
    • Failover가 발생하고 예비 시스템이 완전히 활성화되는 데 걸리는 시간을 측정하여 SLA(Service Level Agreement) 기준을 충족하는지 확인
  • 알림 시스템 확인
    • 장애가 발생했을 때 모니터링 시스템이 관리자에게 적절한 알림을 보내는지 확인

 

 

failover 유형

 

1) 자동 Failover (Automatic Failover)

  • 시스템에서 장애가 감지되면 자동으로 대기 시스템으로 전환하는 방식
  • 사용자의 개입 없이 자동으로 이루어지기 때문에 매우 신속한 장애 복구 가능
  • ex) 데이터베이스 클러스터에서 한 노드가 다운되면 다른 노드가 자동으로 장애를 감지하고 역할을 대체하는 경우

 

2) 수동 Failover (Manual Failover)

  • 관리자나 운영자가 장애를 인지한 후 수동으로 대기 시스템을 활성화하는 방식
  • 자동 Failover에 비해 전환 속도가 느리지만 복잡한 상황에서 더 많은 제어 가능

 

 

failover 주요 구성 요소

 

1) 주 시스템 (Primary System)

주로 서비스를 제공하는 시스템

평상시 이 시스템이 모든 작업을 처리

 

2) 대기 시스템 (Standby System)

주 시스템에 문제가 생기면 이를 대체할 준비가 되어 있는 예비 시스템

주 스템의 데이터를 동기화하여 최신 상태를 유지

 

3) Heartbeat(심장 박동)

주 시스템과 대기 시스템 간의 연결 상태를 감시하기 위한 신호

주 시스템이 주기적으로 대기 시스템에 신호를 보내며 이 신호가 일정 시간 동안 수신되지 않으면 대기 시스템은 주 시스템이 장애를 겪고 있다고 판단하여 자동으로 전환 발생

 

 

failover 예시

  • 데이터베이스 Failover
    • 데이터베이스 클러스터에서 마스터 노드가 장애를 겪을 경우 자동으로 슬레이브 노드가 마스터 역할을 이어받아 서비스 중단 없이 데이터베이스 요청을 처리
  • 네트워크 Failover
    • 네트워크 장비에서 라우터나 스위치에 장애가 발생하면 예비 장비로 전환하여 네트워크 중단을 방지
  • 서버 Failover
    • 웹 서버가 다운되면 로드 밸런서가 자동으로 대기 중인 다른 웹 서버로 트래픽을 전환하여 서비스 중단 회피

 

 

대기 서버를 대기 상태로 두는 이유

  • 주 서버가 정상일 때는 트래픽을 분산하지 않고 리소스를 아끼며 주 서버가 장애를 일으켰을 때만 대기 서버가 활성화되어 장애 복구를 돕는다.
  • 장애 대응 및 시스템의 안정성을 높이고 자원 활용을 최적화하는데 유리하다.

 

 

실습

DB를 master-replica로 나눠 이중화를 할 것이다.

 

 

MySQL Replication

 

 

Master DBMS

웹서버에서 보내는 요청중 수정/등록/삭제에 대항 요청시 바이너리로그를 생성하여 Replica서버에 전송한다.

 

Replica DBMS

Master DBMS로 부터 전달받은 바이너리 로그를 자신의 데이터로 반영한다. (복제)

보통 요청이 많은 읽기를 담당한다.

 

 

MySQL Replication 주의사항

  • Mysql의 버전을 Master와 Replica를 동일하게 가져가는게 좋다. (호환성)
  • 만약에 버전이 다른경우 Replica서버가 상위 버전이여야 한다.
  • Replication을 구동시에 무조건 Master -> Replica 순으로 진행해야 한다.

 

 

등록/수정/삭제는 Master서버로

읽기는 Replica서버가 담당하게 구성할 것이다.

 

 

기존에 DB 인스턴스가 하나 있어서 추가로 하나만 더 만들어준 뒤 실습했다.

 

 

 

slave 서버에서 root로 접속한 뒤 유저에 복제 권한을 부여했다.

 

 

sudo nano /etc/mysql/my.cnf

 

my.cnf 파일에서

 

 

[mysqld]
log-bin=mysql-bin
server-id=1


아래 기타 원래 작성된 것들....

 

binary log, replication을 활성화한다.

binary log(log-bin=mysql-bin)는 mysql에서 수행된 모든 변경 작업들이 로그 파일에 기록되도록 하는 설정이고

server-id=1은 mysql 복제 시 사용할 값이다.

 

 

sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf

 

그리고 위 파일에서

 

 

bind-address = 127.0.0.1 -> bind-address=0.0.0.0(모든 아이피 접속 허용)

 

bind-address를 위와 같이 변경했다.

 

 

sudo service mysql restart

 

설정 파일 수정 후 재시작을 해야 한다.

 

 

 

그리고 마스터 측 mysql에 접속 해 서버 정보를 확인한다.

위에서 로그 파일명은 File과 로그 파일 내 읽을 위치인 Position 값을 기억해야 한다.

 

 

 

이제 생성된 dump 파일을 replica DB가 있는 서버로 전송할 것이다.

mysqldump 명령어로 mysql의 데이터를 백업하고

 

 

 

scp 명령으로 복제 서버로 전송했다.

 

 

 

이제 복제 서버에서 DB를 생성한다.

 

 

 

그리고 설정 파일에 들어가서

 

 

[mysqld]
server-id=2

 

server-id를 부여한다.

이때 서버 아이디는 식별자기 때문에 마스터에게 부여한 값과 달라야 한다.

 

 

 

그리고 위 명령어로 mysql dump 파일을 복원한 뒤

 

 

 

master 서버로 연결하기 위한 설정들을 해주면 된다.

 

 

 

mysql을 재시작한다.

 

 

 

복제 서버 측에서 show slave status\G;로 복제 서버의 상태를 확인할 수 있다.

Slave_IO_Running, Slave_SQL_Running 값이 Yes 여야 정상적으로 복제 서버가 설정된 것이다.

 

 

 

이제 마스터 측에서 데이터베이스를 생성하면

 

 

 

슬레이브 측에도 반영된다.

 

 


 

failover

 

 

 

데이터베이스 백업을 위해 디렉터리를 생성하고 권한을 부여했다.

 

 

slack을 사용해야 하기 때문에 아래 링크에서 프로젝트를 만들었다.

https://final-prj.slack.com/apps

 

작업이 이루어지는 공간

Slack은 작업이 진행되는 공간입니다. Slack은 필요한 사람, 공유할 정보 및 사용할 도구를 모두 불러와서 작업할 수 있는 공간입니다.

slack.com

 

 

 

DB failover 시 알림 시스템을 자동화하기 위해 앱 디렉터리 링크에서 수신 웹 후크를 추가했다.

 

 

 

수신 웹후크 추가를 완료하면 URL을 받을 수 있는데 이 URL을 아래 코드에서 사용하면 된다.

 

 

#!/bin/bash

# MySQL 설정
MYSQL_USER="root"
MYSQL_PASSWORD=""
MYSQL_DATABASE="--all-databases"
PRIMARY_SERVER="마스터 db 인스턴스 ip"
BACKUP_DIR="/var/backups/mysql"
LOG_FILE="/var/log/mysql_backup.log"
SLACK_WEBHOOK_URL="slack url"

# 현재 날짜
DATE=$(date +"%Y-%m-%d")

# 백업 파일 이름
BACKUP_FILE="$BACKUP_DIR/${MYSQL_DATABASE}_backup_$DATE.sql.gz"

# Slack 알림 함수
send_slack_notification() {
    local message=$1
    curl -X POST -H 'Content-type: application/json' --data "{\"text\":\"${message}\"}" $SLACK_WEBHOOK_URL
}

# MySQL 복제 상태 확인 함수
check_mysql_replication() {
    STATUS=$(mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e "SHOW SLAVE STATUS\G" | grep -E "Slave_IO_Running:|Slave_SQL_Running:")
    if echo "$STATUS" | grep "No" > /dev/null; then
        echo "$(date): MySQL replication is not running correctly" >> "$LOG_FILE"
        return 1
    else
        echo "$(date): MySQL replication is running correctly" >> "$LOG_FILE"
        return 0
    fi
}

# MySQL 복구 함수
recover_mysql() {
    mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e "STOP SLAVE; RESET SLAVE ALL;"
    mysqldump -h $PRIMARY_SERVER -u$MYSQL_USER -p$MYSQL_PASSWORD --all-databases --master-data > alldb.sql
    mysql -u$MYSQL_USER -p$MYSQL_PASSWORD < alldb.sql
    mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e "CHANGE MASTER TO MASTER_HOST='$PRIMARY_SERVER', MASTER_USER='$MYSQL_USER', MASTER_PASSWORD='$MYSQL_PASSWORD', MASTER_AUTO_POSITION=1; START SLAVE;"
    echo "$(date): MySQL replication has been reinitialized" >> "$LOG_FILE"
    send_slack_notification "MySQL replication has been reinitialized on the secondary server."
}

# MySQL 백업 수행 및 압축
if mysqldump -u$MYSQL_USER -p$MYSQL_PASSWORD $MYSQL_DATABASE | gzip > $BACKUP_FILE; then
    echo "$(date): Backup completed successfully." >> "$LOG_FILE"
    send_slack_notification "Backup completed successfully for $MYSQL_DATABASE on $DATE."
else
    echo "$(date): Backup failed." >> "$LOG_FILE"
    send_slack_notification "Backup failed for $MYSQL_DATABASE on $DATE."
fi

# 1년이 지난 백업 파일 삭제
find $BACKUP_DIR -type f -name "*.gz" -mtime +365 -exec rm {} \;
echo "$(date): Old backups removed." >> "$LOG_FILE"
send_slack_notification "Old backups removed for $MYSQL_DATABASE."

# MySQL 복제 상태 확인 및 복구
if ! check_mysql_replication; then
    recover_mysql
fi

# 로그 기록
echo "$(date): Backup script executed." >> "$LOG_FILE"

 

MySQL 데이터베이스의 백업을 수행하고 복제 상태를 확인하며 필요시 복제를 복구하는 기능을 갖춘 스크립트다.

백업 및 복제 상태에 대한 Slack 알림 기능이 있다. 

MySQL 설정
   - `MYSQL_USER`: MySQL에 접속할 사용자 이름(여기서는 `root`)
   - `MYSQL_PASSWORD`: MySQL에 접속할 비밀번호
   - `MYSQL_DATABASE`: 백업할 데이터베이스를 지정 (`--all-databases`는 모든 데이터베이스를 백업)
   - `PRIMARY_SERVER`: 마스터 서버의 IP 주소
   - `BACKUP_DIR`: 백업 파일을 저장할 디렉터리
   - `LOG_FILE`: 로그를 기록할 파일 경로
   - `SLACK_WEBHOOK_URL`: Slack 알림을 보낼 웹훅 URL

 


현재 날짜와 백업 파일 이름 설정
   - `DATE`: 현재 날짜를 가져와서 백업 파일 이름에 포함
   - `BACKUP_FILE`: 백업 파일의 전체 경로 및 이름 설정

 


Slack 알림 함수 (`send_slack_notification`)
   - 특정 메시지를 Slack으로 전송
   - `curl`을 사용해 Slack 웹훅 URL로 POST 요청을 보내 알림을 전송

 

MySQL 복제 상태 확인 함수 (`check_mysql_replication`)
   - MySQL 복제(slave) 상태를 확인
   - `SHOW SLAVE STATUS\G` 명령어로 복제 상태를 조회하고 `Slave_IO_Running` 및 `Slave_SQL_Running` 값이 "Yes"인지 확인
   - 복제에 문제가 있으면 로그 파일에 기록하고, 함수가 실패(`return 1`) 표기

 

MySQL 복구 함수 (`recover_mysql`)
   - 복제 상태에 문제가 있을 때 복구를 수행
   - 슬레이브를 중지하고(`STOP SLAVE`) 슬레이브 설정을 초기화(`RESET SLAVE ALL`).
   - 마스터 서버로부터 데이터를 덤프(`mysqldump`)하여 다시 불러옴
   - 슬레이브 서버를 재설정하고 복제를 다시 시작
   - 복제 초기화 후 Slack으로 알림을 보냄

 


MySQL 백업 수행 및 압축
   - `mysqldump`를 사용하여 MySQL 데이터베이스를 백업한 후 gzip으로 압축하여 지정된 디렉터리에 저장
   - 백업 성공 여부에 따라 로그를 남기고 Slack으로 알림을 보냄

 

오래된 백업 파일 삭제
   - `find` 명령어로 1년(365일) 이상 된 백업 파일을 찾아 삭제
   - 삭제 후 로그를 남기고, Slack으로 알림을 보냄

 

MySQL 복제 상태 확인 및 복구
   - 복제 상태를 확인하고(`check_mysql_replication`), 문제가 있으면 복구 함수(`recover_mysql`)를 실행

 

스크립트 실행 로그 기록
   - 스크립트 실행이 완료되면 마지막으로 로그 파일에 기록을 남김

 

 

스크립트에 실행권한을 부여하고

 

0 0 * * * /usr/local/bin/mysql_backup_and_replication.sh

 

매일 자정에 스크립트를 실행하도록 크론탭에 등록한다.