Oliver Gondža
Oliver Gondža

Reputation: 3511

Assign openstack floating IP while making sure it will not be removed from other server

(I am using openstack4j to talk to OpenStack via REST API)

I would like to reuse some of the unassigned floating IPs allocated in my tenant (allocate to newly provisioned servers). However, it seems that addFloatingIp action makes no difference between assigning unused floating IP and reassigning it from server to server.

I would like to automate the process but I am afraid of following race condition: one client check particular IP is free and before it manages to associate it with server A, other client associate it with server B. From the perspective of the second client, the associated floating IP can be removed in any later point after successfully associated.

Is there any better way?

Upvotes: 4

Views: 1198

Answers (2)

Oliver Gondža
Oliver Gondža

Reputation: 3511

The challenges in question concern usage of (now deprecated) Floating IP extension of Compute service that splits floating IP allocation into two steps: allocation (/os-floating-ips endpoint) and assignment (addFloatingIp server action).

Currently supported way is to manipulate floating IPs via Neutron service that permits to create and associate floating IPs in one request (POST to /v2.0/floatingips). This, at least in theory, eliminates the possibility of a client that desire to reuse a floating IP would take one being associated by some other client as the same time. Provided all clients agree to use this mode of Floating IP assignment, unassociated Floating IPs are safe to dispose as dangling entitie.

Upvotes: 0

Jan Zerebecki
Jan Zerebecki

Reputation: 865

Possible workarounds for this are:

  • Only delete and create floating IPs. As you say this is the preferred way. Clean up of floating IPs that are not in use any more can happen regularly from the inside by a small VM. But clean up from the outside by the API client should be preferred. As such every client should integrate this functionality, however care must be taken that this is intended by the user least they loose something important. Examples: The web UI that you use to delete VMs could ask if it should also delete the associated floating VM. Openstack Heat (orchestration via templates) does this automatically. A CLI client could offer to delete freed resources after deleting a VM.
  • Use something that supports synchronisation to coordinate. Examples: etcd, data base (SQL or not) with transaction support, queues that can ensure delivery is done exactly once (e.g. OpenStack Zaqar with its claims feature).
  • Use passage of time for synchronisation: Read, change, waiting for a specific amount of time and finally read again to check that nobody overwrote the change. Abort before the specific waiting time if this change takes too long. Retry with a different floating ip if the change was overwritten. This is hard to get right, as there are many corner cases, especially with correctly aborting soon enough, that can make this fail. For example high load might make the change succeed long after is was aborted if not every place the change passes through ensures that this won't happen.

Other OpenStack APIs have the same problem, e.g. updating security groups. In general this could be avoided by adding revision counters to APIs, for example kubernetes (resourceVersion from ObjectMeta) and etcd (modifiedIndex in v2, mod_revision in v3) do this.

Even for an API that implements options for race free changes, most UIs for humans might only use this for race detection but not avoidance, as a UI that tells them there was a race and what it overwrote is preferred over one that requires them to retry their action each time a race happens.

Upvotes: 1

Related Questions