@@ -35,6 +35,8 @@ const (
3535 controllerAgentName = "longhorn-kubernetes-pod-controller"
3636
3737 remountRequestDelayDuration = 5 * time .Second
38+
39+ podDeletionAnnotation = "longhorn.io/allow-deletion"
3840)
3941
4042type KubernetesPodController struct {
@@ -472,7 +474,7 @@ func (kc *KubernetesPodController) getPodWithConflictedAttachment(pods []*corev1
472474//
473475// Force delete a pod when all of the below conditions are meet:
474476// 1. NodeDownPodDeletionPolicy is different than DoNothing
475- // 2. pod belongs to a StatefulSet/Deployment depend on NodeDownPodDeletionPolicy
477+ // 2. pod belongs to a StatefulSet/Deployment depend on NodeDownPodDeletionPolicy OR is explicitly marked for deletion.
476478// 3. node containing the pod is down
477479// 4. the pod is terminating and the DeletionTimestamp has passed.
478480// 5. pod has a PV with provisioner driver.longhorn.io
@@ -484,7 +486,8 @@ func (kc *KubernetesPodController) handlePodDeletionIfNodeDown(pod *corev1.Pod,
484486
485487 shouldDelete := (deletionPolicy == types .NodeDownPodDeletionPolicyDeleteStatefulSetPod && isOwnedByStatefulSet (pod )) ||
486488 (deletionPolicy == types .NodeDownPodDeletionPolicyDeleteDeploymentPod && isOwnedByDeployment (pod )) ||
487- (deletionPolicy == types .NodeDownPodDeletionPolicyDeleteBothStatefulsetAndDeploymentPod && (isOwnedByStatefulSet (pod ) || isOwnedByDeployment (pod )))
489+ (deletionPolicy == types .NodeDownPodDeletionPolicyDeleteBothStatefulsetAndDeploymentPod && (isOwnedByStatefulSet (pod ) || isOwnedByDeployment (pod ))) ||
490+ (deletionPolicy == types .NodeDownPodDeletionPolicyDeleteBothStatefulsetAndDeploymentPodAndAnnotatedPods && (isOwnedByStatefulSet (pod ) || isOwnedByDeployment (pod ) || isAnnotatedWithDeletionAnnotation (pod )))
488491
489492 if ! shouldDelete {
490493 return nil
@@ -681,6 +684,15 @@ func isOwnedByDeployment(pod *corev1.Pod) bool {
681684 return false
682685}
683686
687+ func isAnnotatedWithDeletionAnnotation (pod * corev1.Pod ) bool {
688+ if val , ok := pod .ObjectMeta .Annotations [podDeletionAnnotation ]; ok {
689+ if strings .ToLower (val ) == "true" {
690+ return true
691+ }
692+ }
693+ return false // We did not find the annotation, or the annotation is something else than "true" or "True"
694+ }
695+
684696// enqueuePodChange determines if the pod requires processing based on whether the pod has a PV created by us (driver.longhorn.io)
685697func (kc * KubernetesPodController ) enqueuePodChange (obj interface {}) {
686698 key , err := controller .KeyFunc (obj )
0 commit comments