Kubernetes Distributions — Build Them Yourself
I ran the snapshot command and the datastore was SQLite
한국어 원문으로 표시합니다.
목표
k3s 서버 한 대의 저장소가 SQLite(kine) 임을 확인하고, etcd 스냅숏이 거절되는 이유를 본 뒤 --cluster-init 재시작으로 내장 etcd 로 옮깁니다. 스냅숏을 토큰과 함께 백업하고 --cluster-reset 으로 복원해, 스냅숏 이후의 변경이 사라지고 이전 데이터가 어디에 남는지 기록합니다.
왜 중요한가
k3s 는 한 대로 시작하면 etcd 대신 SQLite 를 씁니다. 가볍고 빠르지만 여러 서버가 공유할 수 없고, k3s etcd-snapshot 같은 etcd 도구가 동작하지 않습니다.
그래서 "백업을 붙이자" 는 날에 처음으로 저장소가 무엇인지 확인하게 되고, 그때 선택지는 파일을 통째로 복사하는 SQLite 백업이거나 etcd 로 옮기는 것입니다.
etcd 로 옮기는 것은 재시작 한 번이지만, 복원은 "그 시점으로 되돌리기" 라서 스냅숏 이후에 만든 것은 사라집니다. 그리고 서버 토큰이 없으면 스냅숏은 쓸모가 없습니다.
이 실습은 그 세 가지 — 저장소 확인, 이전, 복원이 되돌리는 범위 — 를 진짜 k3s 에서 한 번씩 겪게 합니다. etcd 를 처음부터 쓰는 k0s 실습과 달리 저장소를 바꾸는 과정 자체를 다룹니다.
단계
- 네임스페이스
k3s-ds에 ConfigMapmarker(stage=sqlite)를 만드세요. 그리고/root/k3s-ds/datastore.json에datastore(sqlite또는etcd),db_files(/var/lib/rancher/k3s/server/db의 파일 이름을 정렬한 배열),kine_table(state.db 안의 테이블 이름 중 kine 이 쓰는 것),kine_endpoint(k3s 로그의Kine available at뒤의 주소),marker_uid(marker 의 UID)를 적으세요. - 지금 상태에서
k3s etcd-snapshot save를 실행하고 표준 출력과 표준 오류를 함께/root/k3s-ds/snapshot-refused.txt에 저장하세요. 그리고/root/k3s-ds/sqlite-backup.txt에 SQLite 저장소를 백업하려면 복사해야 하는 디렉터리와 파일의 절대 경로를 한 줄에 하나씩 적으세요. /etc/rancher/k3s/config.yaml에cluster-init: true를 적고 k3s 를 재시작하세요. marker 가 살아 있는지 확인하고/root/k3s-ds/migrate.json에marker_uid(재시작 뒤 marker 의 UID),sqlite_file_now(db 디렉터리에서 원래 state.db 가 바뀐 이름),node_roles(노드의 node-role.kubernetes.io/ 라벨 이름을 정렬한 배열, 예: ["control-plane"]),member_name(db/etcd/name파일의 내용)을 적으세요.- marker 의
stage를snapshotted로 바꾼 다음k3s etcd-snapshot save --name lab-before로 스냅숏을 뜨세요./root/k3s-ds/snapshot.json에name(만들어진 스냅숏 이름 전체),path(파일 절대 경로),size(바이트, 정수),sha256(파일의 SHA-256)을 적으세요. /root/k3s-ds/backup/디렉터리에 4단계의 스냅숏 파일(같은 이름)과 서버 토큰 파일(token이라는 이름, 권한 600)을 복사하세요./root/k3s-ds/token-backup.json에token_source(토큰 원본의 절대 경로),token_sha256(토큰 파일의 SHA-256),snapshot_sha256(백업한 스냅숏의 SHA-256)을 적으세요. 토큰 값 자체는 어디에도 적지 않습니다.- 스냅숏 뒤에 네임스페이스
k3s-ds에 ConfigMapafter-snap(x=1)을 만들고 marker 의stage를changed로 바꾸세요./root/k3s-ds/after.json에after_uid(after-snap 의 UID),after_created(그 creationTimestamp),marker_stage(지금 marker 의 stage)를 적으세요. - k3s 를 멈추고
k3s server --cluster-reset --cluster-reset-restore-path=<4단계 스냅숏 경로>로 복원한 뒤(출력 전체를/root/k3s-ds/reset.log에 저장) k3s 를 다시 시작하세요./root/k3s-ds/restore.json에old_dir(복원이 이전 etcd 데이터를 옮긴 디렉터리 이름),restart_hint(reset.log 에서 k3s 가 다음에 할 일을 알려 준 문장 중restart without이 든 부분까지의 첫 문장),after_snap_exists(불리언),marker_stage(복원 뒤 marker 의 stage),member_name(복원 뒤db/etcd/name의 내용)을 적으세요. /root/k3s-ds/report.json에datastore_now(sqlite또는etcd),lost_objects(복원으로 사라진 ConfigMap 이름을 정렬한 배열),marker_stage(지금 값),snapshot_dir(스냅숏이 저장된 디렉터리 절대 경로),restore_needs_token(다른 서버에서 복원할 때 원래 토큰이 필요한지, 불리언),member_name_changed(복원 전후 etcd 멤버 이름이 바뀌었는지, 불리언)를 적으세요.
참고
- VM 안에 k3s v1.35.8+k3s1 한 대가 있습니다(traefik·metrics-server 는 끔). 재시작은
systemctl restart k3s입니다. - 3단계 뒤
k3s etcd-snapshot명령은 config.yaml 의 cluster-init 을 모르는 키라며 경고를 한 줄 냅니다. 무해합니다(실측). - 복원 명령은 문서 절차대로
systemctl stop k3s로 서비스를 멈춘 뒤에 실행합니다. - 흔한 실수: 스냅숏만 백업하고
/var/lib/rancher/k3s/server/token을 빠뜨리는 것. - 흔한 실수:
--cluster-reset을 서비스 인자나 config.yaml 에 넣는 것. 복원은 한 번 따로 실행하는 명령이고, k3s 는 reset-flag 파일로 연속 초기화를 막습니다. - Cluster Datastore · High Availability Embedded etcd · etcd-snapshot · Backup and Restore
이 클러스터의 저장소는 무엇인가
네임스페이스 k3s-ds 에 ConfigMap marker(stage=sqlite)를 만드세요. 그리고 /root/k3s-ds/datastore.json 에 datastore(sqlite 또는 etcd), db_files(/var/lib/rancher/k3s/server/db 의 파일 이름을 정렬한 배열), kine_table(state.db 안의 테이블 이름 중 kine 이 쓰는 것), kine_endpoint(k3s 로그의 Kine available at 뒤의 주소), marker_uid(marker 의 UID)를 적으세요.
k3s 는 SQLite 를 직접 API 서버에 붙이지 않고, etcd API 를 흉내 내는 kine 을 가운데 둡니다. API 서버의 --etcd-servers 가 무엇을 가리키는지 로그에서 보세요. 테이블 이름은 sqlite3 <파일> .tables 로 볼 수 있습니다.
스냅숏 명령을 걸었는데 저장소가 SQLite 였다
지금 상태에서 k3s etcd-snapshot save 를 실행하고 표준 출력과 표준 오류를 함께 /root/k3s-ds/snapshot-refused.txt 에 저장하세요. 그리고 /root/k3s-ds/sqlite-backup.txt 에 SQLite 저장소를 백업하려면 복사해야 하는 디렉터리와 파일의 절대 경로를 한 줄에 하나씩 적으세요.
etcd-snapshot 은 서버에 요청을 보내고 서버가 내장 etcd 로 스냅숏을 뜹니다. 저장소가 SQLite 면 서버가 거절하고 자세한 이유는 서버 로그에 남깁니다. SQLite 는 특별한 명령 없이 파일을 복사해 백업하는데, 저장소 안의 기밀 데이터를 암호화하는 값도 함께 보관해야 합니다.
재시작 한 번으로 etcd 로 옮긴다
/etc/rancher/k3s/config.yaml 에 cluster-init: true 를 적고 k3s 를 재시작하세요. marker 가 살아 있는지 확인하고 /root/k3s-ds/migrate.json 에 marker_uid(재시작 뒤 marker 의 UID), sqlite_file_now(db 디렉터리에서 원래 state.db 가 바뀐 이름), node_roles(노드의 node-role.kubernetes.io/ 라벨 이름을 정렬한 배열, 예: ["control-plane"]), member_name(db/etcd/name 파일의 내용)을 적으세요.
SQLite 로 돌던 서버를 cluster-init 으로 기동하면 k3s 가 SQLite 의 내용을 etcd 로 옮깁니다. 이미 etcd 데이터가 디스크에 있으면 이 인자는 무시됩니다. 로그의 Migrating content from sqlite to etcd 를 찾아보세요.
이름을 붙여 스냅숏을 뜬다
marker 의 stage 를 snapshotted 로 바꾼 다음 k3s etcd-snapshot save --name lab-before 로 스냅숏을 뜨세요. /root/k3s-ds/snapshot.json 에 name(만들어진 스냅숏 이름 전체), path(파일 절대 경로), size(바이트, 정수), sha256(파일의 SHA-256)을 적으세요.
--name 은 이름의 앞부분만 정하고 k3s 가 노드 이름과 시각을 덧붙입니다. 저장 위치는 --etcd-snapshot-dir 의 기본값입니다. k3s etcd-snapshot ls 와 kubectl get etcdsnapshotfile 이 같은 스냅숏을 보여 줍니다.
스냅숏만으로는 복원할 수 없다
/root/k3s-ds/backup/ 디렉터리에 4단계의 스냅숏 파일(같은 이름)과 서버 토큰 파일(token 이라는 이름, 권한 600)을 복사하세요. /root/k3s-ds/token-backup.json 에 token_source(토큰 원본의 절대 경로), token_sha256(토큰 파일의 SHA-256), snapshot_sha256(백업한 스냅숏의 SHA-256)을 적으세요. 토큰 값 자체는 어디에도 적지 않습니다.
k3s 는 서버 토큰으로 저장소 안의 기밀 부트스트랩 데이터를 암호화합니다. 다른 토큰으로 복원하면 스냅숏을 쓸 수 없습니다. 복사할 때 권한이 넓어지지 않게 하세요.
스냅숏 뒤에 생긴 것들
스냅숏 뒤에 네임스페이스 k3s-ds 에 ConfigMap after-snap(x=1)을 만들고 marker 의 stage 를 changed 로 바꾸세요. /root/k3s-ds/after.json 에 after_uid(after-snap 의 UID), after_created(그 creationTimestamp), marker_stage(지금 marker 의 stage)를 적으세요.
다음 단계의 복원이 이 둘을 어떻게 만드는지 보려는 것입니다. 복원 뒤에도 이 기록이 진짜였는지 확인할 수 있게 UID 와 시각을 정확히 적습니다.
복원하자 스냅숏 뒤의 변경이 사라졌다
k3s 를 멈추고 k3s server --cluster-reset --cluster-reset-restore-path=<4단계 스냅숏 경로> 로 복원한 뒤(출력 전체를 /root/k3s-ds/reset.log 에 저장) k3s 를 다시 시작하세요. /root/k3s-ds/restore.json 에 old_dir(복원이 이전 etcd 데이터를 옮긴 디렉터리 이름), restart_hint(reset.log 에서 k3s 가 다음에 할 일을 알려 준 문장 중 restart without 이 든 부분까지의 첫 문장), after_snap_exists(불리언), marker_stage(복원 뒤 marker 의 stage), member_name(복원 뒤 db/etcd/name 의 내용)을 적으세요.
복원은 서비스가 멈춘 상태에서 같은 바이너리를 한 번 따로 실행하는 것입니다. 끝나면 스스로 종료하며 다시 시작하라고 알립니다. 이전 데이터는 지우지 않고 옆으로 옮겨 둡니다. 연속된 초기화를 막는 표식 파일이 생겼다가 정상 기동하면 지워집니다.
무엇이 남고 무엇이 사라졌나
/root/k3s-ds/report.json 에 datastore_now(sqlite 또는 etcd), lost_objects(복원으로 사라진 ConfigMap 이름을 정렬한 배열), marker_stage(지금 값), snapshot_dir(스냅숏이 저장된 디렉터리 절대 경로), restore_needs_token(다른 서버에서 복원할 때 원래 토큰이 필요한지, 불리언), member_name_changed(복원 전후 etcd 멤버 이름이 바뀌었는지, 불리언)를 적으세요.
앞 단계의 json 과 지금 디스크·클러스터를 근거로 적습니다. 채점기는 같은 값을 기록 파일·etcd-old 디렉터리·클러스터에서 다시 계산합니다.