使用插件扩展 kubectl

通过创建和安装 kubectl 插件来扩展 kubectl。

本指南演示了如何为 kubectl 安装和编写扩展。通过将核心 kubectl 命令视为与 Kubernetes 集群交互的基本构建块,集群管理员可以将插件视为利用这些构建块来创建更复杂行为的一种方式。插件通过新的子命令扩展了 kubectl,从而允许使用 kubectl 的主发行版中未包含的新功能和自定义功能。

开始之前

您需要安装一个可用的 kubectl 二进制文件。

安装 kubectl 插件

插件是一个独立的可执行文件,其名称以 kubectl- 开头。要安装插件,请将其可执行文件移动到 PATH 上的任何位置。

您还可以使用 Krew 发现和安装开源中可用的 kubectl 插件。Krew 是由 Kubernetes SIG CLI 社区维护的插件管理器。

发现插件

kubectl 提供了一个命令 kubectl plugin list,用于在您的 PATH 中搜索有效的插件可执行文件。执行此命令会导致遍历 PATH 中的所有文件。任何可执行且以 kubectl- 开头的文件都将按它们在 PATH 中出现的顺序显示在此命令的输出中。对于任何以 kubectl- 开头但不可执行的文件,都会包含一个警告。对于任何重叠彼此名称的有效插件文件,也会包含一个警告。

您可以使用 Krew 从社区精选的 插件索引 中发现和安装 kubectl 插件。

限制

目前无法创建覆盖现有 kubectl 命令的插件。例如,创建插件 kubectl-version 将导致该插件永远不会执行,因为现有的 kubectl version 命令将始终优先于它。由于此限制,也无法使用插件向现有 kubectl 命令添加新的子命令。例如,通过将插件命名为 kubectl-create-foo 来添加子命令 kubectl create foo 将导致该插件被忽略。

kubectl plugin list 会显示对尝试执行此操作的任何有效插件的警告。

编写 kubectl 插件

您可以使用任何允许您编写命令行命令的编程语言或脚本编写插件。

不需要插件安装或预加载。插件可执行文件会从 kubectl 二进制文件继承环境。插件根据其名称确定它希望实现的命令路径。例如,名为 kubectl-foo 的插件提供了一个命令 kubectl foo。您必须将插件可执行文件安装到 PATH 中的某个位置。

示例插件

#!/bin/bash

# optional argument handling
if [[ "$1" == "version" ]]
then
    echo "1.0.0"
    exit 0
fi

# optional argument handling
if [[ "$1" == "config" ]]
then
    echo "$KUBECONFIG"
    exit 0
fi

echo "I am a plugin named kubectl-foo"

使用插件

要使用插件,请使插件可执行

sudo chmod +x ./kubectl-foo

并将其放置到 PATH 中的任何位置

sudo mv ./kubectl-foo /usr/local/bin

您现在可以将插件作为 kubectl 命令调用

kubectl foo
I am a plugin named kubectl-foo

所有参数和标志都按原样传递给可执行文件

kubectl foo version
1.0.0

所有环境变量也按原样传递给可执行文件

export KUBECONFIG=~/.kube/config
kubectl foo config
/home/<user>/.kube/config
KUBECONFIG=/etc/kube/config kubectl foo config
/etc/kube/config

此外,传递给插件的第一个参数始终是调用它的位置的完整路径(在上面的示例中,$0 等于 /usr/local/bin/kubectl-foo)。

命名插件

如上面的示例所示,插件根据其文件名确定它将实现的命令路径。插件目标命令路径中的每个子命令都用一个连字符 (-) 分隔。例如,一个希望在用户调用 kubectl foo bar baz 命令时被调用的插件,其文件名将为 kubectl-foo-bar-baz

标志和参数处理

kubectl 插件必须解析和验证传递给它们的所有参数。有关针对插件作者的 Go 库的详细信息,请参阅 使用命令行运行时包

以下是一些用户在提供其他标志和参数时调用插件的附加情况。这基于上面场景中的 kubectl-foo-bar-baz 插件。

如果您运行 kubectl foo bar baz arg1 --flag=value arg2,kubectl 的插件机制将首先尝试找到名称最长的插件,在本例中为 kubectl-foo-bar-baz-arg1。在找不到该插件后,kubectl 将最后一个连字符分隔的值视为参数(在本例中为 arg1),并尝试找到下一个最长的可能名称 kubectl-foo-bar-baz。在找到具有此名称的插件后,kubectl 将调用该插件,并将插件名称后的所有参数和标志作为参数传递给插件进程。

示例

# create a plugin
echo -e '#!/bin/bash\n\necho "My first command-line argument was $1"' > kubectl-foo-bar-baz
sudo chmod +x ./kubectl-foo-bar-baz

# "install" your plugin by moving it to a directory in your $PATH
sudo mv ./kubectl-foo-bar-baz /usr/local/bin

# check that kubectl recognizes your plugin
kubectl plugin list
The following kubectl-compatible plugins are available:

/usr/local/bin/kubectl-foo-bar-baz
# test that calling your plugin via a "kubectl" command works
# even when additional arguments and flags are passed to your
# plugin executable by the user.
kubectl foo bar baz arg1 --meaningless-flag=true
My first command-line argument was arg1

如您所见,您的插件是根据用户指定的 kubectl 命令找到的,并且所有额外的参数和标志在找到后都按原样传递给插件可执行文件。

包含连字符和下划线的名称

虽然 kubectl 插件机制在插件文件名中使用连字符 (-) 来分隔插件处理的子命令序列,但仍然可以通过在文件名中使用下划线 (_) 来创建在命令行调用中包含连字符的插件命令。

示例

# create a plugin containing an underscore in its filename
echo -e '#!/bin/bash\n\necho "I am a plugin with a dash in my name"' > ./kubectl-foo_bar
sudo chmod +x ./kubectl-foo_bar

# move the plugin into your $PATH
sudo mv ./kubectl-foo_bar /usr/local/bin

# You can now invoke your plugin via kubectl:
kubectl foo-bar
I am a plugin with a dash in my name

请注意,在插件文件名中引入下划线不会阻止您使用诸如 kubectl foo_bar 之类的命令。上面的示例中的命令可以使用连字符 (-) 或下划线 (_) 调用

# You can invoke your custom command with a dash
kubectl foo-bar
I am a plugin with a dash in my name
# You can also invoke your custom command with an underscore
kubectl foo_bar
I am a plugin with a dash in my name

名称冲突和覆盖

PATH 中的不同位置可能存在多个具有相同文件名的插件。例如,给定一个 PATH,其值为:PATH=/usr/local/bin/plugins:/usr/local/bin/moreplugins,插件 kubectl-foo 的副本可能存在于 /usr/local/bin/plugins/usr/local/bin/moreplugins 中,因此 kubectl plugin list 命令的输出为

PATH=/usr/local/bin/plugins:/usr/local/bin/moreplugins kubectl plugin list
The following kubectl-compatible plugins are available:

/usr/local/bin/plugins/kubectl-foo
/usr/local/bin/moreplugins/kubectl-foo
  - warning: /usr/local/bin/moreplugins/kubectl-foo is overshadowed by a similarly named plugin: /usr/local/bin/plugins/kubectl-foo

error: one plugin warning was found

在上述情况下,/usr/local/bin/moreplugins/kubectl-foo 下的警告告诉您,此插件永远不会执行。相反,PATH 中首先出现的可执行文件 /usr/local/bin/plugins/kubectl-foo 将始终被 kubectl 插件机制首先找到并执行。

解决此问题的一种方法是确保您希望与 kubectl 一起使用的插件的位置始终位于 PATH 中的第一个位置。例如,如果您希望在每次调用 kubectl 命令 kubectl foo 时始终使用 /usr/local/bin/moreplugins/kubectl-foo,请将 PATH 的值更改为 /usr/local/bin/moreplugins:/usr/local/bin/plugins

调用最长的可执行文件名

插件文件名还会发生另一种覆盖。给定用户 PATH 中的两个插件:kubectl-foo-barkubectl-foo-bar-bazkubectl 插件机制将始终为给定的用户命令选择最长的可能插件名称。以下是一些示例,进一步说明了这一点

# for a given kubectl command, the plugin with the longest possible filename will always be preferred
kubectl foo bar baz
Plugin kubectl-foo-bar-baz is executed
kubectl foo bar
Plugin kubectl-foo-bar is executed
kubectl foo bar baz buz
Plugin kubectl-foo-bar-baz is executed, with "buz" as its first argument
kubectl foo bar buz
Plugin kubectl-foo-bar is executed, with "buz" as its first argument

此设计选择确保可以跨多个文件实现插件子命令(如果需要),并且这些子命令可以嵌套在“父”插件命令下

ls ./plugin_command_tree
kubectl-parent
kubectl-parent-subcommand
kubectl-parent-subcommand-subsubcommand

检查插件警告

您可以使用前面提到的 kubectl plugin list 命令来确保您的插件对 kubectl 可见,并验证是否有任何警告阻止它被调用为 kubectl 命令。

kubectl plugin list
The following kubectl-compatible plugins are available:

test/fixtures/pkg/kubectl/plugins/kubectl-foo
/usr/local/bin/kubectl-foo
  - warning: /usr/local/bin/kubectl-foo is overshadowed by a similarly named plugin: test/fixtures/pkg/kubectl/plugins/kubectl-foo
plugins/kubectl-invalid
  - warning: plugins/kubectl-invalid identified as a kubectl plugin, but it is not executable

error: 2 plugin warnings were found

使用命令行运行时包

如果您正在为 kubectl 编写插件并且使用 Go,您可以使用 cli-runtime 实用程序库。

这些库提供了用于解析或更新用户 kubeconfig 文件的帮助程序,用于向 API 服务器发出 REST 样式的请求,或绑定与配置和打印相关的标志。

请参阅 示例 CLI 插件,了解 CLI 运行时存储库中提供的工具的示例用法。

分发 kubectl 插件

如果您为其他人开发了一个插件,您应该考虑如何打包、分发它以及向用户提供更新。

Krew

Krew 提供了一种跨平台的方式来打包和分发您的插件。这样,您就可以使用单个打包格式来针对所有目标平台(Linux、Windows、macOS 等)并向用户提供更新。Krew 还维护了一个 插件索引,以便其他人可以发现您的插件并安装它。

原生/平台特定包管理

或者,您可以使用传统的包管理器,例如 Linux 上的 aptyum、Windows 上的 Chocolatey 以及 macOS 上的 Homebrew。任何包管理器都可以,只要它可以将新的可执行文件放置在用户的 PATH 中的某个位置。作为插件作者,如果您选择此选项,那么您还需要承担在每次发布时跨多个平台更新 kubectl 插件分发包的负担。

源代码

您可以发布源代码;例如,作为 Git 存储库。如果您选择此选项,想要使用该插件的人必须获取代码,设置构建环境(如果需要编译),然后部署插件。如果您还提供编译后的包,或使用 Krew,这将使安装更容易。

下一步

  • 查看示例 CLI 插件存储库,了解用 Go 编写的插件的 详细示例。如有任何问题,请随时联系 SIG CLI 团队
  • 了解 Krew,一个用于 kubectl 插件的包管理器。
上次修改时间:2021 年 2 月 4 日下午 4:41 PST:清理单词的使用:简单 (3fd65482e8)