소유자와 종속자
소유자와 종속자 (Owners and Dependents)
쿠버네티스 객체들 사이에는 소유(ownership) 관계가 있어요. 예를 들어 ReplicaSet은 팟 집합의 소유자이고, 이렇게 소유된 객체들은 소유자의 종속자(dependents) 입니다. 이 페이지는 소유자 참조(owner references)가 무엇인지, 어떻게 동작하는지, 그리고 파이널라이저와의 관계를 설명해 드립니다.
쿠버네티스에서 일부 객체는 다른 객체의 소유자예요. 예를 들어 ReplicaSet은 팟 집합의 소유자입니다. 이렇게 소유된 객체는 소유자의 종속자가 돼요.
소유(Ownership)는 일부 리소스도 사용하는 라벨과 셀렉터 메커니즘과 다릅니다. 예를 들어 EndpointSlice 객체를 만드는 Service를 생각해 보세요. Service는 라벨을 사용해 컨트롤 플레인이 어떤 EndpointSlice 객체가 그 Service에 사용되는지 결정하게 합니다. 라벨 외에도, Service를 대신해 관리되는 각 EndpointSlice는 소유자 참조를 가져요. 소유자 참조는 쿠버네티스의 서로 다른 부분이 자신이 제어하지 않는 객체에 간섭하는 것을 방지하는 데 도움이 됩니다.
객체 스펙의 소유자 참조 (Owner references in object specifications)
종속 객체에는 소유자 객체를 참조하는 metadata.ownerReferences 필드가 있어요. 유효한 소유자 참조는 종속 객체와 같은 네임스페이스 안의 객체 이름과 UID로 구성됩니다. ReplicaSet, DaemonSet, Deployment, Job, CronJob, ReplicationController 같은 다른 객체의 종속자인 객체에는 쿠버네티스가 이 필드 값을 자동으로 설정해요. 이 필드 값을 바꿔 이러한 관계를 수동으로 구성할 수도 있습니다. 다만 보통은 그럴 필요가 없고 쿠버네티스가 관계를 자동으로 관리하게 두는 게 좋아요.
종속 객체에는 ownerReferences.blockOwnerDeletion 필드도 있는데, 불리언 값을 가지며 특정 종속자가 가비지 컬렉션이 소유자 객체를 삭제하는 것을 차단할 수 있는지 제어합니다. 컨트롤러(예: Deployment 컨트롤러)가 metadata.ownerReferences 필드 값을 설정하면 쿠버네티스는 이 필드를 자동으로 true로 설정해요. blockOwnerDeletion 필드 값을 수동으로 설정해 어떤 종속자가 가비지 컬렉션을 차단할지 제어할 수도 있습니다.
쿠버네티스 admission 컨트롤러는 소유자의 삭제 권한에 기반해 종속 리소스에 대해 이 필드를 변경하는 사용자 접근을 제어해요. 이 통제는 권한 없는 사용자가 소유자 객체 삭제를 지연시키는 것을 방지합니다.
참고: 교차 네임스페이스 소유자 참조는 설계상 금지됩니다. 네임스페이스 범위 종속자는 클러스터 범위 또는 네임스페이스 범위 소유자를 지정할 수 있어요. 네임스페이스 범위 소유자는 종속자와 같은 네임스페이스에 반드시 존재해야 합니다. 그렇지 않으면 소유자 참조가 없는 것으로 처리되고, 모든 소유자가 없는 것으로 확인되면 종속자는 삭제 대상이 됩니다.
클러스터 범위 종속자는 클러스터 범위 소유자만 지정할 수 있어요. v1.20 이상에서 클러스터 범위 종속자가 네임스페이스 범위 종류를 소유자로 지정하면 해결 불가능한 소유자 참조를 가진 것으로 처리되어 가비지 컬렉션될 수 없습니다.
v1.20 이상에서 가비지 컬렉터가 잘못된 교차 네임스페이스
ownerReference또는 네임스페이스 범위 종류를 참조하는 클러스터 범위 종속자를 감지하면,OwnerRefInvalidNamespacereason과 잘못된 종속자를involvedObject로 한 경고 Event가 보고됩니다.kubectl get events -A --field-selector=reason=OwnerRefInvalidNamespace로 해당 이벤트를 확인할 수 있어요.
소유와 파이널라이저 (Ownership and finalizers)
리소스를 삭제하라고 쿠버네티스에 알리면, API 서버는 관리 컨트롤러가 해당 리소스의 파이널라이저 규칙을 처리하도록 허용해요. 파이널라이저는 클러스터가 올바르게 동작하기 위해 여전히 필요할 수 있는 리소스의 우발적 삭제를 방지합니다. 예를 들어 팟이 여전히 사용 중인 PersistentVolume을 삭제하려 하면, PersistentVolume에 kubernetes.io/pv-protection 파이널라이저가 붙어 있어 삭제가 즉시 이루어지지 않아요. 대신 볼륨이 PersistentVolume이 더 이상 팟에 바인딩되지 않을 때까지 Terminating 상태로 남습니다. 파이널라이저는 그 후에야 제거됩니다.
포그라운드(foreground) 또는 오펀(orphan) 캐스케이딩 삭제를 사용할 때 쿠버네티스는 소유자 리소스에도 파이널라이저를 추가해요. 포그라운드 삭제에서는 foreground 파이널라이저를 추가해서, 컨트롤러가 소유자를 삭제하기 전에 ownerReferences.blockOwnerDeletion=true를 가진 종속 리소스도 삭제하도록 합니다. orphan 삭제 정책을 지정하면 쿠버네티스는 orphan 파이널라이저를 추가해 컨트롤러가 소유자 객체 삭제 후 종속 리소스를 무시하게 해요.