..

xargs命令的使用

介绍

xargs 是 “extended arguments” 的缩写。 主要是用来在命令行里结合管道扩展传参方式的。

它会根据空格、Tab符、换行符以及EOF来把 pipe 里的字符串分割成一个个参数,喂给后续要执行的命令。

用例

逐一给目标节点打上 taint

升级 eks 的时候,需要给同一个 ASG 下面的所有旧节点打上 taint。用 xargs 配合 grep 以及 awk 命令就能轻松搞定。

# 先 query 出目标节点,确认无误之后再进行下一步
$ kubectl get nodes -l node-group=system | grep v1.26
ip--0-34-xx.ec2.internal     Ready    <none>   11d   v1.26.12-eks-5e0fdde
ip-10-0-43-yy.ec2.internal   Ready    <none>   11d   v1.26.12-eks-5e0fdde

# 然后用 awk 来提取第一列,也就是节点的名称
$ kubectl get nodes -l node-group=system | grep v1.26 | awk '{print $1}'
ip--0-34-xx.ec2.internal
ip-10-0-43-yy.ec2.internal

# 确认无误后,加上 xargs 逐一执行 taint 命令
$ kubectl get nodes -l node-group=system | grep v1.26 | awk '{print $1}' | xargs -n 1 -I {} kubectl taint node {} eks-node-rolling:NoSchedule

讲解下上述 xargs 用到的两个参数的含义:

  1. -n 1-n 表示一次取出多少个参数来执行命令。上面的例子里,上游 pipe 会有两个参数:ip--0-34-xx.ec2.internalip-10-0-43-yy.ec2.internal。我们要的都是一次取一个节点名作为参数,所以这里是 -n 1
  2. -I {}, -I 后面跟一个参数占位字符串,这样 xargs 就会把后面命令里的这个字符串替换成参数。我们这里用的是一对花括号 {},所以 xargs 命令后面的那个 kubectl 命令里的花括号就会被替换成参数。这个一般用于参数要放在命令中间的情况。

给字符串进行 trim 操作 – 获取 Pod 的名字

所谓字符串 trim 操作,就是去除字符串两头的空白字符。xargs 勉强可以做到这一点。

k8s 中 Deployment 的 Pod 名字是带有随机的尾号的。这就导致你要查看的时候,每次都要先 query 一遍 Pod 名字,然后选中复制名字后再进行对应操作。比如,我要登录到某个 Pod 的 shell 上。之前的操作都是:

$ kubectl get pods | grep admin
admin-775d57c7c5-z722v                  3/3     Running   0             3h52m
$ kubectl exec -it admin-775d57c7c5-z722v -- bash

我们可以通过 xargs, awk 以及 grep 把这个动态的 Pod 名存到变量里去。

# 用 awk 提取出 Pod 名后,再用 xargs 去除两头的空格、换行。
$ ADMIN_POD=`kubectl get pods | grep admin | awk '{print $1}' | xargs`
# 然后就可以通过变量 ADMIN_POD 来登录到 Pod 上。
$ kubectl exec -it $ADMIN_POD -- bash

当然,这样依然不太方便。不过只需要写一个函数,就能把上面的两步集中到一个命令里。

function attach-admin-pod {
    local ADMIN_POD=`kubectl get pods | grep admin | awk '{print $1}' | xargs`
    kubectl exec -it $ADMIN_POD -- bash
}