需要对 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 进行处理的方法。
我是 kubectl 的日常用户,但不是 linux 的专家。最近我需要在部署后编辑一些服务类型,所以搜索并使用了 kubectl replace 并且效果很好。
cat yaml | kubectl replace -f -
service/tracs-pool-1sv replaced
但是我不明白为什么要在最后加上一个短横线 -
。
文档只说:
Replace a pod based on the JSON passed into 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 实用程序也具有类似的实现。
除了
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 进行处理的方法。