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

k8s,deployment,pods · 浏览次数 : 0

小编点评

## Summary of the content This document describes the logic used to get pods belonging to a specific deployment using labels. **Key points:** * Tags are not the only way to identify pods belonging to a deployment. * `replicaSets` are generated before `pods` and are used to determine the pods for a deployment. * When a pod is terminated, it is not automatically removed from the `pods` list. * A pod is considered to belong to a deployment if it is not controlled by a replicaSet of the deployment. * The code uses different `LabelSelector`s to find pods belonging to different deployment replicas. * If a pod is found to be in a terminating state, it is added to the `pods` list. ## Conclusion The code uses a combination of labels and `replicaSets` to identify pods belonging to a deployment. While tags are a valid approach, the code may not always use them, especially when dealing with rolling updates. This can lead to pods being missed or not being properly grouped.

正文

标签获取

我们获取那些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

}

与k8s 怎么精准获取deployment关联的pods?相似的内容:

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

标签获取 我们获取那些pods属于某个deployment时最先想到的可能是通过标签获取,其实这个是不准确的。因为标签并不是唯一的,也就是说不同deployment其实是能有相同标签的。 replicaSets获取 deployment 的产生pod流程如下: deployment->replica

[转帖]k8s集群内偶现无法访问外部域名怎么解?

故障现象 容器内频现无法访问外部服务,是用ping测试有如下现象: # ping baidu.com -c 4 PING baidu.com (110.242.68.66) 56(84) bytes of data. 64 bytes from 110.242.68.66 (110.242.68.6

[转帖]k8s部署-22-yaml文件怎么写,规则是什么,在k8s中分别有什么含义

https://www.jianshu.com/p/ba5e3d9ecc1e 在前面的文章中,我们使用了较多的yaml文件,例如测试kubespary方式搭建的集群可用性,亦或者前文中我们搭建ingress-nginx的时候也是用了yaml文件,那么k8s中的yaml文件到底该如何来写,针对k8s中

从k8s 的声明式API 到 GPT的 提示语

命令式命令式有时也称为指令式,命令式的场景下,计算机只会机械的完成指定的命令操作,执行的结果就取决于执行的命令是否正确。GPT 之前的人工智能就是这种典型的命令式,通过不断的炼丹,告诉计算机要怎么做,计算机只是机械的完成指定场景下的任务。声明式声明式也称为描述式或者申明式,这种方式告诉计算机想要的,

欠你们的 → k8s 集群搭建,除夕奉上!

开心一刻 有一天,qq收到一个好友申请,验证消息上写的是:哥哥加我,我是妹妹 我以为是性骚扰,就没加,直接回了一句:我喜欢少妇 过了一会儿,姑姑就给我打了个电话:你妹妹qq加你,你怎么不同意,她想问你几道数学题,你说你喜欢少妇 我:姑姑,你听我狡辩一下...... 祝大家除夕快乐! 节点准备 基于 

[转帖]一文读懂 K8s 持久化存储流程

https://zhuanlan.zhihu.com/p/128552232 作者 | 孙志恒(惠志) 阿里巴巴开发工程师 导读:众所周知,K8s 的持久化存储(Persistent Storage)保证了应用数据独立于应用生命周期而存在,但其内部实现却少有人提及。K8s 内部的存储流程到底是怎样的

k8s集群搭建及对一些组件的简单理解(二)

背景 前面写了一篇,k8s集群搭建及对一些组件的简单理解(一),主要讲了下背景和对一些组件的理解。 今天讲一下正式的安装,有网环境的,后续再说下无外网环境纯内网的。 k8s集群节点、组件 控制面节点,一般就是部署了如下组件:etcd、apiserver、kube-scheduler、kube-con

k8s集群搭建及对一些组件的简单理解(一)

背景 k8s的学习环境(用kubeadm方式搭建),我也搭过几次了,但都有点问题。 要么在云服务器上弄,这个的问题是就只有一台轻量服务器,只能搭个单节点的;后来买了一台便宜的,所以就有了两台,但是不在一个zone,一个是广州,一个是成都,内网不通,感觉搭起来很麻烦,还没试过。 要么是在本机的虚拟机上

实战 k8s----初识

什么是k8s?k8s是谷歌开源的一套完整的容器管理平台,方便我们直接管理容器应用。谷歌称之为,kubernetes,[kubə’netis] ,(跟我一起读库波尔耐题思,重音在耐的音上),由于字母太多,我们简称为k8s,8代表k-->s之间的8个字母。kubernetes 译为舵手,标识是一个航海舵

k8s网络问题以及容器跨宿主机通信原理

【0】资源配置文件 [root@mcwk8s03 mcwtest]# ls mcwdeploy.yaml [root@mcwk8s03 mcwtest]# cat mcwdeploy.yaml apiVersion: apps/v1 kind: Deployment metadata: labels