• 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
    
    }
    
    
  • 相关阅读:
    跌倒检测中的跌倒判断
    什么是深克隆,浅克隆?(案例详解)
    如何在 Keras 中开发具有注意力的编码器-解码器模型
    Cache与内存映射
    【时间序列分析】A Transformer-based Framework for Multivariate Time Series Representation Learning论文笔记
    单调栈及其应用
    mvvm框架下对wpf的DataGrid多选,右键操作
    icmp报文及用go实现
    【论文笔记】4D Millimeter-Wave Radar in Autonomous Driving: A Survey
    将多个文件压缩成zip文件
  • 原文地址:https://www.cnblogs.com/biwentao/p/18215405