You need to enable JavaScript to run this app. Kubernetes中如何区分新Pod部署与副本集、扩缩容等其他场景?
优惠活动
大模型
产品
解决方案
定价
更多

Kubernetes中如何区分新Pod部署与副本集、扩缩容等其他场景?

Mutation Webhook 区分新Deployment与其他Pod创建场景的实现方案

核心逻辑

你要处理的Pod创建请求本身不直接关联Deployment,需要通过所有者引用链溯源+ 自定义标记的方式做判断,完全可以通过client-go的corev1、apps v1包实现。

具体实现步骤

  • 第一步:校验Pod的所有者层级
    直接读取Pod结构体的pod.ObjectMeta.OwnerReferences字段:
    1. 先确认Pod的直接所有者是apps/v1版本的ReplicaSet,排除直接通过ReplicaSet、DaemonSet、Job等资源创建的Pod
    2. 再读取对应ReplicaSet的OwnerReferences,确认其上层所有者是apps/v1版本的Deployment,否则直接跳过处理逻辑
  • 第二步:判断是否为首次创建的新Deployment
    最稳妥的方案是给已经处理过的Deployment加自定义注解标记,避免重复处理:
    1. 读取溯源得到的Deployment对象,检查是否携带自定义注解(比如your-webhook.io/processed: "true")
    2. 如果无该注解,说明是首次触发的新Deployment,正常执行Pod补丁逻辑,完成后给当前Deployment写入上述自定义注解
    3. 如果已经有该注解,说明是已处理过的Deployment触发的扩缩容、滚动更新等场景,直接跳过补丁
  • 第三步:规避边界问题
    • Webhook对应的ServiceAccount需要提前配置Deployment的get、update权限
    • 给Deployment打标记时要加乐观锁重试逻辑,避免多个Pod并发请求时的更新冲突
    • 可以额外加判断条件做兜底:溯源得到的ReplicaSet的deployment.kubernetes.io/revision注解值为1,且Deployment的创建时间与ReplicaSet的创建时间差小于10秒,进一步降低误判概率

核心代码示例(基于client-go)

import (
    "context"
    "encoding/json"
    corev1 "k8s.io/api/core/v1"
    appsv1 "k8s.io/api/apps/v1"
    "sigs.k8s.io/controller-runtime/pkg/client"
    admissionv1 "k8s.io/api/admission/v1"
)

func handleMutation(ctx context.Context, req admissionv1.AdmissionRequest, k8sClient client.Client) admissionv1.AdmissionResponse {
    // 解析请求中的Pod对象
    pod := &corev1.Pod{}
    if err := json.Unmarshal(req.Object.Raw, pod); err != nil {
        return allowResponse()
    }

    // 溯源找所属ReplicaSet
    var rsName string
    for _, owner := range pod.OwnerReferences {
        if owner.APIVersion == "apps/v1" && owner.Kind == "ReplicaSet" {
            rsName = owner.Name
            break
        }
    }
    if rsName == "" {
        return allowResponse()
    }

    // 拿ReplicaSet对象溯源找Deployment
    rs := &appsv1.ReplicaSet{}
    if err := k8sClient.Get(ctx, client.ObjectKey{Name: rsName, Namespace: pod.Namespace}, rs); err != nil {
        return allowResponse()
    }

    var deployName string
    for _, owner := range rs.OwnerReferences {
        if owner.APIVersion == "apps/v1" && owner.Kind == "Deployment" {
            deployName = owner.Name
            break
        }
    }
    if deployName == "" {
        return allowResponse()
    }

    // 检查Deployment是否已经处理过
    deploy := &appsv1.Deployment{}
    if err := k8sClient.Get(ctx, client.ObjectKey{Name: deployName, Namespace: pod.Namespace}, deploy); err != nil {
        return allowResponse()
    }

    if deploy.Annotations != nil && deploy.Annotations["your-webhook.io/processed"] == "true" {
        return allowResponse()
    }

    // 执行你的Pod补丁逻辑
    patchBytes := generatePodPatch(pod)

    // 给Deployment打处理标记
    if deploy.Annotations == nil {
        deploy.Annotations = make(map[string]string)
    }
    deploy.Annotations["your-webhook.io/processed"] = "true"
    if err := k8sClient.Update(ctx, deploy); err != nil {
        // 按需添加重试逻辑,避免并发更新冲突
    }

    return patchResponse(patchBytes)
}

注:allowResponse、generatePodPatch、patchResponse为webhook框架自带或自定义的通用方法,可根据你使用的框架替换

内容的提问来源于stack exchange,提问作者Lior Kesten

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.16 14:15:07