阶段配置 #
本文档将指导您如何配置生命周期的阶段。
什么是阶段? #
Stage
是一个kwok 配置
,允许用户定义和模拟 Kubernetes 资源(如节点和 Pod)生命周期中的不同阶段。每个阶段资源都指定一个resourceRef
字段,用于标识该阶段适用的资源类型,以及一个selector
字段,用于确定何时执行该阶段。
阶段资源具有以下字段
kind: Stage
apiVersion: kwok.x-k8s.io/v1alpha1
metadata:
name: <string>
spec:
resourceRef:
apiGroup: <string>
kind: <string>
selector:
matchLabels:
<string>: <string>
matchAnnotations:
<string>: <string>
matchExpressions:
- key: <expressions-string>
operator: <string>
values:
- <string>
weight: <int>
delay:
durationMilliseconds: <int>
durationFrom:
expressionFrom: <expressions-string>
jitterDurationMilliseconds: <int>
jitterDurationFrom:
expressionFrom: <expressions-string>
next:
statusTemplate: <string>
event:
type: <string>
reason: <string>
message: <string>
finalizers:
add:
- value: <string>
remove:
- value: <string>
empty: <bool>
delete: <bool>
immediateNextStage: <bool>
通过设置阶段资源的 spec 部分中的selector
和next
字段,用户可以指定应用阶段所需的条件,以及应用阶段时对资源进行的更改。next
字段允许用户使用statusTemplate
字段定义资源的新状态,甚至删除
资源。
statusTemplate
和 delete
是 next
中的两个基本字段,分别表示资源生命周期模拟的两个基本阶段:状态更新和资源删除。statusTemplate
提供了一种基于 go 模板渲染来定义资源状态的方法。有关更详细的说明,请参阅 kwok
中的 go 模板。delete: true
优先级高于非空 statusTemplate
,这意味着如果同时设置这两个字段,kwok
将删除资源,而不是更新其状态。
除了这两个基本字段外,next
中还有另外两个字段允许用户在状态更新或删除之前对模拟资源执行一些其他操作。如果需要记录某些内容,event
允许用户发出关联的 Kubernetes 事件。finalizers
允许用户添加或删除最终确定器。请注意,这两个字段都可以单独存在,而无需指定 delete
或 statusTemplate
字段。在这种情况下,kwok
将仅发送事件或修改最终确定器,并且在应用阶段时不会更改状态或删除资源。
值得注意的是,如果没有提供多种资源类型的阶段,则没有专门的字段用于安排执行顺序。阶段的执行顺序可以通过同时使用 selector.matchExpressions
和 next
字段来控制。具体来说,用户可以通过确保阶段的 selector.matchExpressions
匹配前一阶段 next
字段中指定的状态内容来链接阶段。有关详细示例,请参阅 默认 Pod 阶段。如果多种资源类型的阶段共享相同的 selector
设置,kwok
将随机选择一个阶段来应用于特定资源。用户还可以通过 weight
字段自定义选择阶段的概率。当您希望特定类型下的资源根据特定概率分布进入不同的阶段时,这非常有用。请注意,weight
仅对具有相同 resourceRef
和 selector
设置的阶段生效。
此外,阶段资源中的 delay
字段允许用户在应用阶段之前指定延迟,并引入延迟抖动以指定最晚延迟时间,从而使模拟更加真实。这对于模拟事件并不总是在同一时间发生的真实场景非常有用。有关更多详细信息,请参阅 如何计算延迟。
通过配置阶段中的 delay
、selector
和 next
字段,您可以控制阶段的应用时间和方式,从而提供一种灵活且可扩展的方法来模拟 Kubernetes 集群中的真实场景。这使您可以创建复杂且真实的模拟,用于测试、验证和实验,并深入了解应用程序和基础设施的行为和性能。
表达式字符串 #
<expressions-string>
由 Go 实现 的 JQ 表达式 提供
工作原理 #
根据 next
字段的不同设置,阶段通常可分为两类。具有非空 statusTemplate
的阶段是“更改阶段”,kwok
将使用该阶段来更新资源状态。delete
为 true
的阶段表示“删除阶段”,这意味着 kwok
将删除该资源。
kwok
中的 资源生命周期模拟控制器 会应用这些阶段。该控制器监视来自 API 服务器的资源事件,并在收到关联事件时对资源应用一个阶段。我们以一个特定资源为例。从收到该资源的 Added
事件开始,kwok
会检查关联对象是否与某个阶段匹配。如果匹配到“更改阶段”,kwok
就会更新资源状态。更新操作本身会随后生成一个新的 Modified
资源,该资源稍后会被控制器捕获并触发下一轮检查和应用。kwok
会删除资源,直到匹配到“删除阶段”。
但是,这种基于事件的阶段应用方法有一个限制:kwok
不会应用阶段,直到收到与该资源关联的新事件。为了解决这一限制,用户可以使用 immediateNextStage
字段,让控制器立即应用阶段,而不是等待 API 服务器推送的事件。
延迟计算方式 #
应用阶段的延迟时间通过添加一个常量时间段和一个随机间隔来获得,以下分别用 duration 和 jitter 表示。
durationMilliseconds
:提供 duration。jitterDurationMilliseconds
:通过 random(jitterDurationMilliseconds
-duration) 计算 jitter。如果你想向延迟注入抖动,它应该大于durationMilliseconds
。否则,它将直接用作延迟时间,不会进行任何随机化。
kwok
还提供了其他字段,以灵活地处理更多的情况。它们用于提取和解析资源的 RFC3339 时间戳字段,以帮助动态确定延迟时间。
durationFrom
:通过durationFrom
-现在 计算持续时间jitterDurationFrom
:通过 随机(jitterDurationFrom
-现在-持续时间) 计算抖动,其中现在是延迟开始时的时间戳。
如果同时设置了durationFrom
和jitterDurationFrom
,则它们比durationMilliseconds
和jitterDurationMilliseconds
具有更高的优先级。
让我们稍微解释一下这两个高级字段背后的动机。但在那之前,为了更好地理解,我们简要描述一下 kubelet 如何从节点“删除”Pod。
以下是删除 Kubernetes 中 Pod 的步骤
- 执行命令
kubectl delete pod
。API 服务器收到删除请求,但不会立即从 etcd 中删除相应的 Pod 资源。 - API 服务器将
metadata.deletionTimestamp
字段设置为发出请求的时间加上metadata.deletionGracePeriodSeconds
(默认 30 秒)定义的短时间段。 - kubelet 检测到 Pod 的
metadata.deletionTimestamp
非空,并开始向容器的主进程发送TERM
信号。 - 如果
metadata.deletionTimestamp
在进程自行停止之前过期,则使用KILL
信号终止主进程。 - Pod 中的所有容器停止运行后,kubelet 向 API 服务器发送强制删除请求。
- API 服务器从 etcd 中删除 Pod 对象。
要模拟这种情况,可以将“删除阶段”(next.delete: true
)的 jitterDurationFrom
设置为指向 metadata.deletionTimestamp
。这将导致删除操作在 metadata.deletionTimestamp
过期之前随机时刻发生。您还可以通过将 durationFrom
指向 metadata.deletionTimple
,让 kwok
以确定性的方式执行删除,从而使删除操作在 metadata.deletionTimple
处准确发生。
示例 #
节点阶段 #
此示例展示如何配置节点资源的最简单、最快的阶段,这也是 kwok
的默认节点阶段。
Pod 阶段 #
此示例展示如何配置 Pod 资源的最简单、最快的阶段,这也是 kwok
的默认 Pod 阶段。