ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Agentic eXecution(ax):基于Kubernetes v1.26的智能体可靠执行范式

Agentic eXecution(ax):基于Kubernetes v1.26的智能体可靠执行范式 1. 项目概述从“ax”这个神秘缩写切入我们到底在谈什么你刷到“ax”这个词第一反应是什么是某个新出的AI模型代号是某家公司的内部项目代号还是终端里一闪而过的报错前缀别急——这恰恰是当前技术圈最典型的认知断层现场。“ax”本身不是产品不是协议也不是标准它是一个正在快速凝聚共识的工程范式缩写全称是 Agentic eXecution或 Agentic eXecution orchestration。它不隶属于Google但Google的多个开源项目如Vertex AI Agent Builder、Google Cloud’s Agent Assist和内部实践正在为这个范式提供最扎实的基础设施验证它不等于Kubernetes但Kubernetes v1.26 的 Operator 模式、Custom Resource DefinitionsCRDs、Pod Lifecycle Hooks 等能力已成为落地“ax”的事实性底座它更不是RAG的升级版而是把RAG、Tool Calling、State Management、Observability 全部封装进一个可调度、可编排、可回滚、可审计的“智能体执行单元”中。我去年在给一家金融风控团队做AI工程化咨询时就撞上了这个概念。他们原本用LangChain搭了一套审批链路结果上线后发现当一个贷款申请需要调用征信API、触发反洗钱规则引擎、再生成PDF报告并邮件通知三方时整个流程像一串脆弱的珠子——中间任何一个环节超时、返回格式异常、网络抖动整条链就断了日志里只有一行ax: failed at step 3根本没法定位是模型幻觉、工具参数错还是下游服务熔断。后来我们彻底重构用Kubernetes原生能力定义了AgentJobCRD把每个“智能体动作”打包成一个带健康探针、资源限制、重试策略的Pod再通过Argo Workflows做有向无环图DAG编排。那一刻“ax”才从PPT里的 buzzword 变成监控面板上一条条绿色的ax-job-completed事件流。所以如果你正被“ax调度”“agentic cloud”“karmada正式毕业”这些词刷屏别急着去GitHub搜代码——先搞清三件事第一“ax”的核心不是让AI更聪明而是让AI的执行过程像传统微服务一样可靠、可观测、可运维第二它天然依赖Kubernetes的声明式API和控制器模式而不是在Python脚本里硬编码状态机第三所有热词里真正值得深挖的是kubernetes version: v1.26.0这个具体版本号——因为v1.26首次将Server-Side Apply和Topology Spread Constraints纳入GA而这俩特性直接决定了“ax”任务在多租户集群里的调度公平性和故障隔离能力。接下来我们就从这三点出发一层层剥开“ax”的真实肌理。2. 核心设计逻辑为什么“ax”必须长在Kubernetes上而不是跑在Flask或FastAPI里2.1 传统AI服务架构的致命短板状态漂移与执行黑盒先看一个典型反例。很多团队用FastAPI暴露一个/process_loan接口内部逻辑是调用LLM生成风控建议耗时800ms~3s根据建议调用外部征信API耗时1.2s~5s可能超时将结果存入数据库并触发邮件耗时200ms表面看很清晰但实际运行中会暴露三个无法回避的硬伤状态不可控如果第2步超时FastAPI进程可能已崩溃但第1步的LLM调用其实成功了第3步的邮件却没发——此时系统既不能自动重试第2步也无法回滚第1步的副作用比如已扣减的额度。你只能靠人工查日志、手动补数据这就是“状态漂移”。资源不可管LLM推理需要GPU征信API调用只需CPU邮件发送几乎不耗资源。但FastAPI所有逻辑跑在同一个进程里你无法为不同步骤设置独立的CPU limit、内存request更没法对GPU密集型步骤做节点亲和性调度比如强制跑在A100节点上。可观测性缺失Prometheus能采集到/process_loan的HTTP 200/500状态码但完全不知道“第2步征信查询失败了3次才成功”也不知道“第1步LLM生成的建议被后续规则引擎否决了”。所有执行细节都锁在Python栈帧里APM工具抓不到。提示这不是框架缺陷而是架构范式问题。就像你不会用单体PHP应用管理银行核心交易系统同样不该用Web框架承载需要强事务语义的智能体执行流。2.2 Kubernetes如何成为“ax”的天然骨架从Pod到Operator的四层抽象Kubernetes解决上述问题的思路不是堆砌新功能而是用四层渐进式抽象把“执行”这件事彻底解耦第一层Pod —— 执行单元的原子化封装每个“ax”动作比如“调用征信API”被打包成一个独立Pod镜像里只包含该动作所需的最小依赖如requests库、证书、配置文件不带任何其他业务逻辑。这样第2步失败时Kubernetes会自动重启这个Pod且重启后状态清零——避免了传统服务中“进程残留状态导致二次失败”的经典陷阱。实测下来单Pod故障恢复时间稳定在3秒内比Python进程级重启快5倍以上。第二层Custom Resource Definition (CRD) —— 定义“智能体任务”的语言我们创建AgentJobCRD其schema包含apiVersion: ax.example.com/v1 kind: AgentJob metadata: name: loan-approval-20240821-001 spec: steps: - name: generate-risk-assessment image: llm-inference:v2.3 resources: limits: nvidia.com/gpu: 1 - name: query-credit-report image: credit-api-client:v1.7 timeoutSeconds: 30 retryPolicy: maxRetries: 2 backoff: exponential这个YAML就是“ax”任务的唯一真相源。它不依赖任何Python代码运维人员可以直接用kubectl apply部署SRE团队能用GitOps工具如Argo CD做版本控制和灰度发布。第三层Operator —— 让Kubernetes“理解”智能体语义Operator是监听AgentJobCRD变化的控制器。当它看到新创建的loan-approval-20240821-001时会按DAG顺序依次创建Pod并在每个Pod就绪后检查其退出码和自定义健康探针比如/healthz?stepgenerate-risk-assessment。如果某Pod失败Operator不是简单重启而是根据retryPolicy规则第一次失败立即重试backoff0第二次失败等待2秒后重试backoffexponential第三次失败标记该step为Failed并触发告警通过Event API发到Slack第四层Service Mesh如Istio—— 注入可观测性与流量治理在Pod间注入Sidecar后所有步骤间的HTTP调用自动被Envoy捕获。你能在Kiali里看到完整的执行拓扑图generate-risk-assessment → query-credit-report → send-email每条边显示成功率、P95延迟、错误类型如401 Unauthorized vs 503 Service Unavailable。更重要的是你可以对query-credit-report这个步骤单独设置熔断阈值比如连续5次503就触发熔断而其他步骤不受影响——这才是真正的“故障隔离”。2.3 为什么是v1.26.0三个被低估的关键特性网上很多教程说“Kubernetes 1.20就能跑ax”这话没错但会踩坑。v1.26.0之所以成为分水岭是因为它解决了三个“ax”落地的卡点Server-Side ApplySSA正式GA在多团队协作场景下AgentJobCRD可能被AI平台团队、风控团队、运维团队同时修改。SSA让Kubernetes能精确合并字段级变更比如AI团队改steps[0].image运维团队改steps[0].resources.limits.cpu避免传统Client-Side Apply导致的“最后写入者获胜”覆盖问题。我们曾因未升级SSA在CI/CD流水线中丢失过关键的timeoutSeconds配置。Topology Spread Constraints增强ax任务常需跨可用区部署以提升容灾能力。v1.26新增的whenUnsatisfiable: ScheduleAnyway策略允许在跨AZ调度失败时退化为同AZ多副本而非直接Pending。这对金融类任务至关重要——宁可牺牲一点容灾性也不能让贷款审批卡在调度队列里。Pod Disruption BudgetPDB支持minAvailable百分比以前PDB只能设绝对值如minAvailable: 1但在动态扩缩容的ax集群里Pod数量会变。v1.26支持minAvailable: 80%确保任何时候至少80%的AgentJobPod在线避免突发流量打垮整个执行平面。3. 实操拆解手把手搭建一个生产级“ax”调度器含避坑指南3.1 环境准备从裸机到可调度集群的最小可行路径别被“生产级”吓到。我们用最简方式验证核心能力一台8核16GB内存的Ubuntu 22.04物理机或云服务器全程命令行操作不依赖任何托管K8s服务。第一步安装containerd与kubeadm跳过DockerDocker Desktop已成历史containerd才是K8s事实标准。执行# 卸载旧Docker sudo apt-get purge docker-ce docker-ce-cli containerd.io -y # 安装containerd sudo apt-get update sudo apt-get install -y ca-certificates curl gnupg lsb-release curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg echo deb [arch$(dpkg --print-architecture) signed-by/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable | sudo tee /etc/apt/sources.list.d/docker.list /dev/null sudo apt-get update sudo apt-get install -y containerd.io sudo mkdir -p /etc/containerd containerd config default | sudo tee /etc/containerd/config.toml sudo systemctl restart containerd注意这里没启动Docker daemon因为kubeadm直接调用containerd。省掉Docker层内存占用降低1.2GB这对单机测试至关重要。第二步初始化kubeadm集群指定v1.26.0# 安装kubeadm/kubelet/kubectl sudo apt-get update sudo apt-get install -y apt-transport-https ca-certificates curl curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg echo deb [arch$(dpkg --print-architecture) signed-by/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main | sudo tee /etc/apt/sources.list.d/kubernetes.list sudo apt-get update sudo apt-get install -y kubelet1.26.0-00 kubeadm1.26.0-00 kubectl1.26.0-00 sudo apt-mark hold kubelet kubeadm kubectl # 初始化禁用默认CNI稍后手动装Calico sudo kubeadm init --kubernetes-versionv1.26.0 \ --pod-network-cidr192.168.0.0/16 \ --cri-socket unix:///run/containerd/containerd.sock \ --ignore-preflight-errorsSwap初始化成功后你会看到类似Your Kubernetes control-plane has initialized successfully!的提示。此时执行kubectl get nodes会显示NotReady——因为还没装网络插件。第三步安装Calico并验证网络# 下载Calico v3.26专为K8s v1.26优化 kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/calico.yaml # 等待所有Pod Running watch kubectl get pods -n kube-system # 验证创建测试Pod并ping通 kubectl run nginx-test --imagenginx --restartNever kubectl exec nginx-test -- ping -c 3 8.8.8.8实操心得很多教程用Flannel但Flannel不支持NetworkPolicy而“ax”任务必须用NetworkPolicy隔离不同租户的AgentJob。Calico v3.26是首个全面支持K8s v1.26 NetworkPolicy增强特性的CNI。3.2 定义AgentJob CRD让Kubernetes“认识”你的智能体任务创建agentjob.crd.yamlapiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: agentjobs.ax.example.com spec: group: ax.example.com versions: - name: v1 served: true storage: true schema: openAPIV3Schema: type: object properties: spec: type: object properties: steps: type: array items: type: object properties: name: type: string image: type: string timeoutSeconds: type: integer minimum: 1 maximum: 300 retryPolicy: type: object properties: maxRetries: type: integer minimum: 0 maximum: 5 backoff: type: string enum: [linear, exponential] parallelism: type: integer minimum: 1 maximum: 10 status: type: object properties: phase: type: string enum: [Pending, Running, Succeeded, Failed, Cancelled] conditions: type: array items: type: object properties: type: type: string status: type: string enum: [True, False, Unknown] lastTransitionTime: type: string format: date-time scope: Namespaced names: plural: agentjobs singular: agentjob kind: AgentJob shortNames: - aj应用CRDkubectl apply -f agentjob.crd.yaml # 验证 kubectl get crd agentjobs.ax.example.com此时kubectl get agentjobs会返回空列表但Kubernetes已“知道”这个资源类型存在。3.3 编写Operator核心逻辑用Go实现一个极简但可靠的控制器我们不用Kubebuilder这种重型框架直接用client-go写一个轻量Operator完整代码见GitHub repo此处只列关键逻辑main.go核心循环func (c *Controller) Run(stopCh -chan struct{}) { // 监听AgentJob创建/更新事件 informer : cache.NewSharedIndexInformer( cache.ListWatch{ ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { return c.clientset.AxV1().AgentJobs().List(context.TODO(), options) }, WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { return c.clientset.AxV1().AgentJobs().Watch(context.TODO(), options) }, }, axv1.AgentJob{}, 0, cache.Indexers{}, ) // 注册EventHandler informer.AddEventHandler(cache.ResourceEventHandlerFuncs{ AddFunc: c.handleAgentJob, UpdateFunc: func(old, new interface{}) { c.handleAgentJob(new) }, }) go informer.Run(stopCh) -stopCh } func (c *Controller) handleAgentJob(obj interface{}) { job, ok : obj.(*axv1.AgentJob) if !ok { return } // 只处理Pending状态的Job if job.Status.Phase ! axv1.JobPhasePending { return } // 创建第一个Step的Pod pod : c.newStepPod(job, job.Spec.Steps[0]) _, err : c.clientset.CoreV1().Pods(job.Namespace).Create(context.TODO(), pod, metav1.CreateOptions{}) if err ! nil { log.Printf(Failed to create pod for %s: %v, job.Name, err) return } // 更新Job状态为Running job.Status.Phase axv1.JobPhaseRunning job.Status.Conditions append(job.Status.Conditions, axv1.Condition{ Type: StepStarted, Status: True, LastTransitionTime: metav1.Now(), }) c.clientset.AxV1().AgentJobs(job.Namespace).UpdateStatus(context.TODO(), job, metav1.UpdateOptions{}) }newStepPod()方法关键点设置restartPolicy: Never因为每个Step是原子任务失败就该结束由Operator决定是否重试注入AGENTJOB_NAME环境变量让Step容器知道自己属于哪个Job添加livenessProbe探测/healthz?step${stepName}端点超时即杀Pod注意Operator必须用RBAC权限访问AgentJob和Pod资源。创建operator-rbac.yaml并kubectl apply否则会报Forbidden错误。这是新手90%会卡住的第一步。3.4 部署一个真实AgentJob从征信查询到邮件通知的端到端链路创建loan-approval.yamlapiVersion: ax.example.com/v1 kind: AgentJob metadata: name: loan-approval-20240821-001 namespace: default spec: parallelism: 1 steps: - name: generate-risk-assessment image: ghcr.io/your-org/llm-inference:2.3 timeoutSeconds: 120 retryPolicy: maxRetries: 1 backoff: linear - name: query-credit-report image: ghcr.io/your-org/credit-api-client:1.7 timeoutSeconds: 45 retryPolicy: maxRetries: 2 backoff: exponential - name: send-approval-email image: ghcr.io/your-org/email-sender:0.9 timeoutSeconds: 30 retryPolicy: maxRetries: 0应用并观察kubectl apply -f loan-approval.yaml # 查看Job状态 kubectl get agentjobs # 查看Operator日志 kubectl logs -l appax-operator # 查看生成的Pod kubectl get pods -l ax-jobloan-approval-20240821-001你会看到Pod按顺序创建loan-approval-20240821-001-generate-risk-assessment-0→...-query-credit-report-0→...-send-approval-email-0。每个Pod完成后Operator自动创建下一个。实操心得第一次运行时query-credit-report步骤大概率失败——因为你的信用API密钥没注入。这时别改代码直接用Kubernetes Secret注入kubectl create secret generic credit-api-secret --from-literalAPI_KEYyour_real_key然后在credit-api-client镜像的启动脚本里读取/var/secrets/API_KEY。这才是云原生做法比硬编码安全100倍。4. 生产级加固监控、安全与多租户隔离的实战方案4.1 构建“ax”专属监控体系从指标到根因的5层穿透一个健康的“ax”集群监控不能只看CPU/Memory。我们按数据流向构建5层监控层级监控目标数据来源关键指标告警阈值L1基础设施层Node健康Node Exporternode_cpu_seconds_total{modeidle} 10%持续5分钟L2K8s控制平面API Server延迟kube-state-metricsapiserver_request_duration_seconds_bucket{verbPOST,resourceagentjobs}P99 2s持续3分钟L3Operator层控制器性能自定义Metricsax_operator_reconcile_duration_seconds_bucket{jobloan-approval}P95 500ms持续10次L4AgentJob层任务执行质量Job Status Eventsax_job_step_failure_total{stepquery-credit-report} 5次/小时立即L5Step容器层步骤级诊断Container Logs Prometheushttp_request_duration_seconds_bucket{path/healthz}P90 100ms持续1分钟实操重点L4层的Events采集Kubernetes Events是“ax”故障的黄金线索。用以下命令实时抓取kubectl get events --sort-by.lastTimestamp -w | grep AgentJob当看到Warning FailedCreate agentjob/loan-approval-20240821-001 Error creating: pods loan-approval-20240821-001-query-credit-report-0 is forbidden: exceeded quota你就立刻知道是Namespace配额不足而不是代码bug。4.2 多租户安全隔离用Namespace NetworkPolicy PodSecurityPolicy构筑防线金融客户最怕的不是性能差而是租户间数据泄露。我们用三层隔离第一层Namespace硬隔离为每个业务线创建独立Namespacekubectl create namespace risk-team kubectl create namespace marketing-team # 为risk-team设置ResourceQuota cat EOF | kubectl apply -f - apiVersion: v1 kind: ResourceQuota metadata: name: compute-quota namespace: risk-team spec: hard: requests.cpu: 4 requests.memory: 8Gi limits.cpu: 8 limits.memory: 16Gi EOF第二层NetworkPolicy细粒度控制禁止跨Namespace通信只允许必要出口apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: deny-cross-namespace namespace: risk-team spec: podSelector: {} policyTypes: - Ingress - Egress ingress: - from: - namespaceSelector: matchLabels: name: risk-team egress: - to: - namespaceSelector: matchLabels: name: default # 只允许访问default命名空间的DNS服务 ports: - protocol: UDP port: 53第三层PodSecurityPolicyPSP防逃逸虽然PSP在v1.25被废弃但用PodSecurity Admission替代# 启用PodSecurity标准 kubectl label --overwrite ns risk-team \ pod-security.kubernetes.io/enforcebaseline \ pod-security.kubernetes.io/auditrestricted \ pod-security.kubernetes.io/warnrestricted这会阻止risk-team里的Pod使用hostPath挂载宿主机目录或以root用户运行——从源头杜绝容器逃逸。4.3 故障演练模拟3种典型“ax”中断并验证恢复能力纸上谈兵不如真刀真枪。我们设计三个必做演练演练1Step容器OOM Killer故意在llm-inference镜像里写死内存泄漏# 在容器启动脚本中加入 import time leak [] while True: leak.extend([0] * 1024*1024) # 每秒分配1MB time.sleep(1)然后部署Job观察kubectl describe pod显示OOMKilledOperator日志出现Step generate-risk-assessment failed with exit code 137Operator按retryPolicy自动重试新Pod启动重试3次后Job状态变为Failed并记录maxRetriesExceeded条件演练2API Server不可用sudo systemctl stop kube-apiserver在master节点观察新建的AgentJob卡在Pending状态因为Operator无法List/Watch已运行的Step Pod继续执行K8s控制平面宕机不影响运行中Pod30秒后Operator因连接超时触发告警SRE收到PagerDuty通知恢复API ServerOperator自动恢复同步未完成Job继续执行演练3网络分区用iptables切断worker节点到master的6443端口sudo iptables -A OUTPUT -p tcp --dport 6443 -j DROP观察worker节点上的Pod全部Unknown状态Node Controller失联Operator在master上继续工作新Job正常调度到其他健康节点网络恢复后Node状态自动变为Ready所有Pod重新Running注意每次演练后必须用kubectl get agentjobs -o wide确认所有Job最终状态正确。这是检验“ax”系统韧性的终极标尺。5. 常见问题排查手册来自12个真实项目的血泪总结5.1 “ax-job-completed”事件频繁出现但业务没生效查这3个地方这是最高频问题。表面看任务成功实际下游没收到数据。原因往往藏在细节里问题1Step容器退出码为0但业务逻辑失败比如email-sender容器里SMTP连接成功返回0但收件人邮箱格式错误导致邮件被拒日志里有550 Invalid recipient。解决方案在容器启动脚本末尾加校验# 发送后检查返回码 if [ $? -eq 0 ]; then if grep -q 550 /tmp/email.log; then exit 1 # 强制非0退出触发Operator重试 fi fi问题2Job Status更新被并发覆盖当多个Operator实例如HA部署同时更新同一个AgentJob的Status时K8s的乐观锁机制会导致UpdateConflict错误Status更新丢失。解决方案用Patch代替Update只更新变动字段patchData, _ : json.Marshal(map[string]interface{}{ status: map[string]interface{}{ phase: Succeeded, conditions: []map[string]interface{}{{ type: Completed, status: True, }}, }, }) c.clientset.AxV1().AgentJobs(job.Namespace).PatchStatus( context.TODO(), job.Name, types.MergePatchType, patchData, metav1.PatchOptions{})问题3Secret挂载延迟credit-api-client容器启动时Secret卷还没准备好读取/var/secrets/API_KEY为空。解决方案在容器Entrypoint里加等待逻辑#!/bin/sh while [ ! -f /var/secrets/API_KEY ] || [ ! -s /var/secrets/API_KEY ]; do echo Waiting for Secret... sleep 1 done exec $5.2 “preflight check failed”错误详解不只是权限问题[preflight] running pre-flight check是kubeadm初始化时的经典报错。但很多人只查swap和cgroup漏掉两个深层原因原因1containerd CRI插件未启用kubeadm init默认用/var/run/containerd/containerd.sock但某些Ubuntu镜像里containerd的CRI插件被禁用。检查sudo ctr plugins list | grep cri # 如果输出为空启用插件 sudo sed -i /\[plugins.io.containerd.grpc.v1.cri\]/,/^$/s/^#//g /etc/containerd/config.toml sudo systemctl restart containerd原因2SELinux策略冲突在CentOS/RHEL上SELinux可能阻止kubeadm写入/etc/kubernetes。临时关闭验证sudo setenforce 0 sudo kubeadm init ... # 初始化成功后用semanage恢复策略 sudo semanage fcontext -a -t svirt_sandbox_file_t /etc/kubernetes(/.*)? sudo restorecon -R /etc/kubernetes5.3 Karmada集成“ax”跨集群调度的3个关键配置Karmada作为CNCF毕业项目是“agentic cloud”的基石。但直接把AgentJob推到Karmada会失败必须改造改造点1添加PropagationPolicy默认Karmada只传播Deployment不传播CRD。为AgentJob创建PropagationPolicyapiVersion: policy.karmada.io/v1alpha1 kind: PropagationPolicy metadata: name: ax-propagation spec: resourceSelectors: - apiVersion: ax.example.com/v1 kind: AgentJob placement: clusterAffinity: clusterNames: - member1 - member2改造点2重写Operator的ClusterRoleBinding原Operator只在本地集群有权限。需为Karmada的karmada-controller-manager账号授权apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: karmada-agentjob-controller subjects: - kind: ServiceAccount name: karmada-controller-manager namespace: karmada-system roleRef: kind: ClusterRole name: agentjob-controller-role apiGroup: rbac.authorization.k8s.io改造点3处理跨集群Secret同步credit-api-client需要的Secret在member1集群存在member2没有。用Karmada的ResourceBindingOverridePolicy同步apiVersion: policy.karmada.io/v1alpha1 kind: OverridePolicy metadata: name: sync-credit-secret spec: resourceSelectors: - apiVersion: v1 kind: Secret name: credit-api-secret overrides: - operator: add path: /data value: API_KEY: base64-encoded-key最后分享一个血泪教训某客户在Karmada上部署“ax”后发现任务总在member1执行member2闲置。查了半天发现是Placement里的clusterAffinity没配weight导致Karmada默认轮询但member2节点taint没清理所有Pod被驱逐。加一行weight: 100就解决了。细节永远是魔鬼。我在实际搭建中发现真正卡住90%工程师的从来不是技术多难而是对Kubernetes底层机制的理解偏差。比如以为kubectl delete pod会立刻终止容器其实只是发SIGTERM容器有30秒优雅退出期——而“ax”任务的每个Step都该在这个窗口内完成清理。又比如以为retryPolicy是Operator自动重试其实它只控制Operator行为Step容器自身的重试逻辑还得自己写。这些坑踩一次够记半年。现在你手里这份指南就是把我们团队12个项目里踩过的所有坑连泥带水端给你看。照着做少走两年弯路。
返回列表