가비지 컬렉션
가비지 컬렉션 (Garbage Collection)
가비지 컬렉션은 쿠버네티스가 클러스터 리소스를 정리하는 데 사용하는 다양한 메커니즘을 통틀어 부르는 용어예요. 이를 통해 다음과 같은 리소스를 정리할 수 있어요:
- 종료된 파드
- 완료된 Job
- 오너 참조가 없는 객체
- 사용하지 않는 컨테이너와 컨테이너 이미지
- StorageClass 회수 정책이 Delete인 동적 프로비저닝된 PersistentVolume
- 오래되었거나 만료된 CertificateSigningRequest (CSRs)
- 다음 시나리오에서 삭제된 Nodes:
- Node Lease 객체
출처: 문서
본문
오너와 종속 객체 (Owners and dependents)
쿠버네티스의 많은 객체는 오너 참조를 통해 서로 연결돼요. 오너 참조는 제어 플레인에 어떤 객체가 다른 객체에 의존하는지 알려줘요. 쿠버네티스는 오너 참조를 사용해 제어 플레인과 다른 API 클라이언트가 객체를 삭제하기 전에 관련 리소스를 정리할 기회를 주어요. 대부분의 경우 쿠버네티스가 오너 참조를 자동으로 관리해요.
소유권은 일부 리소스도 사용하는 라벨과 셀렉터 메커니즘과 다르다는 점을 유의해요. 예를 들어 EndpointSlice 객체를 만드는 Service를 고려해 봐요. Service는 라벨을 사용해 제어 플레인이 그 Service에 사용되는 EndpointSlice 객체를 결정하게 해요. 라벨에 더해, Service를 대신해 관리되는 각 EndpointSlice 는 오너 참조를 가져요. 오너 참조는 쿠버네티스의 여러 부분이 제어하지 않는 객체에 간섭하는 것을 피하도록 도와줘요.
참고:
교차 네임스페이스 오너 참조는 설계상 허용되지 않아요. 네임스페이스 범위 종속 객체는 클러스터 범위 또는 네임스페이스 범위 오너를 지정할 수 있어요. 네임스페이스 범위 오너는 종속 객체와 반드시 같은 네임스페이스에 존재해야 해요. 그렇지 않으면 오너 참조는 존재하지 않는 것으로 취급되고, 모든 오너가 존재하지 않는 것으로 확인되면 종속 객체는 삭제 대상이 돼요.
클러스터 범위 종속 객체는 클러스터 범위 오너만 지정할 수 있어요. v1.20+에서 클러스터 범위 종속 객체가 네임스페이스 범위 종류를 오너로 지정하면, 해결할 수 없는 오너 참조가 있는 것으로 취급되어 가비지 컬렉션될 수 없어요.
v1.20+에서 가비지 컬렉터가 잘못된 교차 네임스페이스 ownerReference 나, 네임스페이스 범위 종류를 참조하는 ownerReference 를 가진 클러스터 범위 종속 객체를 감지하면, OwnerRefInvalidNamespace 이유(reason)와 잘못된 종속 객체를 involvedObject 로 하는 경고 Event가 보고돼요. 이 Event 종류를 확인하려면 kubectl get events -A --field-selector=reason=OwnerRefInvalidNamespace 를 실행해요.
종속 삭제 (Cascading deletion)
쿠버네티스는 ReplicaSet을 삭제할 때 남겨지는 파드처럼 더 이상 오너 참조가 없는 객체를 확인하고 삭제해요. 객체를 삭제할 때, 종속 삭제(cascading deletion) 라는 프로세스에서 쿠버네티스가 객체의 종속 객체를 자동으로 삭제할지 제어할 수 있어요. 종속 삭제에는 두 가지 유형이 있어요:
- 전경(foreground) 종속 삭제
- 배경(background) 종속 삭제
또한 쿠버네티스 finalizer를 사용해 가비지 컬렉션이 오너 참조가 있는 리소스를 어떻게·언제 삭제하는지 제어할 수 있어요.
전경 종속 삭제 (Foreground cascading deletion)
전경 종속 삭제에서 삭제하는 오너 객체는 먼저 삭제 진행 중(deletion in progress) 상태로 들어가요. 이 상태에서 오너 객체에 다음과 같은 일이 일어나요:
- 쿠버네티스 API 서버가 객체의
metadata.deletionTimestamp필드를 삭제 대상으로 표시된 시간으로 설정해요. - 쿠버네티스 API 서버가
metadata.finalizers필드도foregroundDeletion으로 설정해요. - 삭제 프로세스가 완료될 때까지 객체는 쿠버네티스 API를 통해 보인 상태로 유지돼요.
오너 객체가 삭제 진행 중 상태로 들어간 후 컨트롤러는 아는 종속 객체를 삭제해요. 아는 모든 종속 객체를 삭제한 후 컨트롤러는 오너 객체를 삭제해요. 이 시점에서 객체는 더 이상 쿠버네티스 API에서 보이지 않아요.
전경 종속 삭제 동안 오너 삭제를 차단하는 유일한 종속 객체는 ownerReference.blockOwnerDeletion=true 필드를 가진 것들로 가비지 컬렉션 컨트롤러 캐시에 있는 것들이에요. 가비지 컬렉션 컨트롤러 캐시에는 리소스 유형을 성공적으로 나열/감시할 수 없는 객체나, 오너 객체 삭제와 동시에 생성된 객체가 포함되지 않을 수 있어요. 자세한 내용은 전경 종속 삭제 사용하기를 참고해요.
배경 종속 삭제 (Background cascading deletion)
배경 종속 삭제에서 쿠버네티스 API 서버는 오너 객체를 즉시 삭제하고, 가비지 컬렉터 컨트롤러(커스텀 또는 기본)가 종속 객체를 배경에서 정리해요. finalizer가 있으면 필요한 모든 정리 작업이 완료될 때까지 객체가 삭제되지 않도록 보장해요.
기본적으로 쿠버네티스는 수동으로 전경 삭제를 사용하거나 종속 객체를 고아로 만들지 않는 한 배경 종속 삭제를 사용해요.
자세한 내용은 배경 종속 삭제 사용하기를 참고해요.
고아가 된 종속 객체 (Orphaned dependents)
쿠버네티스가 오너 객체를 삭제할 때 뒤에 남겨진 종속 객체를 고아(orphan) 객체라고 해요. 기본적으로 쿠버네티스는 종속 객체를 삭제해요. 이 동작을 재정의하는 방법은 오너 객체 삭제하고 종속 객체를 고아로 두기를 참고해요.
사용하지 않는 컨테이너와 이미지의 가비지 컬렉션
kubelet은 사용하지 않는 이미지를 5분마다, 사용하지 않는 컨테이너를 1분마다 가비지 컬렉션해요. 외부 가비지 컬렉션 도구는 kubelet 동작을 깨뜨리고 존재해야 할 컨테이너를 제거할 수 있으므로 사용을 피해야 해요.
사용하지 않는 컨테이너·이미지 가비지 컬렉션 옵션을 구성하려면 구성 파일로 kubelet을 조정하고 KubeletConfiguration 리소스 유형으로 가비지 컬렉션 관련 매개변수를 변경해요.
컨테이너 이미지 수명주기
쿠버네티스는 모든 이미지의 수명주기를 kubelet의 일부인 image manager를 통해, cadvisor의 협력과 함께 관리해요. kubelet은 가비지 컬렉션 결정을 내릴 때 다음 디스크 사용량 한도를 고려해요:
HighThresholdPercentLowThresholdPercent
구성된 HighThresholdPercent 값 이상의 디스크 사용량은 가비지 컬렉션을 트리거하며, 마지막으로 사용된 시간을 기준으로 오래된 순서부터 이미지를 삭제해요. kubelet은 디스크 사용량이 LowThresholdPercent 값에 도달할 때까지 이미지를 삭제해요.
사용하지 않는 컨테이너 이미지의 가비지 컬렉션
디스크 사용량과 무관하게 로컬 이미지가 사용되지 않을 수 있는 최대 시간을 지정할 수 있어요. 이것은 각 노드에 대해 구성하는 kubelet 설정이에요.
설정을 구성하려면 kubelet 구성 파일의 imageMaximumGCAge 필드에 값을 설정해야 해요.
값은 쿠버네티스 duration으로 지정돼요. 자세한 내용은 용어집의 duration을 참고해요.
예를 들어 구성 필드를 12h45m 으로 설정하면 12시간 45분을 의미해요.
참고:
컨테이너 가비지 컬렉션
kubelet은 정의할 수 있는 다음 변수에 따라 사용하지 않는 컨테이너를 가비지 컬렉션해요:
MinAge: kubelet이 컨테이너를 가비지 컬렉션할 수 있는 최소 나이.0으로 설정하면 비활성화돼요.MaxPerPodContainer: 각 Pod가 가질 수 있는 죽은 컨테이너의 최대 수.0보다 작게 설정하면 비활성화돼요.MaxContainers: 클러스터가 가질 수 있는 죽은 컨테이너의 최대 수.0보다 작게 설정하면 비활성화돼요.
이 변수들에 더해 kubelet은 보통 오래된 순서부터 미식별·삭제된 컨테이너를 가비지 컬렉션해요.
MaxPerPodContainer 와 MaxContainers 는 파드당 최대 컨테이너 수(MaxPerPodContainer)를 유지하는 것이 전역 죽은 컨테이너의 허용 총합(MaxContainers)을 벗어나는 상황에서 서로 충돌할 수 있어요. 이런 상황에서 kubelet은 충돌을 해결하기 위해 MaxPerPodContainer 를 조정해요. 최악의 시나리오는 MaxPerPodContainer 를 1 로 낮추고 가장 오래된 컨테이너를 축출하는 것이에요. 추가로 삭제된 파드가 소유한 컨테이너는 MinAge 보다 오래되면 제거돼요.
참고:
가비지 컬렉션 구성하기
그 리소스를 관리하는 컨트롤러에 특정한 옵션을 구성해 리소스의 가비지 컬렉션을 조정할 수 있어요. 다음 페이지가 가비지 컬렉션을 구성하는 방법을 보여줘요:
더 알아보기 (Learn more)
- 쿠버네티스 객체의 소유권에 대해 더 알아보기
- 쿠버네티스 finalizer에 대해 더 알아보기
- 완료된 Job을 정리하는 TTL 컨트롤러에 대해 알아보기