@@ -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 {
@@ -501,7 +503,7 @@ func (kc *KubernetesPodController) getPodWithConflictedAttachment(pods []*corev1
501503//
502504// Force delete a pod when all of the below conditions are meet:
503505// 1. NodeDownPodDeletionPolicy is different than DoNothing
504- // 2. pod belongs to a StatefulSet/Deployment depend on NodeDownPodDeletionPolicy
506+ // 2. pod belongs to a StatefulSet/Deployment depend on NodeDownPodDeletionPolicy OR is explicitly marked for deletion.
505507// 3. node containing the pod is down
506508// 4. the pod is terminating and the DeletionTimestamp has passed.
507509// 5. pod has a PV with provisioner driver.longhorn.io
@@ -513,7 +515,8 @@ func (kc *KubernetesPodController) handlePodDeletionIfNodeDown(pod *corev1.Pod,
513515
514516 shouldDelete := (deletionPolicy == types .NodeDownPodDeletionPolicyDeleteStatefulSetPod && isOwnedByStatefulSet (pod )) ||
515517 (deletionPolicy == types .NodeDownPodDeletionPolicyDeleteDeploymentPod && isOwnedByDeployment (pod )) ||
516- (deletionPolicy == types .NodeDownPodDeletionPolicyDeleteBothStatefulsetAndDeploymentPod && (isOwnedByStatefulSet (pod ) || isOwnedByDeployment (pod )))
518+ (deletionPolicy == types .NodeDownPodDeletionPolicyDeleteBothStatefulsetAndDeploymentPod && (isOwnedByStatefulSet (pod ) || isOwnedByDeployment (pod ))) ||
519+ (deletionPolicy == types .NodeDownPodDeletionPolicyDeleteBothStatefulsetAndDeploymentPodAndAnnotatedPods && (isOwnedByStatefulSet (pod ) || isOwnedByDeployment (pod ) || isAnnotatedWithDeletionAnnotation (pod )))
517520
518521 if ! shouldDelete {
519522 return nil
@@ -712,6 +715,15 @@ func isOwnedByDeployment(pod *corev1.Pod) bool {
712715 return false
713716}
714717
718+ func isAnnotatedWithDeletionAnnotation (pod * corev1.Pod ) bool {
719+ if val , ok := pod .ObjectMeta .Annotations [podDeletionAnnotation ]; ok {
720+ if strings .ToLower (val ) == "true" {
721+ return true
722+ }
723+ }
724+ return false // We did not find the annotation, or the annotation is something else than "true" or "True"
725+ }
726+
715727// enqueuePodChange determines if the pod requires processing based on whether the pod has a PV created by us (driver.longhorn.io)
716728func (kc * KubernetesPodController ) enqueuePodChange (obj interface {}) {
717729 key , err := controller .KeyFunc (obj )
0 commit comments