I'm daily user of kubectl, but not expert of linux. Recently I need edit some service type after deployment, so searched and used kubectl replace and it worked well.
cat yaml | kubectl replace -f -
service/tracs-pool-1sv replaced
But I don't understand why add a short dash -
at the last.
The doc only says:
Replace a pod based on the JSON passed into stdin.
I searched and found this SO question, and learned kubectl command may be that kind of command that does not read stdin(am I right?).
I tried
cat yaml |xargs kubectl replace -f
but error returned:
the path "apiVersion:" does not exist
So is the ending short dash(-) syntax built for kubectl ONLY? or is some more common syntax of linux bash stdin pipe? Can some one explain why xargs not work here and I must place a short dash(-) at the end?
Kubectl controls the Kubernetes Cluster. It is one of the key components of Kubernetes which runs on the workstation on any machine when the setup is done. It has the capability to manage the nodes in the cluster. Kubectl commands are used to interact and manage Kubernetes objects and the cluster.
kubectl is the main way in which you will interact with your Kubernetes cluster. Kubectl is a command line tool used to run commands against Kubernetes clusters. It does this by authenticating with the Master Node of your cluster and making API calls to do a variety of management actions.
The command set kubectl apply is used at a terminal's command-line window to create or modify Kubernetes resources defined in a manifest file. This is called a declarative usage. The state of the resource is declared in the manifest file, then kubectl apply is used to implement that state.
This is a reasonably common, but not universal, Un*x convention. (It is mentioned in the POSIX specification and so most non-Linux Unices will support it as well.)
The important detail here is that the kubectl ... -f
option expects a filename. If you have a file named x.yaml
, a more direct way to write what you've shown is just
kubectl replace -f x.yaml
Where you say -f -
, that ostensibly means "a file named -
", but kubectl
(along with many other tools) actually interprets this to mean "the process's standard input". For instance, you could use this for a very lightweight templating system, like
sed 's/TAG/1.2.3-20190103/g' x.yaml | kubectl replace -f -
For Un*x tooling in general, POSIX.1 states that, for many commands,
...an operand naming a file can be specified as '-', which means to use the standard input instead of a named file....
Some commands that support this include cat, grep, sort, and tar (not required by POSIX). One way to move a directory tree between two Linux machines, for instance, is to create a tar file on stdout, pipe that stream via ssh to a remote machine, and then unpack the tar file from stdin:
tar cf - . | ssh elsewhere tar xf - -C /other/dir
xargs is a tool that converts (most often) a list of filenames on standard input to command line arguments. For instance, find(1) can print a list of matching filenames to its stdout, so you could build a pipeline to delete shell backup files like
find . -name '*~' | xargs rm
You wouldn't usually use this with Kubernetes; your example tries to pass the YAML content itself as command-line arguments to kubectl
, for example. You could apply kubectl
across a directory tree with something like
find . name '*.yaml' | xargs -n1 kubectl apply -f
but since kubectl ... -f
also supports directory names (not a universal convention) you could do the same thing more directly as
kubectl apply -f . # where . is the current directory
Short dash(-) here represents stdin. This is a kubectl specific implementation. There are many other linux utilities as well that have similar implementation.
Apart from David's answer, there is another common format that we see used with kubectl. Its called Heredoc.
kubectl apply -f - <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
name: kubectl-actions
namespace: my-v2-restore
EOF
OR
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
name: kubectl-actions
namespace: my-v2-restore
EOF
Heredoc: is a way to send multiline string to the tool/command for processing.
https://tldp.org/LDP/abs/html/here-docs.html
https://linuxize.com/post/bash-heredoc/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With