Files

5.7 KiB

k3s Secret 암호화 수동 운영 절차

현재 경계(2026-08-09): bootstrap의 --recovery-policy local-separate-disk-luks, 물리 디스크 lineage validator, LOCAL_RISK_ACCEPTED, pre/post 동적 용량 gate는 구현·fixture 검증을 마쳤다. 수동 LUKS header 복구 proof, recovery close·잔류 없음 검사와 closed validator를 통과한 뒤 live 전환도 완료했다. 현재 Secret encryption은 Enabled/reencrypt_finished이며 hash·integrity·API·node 검사와 post bundle 기록, 최신 bundle marker 검증이 모두 통과했다. lifecycle 자동화, 격리 restore drill, off-host 복제와 암호화 escrow 검증은 별도 미완료 gate이므로 관측성 Phase 4를 열지 않는다.

이 문서는 단일 k3s server에서 Kubernetes Secret 저장 암호화를 fail-stop 방식으로 전환하는 수동 절차다. 아래 상태 순서의 live 전 역사적 기준선v1.36.2+k3s1, 단일 Ready 노드 donghyeon-system-product-name, SQLite, Secret encryption Disabled, API readyz pass였다. 현재 live 상태는 위 banner의 Enabled/reencrypt_finished다. 모든 단계는 운영자가 명시적으로 실행하고 확인한다. 자동화는 상태가 불명확하거나 검증이 실패하면 다음 단계로 진행하지 않는다.

상태 순서

다음 순서와 각 화살표 사이의 검증을 바꾸지 않는다.

disabled_no_config
  -> k3s secrets-encrypt enable
  -> drop-in install + restart
  -> transition_start + hashes_match
  -> k3s secrets-encrypt rotate-keys
  -> bounded wait for reencrypt_finished
  -> final restart
  -> Enabled/reencrypt_finished + server_hashes_match + local_integrity_match

각 상태 전환 전후에는 Task 2 validator를 해당 기대 상태로 실행해 version, 단일 Ready server, datastore, API readyz, status와 hash/integrity를 확인한다. validator 출력이나 운영 로그에 server token, 비밀번호, encryption config 본문을 기록하지 않는다.

사전 판정과 소유 위치

이미 enabled_stable로 분류되면 Task 1 effective-source resolver를 사용하여 ExecStart, Environment/EnvironmentFile, systemd drop-in, default 또는 alternate config 및 그 config drop-in을 순서대로 판정한다. 여기서 secrets-encryption과 provider의 유효 소유 위치만 확인한다.

계획한 40-secrets-encryption.yaml이 아닌 기존 위치가 owner이면 그 위치를 그대로 보존하고 config rewrite를 하지 않는다. 서로 충돌하는 두 owner, provider 판정 불가, 또는 기존 provider가 aescbc가 아닌 경우에는 자동 변경하지 않는다. 이 경우에는 별도 ADR을 먼저 승인해야 한다.

enabled_stable의 stage가 reencrypt_finished이면 rotation을 건너뛴다. stage가 start이면 Phase 4 전에 --rotate-existing을 사용한 명시 승인 재암호화만 수행한다.

Bootstrap 진입 명령

인자 없는 명령은 상태만 읽고 변경하지 않는다.

cd /home/donghyeon/workspace/platform
bash scripts/bootstrap/apply-k3s-secret-encryption.sh

실제 전환 명령은 recovery volume이 열린 상태에서 backup root를 직접 지정하고 로컬 정책을 명시한다. 다음 명령은 maintenance 승인 전에는 실행하지 않는다.

cd /home/donghyeon/workspace/platform
bash scripts/bootstrap/apply-k3s-secret-encryption.sh \
  --execute \
  --backup-root /srv/recovery/k3s \
  --recovery-policy local-separate-disk-luks

실행 확인 순서는 APPLY <context> → 자동 root·lineage·용량 검증 → RECOVERY <context>ENCRYPTED <context>LOCAL_RISK_ACCEPTED <context>다. 어느 검사나 확인이 실패해도 다음 mutation으로 진행하지 않는다. 비밀번호나 복구 키를 이 명령의 인자·환경변수로 전달하지 않는다.

실행 단계

  1. disabled_no_config을 validator로 확인한 뒤에만 k3s secrets-encrypt enable을 실행한다.

  2. repository의 host artifact를 root 소유, mode 0644로 설치한다.

    install -o root -g root -m 0644 \
      infrastructure/security/k3s/40-secrets-encryption.yaml \
      /etc/rancher/k3s/config.yaml.d/40-secrets-encryption.yaml
    
  3. k3s를 재시작하고, transition_start + hashes_match가 validator로 확인될 때까지 중단한다.

  4. 확인 뒤에만 k3s secrets-encrypt rotate-keys를 한 번 실행한다.

  5. 제한된 시간 동안 reencrypt_finished를 기다린다. 시간 초과, API 실패, hash mismatch 또는 local integrity mismatch이면 중단하고 조사한다.

  6. 완료 상태를 확인한 후 final restart를 하고, Enabled/reencrypt_finished + server_hashes_match + local_integrity_match를 다시 확인한다.

금지 및 중단 조건

  • transition_start 확인 전에는 rotate-keys를 실행하지 않는다.
  • 중간 stage에서는 다른 rotation 명령을 실행하지 않는다.
  • drop-in을 자동 삭제하지 않는다.
  • live datastore 자동 restore 금지: 복구 판단과 수행은 별도 승인 절차다.
  • server token 또는 encryption key material을 명령 인자, 로그, ticket, Git에 남기지 않는다.

post bundle의 격리 복구, 결과 반출·파기와 evidence 등록은 k3s Secret 암호화 복구 drill을 따른다.

재시도와 복구 경계

상태가 disabled_no_config, transition_start, enabled_stable 중 하나로 명확히 판정되지 않으면 재시도나 설정 변경을 하지 않는다. 특히 hash mismatch, provider 불명확, owner 충돌, API readyz 실패는 자동 보정 대상이 아니다. 라이브 datastore를 되돌리거나 Secret을 변경하는 동작도 이 절차의 권한 밖이며, 별도 ADR과 명시 승인을 필요로 한다.