LabHub
学习 学习路径 课程

CRD 与 Operator

用 shell 做一个调谐循环

在 LabHub 中继续学习

目标

用Shell脚本直接实现读取CR的明细,调整下游资源,将结果写回status的调整循环,并用对象版本证明第二次运行什么都没有改变。

为什么重要

在这个练习中制作的不是控制器二进制文件,而是 重新初始化函数的本质。 在实际的控制器中,重新初始化传递给的不是对象,而是键,也不会告知发生了什么变化。 因此,重新初始化总是从“现在想要的状态是什么,实际是什么”中重新开始。 这个设计所强制的就是 等效性。 在已经正确的情况下重新编写时,会产生新的 watch 事件,该事件会再次调用重新初始化,无限次触发自己。 因此,等效性的真正判断标准不是“没有发生错误”,而是 “子对象的 resourceVersion 保持不变”。 另一个重要的区分是错误和重启。 依赖对象尚未准备就绪的情况不是失败,因此不能返回错误。 错误会累积指数重置并污染日志,使该对象的重试间隔变长,真正出现问题时响应会变慢。 最后,最终化器是打破“删除 = 即刻消失”直觉的装置。 删除请求只是记录删除时间,而重新初始化调用的那一刻是清理外部资源的最后机会。

阶段

开始前准备:练习板每次练习都会重新生成,所以前一次练习的群集状态不会保留。kubectl get crd webservices.apps.labhub.io如果空着的话,请重新填写CRD后再应用。kubectl create ns crd-lab也做吧。在这个实习中subresources.statusproperties.status下面replicas·observedGeneration·conditions必须要有正义,spec里面有image(required),replicas(default 1),tier需要(default dev)。

  1. 首先crd-lab在WebServicecheckout请制作spec.image: nginx:1.27spec.replicas: 3spec.tier: dev). 然后/root/op/reconcile/reconcile.sh制作并chmod +x请做。这个脚本是kubectl getCR的spec(desired)和子ConfigMapcheckout-desired读(actual)/root/op/reconcile/out/observe.json{"desired": {...}, "actual": {...}}必须以形状保存,desired.image是CR的spec.image和必须完全相同。
  2. 第一次执行的判断/root/op/reconcile/out/decision-1.json请保存到。actioncreatereason写下为什么做出那样判断的字符串,target是关于什么的判断(例如:configmap/checkout-desired)包含。
  3. 请让脚本按照判断执行。crd-labConfigMapcheckout-desired制作data.image是CR的spec.image应该有价值,metadata.ownerReferences[0].uidcheckout的实际uid,metadata.labelsapp.kubernetes.io/managed-by: webservice-controller必须去。
  4. kubectl get cm checkout-desired -n crd-lab -o jsonpath='{.metadata.resourceVersion}'价格/root/op/reconcile/out/rv-before.txt保存到,再执行一次脚本后,将相同的值/root/op/reconcile/out/rv-after.txt请保存到。两个值必须相同,第二个判断是/root/op/reconcile/out/decision-2.jsonaction这个noop必须进入。
  5. 请让脚本重写status。checkoutstatus.conditionstype: Readystatus: "True"输入条件,status.observedGenerationmetadata.generation和一样,status.replicasspec.replicas请制作成像这样。脚本中包含--subresource=status字符串必须实际包含。
  6. /root/op/reconcile/out/requeue.json请制作。actionrequeueafter_seconds是大于0的整数,is_errorfalse是。还有/root/op/reconcile/out/backoff-note.txt请分别用一个句子以上写出两点——为什么需要指数级地增加重试间隔的backoff,以及如果全部将“还没有准备好”处理为错误的话,错误日志会暴走,导致一个对象被排队饿死的问题。
  7. crd-lab在WebServiceephemeral制作并metadata.finalizerswebservice.labhub.io/cleanup请放入。以3号相同的方式子ConfigMapephemeral-desired也制作。然后kubectl delete webservice ephemeral -n crd-lab --wait=false请求删除,紧接着的整个对象/root/op/reconcile/out/terminating.json请保存到(此文件中包含metadata.deletionTimestampmetadata.finalizers都必须显示出来)。然后子ConfigMapephemeral-desired删除了什么,整理了什么/root/op/reconcile/out/cleanup.txt写在后面的话,请移除最终处理器。ephemeral请让它实际消失。
  8. crd-lab在WebServicebillingsearch另外创建(分别拥有image和replicas),作为reconcilercheckout·billing·search三个都绕了一圈后/root/op/reconcile/out/reconcile-report.json请制作。items是各元素nameaction(create/update/noop/requeue拥有其中一个)的数组,summary.noop没有做任何事情的次数,convergedtrue包含。三个CR都status.observedGeneration这个metadata.generation应该和一样。

参考

读取想要的状态和实际状态

首先crd-lab在WebServicecheckout请制作spec.image: nginx:1.27spec.replicas: 3spec.tier: dev). 然后/root/op/reconcile/reconcile.sh制作并chmod +x请做。这个脚本是kubectl getCR的spec(desired)和子ConfigMapcheckout-desired读(actual)/root/op/reconcile/out/observe.json{"desired": {...}, "actual": {...}}必须以形状保存,desired.image是CR的spec.image和必须完全相同。

Recon Sale的第一步不是判断,而是阅读。CR的spec是desired,子对象是actual。如果没有子对象,actual是空的也是正常的,脚本需要执行权限。

通过比较做出调整判断

第一次执行的判断/root/op/reconcile/out/decision-1.json请保存到。actioncreatereason写下为什么做出那样判断的字符串,target是关于什么的判断(例如:configmap/checkout-desired)包含。

判断不能只以action结束。要留下为什么做出这样的判断以及是对什么做出判断,这样以后才能只看日志进行追踪。

根据判断制作子资源

请让脚本按照判断执行。crd-labConfigMapcheckout-desired制作data.image是CR的spec.image应该有价值,metadata.ownerReferences[0].uidcheckout的实际uid,metadata.labelsapp.kubernetes.io/managed-by: webservice-controller必须去。

不要用手抄写价格,请在CR中输入。需要与父母的联系和表示是我制作的标记标签。

防止第二次运行不改变任何东西

kubectl get cm checkout-desired -n crd-lab -o jsonpath='{.metadata.resourceVersion}'价格/root/op/reconcile/out/rv-before.txt保存到,再执行一次脚本后,将相同的值/root/op/reconcile/out/rv-after.txt请保存到。两个值必须相同,第二个判断是/root/op/reconcile/out/decision-2.jsonaction这个noop必须进入。

差异性的证据不是日志,而是对象的版本。在第二次运行前后分别记录下子对象的resourceVersion,然后比较一下。内容相同的话,服务器不会重新写入。

将调整结果重新写入status

请让脚本重写status。checkoutstatus.conditionstype: Readystatus: "True"输入条件,status.observedGenerationmetadata.generation和一样,status.replicasspec.replicas请制作成像这样。脚本中包含--subresource=status字符串必须实际包含。

status以与spec不同的路径写入。指定该路径的字符串必须实际存在于脚本中。请同时匹配处理的世代编号和观测的副本。

整理杰奎的判断和白开水

/root/op/reconcile/out/requeue.json请制作。actionrequeueafter_seconds是大于0的整数,is_errorfalse是。还有/root/op/reconcile/out/backoff-note.txt请分别用一个句子以上写出两点——为什么需要指数级地增加重试间隔的backoff,以及如果全部将“还没有准备好”处理为错误的话,错误日志会暴走,导致一个对象被排队饿死的问题。

还没有依赖对象并不意味着失败。请按秒记录下何时再次查看,并明确说明这不是错误。备忘录中必须分别写下重新尝试间隔增加的原因和全部被处理为错误时出现的问题。

用最终整理器整理后删除

crd-lab在WebServiceephemeral制作并metadata.finalizerswebservice.labhub.io/cleanup请放入。以3号相同的方式子ConfigMapephemeral-desired也制作。然后kubectl delete webservice ephemeral -n crd-lab --wait=false请求删除,紧接着的整个对象/root/op/reconcile/out/terminating.json请保存到(此文件中包含metadata.deletionTimestampmetadata.finalizers都必须显示出来)。然后子ConfigMapephemeral-desired删除了什么,整理了什么/root/op/reconcile/out/cleanup.txt写在后面的话,请移除最终处理器。ephemeral请让它实际消失。

删除请求不是立即删除。首先保存拍下删除时间点的瞬间,整理完毕后才能移除最终化程序,对象才会消失。有不等待的删除选项。

做了一圈多个CR,然后制作报告

crd-lab在WebServicebillingsearch另外创建(分别拥有image和replicas),作为reconcilercheckout·billing·search三个都绕了一圈后/root/op/reconcile/out/reconcile-report.json请制作。items是各元素nameaction(create/update/noop/requeue拥有其中一个)的数组,summary.noop没有做任何事情的次数,convergedtrue包含。三个CR都status.observedGeneration这个metadata.generation应该和一样。

Recon Slayer不是特定CR专用的。一边照顾多个对象一边收集各自的判断,用一行总结是否都达到了想要的状态。所有对象的世代编号必须正确才能收敛。