Remove specific taint from a node with one API request

1/28/2020

Is there a way with a single kubernetes API request to remove a specific node taint by key name? As far as I can see the JSON merge patch spec only allows for modifying arrays by index, which I won't know without an additional request and risking a race condition.

Specifically, I am trying to add/remove dedicated NoSchedule keys.

Patching the following body will wipe away all taints:

spec: {
    taints: []
}

Or I can query the node then modify the taints array and patch it back in, but that risks another operation occurring which will be overwritten. This is quite low risk, but feels like a risk that should be avoidable regardless of likelihood.

kubectl as of 1.16, at least, takes the second approach when adding or removing taints, with two requests each, a GET and a PATCH, so I'm not optimistic this is possible:

# following command removes the taint with the key 'dedicated'

kubectl taint nodes my-node-1 dedicated- -v8

# (output clearly shows a GET followed by a PATCH request)

So is there any way to write a single API request that results in a specific named taint being removed while leaving others unaffected (without prior knowledge of the taint's position in the taints array)?

-- Ben Fletcher
kubernetes

1 Answer

1/29/2020

There isn't a way to delete an entry from the taints array in a NodeSpec in a single request, short of doing something to data inside the etcd store.

The default array patch strategy in the Kubernetes API is to replace the array, so you need to send the complete contents of the taints array. Some arrays in the API allow you to merge new elements in, but I don't think there is even an available strategy that does deletion the way you want.

but that risks another operation occurring which will be overwritten. This is quite low risk, but feels like a risk that should be avoidable regardless of likelihood.

The Kuberenetes API provides a generic method to protect against stale data updates. All kubernetes resources include a resourceVersion property in their metadata.

When you send the PATCH, include the received resourceVersion and the update will fail if the server side record has been updated since you retrieved the resource.

{
  "metadata": { "resourceVersion": "27409402" },
  "spec": {
    "taints": [
      { "effect":"NoSchedule", "key":"whatever", "value":"special" }
    ]
  }
}
-- Matt
Source: StackOverflow