我想知道 Kubernetes 如何执行更新。假设两个实体同时执行更新。配置将如何应用?应用/删除配置以及通过 K8S API 执行变更是否是原子操作?是否可以根据条件执行变更?
我们以这个简单的 ConfigMap 为例:
apiVersion: v1
kind: ConfigMap
metadata:
name: testmap
data:
foo: "1"
我想通过设置来更新此配置foo: "2"
,但前提是foo: "1"
ConfigMap 中存在。MongoDB(例如 findAndModify)、Redis 等数据库中可以找到此类原子特性。如何在 K8S 中实现原子性?
答案1
在 Kubernetes 中,你需要与kube-api服务器查看资源或对其进行更改。
kube-apiserver
用作etcd
存储 Kubernetes 所需数据的地方。
etcd 是一个一致且高度可用的键值存储,用作 Kubernetes 所有集群数据的后备存储
您可以在官方网站上阅读etcd
:
etcd 具体定义
操作完成
当 etcd 操作通过共识提交时,该操作被视为完成,因此由 etcd 存储引擎“执行” - 永久存储。当客户端收到来自 etcd 服务器的响应时,它就知道操作已完成。请注意,如果操作超时,或者客户端与 etcd 成员之间出现网络中断,客户端可能不确定操作的状态。当发生领导者选举时,etcd 也可能会中止操作。在这种情况下,etcd 不会向客户端的未完成请求发送中止响应。
提供的担保
原子性
所有 API 请求都是原子的;操作要么完全完成,要么根本不完成对于监视请求,一个操作生成的所有事件将包含在一个监视响应中。监视永远不会观察单个操作的部分事件。
正如您在上面看到的,etcd
保证是一致的。
关于资源操作的更多信息可以参阅以下博文:
您可以在那里阅读(博客文章很长但具有解释性):
在某些情况下,您可能希望确保在读取资源和更新资源之间没有对资源进行任何更改。换句话说,您需要确保对资源的所有更改都是原子。这是使用 replace 更新资源的用例。例如,如果您有一个带有由多个源更新的计数器的 ConfigMap,您可能希望确保两个源不会同时尝试更新计数器,从而导致您“丢失”更新。
<-- 已跳过 -->
替换请求中提供的规范应为完整形成的资源规范,而不是部分规范,也不只是使用 kubectl apply 时所需的部分。特别是,您必须
resourceVersion
在规范元数据。如果您不包含resourceVersion
或者您提供的版本不是最新版本,替换将被拒绝。
其他资源:
我在 Stackoverflow 上发现了类似的案例,它也处理类似的问题: