1

I wonder how Kubernetes executes updates. Let's say that two entities perform an update at the same time. How will the configuration be applied? Is applying/deleting configuration and in general performing mutations over K8S API an atomic operation? Is it possible to perform a mutation based on a condition?

Let's take this simple ConfigMap for an example:

apiVersion: v1
kind: ConfigMap
metadata:
  name: testmap
data:
  foo: "1"

I'd like to update this configuration by setting foo: "2" but only if the foo: "1" exists in the ConfigMap. Such atomic features can be found in databases like MongoDB (e.g. findAndModify), Redis, etc. How can I achieve atomicity in K8S?

xpepermint
  • 267
  • 3
  • 9

1 Answers1

2

In Kubernetes you will need to communicate with kube-apiserver to view resources or make changes to them.

kube-apiserver is using etcd as a place to store data required by Kubernetes.

etcd is a consistent and highly-available key value store used as Kubernetes' backing store for all cluster data

Kubernetes.io: Operating etcd clusters for Kubernetes

You can read on the official site of etcd:

etcd specific definitions

Operation completed

An etcd operation is considered complete when it is committed through consensus, and therefore “executed” – permanently stored – by the etcd storage engine. The client knows an operation is completed when it receives a response from the etcd server. Note that the client may be uncertain about the status of an operation if it times out, or there is a network disruption between the client and the etcd member. etcd may also abort operations when there is a leader election. etcd does not send abort responses to clients’ outstanding requests in this event.

Guarantees provided

Atomicity

All API requests are atomic; an operation either completes entirely or not at all. For watch requests, all events generated by one operation will be in one watch response. Watch never observes partial events for a single operation.

As you can read above, etcd has a guarantee to be consistent.


More information about the operations on resources can be found in this blog post:

You can read there (blog post is quite lengthy but explanatory):

There may be certain instances when you want to be sure that no changes have been made to a resource between the time you read the resource and when you are updating it. Put another way, you need to make sure all changes to a resource are atomic. This is the use case for updating a resource using replace. For example, if you have a ConfigMap with a counter that is updated by multiple sources, you may want to make sure that two sources do not attempt to update the counter simultaneously, causing you to “lose” an update.

<-- SKIPPED -->

The spec supplied in the replace request should be the fully formed resource spec, not a partial spec and not just the parts required when using kubectl apply. In particular, you must include the current resourceVersion in the spec metadata. If you do not include the resourceVersion or the version you provide is not the current one, the replacement will be rejected.


Additional resources:

I found similar case on Stackoverflow which is also dealing with similar question:

Dawid Kruk
  • 588
  • 2
  • 8