Skip to content

IP is not released after deleting IPClaim #694

Open
@haijianyang

Description

@haijianyang

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:

  1. First set and save IPClaimFinalizer for IPClaim, then create IPAddress.
  2. 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

Labels

kind/bugCategorizes issue or PR as related to a bug.triage/acceptedIndicates an issue is ready to be actively worked on.

Type

Projects

Status

CAPM3 WIP

Relationships

None yet

Development

No branches or pull requests

Issue actions