[AI生成] 判断k8s deploy/statefulset是否已到达终态

package check_sts_deploy_status

import (
	"errors"
	"fmt"

	appsv1 "k8s.io/api/apps/v1"
)

// IsDeploymentReady 检查 Deployment 是否到达终态
// 终态条件:
// 1. ObservedGeneration 等于 Generation(控制器已看到最新的 spec)
// 2. UpdatedReplicas 等于 spec.Replicas(所有副本已更新)
// 3. ReadyReplicas 等于 spec.Replicas(所有副本已就绪)
// 4. AvailableReplicas 等于 spec.Replicas(所有副本可用)
// 5. Available condition 为 True
// 6. Progressing condition 为 True 且 Reason 为 NewReplicaSetAvailable
// 返回值:
// - bool: 是否到达终态
// - error: 错误信息,当资源未到达终态时返回具体原因
func IsDeploymentReady(deploy *appsv1.Deployment) (bool, error) {
	// 检查 Deployment 是否为 nil
	if deploy == nil {
		return false, errors.New("deployment is nil")
	}

	// 检查 ObservedGeneration 是否等于 Generation
	if deploy.Status.ObservedGeneration < deploy.Generation {
		return false, fmt.Errorf("observed generation %d < generation %d", deploy.Status.ObservedGeneration, deploy.Generation)
	}

	// 检查 spec.Replicas 是否为 nil
	if deploy.Spec.Replicas == nil {
		return false, errors.New("deployment spec.replicas is nil")
	}

	// 检查 UpdatedReplicas 是否等于 spec.Replicas
	if deploy.Status.UpdatedReplicas != *deploy.Spec.Replicas {
		return false, fmt.Errorf("updated replicas %d != spec.replicas %d", deploy.Status.UpdatedReplicas, *deploy.Spec.Replicas)
	}

	// 检查 ReadyReplicas 是否等于 spec.Replicas
	if deploy.Status.ReadyReplicas != *deploy.Spec.Replicas {
		return false, fmt.Errorf("ready replicas %d != spec.replicas %d", deploy.Status.ReadyReplicas, *deploy.Spec.Replicas)
	}

	// 检查 AvailableReplicas 是否等于 spec.Replicas
	if deploy.Status.AvailableReplicas != *deploy.Spec.Replicas {
		return false, fmt.Errorf("available replicas %d != spec.replicas %d", deploy.Status.AvailableReplicas, *deploy.Spec.Replicas)
	}

	// 检查 conditions
	for _, cond := range deploy.Status.Conditions {
		// 检查 Available condition 是否为 True
		if cond.Type == appsv1.DeploymentAvailable && cond.Status != "True" {
			return false, fmt.Errorf("deployment available condition is %s, not True", cond.Status)
		}
		// 检查 Progressing condition
		if cond.Type == appsv1.DeploymentProgressing {
			// 检查 Progressing condition 是否为 True
			if cond.Status != "True" {
				return false, fmt.Errorf("deployment progressing condition is %s, not True", cond.Status)
			}
			// 检查 Progressing reason 是否为 NewReplicaSetAvailable
			if cond.Reason != "NewReplicaSetAvailable" {
				return false, fmt.Errorf("deployment progressing reason is %s, not NewReplicaSetAvailable", cond.Reason)
			}
		}
	}

	// 所有条件都满足,到达终态
	return true, nil
}

// IsStatefulSetReady 检查 StatefulSet 是否到达终态
// 终态条件:
// 1. ObservedGeneration 等于 Generation(控制器已看到最新的 spec)
// 2. UpdatedReplicas 等于 spec.Replicas(所有副本已更新)
// 3. ReadyReplicas 等于 spec.Replicas(所有副本已就绪)
// 4. AvailableReplicas 等于 spec.Replicas(所有副本可用)
// 5. CurrentRevision 等于 UpdateRevision(版本一致)
// 返回值:
// - bool: 是否到达终态
// - error: 错误信息,当资源未到达终态时返回具体原因
func IsStatefulSetReady(sts *appsv1.StatefulSet) (bool, error) {
	// 检查 StatefulSet 是否为 nil
	if sts == nil {
		return false, errors.New("statefulset is nil")
	}

	// 检查 ObservedGeneration 是否等于 Generation
	if sts.Status.ObservedGeneration < sts.Generation {
		return false, fmt.Errorf("observed generation %d < generation %d", sts.Status.ObservedGeneration, sts.Generation)
	}

	// 检查 spec.Replicas 是否为 nil
	if sts.Spec.Replicas == nil {
		return false, errors.New("statefulset spec.replicas is nil")
	}

	// 检查 UpdatedReplicas 是否等于 spec.Replicas
	if sts.Status.UpdatedReplicas != *sts.Spec.Replicas {
		return false, fmt.Errorf("updated replicas %d != spec.replicas %d", sts.Status.UpdatedReplicas, *sts.Spec.Replicas)
	}

	// 检查 ReadyReplicas 是否等于 spec.Replicas
	if sts.Status.ReadyReplicas != *sts.Spec.Replicas {
		return false, fmt.Errorf("ready replicas %d != spec.replicas %d", sts.Status.ReadyReplicas, *sts.Spec.Replicas)
	}

	// 检查 AvailableReplicas 是否等于 spec.Replicas
	if sts.Status.AvailableReplicas != *sts.Spec.Replicas {
		return false, fmt.Errorf("available replicas %d != spec.replicas %d", sts.Status.AvailableReplicas, *sts.Spec.Replicas)
	}

	// 检查 CurrentRevision 是否等于 UpdateRevision
	if sts.Status.CurrentRevision != sts.Status.UpdateRevision {
		return false, fmt.Errorf("current revision %s != update revision %s", sts.Status.CurrentRevision, sts.Status.UpdateRevision)
	}

	// 所有条件都满足,到达终态
	return true, nil
}

 

posted on 2026-04-05 11:44  王景迁  阅读(7)  评论(0)    收藏  举报

导航