SAS Studio 접속이 되지 않거나 극도로 느려지고, 네임스페이스를 보면 세션 파드가 수십에서 수백 개가 Running 으로 남아 있다. 브라우저 탭만 닫고 세션을 정상 종료하지 않은 접속이 쌓인 것으로, 노드 자원을 계속 붙잡고 있어 새 세션이 뜨지 못하게 만든다.
Completed 상태로 남은 파드는 자원을 쓰지 않으므로 다른 문제다. 여기서 다루는 것은 Running 인데 실제로는 아무도 쓰지 않는 파드 다.
세션 파드의 이름과 소유 관계는 릴리스에 따라 다르다. 정리 명령을 그대로 옮겨 쓰기 전에 실제 이름과 소유자를 먼저 확인한다.
kubectl get pod -n <namespace> --sort-by=.metadata.creationTimestamp | head -40
kubectl get pod -n <namespace> <파드> -o jsonpath='{.metadata.ownerReferences}{"\n"}'
kubectl get pod -n <namespace> <파드> --show-labels
오래된 릴리스에서는 launcher 와 compute server 가 한 파드였고, 최근 릴리스는 sas-compute-server-... 형태로 뜬다. 소유자가 Job 이면 파드만 지워도 Job 이 다시 만든다. 이 확인을 건너뛰고 지우기 시작하면 "지워도 계속 생긴다" 는 상태가 된다.
정리하는 동안 새 세션이 계속 생기면 끝나지 않는다. 유지보수 창을 잡고 Studio 를 잠시 내린다.
kubectl -n <namespace> scale deploy sas-studio-app --replicas=0
배포판에 따라 Deployment 이름이 다르므로 kubectl get deploy -n <namespace> | grep studio 로 확인한다. 정리가 끝나면 다시 올린다.
사용 중인 세션까지 지우지 않도록 생성 시각 기준 같은 보수적인 조건을 반드시 건다. 아래는 3시간 이상 된 세션 파드를 고르는 예다.
kubectl get pod -n <namespace> -o json \
| jq -r '.items[]
| select(.status.phase=="Running")
| select(.metadata.name | test("compute|launcher|batch"))
| select((now - (.metadata.creationTimestamp | fromdate)) > 3*3600)
| .metadata.name'
먼저 목록만 뽑아 눈으로 확인한 뒤 삭제로 넘어간다.
kubectl get pod -n <namespace> -o json \
| jq -r '...위와 같은 필터...' \
| xargs -r -n1 kubectl -n <namespace> delete pod
--grace-period=0 --force 는 기본값으로 쓰지 않는다. 정상 종료 신호로 정리되는 파드가 대부분이고, 강제 삭제는 API 오브젝트만 지우고 노드의 컨테이너를 남길 수 있다. 일반 삭제로 끝나지 않을 때만 쓴다.
소유자가 Job 이면 Job 을 지운다.
kubectl get pod -n <namespace> -o json \
| jq -r '.items[]
| select(.status.phase=="Running")
| .metadata.ownerReferences[]? | select(.kind=="Job") | .name' \
| sort -u \
| xargs -r -n1 kubectl -n <namespace> delete job
정리는 증상 대응이고, 쌓이지 않게 하는 것이 본치료다.
컴퓨트 컨텍스트에 유휴 시간과 최대 지속 시간을 건다. Environment Manager 의 Compute Context 설정에서 idle timeout 과 최대 세션 시간을 정한다. 이것이 없으면 브라우저를 닫은 세션이 영원히 남는다.
끝난 Job 오브젝트를 자동으로 지운다. 세션이 Job 으로 생성되는 경로에는 ttlSecondsAfterFinished 가 효과가 있다.
spec:
ttlSecondsAfterFinished: 3600
안전장치로 총량 상한을 둔다. ResourceQuota 는 폭주가 플랫폼 전체를 무너뜨리는 것을 막는다.
apiVersion: v1
kind: ResourceQuota
metadata:
name: session-quota
namespace: <namespace>
spec:
hard:
pods: "200"
플랫폼 파드에 더 높은 우선순위를 준다. PriorityClass 를 나누면 자원 압박 때 세션 파드가 먼저 축출되어 플랫폼 서비스가 살아남는다.
운영 항목으로 넣는다. 세션 파드 수를 지표로 잡아 임계치 알람을 걸고, 사용자에게는 탭을 닫지 말고 세션을 종료하도록 안내한다. 정리 스크립트를 CronJob 으로 돌린다면 조건을 보수적으로 잡고 삭제 대상을 로그로 남긴다.