kubectl: kubectl plugins do not work when options placed before plugin name

Edit: The root cause of this issue has nothing to do with strace; it is because calling a kubectl plugin with options before the plugin name causes kubectl to not know how to find the plugin.

# works
kubectl my-plugin -n some-namespace

# fails, because kubectl stops looking for a plugin name after it sees the -n
kubectl -n some-namespace my-plugin

What happened:

kubectl plugin list shows that I have some plugins installed:

$ kubectl plugin list
The following compatible plugins are available:

/usr/bin/kubectl-pkrizak
/usr/local/bin/kubectl-who_can

But calling them does not work:

$ kubectl pkrizak
Error: unknown command "pkrizak" for "kubectl"
Run 'kubectl --help' for usage.
$ kubectl who-can
Error: unknown command "who-can" for "kubectl"
Run 'kubectl --help' for usage.

However, calling them under strace works somehow:

$ strace -f -o /tmp/trace kubectl pkrizak
hello there
$ strace -f -o /tmp/trace kubectl who-can
Error: you must specify two or three arguments: verb, resource, and optional resourceName

What you expected to happen: Plugins listed in kubectl plugin list should be called without having to wrap the command with strace.

How to reproduce it (as minimally and precisely as possible):

  1. Install a kubectl plugin somewhere in $PATH
  2. Verify that kubectl plugin list shows the plugin
  3. Run kubectl <plugin> and it returns an error
  4. Run strace <args> kubectl <plugin> and it works

Anything else we need to know?:

Environment:

  • Kubernetes client and server versions (use kubectl version):
Client Version: version.Info{Major:"1", Minor:"18", GitVersion:"v1.18.3", GitCommit:"2e7996e3e2712684bc73f0dec0200d64eec7fe40", GitTreeState:"clean", BuildDate:"2020-05-20T12:52:00Z", GoVersion:"go1.13.9", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"15", GitVersion:"v1.15.12", GitCommit:"e2a822d9f3c2fdb5c9bfbe64313cf9f657f0a725", GitTreeState:"clean", BuildDate:"2020-05-06T05:09:48Z", GoVersion:"go1.12.17", Compiler:"gc", Platform:"linux/amd64"}
  • Cloud provider or hardware configuration: n/a
  • OS (e.g: cat /etc/os-release):
NAME="Ubuntu"
VERSION="16.04.6 LTS (Xenial Xerus)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 16.04.6 LTS"
VERSION_ID="16.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
VERSION_CODENAME=xenial
UBUNTU_CODENAME=xenial

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 1
  • Comments: 28 (17 by maintainers)

Most upvoted comments

@ahmetb Thanks for that data point. It seems fair that we shouldn’t worry about supporting this use case. I do agree that the error output could be improved.

It seems like plugins tend to rely on the KUBECONFIG env, so for anyone else reading this issue, I changed my alias from

alias ka='kubectl --kubeconfig="$ADMIN_KUBECONFIG"'

to

alias ka='KUBECONFIG="$ADMIN_KUBECONFIG" kubectl'

And now I can run commands like ka krew

Without going into the way kubectl employs plugins.

When considering aliases you should look into functions instead, which can handle parameters.

# Create an alias
$ alias kd="kubectl -n devops"

# Getting an error
$ kd view-secret deployer-token-8d28z
Error: flags cannot be placed before plugin name: -n

# Removing the alias and adding a function instead
$ unalias kd
$ function kd(){ kubectl "$@" -n devops; }

# Using the function
$ kd view-secret deployer-token-8d28z
Multiple sub keys found. Specify another argument, one of:
-> ca.crt
-> namespace
-> service-ca.crt
-> token

Indeed!

$ alias kubectl
alias kubectl='kubectl -n ${K8S_NAMESPACE:-default}

Removing the alias makes it work. Is this a bug in kubectl, or an odd side-effect of how aliases work?

I was able to reproduce your problem when I made an alias for kubectl, like this:

alias kubectl="kubectl -v9"

By any chance, have you defined an alias for kubectl? What is the output of alias | grep kubectl?