연재 시리즈

쿠버네티스 오퍼레이터 스터디 2주차 - mysql operator 장애테스트

악분 2022. 6. 5. 00:02
반응형

이 글은 mysql operator 장애 테스트를 다룹니다.

 

1. 장애 테스트 시나리오

  • 시나리오1: pod레벨 장애
    • 데이터 삽입도중에 pod를 삭제
  • 시나리오2: node레벨 장애
    • node drain을 실행하여 mysql 쿠버네티스 리소스를 다른 노드로 이동

 

2. 준비

2.1 mysql-client 설치

노드에서 mysql에 쿼리를 요청하기 위해 mysql-client를 설치합니다.

apt-get install mysql-client

 

mysql router endpoint주소를 리눅스 변수에 저장합니다.

MYSQLIP=$(kubectl get svc -n mysql-cluster mycluster -o jsonpath={.spec.clusterIP})

 

2.2 모니터링 실시간 로그

InnoDB클러스터에 속한 mysql 인스턴스 이름과 역할을 실시간으로 화면에 출력합니다.

while true; do mysql -h $MYSQLIP -uroot -psakila -e 'SELECT VIEW_ID FROM performance_schema.replication_group_member_stats LIMIT 1;SELECT MEMBER_HOST, MEMBER_ROLE FROM performance_schema.replication_group_members;'; date;sleep 1; done

 

2.3 테스트를 위한 table 생성

# mysql 쉘 접속
mysql -h $MYSQLIP -uroot -psakila

# 테이블 생성
CREATE DATABASE test;
USE test;
CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 TEXT NOT NULL);
INSERT INTO t1 VALUES (1, 'Luis');
SELECT * FROM t1;
exit;

 

3. 시나리오1 테스트

시나리오1은 pod를 대상으로 장애를 발생시킵니다. 

 

3.1 secondary pod삭제

데이터를 삽입하는 도중에 Secondary pod를 삭제해보겠습니다. 먼저 데이터를 삽입하는 스크립트를 실행합니다.

# 테스트 데이터 추가
for ((i=1001; i<=5000; i++)); do mysql -h $MYSQLIP -uroot -psakila -e "SELECT NOW();INSERT INTO test.t1 VALUES ($i, 'Luis$i');";echo; done

 

secondary pod가 삭제합니다.

kubectl delete pod -n mysql-cluster mycluster-1 && kubectl get pod -n mysql-cluster -w

 

pod가 삭제되면 router에서 관리하는 목록에서 삭제됩니다. statefulset이 pod가 죽은 것을 감지하고 다시 실행합니다. 새로운 pod는 바로 running상태로 변경되지 않고, 장애시간동안 처리하지 못한 데이터를 자신의 데이터베이스에 동기화합니다.

 

다시 살아난 pod로그를 보면 동기화 작업 메세지(group_replication_recovery)가 보입니다.

kubectl -n mysql-cluster logs mycluster-1 -c mysql

 

3.2 primary pod삭제

primary pod를 삭제하면 삽입 동작이 잠시 중단됩니다. 그리고 secondary 중 하나가 primary로 승격되어 다시 삽입 스크립트가 동작합니다.

kubectl delete pod -n mysql-cluster mycluster-0 && kubectl get pod -n mysql-cluster -w

 

장애가 났던 primary가 다시 클러스터에 조인되면, secondary로 역할이 변경됩니다.

 

4. 시나리오2 테스트

시나리오2는 노드가 장애가 났을 때 상황을 다룹니다.

 

4.1 첫번째 노드 drain 

secondary pod가 있는 노드를 대상으로 drain을 실행해보겠습니다.

kubectl drain k8s-w3 --ignore-daemonsets --delete-emptydir-data

 

drain한 노드는 스케쥴 비활성화 되었습니다.

 

mysql pod가 다른 노드로 이동되었습니다.

 

실습하는 서버는 hostpath를 pv로 사용하고 있어서 pending상태로 pod가 실행되지 않았습니다. 하지만, 정상적으로 다른 노드로 이동된 것을 확인했습니다.

 

4.2 두번째 노드 drain

현재 클러스터에 2개 mysql 인스턴스가 있습니다. 이 상황에서 secondary가 있는 노드를 drain시켜보겠습니다.

kubectl drain k8s-w2 --ignore-daemonsets --delete-emptydir-data

 

로그를 보면 mysql pod 이동이 실패했습니다. 쿠버네티스 pdb가 설정되어 있기 때문입니다.

 

클러스터 특징이 있는 아키텍처는 “종족수”라는 개념이 있습니다. 클러스터를 유지하기 위한 최소 인스턴스 수인데요. 쿠버네티스로 그대로 적용하면 pdb로 종족수를 유지시킬수 있습니다. mysql-operator는 최소 1개를 실행하게 설정되어 있습니다. 억지로 종족수 개념을 해제하려면 pdb를 삭제하면 됩니다.

kubectl get pdb -n mysql-cluster

반응형