Open
Description
What steps did you take and what happened:
Create an IPClaim and then delete it immediately. It may happen that the IPClaim is deleted, but the IPAddress associated with the IPClaim still exists.
Here is IPAM logs:
2024-09-23T09:51:08.093162287+08:00 stderr F I0923 09:51:08.092992 1 ippool_manager.go:336] "controllers/IPPool/IPPool-controller: Getting address" metal3-ippool="default/myippool" Claim="default-myippoolqamn-jzm958-wvkz2-0"
2024-09-23T09:51:08.093188235+08:00 stderr F I0923 09:51:08.093072 1 ippool_manager.go:346] "controllers/IPPool/IPPool-controller: Address allocated" metal3-ippool="default/myippool" Claim="default-myippool-qamn-jzm958-wvkz2-0" address="10.60.70.160"
2024-09-23T09:51:08.136815948+08:00 stderr F E0923 09:51:08.133958 1 ippool_manager.go:221] "controllers/IPPool/IPPool-controller: failed to Patch IPClaim" err="ipclaims.ipam.metal3.io \"default-myippool-qamn-jzm958-wvkz2-0\" not found" metal3-ippool="default/myippool"
What did you expect to happen:
The IP should be released after deleting IPClaim, otherwise the IP resources will be leaked.
Anything else you would like to add:
I found that createAddress first sets IPClaimFinalizer for IPClaim in the same reconcile, then creates IPAddress, and finally saves IPClaimFinalizer. So if IPClaim is deleted before saving IPClaimFinalizer, there should be a situation where IPAddress is not deleted in cascade.
// https://github.com/metal3-io/ip-address-manager/blob/ce1b21f332bab3af1d52d87f7e6b95e7311c4e85/ipam/ippool_manager.go#L318
func (m *IPPoolManager) createAddress(ctx context.Context,
addressClaim *ipamv1.IPClaim, addresses map[ipamv1.IPAddressStr]string,
) (map[ipamv1.IPAddressStr]string, error) {
if !Contains(addressClaim.Finalizers, ipamv1.IPClaimFinalizer) {
addressClaim.Finalizers = append(addressClaim.Finalizers,
ipamv1.IPClaimFinalizer,
)
}
// other codes
// Create the IPAddress object. If we get a conflict (that will set
// HasRequeueAfterError), then requeue to retrigger the reconciliation with
// the new state
if err := createObject(ctx, m.client, addressObject); err != nil {
var reqAfter *RequeueAfterError
if ok := errors.As(err, &reqAfter); !ok {
addressClaim.Status.ErrorMessage = pointer.String("Failed to create associated IPAddress object")
}
return addresses, err
}
// other codes
return addresses, nil
}
There are two possible solutions:
- First set and save IPClaimFinalizer for IPClaim, then create IPAddress.
- Keep the current way of using IPClaimFinalizer and clean up the IPAddress of the deleted IPClaim.
Environment:
- Cluster-api version: v1.6.x
- CAPM3 version:
- IPAM version: v1.6.3
- Minikube version:
- environment (metal3-dev-env or other): other
- Kubernetes version: (use
kubectl version
): v1.25.6
/kind bug
Metadata
Metadata
Assignees
Labels
Type
Projects
Status
CAPM3 WIP