使用 kubectl 在 Kubernetes 中获取 pods,其中所有容器在一行中 "ready"

Get pods in Kubernetes where all containers are "ready" in one line using kubectl

我们有 Istio 集群和 Jenkins 作业以获得“稳定”pods,它使用这个 kubectl 查询:

kubectl get po -o=jsonpath="{range .items[?(@.status.containerStatuses[-1].ready==true)]}{.spec.containers[0].image}{'\n'}{end}"
registry/my-proj/admin:2.0.0.000123
registry/my-proj/foo:2.0.0.000123
registry/my-proj/bar:2.0.0.000123

此查询获取 pods 最后一个容器(应用程序)准备就绪的位置,因为我们也有 Istio sidecar 容器。但是这里有一个棘手的事情,它看起来像数组是使用字母表构建的,所以如果 Istio 容器将是最后一个 - 它会把它作为就绪的 pod 获取,因为最后一个容器已经准备好了。

我也尝试过使用 go-template,但我设法做到的最好的事情

kubectl get po -o go-template='{{range .items}}{{range .status.containerStatuses}}{{if eq .ready true }}{{end}}{{end}}{{.metadata.name}}{{println}}{{end}}
registry/my-proj/admin:2.0.0.000123
registry/my-proj/admin:2.0.0.000123
registry/my-proj/foo:2.0.0.000123
registry/my-proj/foo:2.0.0.000123
registry/my-proj/bar:2.0.0.000123

它获取 2 次 pods,其中 2 个容器已准备就绪,只有 1 如果 1 容器已准备就绪。

TL;DR;

我正在寻找可以获取 pods 的最终查询,其中 所有容器都已准备就绪 ,谢谢

这样的事情怎么样?

kubectl get po -o go-template='{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}{{range .items}}{{$pod := .}}{{range .status.containerStatuses}}{{if eq .ready false}}{{$pod.metadata.name}}{{"\n"}}{{end}}{{end}}{{end}}' | sort | uniq -u

这里发生了什么:

  1. 我们正在获取所有现有的 pod 名称,以换行符分隔
  2. 附加所有 pod 名称,其中至少有一个未就绪的容器,由换行符分隔
  3. 按字母顺序对输出进行排序
  4. 获取唯一行,同时排除重复行。

诀窍是 -u 键排除了所有重复的条目,所以剩下的就是 运行 pods。 {{ $pod := .}} 用于保存外部范围以在内部循环中打印 pod 名称。 “Get all pods”在“get not ready pods”之后出现,以降低可能出现竞争条件的风险,当我们执行“get all”时,某些 pods 可能已经准备就绪pods”查询。

我确实相信使用 jsonpath 也可以轻松实现类似的功能,但我认为您无法仅使用 kubectl 来完成,而不使用 sortuniq.

如果您对grep没问题,您可以使用以下命令:

kubectl get pod |grep -Po '^([^ ]+)(?=\s+((\d+)\/))'

示例:

kubectl get pod
NAME    READY   STATUS     RESTARTS        AGE
bar     2/2     Running    0               5m12s
foo     1/3     NotReady   6               6m9s
mypod   1/1     Running    2 (9m58s ago)   21h

kubectl get pod |grep -Po '^([^ ]+)(?=\s+((\d+)\/))'
bar
mypod
ps@controller:~$

准备就绪pods:

kubectl get po -o go-template='{{ $readyFlag := true}}{{range .items}}{{range .status.containerStatuses}}{{ if not .ready}}{{ $readyFlag = false}}{{end}}{{end}}{{if $readyFlag }}{{.metadata.name}}{{"\n"}}{{end}}{{end}}'

还没准备好pods:

kubectl get po -o go-template='{{ $readyFlag := true}}{{range .items}}{{range .status.containerStatuses}}{{ if not .ready}}{{ $readyFlag = false}}{{end}}{{end}}{{if not $readyFlag }}{{.metadata.name}}{{"\n"}}{{end}}{{end}}'

实现细节:

  1. 我们定义变量$readyFlag,初始值为true
  2. 我们遍历所有容器状态,如果它的字段“.ready”不是 true - 将我们的标志值更新为 false
  3. 最后我们只检查 $readyFlag 是否有值 false - 那么至少有一个被检查的容器状态未准备好。如果值 true - 那么所有容器都准备就绪