舵插件指南
舵插件是可以通过 helm
CLI 访问但不是内置舵代码库的一部分的工具。
可以在 相关 部分找到现有插件,或者通过搜索 GitHub 来找到现有插件。
本指南解释了如何使用和创建插件。
概述
舵插件是与舵无缝集成的附加工具。它们提供了一种扩展舵核心功能集的方法,但无需将每个新功能都用 Go 编写并添加到核心工具中。
舵插件具有以下功能
- 它们可以添加到舵安装中并从中删除,而不会影响核心舵工具。
- 它们可以用任何编程语言编写。
- 它们与舵集成,并将显示在
helm help
和其他地方。
舵插件位于 $HELM_PLUGINS
中。您可以使用 helm env
命令找到它的当前值,包括未在环境中设置时的默认值。
舵插件模型部分借鉴了 Git 的插件模型。因此,您有时可能会听到将 helm
称为表面层,而插件是底层。这是一种简写的方式,表明舵提供用户体验和顶级处理逻辑,而插件则执行执行所需操作的“详细信息”。
安装插件
使用 $ helm plugin install <path|url>
命令安装插件。您可以传递本地文件系统上插件的路径或远程 VCS 仓库的 URL。helm plugin install
命令会将给定路径/URL 上的插件克隆或复制到 $HELM_PLUGINS
中。
$ helm plugin install https://github.com/adamreese/helm-env
如果您有插件 tar 分发包,只需将其解压到 $HELM_PLUGINS
目录中。您还可以通过发出 helm plugin install https://domain/path/to/plugin.tar.gz
直接从 URL 安装 tarball 插件。
构建插件
在许多方面,插件类似于图表。每个插件都有一个顶级目录,然后是一个 plugin.yaml
文件。
$HELM_PLUGINS/
|- last/
|
|- plugin.yaml
|- last.sh
在上面的示例中,last
插件包含在名为 last
的目录中。它有两个文件:plugin.yaml
(必需)和一个可执行脚本 last.sh
(可选)。
插件的核心是一个名为 plugin.yaml
的简单 YAML 文件。以下是一个帮助获取最后一个发布名称的插件的插件 YAML
name: "last"
version: "0.1.0"
usage: "get the last release name"
description: "get the last release name"
ignoreFlags: false
command: "$HELM_BIN --host $TILLER_HOST list --short --max 1 --date -r"
platformCommand:
- os: linux
arch: i386
command: "$HELM_BIN list --short --max 1 --date -r"
- os: linux
arch: amd64
command: "$HELM_BIN list --short --max 1 --date -r"
- os: windows
arch: amd64
command: "$HELM_BIN list --short --max 1 --date -r"
name
是插件的名称。当舵执行此插件时,它将使用此名称(例如 helm NAME
将调用此插件)。
name
应与目录名称匹配。 在我们上面的示例中,这意味着 name: last
的插件应包含在名为 last
的目录中。
对 name
的限制
name
不能与现有的helm
顶级命令之一重复。name
必须限制为 ASCII a-z、A-Z、0-9、_
和-
字符。
version
是插件的 SemVer 2 版本。usage
和 description
都用于生成命令的帮助文本。
ignoreFlags
开关告诉舵不要将标志传递给插件。因此,如果使用 helm myplugin --foo
和 ignoreFlags: true
调用插件,则 --foo
将被静默丢弃。
最后,也是最重要的是,platformCommand
或 command
是在调用此插件时将执行的命令。platformCommand
部分定义了命令的操作系统/架构特定变体。以下规则将适用于决定使用哪个命令
- 如果存在
platformCommand
,它将首先被搜索。 - 如果
os
和arch
都与当前平台匹配,则搜索将停止,并将使用该命令。 - 如果
os
匹配,并且没有更具体的arch
匹配,则将使用该命令。 - 如果没有找到
platformCommand
匹配,则将使用默认的command
。 - 如果在
platformCommand
中没有找到匹配项,并且没有command
,舵将退出并显示错误。
在执行插件之前,会对环境变量进行插值。上面的模式说明了指示插件程序所在位置的首选方法。
有一些使用插件命令的策略
- 如果插件包含可执行文件,则
platformCommand:
或command:
的可执行文件应打包在插件目录中。 platformCommand:
或command:
行将对任何环境变量进行扩展,然后再执行。$HELM_PLUGIN_DIR
将指向插件目录。- 命令本身不会在 shell 中执行。因此,您不能在一行中写 shell 脚本。
- 舵会将大量配置注入环境变量。查看环境以了解有哪些信息可用。
- 舵对插件的语言不做任何假设。您可以用您喜欢的任何语言编写它。
- 命令负责为
-h
和--help
实现特定帮助文本。舵将使用usage
和description
用于helm help
和helm help myplugin
,但不会处理helm myplugin --help
。
下载器插件
默认情况下,舵能够使用 HTTP/S 拉取图表。从舵 2.4.0 开始,插件可以具有从任意来源下载图表的特殊功能。
插件应在 plugin.yaml
文件(顶级)中声明此特殊功能
downloaders:
- command: "bin/mydownloader"
protocols:
- "myprotocol"
- "myprotocols"
如果安装了此类插件,舵可以通过调用 command
来使用指定的协议方案与仓库交互。应类似于添加常规仓库来添加特殊仓库:helm repo add favorite myprotocol://example.com/
特殊仓库的规则与常规仓库相同:舵必须能够下载 index.yaml
文件才能发现和缓存可用图表的列表。
定义的命令将使用以下方案调用:command certFile keyFile caFile full-URL
。SSL 凭据来自仓库定义,存储在 $HELM_REPOSITORY_CONFIG
中(即 $HELM_CONFIG_HOME/repositories.yaml
)。预计下载器插件会将原始内容转储到标准输出,并将错误报告到标准错误。
下载器命令还支持子命令或参数,允许您在 plugin.yaml
中指定例如 bin/mydownloader subcommand -d
。如果您希望对主插件命令和下载器命令使用相同的可执行文件,但每个命令使用不同的子命令,这将很有用。
环境变量
当舵执行插件时,它会将外部环境传递给插件,还会注入一些额外的环境变量。
如果在外部环境中设置了 KUBECONFIG
之类的变量,则会为插件设置它们。
以下变量保证会设置
HELM_PLUGINS
:插件目录的路径。HELM_PLUGIN_NAME
:插件的名称,由helm
调用。因此,helm myplug
将具有简短名称myplug
。HELM_PLUGIN_DIR
:包含插件的目录。HELM_BIN
:helm
命令的路径(由用户执行)。HELM_DEBUG
:指示是否由 helm 设置了调试标志。HELM_REGISTRY_CONFIG
:注册表配置的位置(如果使用)。请注意,使用注册表的 helm 是一种实验性功能。HELM_REPOSITORY_CACHE
:仓库缓存文件的路径。HELM_REPOSITORY_CONFIG
:仓库配置文件的路径。HELM_NAMESPACE
:传递给helm
命令的命名空间(通常使用-n
标志)。HELM_KUBECONTEXT
:传递给helm
命令的 Kubernetes 配置上下文名称。
此外,如果明确指定了 Kubernetes 配置文件,它将被设置为 KUBECONFIG
变量。
关于标志解析的说明
执行插件时,舵会解析全局标志以供自身使用。这些标志都不会传递给插件。
--debug
:如果指定了此标志,$HELM_DEBUG
将被设置为1
。--registry-config
:这将转换为$HELM_REGISTRY_CONFIG
。--repository-cache
:这将转换为$HELM_REPOSITORY_CACHE
。--repository-config
:这将转换为$HELM_REPOSITORY_CONFIG
。--namespace
和-n
: 转换为$HELM_NAMESPACE
--kube-context
: 转换为$HELM_KUBECONTEXT
--kubeconfig
: 转换为$KUBECONFIG
插件应该在 -h
和 --help
时显示帮助文本并退出。在所有其他情况下,插件可以根据需要使用标志。
提供 shell 自动补全
从 Helm 3.2 开始,插件可以选择在 Helm 的现有自动补全机制中提供对 shell 自动补全的支持。
静态自动补全
如果插件提供自己的标志和/或子命令,它可以通过在插件根目录中包含一个 completion.yaml
文件来告知 Helm。completion.yaml
文件具有以下形式
name: <pluginName>
flags:
- <flag 1>
- <flag 2>
validArgs:
- <arg value 1>
- <arg value 2>
commands:
name: <commandName>
flags:
- <flag 1>
- <flag 2>
validArgs:
- <arg value 1>
- <arg value 2>
commands:
<and so on, recursively>
注意
- 所有部分都是可选的,但如果适用,应提供。
- 标志不应包含
-
或--
前缀。 - 短标志和长标志都可以也应该指定。短标志不必与其对应长形式相关联,但两种形式都应列出。
- 标志不必按任何方式排序,但需要在文件中的子命令层次结构的正确位置列出。
- Helm 的现有全局标志已由 Helm 的自动补全机制处理,因此插件不必指定以下标志
--debug
、--namespace
或-n
、--kube-context
和--kubeconfig
或任何其他全局标志。 validArgs
列表提供了子命令之后第一个参数的可能补全的静态列表。在某些情况下,无法提前提供此类列表(参见下面的 动态补全 部分),在这种情况下,可以省略validArgs
部分。
completion.yaml
文件完全是可选的。如果未提供,Helm 不会为插件提供 shell 自动补全(除非插件支持 动态补全)。此外,添加 completion.yaml
文件是向后兼容的,并且在使用旧版 helm 版本时不会影响插件的行为。
例如,对于没有子命令但接受与 helm status
命令相同的标志的 fullstatus 插件
,completion.yaml
文件为
name: fullstatus
flags:
- o
- output
- revision
对于 2to3 插件
的一个更复杂示例,它有一个 completion.yaml
文件,其内容为
name: 2to3
commands:
- name: cleanup
flags:
- config-cleanup
- dry-run
- l
- label
- release-cleanup
- s
- release-storage
- tiller-cleanup
- t
- tiller-ns
- tiller-out-cluster
- name: convert
flags:
- delete-v2-releases
- dry-run
- l
- label
- s
- release-storage
- release-versions-max
- t
- tiller-ns
- tiller-out-cluster
- name: move
commands:
- name: config
flags:
- dry-run
动态补全
同样从 Helm 3.2 开始,插件可以提供自己的动态 shell 自动补全。动态 shell 自动补全是对无法提前定义的参数值或标志值的补全。例如,对集群上当前可用的 helm 版本名称的补全。
为了让插件支持动态自动补全,它必须在其根目录中提供一个名为 plugin.complete
的可执行文件。当 Helm 补全脚本需要插件的动态补全时,它将执行 plugin.complete
文件,并向其传递需要补全的命令行。plugin.complete
可执行文件需要包含逻辑来确定适当的补全选择并将其输出到标准输出,以便 Helm 补全脚本使用。
plugin.complete
文件完全是可选的。如果未提供,Helm 不会为插件提供动态自动补全。此外,添加 plugin.complete
文件是向后兼容的,并且在使用旧版 helm 版本时不会影响插件的行为。
plugin.complete
脚本的输出应该是换行符分隔的列表,例如
rel1
rel2
rel3
当调用 plugin.complete
时,插件环境与调用插件主脚本时一样。因此,变量 $HELM_NAMESPACE
、$HELM_KUBECONTEXT
和所有其他插件变量都将已设置,并且其对应的全局标志将被删除。
plugin.complete
文件可以采用任何可执行形式;它可以是 shell 脚本、Go 程序或 Helm 可以执行的任何其他类型的程序。plugin.complete
文件必须对用户具有可执行权限。plugin.complete
文件必须以成功代码(值 0)退出。
在某些情况下,动态补全将需要从 Kubernetes 集群中获取信息。例如,helm fullstatus
插件需要发布名称作为输入。在 fullstatus
插件中,为了让其 plugin.complete
脚本提供对当前发布名称的补全,它可以简单地运行 helm list -q
并输出结果。
如果希望使用相同的可执行文件来执行插件和补全插件,则可以使 plugin.complete
脚本使用一些特殊参数或标志来调用主插件可执行文件;当主插件可执行文件检测到特殊参数或标志时,它将知道运行补全。在我们的示例中,plugin.complete
可以像这样实现
#!/usr/bin/env sh
# "$@" is the entire command-line that requires completion.
# It is important to double-quote the "$@" variable to preserve a possibly empty last parameter.
$HELM_PLUGIN_DIR/status.sh --complete "$@"
fullstatus
插件的真实脚本 (status.sh
) 必须查找 --complete
标志,如果找到,则打印出适当的补全。
技巧和窍门
- shell 将自动过滤掉与用户输入不匹配的补全选择。因此,插件可以返回所有相关的补全,而无需删除与用户输入不匹配的补全。例如,如果命令行是
helm fullstatus ngin<TAB>
,plugin.complete
脚本可以打印所有发布名称(default
命名空间的),而不仅仅是那些以ngin
开头的名称;shell 仅保留以ngin
开头的名称。 - 为了简化动态补全支持,尤其是在插件很复杂的情况下,可以让
plugin.complete
脚本调用主插件脚本并请求补全选择。有关示例,请参阅上面的 动态补全 部分。 - 要调试动态补全和
plugin.complete
文件,可以运行以下命令以查看补全结果helm __complete <pluginName> <arguments to complete>
。例如helm __complete fullstatus --output js<ENTER>
,helm __complete fullstatus -o json ""<ENTER>