需要对 kubectl stdin 和 pipe 进行一些解释

Need some explaination of kubectl stdin and pipe

我是 kubectl 的日常用户,但不是 linux 的专家。最近我需要在部署后编辑一些服务类型,所以搜索并使用了 kubectl replace 并且效果很好。

cat yaml | kubectl replace -f -

service/tracs-pool-1sv replaced

但是我不明白为什么要在最后加上一个短横线 -。 文档只说:

Replace a pod based on the JSON passed into stdin.

搜了一下发现了 SO问题,了解到kubectl命令可能是那种不读stdin的命令(对吗?)。

我试过了

cat yaml |xargs kubectl replace -f

但返回错误:

the path "apiVersion:" does not exist

那么 kubectl ONLY 的结尾短破折号 (-) 语法是构建的吗?还是 linux bash stdin 管道的更多 common 语法? 有人可以解释为什么 xargs 在这里不起作用,我必须在末尾放置一个短破折号 (-) 吗?

这是一个相当普遍但不普遍的 Un*x 约定。 (它在 POSIX 规范中提到,因此大多数非 Linux Unices 也将支持它。)

此处的重要细节是 kubectl ... -f 选项需要一个 文件名 。如果您有一个名为 x.yaml 的文件,一种更直接的方式来编写您所显示的内容就是

kubectl replace -f x.yaml

你说 -f - 的地方,表面上是指 "a file named -",但 kubectl(以及许多其他工具)实际上将其解释为 "the process's standard input"。例如,您可以将其用于非常轻量级的模板系统,例如

sed 's/TAG/1.2.3-20190103/g' x.yaml | kubectl replace -f -

对于一般的 Un*x 工具,POSIX.1 states 对于许多命令,

...an operand naming a file can be specified as '-', which means to use the standard input instead of a named file....

一些支持此功能的命令包括 cat, grep, sort 和 tar(POSIX 不需要)。例如,在两台 Linux 机器之间移动目录树的一种方法是在 stdout 上创建一个 tar 文件,通过 ssh 将该流通过管道传输到远程机器,然后解压缩 tar 来自标准输入的文件:

tar cf - . | ssh elsewhere tar xf - -C /other/dir

xargs 是一种将标准输入上的文件名列表(最常见)转换为命令行参数的工具。例如,find(1) 可以将匹配文件名列表打印到其标准输出,因此您可以构建一个管道来删除 shell 备份文件,例如

find . -name '*~' | xargs rm

您通常不会将其与 Kubernetes 一起使用;例如,您的示例尝试将 YAML 内容本身作为命令行参数传递给 kubectl。您可以在目录树中应用 kubectl,例如

find . name '*.yaml' | xargs -n1 kubectl apply -f

但是因为 kubectl ... -f 支持目录名称(不是通用约定)你可以更直接地做同样的事情

kubectl apply -f . # where . is the current directory

这里的短破折号(-)代表标准输入。这是一个kubectl specific implementation。还有许多其他 linux 实用程序也具有类似的实现。

除了, there is another common format that we see used with kubectl。它叫做 Heredoc。

kubectl apply -f - <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
  name: kubectl-actions
  namespace: my-v2-restore
EOF

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
  name: kubectl-actions
  namespace: my-v2-restore
EOF

Heredoc: 是一种将多行字符串发送到 tool/command 进行处理的方法。