@@ -1043,23 +1043,25 @@ func (c *Controller) handleDeletePod(key string) error {
10431043
10441044 podKey := fmt .Sprintf ("%s/%s" , pod .Namespace , podName )
10451045
1046- var keepIPCR bool
1047- if ok , stsName , stsUID := isStatefulSetPod (pod ); ok {
1048- if pod .DeletionTimestamp != nil {
1049- klog .Infof ("handle deletion of sts pod %s" , podName )
1050- toDel := isStatefulSetPodToDel (c .config .KubeClient , pod , stsName , stsUID )
1051- if ! toDel {
1046+ var keepIPCR , isOwnerRefToDel , isOwnerRefDeleted bool
1047+ var ipcrToDelete []string
1048+ isStsPod , stsName , stsUID := isStatefulSetPod (pod )
1049+ if isStsPod {
1050+ if ! pod .DeletionTimestamp .IsZero () {
1051+ klog .Infof ("handle deletion of sts pod %s" , podKey )
1052+ isOwnerRefToDel = isStatefulSetPodToDel (c .config .KubeClient , pod , stsName , stsUID )
1053+ if ! isOwnerRefToDel {
10521054 klog .Infof ("try keep ip for sts pod %s" , podKey )
10531055 keepIPCR = true
10541056 }
10551057 }
10561058 if keepIPCR {
1057- isDelete , err := appendCheckPodToDel (c , pod , stsName , util .StatefulSet )
1059+ isOwnerRefDeleted , ipcrToDelete , err := appendCheckPodNetToDel (c , pod , stsName , util .StatefulSet )
10581060 if err != nil {
10591061 klog .Error (err )
10601062 return err
10611063 }
1062- if isDelete {
1064+ if isOwnerRefDeleted || len ( ipcrToDelete ) != 0 {
10631065 klog .Infof ("not keep ip for sts pod %s" , podKey )
10641066 keepIPCR = false
10651067 }
@@ -1080,20 +1082,20 @@ func (c *Controller) handleDeletePod(key string) error {
10801082 }
10811083 }
10821084 if pod .DeletionTimestamp != nil {
1083- klog .Infof ("handle deletion of vm pod %s" , podName )
1084- vmToBeDel : = c .isVMToDel (pod , vmName )
1085- if ! vmToBeDel {
1085+ klog .Infof ("handle deletion of vm pod %s" , podKey )
1086+ isOwnerRefToDel = c .isVMToDel (pod , vmName )
1087+ if ! isOwnerRefToDel {
10861088 klog .Infof ("try keep ip for vm pod %s" , podKey )
10871089 keepIPCR = true
10881090 }
10891091 }
10901092 if keepIPCR {
1091- isDelete , err := appendCheckPodToDel (c , pod , vmName , util .VMInstance )
1093+ isOwnerRefDeleted , ipcrToDelete , err = appendCheckPodNetToDel (c , pod , vmName , util .VMInstance )
10921094 if err != nil {
10931095 klog .Error (err )
10941096 return err
10951097 }
1096- if isDelete {
1098+ if isOwnerRefDeleted || len ( ipcrToDelete ) != 0 {
10971099 klog .Infof ("not keep ip for vm pod %s" , podKey )
10981100 keepIPCR = false
10991101 }
@@ -1170,6 +1172,12 @@ func (c *Controller) handleDeletePod(key string) error {
11701172 klog .Infof ("try release all ip address for deleting pod %s" , podKey )
11711173 for _ , podNet := range podNets {
11721174 portName := ovs .PodNameToPortName (podName , pod .Namespace , podNet .ProviderName )
1175+ // if the OwnerRef has been deleted or is in the process of being deleted, all associated IPCRs must be cleaned up
1176+ if (isStsPod || isVMPod ) && ! isOwnerRefToDel && ! isOwnerRefDeleted &&
1177+ ! slices .Contains (ipcrToDelete , portName ) {
1178+ klog .Infof ("skip clean ip CR %s" , portName )
1179+ continue
1180+ }
11731181 ipCR , err := c .ipsLister .Get (portName )
11741182 if err != nil {
11751183 if k8serrors .IsNotFound (err ) {
@@ -1967,93 +1975,132 @@ func (c *Controller) acquireStaticAddress(key, nicName, ip string, mac *string,
19671975 return v4IP , v6IP , macStr , nil
19681976}
19691977
1970- func appendCheckPodToDel (c * Controller , pod * v1.Pod , ownerRefName , ownerRefKind string ) (bool , error ) {
1971- // subnet for ns has been changed, and statefulset pod's ip is not in the range of subnet's cidr anymore
1978+ func appendCheckPodNetToDel (c * Controller , pod * v1.Pod , ownerRefName , ownerRefKind string ) (bool , [] string , error ) {
1979+ // subnet for ns has been changed, and statefulset/vm pod's ip is not in the range of subnet's cidr anymore
19721980 podNs , err := c .namespacesLister .Get (pod .Namespace )
19731981 if err != nil {
19741982 klog .Errorf ("failed to get namespace %s, %v" , pod .Namespace , err )
1975- return false , err
1983+ return false , nil , err
19761984 }
19771985
1978- // check if subnet exist in OwnerReference
1979- var ownerRefSubnetExist bool
1980- var ownerRefSubnet string
1986+ var ownerRefAnnotations map [string ]string
19811987 switch ownerRefKind {
19821988 case util .StatefulSet :
19831989 ss , err := c .config .KubeClient .AppsV1 ().StatefulSets (pod .Namespace ).Get (context .Background (), ownerRefName , metav1.GetOptions {})
19841990 if err != nil {
19851991 if k8serrors .IsNotFound (err ) {
19861992 klog .Infof ("Statefulset %s is not found" , ownerRefName )
1987- return true , nil
1993+ return true , nil , nil
19881994 }
19891995 klog .Errorf ("failed to get StatefulSet %s, %v" , ownerRefName , err )
19901996 }
1991- if ss .Spec .Template .ObjectMeta .Annotations [util .LogicalSwitchAnnotation ] != "" {
1992- ownerRefSubnetExist = true
1993- ownerRefSubnet = ss .Spec .Template .ObjectMeta .Annotations [util .LogicalSwitchAnnotation ]
1997+ if ss .Spec .Template .Annotations != nil {
1998+ ownerRefAnnotations = ss .Spec .Template .Annotations
19941999 }
19952000
19962001 case util .VMInstance :
19972002 vm , err := c .config .KubevirtClient .VirtualMachine (pod .Namespace ).Get (context .Background (), ownerRefName , metav1.GetOptions {})
19982003 if err != nil {
19992004 if k8serrors .IsNotFound (err ) {
20002005 klog .Infof ("VirtualMachine %s is not found" , ownerRefName )
2001- return true , nil
2006+ return true , nil , nil
20022007 }
20032008 klog .Errorf ("failed to get VirtualMachine %s, %v" , ownerRefName , err )
20042009 }
20052010 if vm != nil &&
20062011 vm .Spec .Template != nil &&
2007- vm .Spec .Template .ObjectMeta .Annotations != nil &&
2008- vm .Spec .Template .ObjectMeta .Annotations [util .LogicalSwitchAnnotation ] != "" {
2009- ownerRefSubnetExist = true
2010- ownerRefSubnet = vm .Spec .Template .ObjectMeta .Annotations [util .LogicalSwitchAnnotation ]
2011- }
2012- }
2013- podSwitch := strings .TrimSpace (pod .Annotations [util .LogicalSwitchAnnotation ])
2014- if ! ownerRefSubnetExist {
2015- nsSubnetNames := podNs .Annotations [util .LogicalSwitchAnnotation ]
2016- // check if pod use the subnet of its ns
2017- if nsSubnetNames != "" && podSwitch != "" && ! slices .Contains (strings .Split (nsSubnetNames , "," ), podSwitch ) {
2018- klog .Infof ("ns %s annotation subnet is %s, which is inconstant with subnet for pod %s, delete pod" , pod .Namespace , nsSubnetNames , pod .Name )
2019- return true , nil
2012+ vm .Spec .Template .ObjectMeta .Annotations != nil {
2013+ ownerRefAnnotations = vm .Spec .Template .ObjectMeta .Annotations
20202014 }
20212015 }
20222016
2017+ var ipcrToDelete []string
2018+ if defaultIPCRName := appendCheckPodNonMultusNetToDel (c , pod , ownerRefName , ownerRefAnnotations , podNs ); defaultIPCRName != "" {
2019+ ipcrToDelete = append (ipcrToDelete , defaultIPCRName )
2020+ }
2021+
2022+ if multusIPCRNames := appendCheckPodMultusNetToDel (c , pod , ownerRefName , ownerRefAnnotations ); len (multusIPCRNames ) != 0 {
2023+ ipcrToDelete = append (ipcrToDelete , multusIPCRNames ... )
2024+ }
2025+
2026+ return false , ipcrToDelete , nil
2027+ }
2028+
2029+ func appendCheckPodNonMultusNetToDel (c * Controller , pod * v1.Pod , ownerRefName string , ownerRefAnnotations map [string ]string , podNs * v1.Namespace ) string {
2030+ podDefaultSwitch := strings .TrimSpace (pod .Annotations [util .LogicalSwitchAnnotation ])
2031+ if podDefaultSwitch != "" {
2032+ ownerRefSubnet := ownerRefAnnotations [util .LogicalSwitchAnnotation ]
2033+ defaultIPCRName := ovs .PodNameToPortName (ownerRefName , pod .Namespace , util .OvnProvider )
2034+ if ownerRefSubnet == "" {
2035+ nsSubnetNames := podNs .Annotations [util .LogicalSwitchAnnotation ]
2036+ // check if pod use the subnet of its ns
2037+ if nsSubnetNames != "" && ! slices .Contains (strings .Split (nsSubnetNames , "," ), podDefaultSwitch ) {
2038+ klog .Infof ("ns %s annotation subnet is %s, which is inconstant with subnet for pod %s, delete pod" , pod .Namespace , nsSubnetNames , pod .Name )
2039+ return defaultIPCRName
2040+ }
2041+ } else {
2042+ podIP := pod .Annotations [util .IPAddressAnnotation ]
2043+ if shouldCleanPodNet (c , pod , ownerRefName , ownerRefSubnet , podDefaultSwitch , podIP ) {
2044+ return defaultIPCRName
2045+ }
2046+ }
2047+ }
2048+ return ""
2049+ }
2050+
2051+ func appendCheckPodMultusNetToDel (c * Controller , pod * v1.Pod , ownerRefName string , ownerRefAnnotations map [string ]string ) []string {
2052+ var multusIPCRNames []string
2053+ attachmentNets , _ := c .getPodAttachmentNet (pod )
2054+ for _ , attachmentNet := range attachmentNets {
2055+ ipCRName := ovs .PodNameToPortName (ownerRefName , pod .Namespace , attachmentNet .ProviderName )
2056+ podSwitch := strings .TrimSpace (pod .Annotations [fmt .Sprintf (util .LogicalSwitchAnnotationTemplate , attachmentNet .ProviderName )])
2057+ ownerRefSubnet := ownerRefAnnotations [fmt .Sprintf (util .LogicalSwitchAnnotationTemplate , attachmentNet .ProviderName )]
2058+ podIP := pod .Annotations [fmt .Sprintf (util .IPAddressAnnotationTemplate , attachmentNet .ProviderName )]
2059+ if shouldCleanPodNet (c , pod , ownerRefName , ownerRefSubnet , podSwitch , podIP ) {
2060+ multusIPCRNames = append (multusIPCRNames , ipCRName )
2061+ }
2062+ }
2063+ return multusIPCRNames
2064+ }
2065+
2066+ func shouldCleanPodNet (c * Controller , pod * v1.Pod , ownerRefName , ownerRefSubnet , podSwitch , podIP string ) bool {
20232067 // subnet cidr has been changed, and statefulset pod's ip is not in the range of subnet's cidr anymore
20242068 podSubnet , err := c .subnetsLister .Get (podSwitch )
20252069 if err != nil {
2070+ if k8serrors .IsNotFound (err ) {
2071+ klog .Infof ("subnet %s not found for pod %s/%s, not auto clean ip" , podSwitch , pod .Namespace , pod .Name )
2072+ return false
2073+ }
20262074 klog .Errorf ("failed to get subnet %s, %v, not auto clean ip" , podSwitch , err )
2027- return false , err
2075+ return false
20282076 }
20292077 if podSubnet == nil {
20302078 // TODO: remove: CRD get interface will retrun a nil subnet ?
20312079 klog .Errorf ("pod %s/%s subnet %s is nil, not auto clean ip" , pod .Namespace , pod .Name , podSwitch )
2032- return false , nil
2080+ return false
20332081 }
2034- podIP := pod .Annotations [util .IPAddressAnnotation ]
20352082 if podIP == "" {
20362083 // delete pod just after it created < 1ms
20372084 klog .Infof ("pod %s/%s annotaions has no ip address, not auto clean ip" , pod .Namespace , pod .Name )
2038- return false , nil
2085+ return false
20392086 }
20402087 podSubnetCidr := podSubnet .Spec .CIDRBlock
20412088 if podSubnetCidr == "" {
20422089 // subnet spec cidr changed by user
20432090 klog .Errorf ("invalid pod subnet %s empty cidr %s, not auto clean ip" , podSwitch , podSubnetCidr )
2044- return false , nil
2091+ return false
20452092 }
20462093 if ! util .CIDRContainIP (podSubnetCidr , podIP ) {
2047- klog .Infof ("pod's ip %s is not in the range of subnet %s, delete pod" , pod . Annotations [ util . IPAddressAnnotation ] , podSubnet .Name )
2048- return true , nil
2094+ klog .Infof ("pod's ip %s is not in the range of subnet %s, delete pod" , podIP , podSubnet .Name )
2095+ return true
20492096 }
20502097 // subnet of ownerReference(sts/vm) has been changed, it needs to handle delete pod and create port on the new logical switch
20512098 if ownerRefSubnet != "" && podSubnet .Name != ownerRefSubnet {
20522099 klog .Infof ("Subnet of owner %s has been changed from %s to %s, delete pod %s/%s" , ownerRefName , podSubnet .Name , ownerRefSubnet , pod .Namespace , pod .Name )
2053- return true , nil
2100+ return true
20542101 }
20552102
2056- return false , nil
2103+ return false
20572104}
20582105
20592106func isVMPod (pod * v1.Pod ) (bool , string ) {
0 commit comments