TT Lab
블로그 시작하기
배우기 러닝패스 코스

Helm 으로 Rook-Ceph 세우기 — 블록·파일·오브젝트와 장애

운영의 눈 — 용량, 쿼터, 그리고 OSD 를 잃었을 때

TT Lab 에서 이어서 보기

한 줄 요약

Ceph 는 디스크 하나를 잃어도 남은 사본으로 계속 일합니다. 다만 "몇 개가 남아야 쓰는가(min_size)", "언제 포기하고 사본을 새로 만드는가", "가장 많이 찬 디스크가 어디인가" 를 운영자가 알고 있어야 그 약속이 지켜집니다.

왜 이게 필요했나

설치가 끝나고 HEALTH_OK 를 본 순간부터는 운영입니다. 운영에서 묻는 질문은 셋입니다. 얼마나 찼나, 지금 건강한가, 무언가 잃으면 어떻게 되나. Ceph 는 이 셋에 각각 도구를 줍니다 — ceph df 와 ceph osd df, 대시보드와 health 검사, 그리고 PG 의 상태 이름(active, degraded, undersized, recovering)입니다. 이 도구들을 장애가 나기 전에 읽어 보지 않으면, 장애 때 처음 보는 단어 앞에서 시간을 씁니다.

어떻게 동작하나

용량은 두 단위로 봅니다. ceph df 는 풀 단위입니다. STORED 는 사용자가 넣은 양, USED 는 복제나 이레이저 코딩까지 친 디스크 사용량, MAX AVAIL 은 그 풀에 더 넣을 수 있는 양입니다. ceph osd df 는 디스크 단위입니다. PG 가 OSD 에 고르게 퍼지지 않으면 어떤 OSD 는 다른 것보다 빨리 찹니다. Ceph 는 OSD 하나가 nearfull(85%)이면 경고하고, full(95%)이면 클러스터 전체의 쓰기를 멈춥니다. 그래서 운영 지표는 평균이 아니라 가장 많이 찬 OSD 입니다.

쿼터. 풀에 max_bytes 나 max_objects 를 걸면, 넘는 순간 그 풀은 POOL_FULL 이 되고 쓰기를 받지 않습니다. 다른 풀은 그대로입니다. 팀마다 풀을 나눠 주고 상한을 거는 데 씁니다. librados 클라이언트는 기본으로 실패를 돌려주지 않고 공간이 생기기를 기다리므로, 클라이언트 쪽에서는 쓰기가 "멈춘" 것처럼 보입니다.

OSD 를 잃으면. OSD 들은 서로 하트비트를 주고받습니다. 한 OSD 가 응답하지 않으면 다른 OSD 들이 mon 에 알리고, mon 이 그 OSD 를 down 으로 표시합니다. 그 OSD 에 사본이 있던 PG 들은 사본이 하나 모자란 채(undersized) 남은 사본으로 계속 일하고, 그동안 바뀐 객체는 degraded 로 셉니다. 풀의 min_size(3벌이면 기본 2)보다 사본이 적어지면 그 PG 는 쓰기를 멈춥니다 — 사본 하나에만 쓴 데이터는 그 디스크까지 잃으면 사라지기 때문입니다. OSD 가 돌아오면 자기가 없던 동안 바뀐 것만 다른 사본에서 받아 맞추고(recovery), 바뀐 것이 적으면 금방 끝납니다. 돌아오지 않으면 mon 이 정해진 시간(기본 10분) 뒤 그 OSD 를 out 으로 빼고, 노드가 남아 있으면 다른 곳에 사본을 새로 만듭니다(backfill).

대시보드를 여는 법. mgr 의 대시보드는 클러스터 안의 Service 로만 열려 있습니다. 운영에서는 Ingress 로 내보내기도 하지만, 관리 화면을 바깥에 두면 그만큼 공격 면이 늘어납니다. 이 실습처럼 필요할 때만 kubectl port-forward 로 자기 자리에 잇는 편이 안전합니다 — 포워딩은 kubeconfig 권한이 있는 사람만 할 수 있고, 명령을 끝내면 닫힙니다. 관리자 비밀번호는 Rook 이 만든 Secret 에 있고, 대시보드의 모든 화면은 같은 REST API 를 부르므로 스크립트로도 똑같이 읽을 수 있습니다. 그 API 를 부를 때 비밀번호와 토큰을 명령줄 인자나 파일에 남기지 않는 것까지가 운영 습관입니다.

현장에서 만나는 모습

계획된 정비라면 노드를 내리기 전에 ceph osd set noout 을 겁니다. 10분 넘게 걸리는 정비 동안 Ceph 가 OSD 를 out 으로 빼고 대량 backfill 을 시작하는 것을 막기 위해서입니다. 정비가 끝나면 반드시 unset 합니다 — 걸어 둔 채 잊으면 진짜 장애 때 사본을 다시 만들지 않습니다.

노드가 셋뿐인 클러스터의 한계도 자주 만납니다. 3벌 복제를 노드 단위로 나눴으니 노드 하나를 영영 잃으면 셋째 사본을 놓을 노드가 없어 undersized 로 계속 버팁니다. 그 상태에서 디스크 하나를 더 잃으면 min_size 아래로 떨어져 쓰기가 멈춥니다. 그래서 운영 클러스터는 노드를 복제 수보다 하나 이상 많이 둡니다.

복구 속도도 조절 대상입니다. 큰 디스크를 잃으면 사본을 새로 만드는 동안 클러스터 전체가 그 일에 대역폭을 씁니다. Ceph 는 이 일과 클라이언트 요청 사이의 몫을 mClock 스케줄러로 나누고, 운영자는 osd_mclock_profile 로 '클라이언트 우선' 이나 '복구 우선' 을 고릅니다. 장애 중에 서비스 지연이 늘었다면 그 원인이 장애 자체가 아니라 복구일 수 있습니다.

다음 실습에서 할 것

1실습의 values 로 Ceph 를 다시 세운 뒤, 용량을 풀과 OSD 두 단위로 읽고, 대시보드 REST API 를 포트 포워딩으로 부릅니다. 64MiB 쿼터를 건 풀을 채워 POOL_FULL 을 보고 상한을 올립니다. 100MiB 파일을 둔 볼륨을 남겨 두고 node03 의 OSD 를 내려 degraded 상태를 기록하고, 그 상태에서 읽고 쓴 뒤, OSD 를 되살려 HEALTH_OK 까지 걸린 시간을 잽니다.