Skip to content

K3s Node Hygiene

FractalOps K3s 노드는 수동 컨테이너 런타임 청소에 의존하면 안 됩니다. kubelet GC, 디스크 eviction 임계치, 컨테이너 로그 로테이션을 관리되는 drop-in으로 선언하고, finished 워크로드는 네이티브 retention 설정으로 줄입니다.

flowchart TB
  subgraph control["클러스터 프로비저너"]
    gc["kubelet config\nimage GC / eviction / log rotate"]
  end
  subgraph runner["Daytona 샌드박스 (native Kubernetes pods, ADR-0007)"]
    region["runner region = fractalops-k3s\n(옛 dev-workspaces_v7FU 금지)"]
  end
  subgraph retention["finished 워크로드 retention (네이티브)"]
    cj["CronJob successful/failedJobsHistoryLimit"]
    ttl["Job ttlSecondsAfterFinished"]
    rev["Deployment revisionHistoryLimit"]
  end
  gc --> nodeok["노드 Ready 유지\n디스크 압박 회피"]
  retention --> nodeok

Kubelet GC와 eviction은 노드 프로비저너가 소유합니다. Assembly의 Kubernetes 디렉터리는 SSH로 노드 파일을 쓰거나 K3s를 재시작하지 않습니다. 아래 값은 클러스터 프로비저너에서 선언하고 유지보수 윈도우에 배포하세요.

kubelet-arg:
- "image-gc-high-threshold=85"
- "image-gc-low-threshold=80"
- "eviction-hard=nodefs.available<10%,imagefs.available<10%"
- "eviction-minimum-reclaim=nodefs.available=5Gi,imagefs.available=5Gi"
- "container-log-max-size=20Mi"
- "container-log-max-files=3"
Terminal window
pnpm assembly:kubectl -- get --raw=/readyz?verbose
pnpm assembly:kubectl -- get nodes -o wide
pnpm assembly:kubectl -- get cronjobs -A

/readyz가 ok이고 모든 노드가 Ready면 위생이 유지된 것입니다.

Daytona 샌드박스 (native Kubernetes pods)

Section titled “Daytona 샌드박스 (native Kubernetes pods)”

ADR-0007 이후 Daytona 샌드박스는 in-pod DinD runner DaemonSet이 아니라 native Kubernetes 팟(runner-manager provider, 샌드박스당 팟 1개)입니다. 노드에 in-pod dockerd를 준비하는 reconcile_daytona_runner_docker.sh 화해는 더 이상 필요하지 않아 제거되었습니다. 노드 위생은 위의 GC/retention 정책만으로 유지됩니다.

finished 워크로드 누적 (네이티브 retention 선호)

Section titled “finished 워크로드 누적 (네이티브 retention 선호)”
CronJob.spec.successfulJobsHistoryLimit
CronJob.spec.failedJobsHistoryLimit
Job.spec.ttlSecondsAfterFinished # 차트가 노출하면
Deployment.spec.revisionHistoryLimit # high-churn Deployment용

직접 삭제는 오너를 확인한 뒤 이미-stale한 객체에만 쓰세요.

Terminal window
pnpm assembly:kubectl -- delete pod -A --field-selector=status.phase=Succeeded --wait=false
pnpm assembly:kubectl -- delete pod -A --field-selector=status.phase=Failed --wait=false
pnpm assembly:kubectl -- get rs -A -o json \
| jq -r '.items[] | select((.spec.replicas // 0) == 0) | [.metadata.namespace, .metadata.name] | @tsv' \
| while IFS=$'\t' read -r ns name; do pnpm assembly:kubectl -- -n "$ns" delete rs "$name" --wait=false; done