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

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

Ceph 운영 — 용량·대시보드·쿼터, 그리고 OSD 하나를 잃었을 때

TT Lab 에서 이어서 보기

목표

돌고 있는 Ceph 클러스터를 운영자의 눈으로 봅니다. 용량을 풀과 디스크 두 단위로 읽고, 대시보드의 REST API 를 포트 포워딩으로 부르고, 풀에 쿼터를 걸어 쓰기가 막히는 순간을 봅니다. 마지막으로 데이터를 둔 채 OSD 하나를 내려, 클러스터가 그 사실을 어떻게 알리는지, 그동안 데이터를 계속 읽고 쓸 수 있는지, 되살린 뒤 몇 초 만에 원래대로 돌아오는지를 직접 잽니다.

왜 중요한가

분산 스토리지를 쓰는 이유는 결국 "디스크 하나, 노드 하나를 잃어도 서비스가 계속된다" 입니다. 그런데 그 약속에는 조건이 있습니다. 사본이 몇 개 남아야 쓰기를 계속하는지(min_size), 잃은 디스크를 언제 포기하고 다른 곳에 사본을 새로 만드는지, 그리고 가장 많이 찬 디스크가 가득 차면 클러스터 전체가 멈춘다는 것입니다. 이 조건들은 평소에는 보이지 않다가 장애 때 한꺼번에 드러납니다. 그래서 장애를 일부러 만들어 보고, 숫자로 재 두는 것이 운영 준비입니다.

단계

  1. /root/rook/cluster-values.yaml(1실습에서 만든 values)로 Rook 을 다시 세우세요. 1실습과 같은 차트 셋을 같은 판으로 네임스페이스 rook-ceph 에 설치합니다 — rook-ceph(rook-release/rook-ceph v1.21.1), ceph-csi-drivers(ceph-csi-operator/ceph-csi-drivers 1.1.0, Rook 이 권하는 values 를 /root/rook/csi-drivers-values.yaml 로 받아서), rook-ceph-cluster(rook-release/rook-ceph-cluster v1.21.1, -f /root/rook/cluster-values.yaml). 세 릴리스가 deployed 이고 CephCluster 가 만들어져야 합니다.
  2. CephCluster 가 Ready 가 될 때까지 기다린 뒤, 1실습처럼 커널(6.8) 때문에 생기는 AUTH_INSECURE_ 경고 셋만 ceph health mute <코드> --sticky 로 묵음 처리하세요. Ceph 가 HEALTH_OK 이고, mon 셋이 정족수를 이루고, OSD 셋이 up·in 이어야 합니다.
  3. toolbox 에서 ceph df 출력을 /root/rook/df.txt 에, ceph osd df 출력을 /root/rook/osd-df.txt 에 저장하세요. 풀 단위로 본 용량과 OSD(디스크) 단위로 본 사용률이 무엇이 다른지 확인합니다.
  4. mgr 의 대시보드 Service rook-ceph-mgr-dashboard 를 controlplane 의 127.0.0.1:8443 으로 포트 포워딩하고, 관리자(admin) 비밀번호를 Secret rook-ceph-dashboard-password 에서 꺼내 REST API 로 로그인(POST /api/auth)한 뒤 GET /api/health/minimal 의 응답 JSON 을 /root/rook/dashboard.json 에 저장하세요. 비밀번호와 토큰은 어떤 파일에도 남기지 않습니다.
  5. CephBlockPool quota-pool(복제 3벌, failureDomain host)을 spec.quotas.maxSize: 64Mi 로 만들고, toolbox 에서 rados 로 이 풀에 16MiB 객체를 여러 개 넣어 쿼터에 닿게 하세요. 그때의 ceph health detail 을 /root/rook/quota.txt 에 저장한 뒤, 쿼터를 1Gi 로 올려 경고를 풀어야 합니다.
  6. 네임스페이스 ops-demo 에 1Gi RBD PVC keep 과 controlplane 의 파드 keeper 를 만들어 100MiB 무작위 파일 /data/keep.bin 을 쓰고 sha256 을 /root/rook/keep-sum.txt 에 적으세요. 그다음 node03 의 OSD Deployment 를 0 으로 줄여 OSD 하나를 내리고, Ceph 가 그것을 알아챈 뒤의 ceph status 를 /root/rook/degraded.txt 에 저장합니다.
  7. OSD 가 내려가 있는 동안 keeper 에서 /data/keep.bin 의 sha256 을 다시 계산하고, 새 파일 /data/during.txt 를 쓰세요. 결과를 /root/rook/during.txt 에 sha=<계산값>·write=ok 두 줄로 적습니다. sha 는 keep-sum.txt 와 같아야 하고, 그동안 OSD 는 계속 하나가 down 이어야 합니다.
  8. node03 의 OSD Deployment 를 다시 1 로 늘리고, Ceph 가 HEALTH_OK 로 돌아올 때까지 걸린 시간을 재세요. OSD 를 늘린 순간부터 HEALTH_OK 까지의 초를 /root/rook/recovery.txt 에 recovery_sec=<초> 로 적습니다. 마지막에 OSD 셋이 up 이고 keep.bin 의 sha 가 그대로여야 합니다.

참고

1실습의 values 로 Ceph 를 다시 설치한다

/root/rook/cluster-values.yaml(1실습에서 만든 values)로 Rook 을 다시 세우세요. 1실습과 같은 차트 셋을 같은 판으로 네임스페이스 rook-ceph 에 설치합니다 — rook-ceph(rook-release/rook-ceph v1.21.1), ceph-csi-drivers(ceph-csi-operator/ceph-csi-drivers 1.1.0, Rook 이 권하는 values 를 /root/rook/csi-drivers-values.yaml 로 받아서), rook-ceph-cluster(rook-release/rook-ceph-cluster v1.21.1, -f /root/rook/cluster-values.yaml). 세 릴리스가 deployed 이고 CephCluster 가 만들어져야 합니다.

1실습의 2·3·5단계와 같습니다. 오퍼레이터 차트가 CRD 를 함께 깔기 때문에 그것을 먼저 설치하고, CRD 가 등록될 때까지 기다린 뒤(kubectl wait --for=condition=Established crd/drivers.csi.ceph.io) 드라이버 차트를 설치합니다. Rook 의 CSI values 주소는 {CSI_VALUES_URL} 입니다. 설치 명령은 금방 끝나고, 클러스터가 서는 것은 다음 단계에서 기다립니다.

HEALTH_OK 까지 기다린다

CephCluster 가 Ready 가 될 때까지 기다린 뒤, 1실습처럼 커널(6.8) 때문에 생기는 AUTH_INSECURE_ 경고 셋만 ceph health mute <코드> --sticky 로 묵음 처리하세요. Ceph 가 HEALTH_OK 이고, mon 셋이 정족수를 이루고, OSD 셋이 up·in 이어야 합니다.

처음 설치는 이미지와 OSD 준비 때문에 수 분이 걸립니다 — kubectl -n rook-ceph get pods -w. toolbox 의 ceph health detail 이 남은 경고를 말합니다. AUTH_INSECURE_ 가 아닌 경고는 묵음 처리하지 말고 기다리거나 원인을 고치세요.

용량을 두 가지 눈으로 읽는다

toolbox 에서 ceph df 출력을 /root/rook/df.txt 에, ceph osd df 출력을 /root/rook/osd-df.txt 에 저장하세요. 풀 단위로 본 용량과 OSD(디스크) 단위로 본 사용률이 무엇이 다른지 확인합니다.

ceph df 의 RAW STORAGE 는 디스크 전체, POOLS 의 STORED 는 사용자가 넣은 양, USED 는 복제까지 친 양입니다. ceph osd df 는 디스크마다의 %USE 와 PG 수(PGS)를 보여 줍니다. 운영에서는 클러스터 평균보다 가장 많이 찬 OSD 를 봅니다 — 그 OSD 가 95%(full_ratio)에 닿으면 클러스터 전체의 쓰기가 멈춥니다.

대시보드 API 를 포트 포워딩으로 부른다

mgr 의 대시보드 Service rook-ceph-mgr-dashboard 를 controlplane 의 127.0.0.1:8443 으로 포트 포워딩하고, 관리자(admin) 비밀번호를 Secret rook-ceph-dashboard-password 에서 꺼내 REST API 로 로그인(POST /api/auth)한 뒤 GET /api/health/minimal 의 응답 JSON 을 /root/rook/dashboard.json 에 저장하세요. 비밀번호와 토큰은 어떤 파일에도 남기지 않습니다.

kubectl -n rook-ceph port-forward svc/rook-ceph-mgr-dashboard 8443:8443 & 로 뒤에 띄웁니다. 인증서가 자체 서명이라 curl -k 입니다. API 는 Accept: application/vnd.ceph.api.v1.0+json 머리글을 요구합니다. 로그인 응답의 token 을 Authorization: Bearer 로 씁니다. 비밀번호는 셸 변수에만 두세요 — 명령줄 인자로 넘기면 ps 에 보이고, 파일로 남기면 그대로 유출입니다. 같은 일을 브라우저로 하려면 이 터미널에서는 안 되고, 자기 PC 에서 kubeconfig 로 포트 포워딩해야 합니다.

풀 쿼터로 용량 상한을 걸고, 걸리는 것을 본다

CephBlockPool quota-pool(복제 3벌, failureDomain host)을 spec.quotas.maxSize: 64Mi 로 만들고, toolbox 에서 rados 로 이 풀에 16MiB 객체를 여러 개 넣어 쿼터에 닿게 하세요. 그때의 ceph health detail 을 /root/rook/quota.txt 에 저장한 뒤, 쿼터를 1Gi 로 올려 경고를 풀어야 합니다.

쿼터에 닿은 풀은 쓰기를 받지 않고 POOL_FULL 경고가 납니다. librados 클라이언트는 기본으로 그 자리에서 멈춰 기다리므로 timeout 20 rados … 로 감싸야 셸이 돌아옵니다. 통계는 몇 초 늦게 갱신되므로 경고를 바로 못 보면 잠깐 기다리세요. 쿼터를 바꾸는 것도 CephBlockPool 의 spec 을 고쳐 적용합니다 — toolbox 에서 바꾸면 오퍼레이터가 다시 64Mi 로 되돌립니다.

데이터를 두고 OSD 하나를 내린다

네임스페이스 ops-demo 에 1Gi RBD PVC keep 과 controlplane 의 파드 keeper 를 만들어 100MiB 무작위 파일 /data/keep.bin 을 쓰고 sha256 을 /root/rook/keep-sum.txt 에 적으세요. 그다음 node03 의 OSD Deployment 를 0 으로 줄여 OSD 하나를 내리고, Ceph 가 그것을 알아챈 뒤의 ceph status 를 /root/rook/degraded.txt 에 저장합니다.

어느 OSD 가 node03 에 있는지는 라벨로 고릅니다 — kubectl -n rook-ceph get deploy -l app=rook-ceph-osd,topology-location-host=node03. OSD 가 사라지면 다른 OSD 들이 하트비트로 알아채고(약 20초) mon 이 down 으로 표시합니다. PG 는 active+undersized+degraded 가 됩니다 — 사본 셋 중 둘로 계속 일하는 상태입니다. Rook 오퍼레이터가 다시 맞출 수 있으니 실습이 끝날 때까지 다른 values 를 바꾸지 마세요.

OSD 하나가 없는 채로 읽고 쓴다

OSD 가 내려가 있는 동안 keeper 에서 /data/keep.bin 의 sha256 을 다시 계산하고, 새 파일 /data/during.txt 를 쓰세요. 결과를 /root/rook/during.txt 에 sha=<계산값>·write=ok 두 줄로 적습니다. sha 는 keep-sum.txt 와 같아야 하고, 그동안 OSD 는 계속 하나가 down 이어야 합니다.

풀의 size 3, min_size 2 는 사본이 둘 이상 살아 있으면 읽기·쓰기를 계속한다는 뜻입니다. 사본이 하나만 남으면(min_size 미만) 그 PG 는 쓰기를 멈춥니다 — 데이터를 지키려고 일부러 멈추는 것입니다. ceph osd pool get ceph-blockpool min_size 로 확인해 보세요. 페이지 캐시가 아니라 디스크에서 읽게 하려면 echo 3 > /proc/sys/vm/drop_caches(controlplane 에서)를 먼저 해도 좋습니다.

OSD 를 되살리고 복구 시간을 잰다

node03 의 OSD Deployment 를 다시 1 로 늘리고, Ceph 가 HEALTH_OK 로 돌아올 때까지 걸린 시간을 재세요. OSD 를 늘린 순간부터 HEALTH_OK 까지의 초를 /root/rook/recovery.txt 에 recovery_sec=<초> 로 적습니다. 마지막에 OSD 셋이 up 이고 keep.bin 의 sha 가 그대로여야 합니다.

되살아난 OSD 는 자기가 없던 동안 바뀐 객체(7단계에서 쓴 during.txt 등)를 다른 사본에서 받아 맞춥니다(recovery). 바뀐 것이 적으면 수십 초면 끝납니다. ceph -w 나 watch ceph pg stat 으로 degraded 가 줄어드는 것을 보세요. 오래 내려 둔 OSD(기본 10분, mon_osd_down_out_interval)는 out 으로 빠지고, 노드가 넷 이상이면 남은 노드로 사본을 새로 만드는(backfill) 일이 시작됩니다. 이 실습은 노드가 셋이라 옮겨 갈 자리가 없어 undersized 로 버팁니다.