k8s 怎么精准获取deployment关联的pods?

标签获取

我们获取那些pods属于某个deployment时最先想到的可能是通过标签获取,其实这个是不准确的。因为标签并不是唯一的,也就是说不同deployment其实是能有相同标签的。

replicaSets获取

deployment 的产生pod流程如下: deployment->replicaSets->pod。
deployment 先产生replicaSets, replicaSets再产生pod。所以我们可以根据以下步骤获取到pod。

  1. 根据标签获取到replicaSets
  2. 根据replicaSets ownerReferences字段进行过滤。就可以得到属于某个deployment的replicaset。
  3. 根据标签获取到pods
  4. 根据pods ownerReferences字段进行过滤。就可以得到属于某个replicaset的pods。

注意一点这里有个比较坑的地方,就是deployment在滚动更新中会产生多个replicaset, 如果没有设置revisionHistoryLimit保留历史的replicaSet的话。那么当新的pod起来了,老的pod在终止时, 此时老的replicaSets会被删除,但是
老的pod又是被老的replicaSets控制的,这个时候去查询deployment 下面的pods就会将这些终止态的pod忽略掉,这在某些系统其实问题很大,就比如我现在做的发布系统,某个发布必须要等老的都终止掉了才能执行下一个业务,那么这个时候其实是有问题的。目前我能想到的解决办法是通过标签筛选出来的pod如果是终止态的话,也归属于这个deployment。大家如果有更好的方法请在下面留言。

代码

func (r *Usecase) podsListByDeploymentV2(deployment *appv1.Deployment) ([]v1.Pod, error) {

	replicaSetSelector, err := metav1.LabelSelectorAsSelector(deployment.Spec.Selector)
	if err != nil {
		return nil, xerrors.WithStack(err)
	}

	replicaSetListOptions := metav1.ListOptions{LabelSelector: replicaSetSelector.String()}
	allReplicaSets, err := r.k8sClient.AppsV1().ReplicaSets(deployment.Namespace).List(context.TODO(), replicaSetListOptions)
	if err != nil {
		return nil, xerrors.WithStack(err)
	}
	ownedReplicaSetsUids := make(map[types.UID]struct{})
	for i := range allReplicaSets.Items {
		if !metav1.IsControlledBy(&allReplicaSets.Items[i], deployment) {
			continue
		}
		ownedReplicaSetsUids[allReplicaSets.Items[i].UID] = struct{}{}
	}

	podSelector, err := metav1.LabelSelectorAsSelector(deployment.Spec.Selector)
	if err != nil {
		return nil, xerrors.WithStack(err)
	}
	podListOptions := metav1.ListOptions{LabelSelector: podSelector.String()}
	allPods, err := r.k8sClient.CoreV1().Pods(deployment.Namespace).List(context.TODO(), podListOptions)
	if err != nil {
		return nil, xerrors.WithStack(err)
	}

	//replicaSetUID := replicaSet.UID
	rsPods := make([]v1.Pod, 0)
	for i, pod := range allPods.Items {
		controllerRef := metav1.GetControllerOf(&allPods.Items[i])
		if controllerRef != nil {
			if _, ok := ownedReplicaSetsUids[controllerRef.UID]; ok {
				rsPods = append(rsPods, pod)
				continue
			}
		}
		podStatus := r.k8sRepo.GetPodStatus(&pod)
		if podStatus.Status == repo.TerminatingStatus { // 终止态的也可以认为属于这个deployment
			rsPods = append(rsPods, pod)
			continue
		}
	}

	return rsPods, nil

}

posted on   biwentao  阅读(416)  评论(2编辑  收藏  举报

相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示