개요
Kubernetes 환경에서 mysql-operator를 통해 MySQL InnoDB Cluster를 배포한 후, Operator를 제거했다가 다시 설치하는 경우 기존 Persistent Volume (PV)에 저장된 데이터를 그대로 사용하려면 다음과 같은 문제가 발생합니다
- Secret에 저장된 mysqladmin 비밀번호와 실제 Pod 내 비밀번호가 일치하지 않는 경우, Operator는 클러스터 구성에 실패하게 됩니다.
- mysql_innodb_cluster_metadata 시스템 데이터베이스가 기존 상태로 존재할 경우, Operator가 재설치된 상태에서 클러스터를 새로 구성하려다 충돌이 발생하게 됩니다.
결과적으로, 데이터는 살아있어도 클러스터가 구성되지 않음 → Pod가 무한 Crash → 서비스 불가 상태가 됩니다.
문제 발생 가정
- MySQL Operator를 사용하여 최초 InnoDB Cluster를 배포함.
- 운영 중 MySQL Operator를 제거하고, 동일한 PV를 마운트한 상태에서 재설치를 시도함.
- PVC는 유지된 상태이며, 해당 PVC는 실제로 물리적 디스크나 StorageClass에 연결됨.
문제 발생 이유
MySQL Operator는 InnoDBCluster CRD(Custom Resource Definition)를 기반으로 Pod, Secret, ConfigMap 등을 생성하고 InnoDB Cluster 구성 작업을 자동으로 수행합니다. 이 과정에서 Operator는 다음과 같은 상태 정보 및 메타데이터를 클러스터 내에 저장합니다:
- mysql_innodb_cluster_metadata라는 시스템 데이터베이스에 클러스터 구성 정보 저장
- Secret ([클러스터명]-privsecrets)에 관리자 계정 mysqladmin의 비밀번호 저장
- StatefulSet을 통해 복제된 Pod들이 클러스터 내부 설정에 따라 동작
Operator를 제거한 후 재설치하고 동일한 PVC를 사용하면, MySQL 서버는 데이터 자체는 그대로 가지고 있지만 메타데이터와 현재 Operator 상태가 일치하지 않아 클러스터 구성에 실패하게 됩니다. 이는 다음과 같은 현상으로 이어질 수 있습니다:
- Pod가 CrashLoopBackOff 상태에 빠짐
- Operator 로그에 "metadata already exists" 또는 "instance already in cluster" 등의 메시지 출력
- kubectl get innodbcluster 명령어 결과에서 상태가 "Error" 또는 "Recovering"으로 계속 유지됨
문제 해결 방법
mysqladmin 비밀번호 확인
kubectl get secret [클러스터이름]-privsecrets -n [네임스페이스] -o go-template="{{.data.clusterAdminPassword | base64decode}}" && echo ""
이 비밀번호는 재접속 및 복구에 사용됩니다. 재설치된 Operator가 새 비밀번호를 생성하면서 기존 클러스터와 충돌이 발생할 수 있기 때문에, 기존 비밀번호로 되돌리는 작업이 필요합니다.
Master Instance 접속
Operator가 관리하는 인스턴스 중 master 역할의 Pod에 접속:
kubectl exec -it [master-pod명] -n [네임스페이스] -- /bin/bash
mysqlsh root@localhost
\sql
mysqladmin 비밀번호 재설정
SET sql_log_bin=off;
SET GLOBAL super_read_only = OFF;
ALTER USER 'mysqladmin'@'%' IDENTIFIED BY '[앞서 확인한 비밀번호]';
SET GLOBAL super_read_only = ON;
여기서 비밀번호를 이전 값으로 되돌리는 이유는, innodbcluster CRD가 생성될 때 사용하는 인증정보가 Secret에 저장된 비밀번호를 기반으로 하기 때문입니다. 불일치하면 연결이 실패하게 됩니다.
클러스터 메타데이터 삭제
기존 클러스터 구성 정보가 담긴 메타데이터 DB를 삭제:
DROP DATABASE mysql_innodb_cluster_metadata;
해당 DB가 삭제되면 InnoDBCluster를 처음부터 다시 구성하는 것과 같아짐. 하지만 데이터베이스 자체(사용자 데이터)는 그대로 보존되므로, 클러스터 재생성이 가능해짐.
상태 확인
kubectl describe pod [pod명] -n [네임스페이스]
kubectl get innodbcluster -n [네임스페이스]
STATUS 항목이 ONLINE 또는 OK 상태로 바뀌는지 확인합니다. 또한 Operator 로그에서 클러스터 구성이 정상적으로 진행되었는지 확인합니다.
다른 해결 방법에 대한 고민
metadata DB를 백업 → 삭제 → 복원
- mysqldump -u root -p로 mysql_innodb_cluster_metadata 백업
- 클러스터 재설치 후 metadata 삭제 → 다시 dump 복원
- 복원한 metadata를 기반으로 Operator가 제대로 연결 가능한지 확인
❗ 단점: 복원 시점의 metadata가 오래되었거나 구성 정보가 불완전할 경우, 클러스터 구성에 실패하거나 상태가 지속적으로 "Recovering" 상태로 유지될 수 있습니다.
forceRestart를 활용한 재시도
apiVersion: mysql.oracle.com/v2
kind: InnoDBCluster
metadata:
name: mycluster
spec:
restartPolicy: Always
forceRestart: true
실질적으로 metadata에는 문제가 없고, 단지 Pod 재시작이나 연결 문제인 경우 사용할 수 있습니다.
단, Secret의 비밀번호와 실제 mysqladmin 비밀번호가 일치하지 않으면 여전히 실패합니다.
완전히 새로운 클러스터로 구성하고 데이터만 mount
- 기존 PVC 유지
- mysql-operator, innodbcluster 리소스 모두 새로 생성 (기존 metadata 사용 안함)
- InnoDB Cluster 구성 후 수동으로 기존 DB를 attach하거나 import
결론
위에서 소개한 방법들은 모두 "완전한 복구 방식"이라고 보기엔 어렵습니다. 운영자가 수작업으로 metadata를 삭제하거나 비밀번호를 맞춰주는 방식은 다음과 같은 점에서 임시적이며 신뢰성이 떨어지는 접근입니다:
- mysql_innodb_cluster_metadata 삭제는 Operator가 자동으로 관리하는 구조에 반하는 행위이며, 향후 업그레이드나 스케일링에 문제가 발생할 수 있습니다.
- Secret의 비밀번호를 수동으로 맞추는 방식 역시 관리 일관성을 깨트릴 수 있고, 보안 측면에서도 권장되지 않습니다.
- 복구는 가능하지만 운영 환경에서 신뢰하기 어려운 방식으로, 테스트/비상 복구 외에는 사용을 지양하는 것이 좋습니다.
'DevOps & Infra > Kubernetes' 카테고리의 다른 글
| [k8s] cronjob 기반 pod 자동 재시작 및 slack 알림 제어 구현 (2) | 2025.10.06 |
|---|---|
| [k8s] Kubernetes Pod에서 The node was low on resource: ephemeral-storage 부족 현상 분석 (0) | 2025.08.24 |

