Kubernetes 中如何开发一个 kubectl 的插件命令

背景

在平常使用中,Kubectl 做为和 Kubernetes 集群进行交互的工具,提供了丰富的功能。可是偶尔也有时候,你想作一些 Kubectl 暂时还不支持的功能。那么在这种状况下,如何不改变 Kubectl 的代码而且从新编译就能引入新的功能呢? 这个问题的答案就是采用 Kubectl 的 Plugin 机制。工具

Kubectl 的 Plugin 机制在 v1.8.0 版本的时候就引入了,而且在 v1.12.0 版本中进行了大规模的重构以适应更加复杂多样的场景,而且最终在 v1.14.0 版本中稳定下来。因此你必须使用 Kubectl v1.12.0 及以上版本才能够支持当前的插件命令。插件

插件命令

所谓的插件命令其实很简单,只要符合如下几个特色便可:code

(1) 该命令是一个可执行的文件;
(2) 该命令可以经过 $PATH 搜索到,也就是说若是须要,你必须把这个命令加入到 $PATH 中;
(3) 该命令必须以 kubectl- 开头,例如 kubectl-echo 就是一个合法的插件命令名称。 继承

基于以上的要求,咱们能够用任何语言去编写这个命令,好比咱们最简单的用 C 语言写一个 kubectl-hello 的插件命令尝试下。文档

#include <stdio.h>
int
main(int argc, char *argv[])
{
    printf("hello, i am a kubelet plugin command\n");
}

而后咱们编译一下:get

$ gcc -o kubectl-hello kubectl-hello.c

而后咱们把这个命令所在的目录放到系统的 $PATH 变量中,最后经过 kubectl 命令尝试下。cmd

$  kubectl hello
hello, i am a kubelet plugin command

经过上面的输出咱们能够看到,这个插件命令已经成功完成了,那么剩下来就是利用你熟悉的语言来编写二进制工具来知足你的需求了。kubernetes

发现插件

Kubectl 提供了一个 plugin 的命令,该命令可使用子命令 list 来列举当前系统中的插件命令。具体的搜索方法以下:io

(1) 搜索系统的 $PATH 中指定的全部的目录,查找全部以 kubectl- 开头的文件;
(2) 若是搜索到的匹配以 kubectl- 开头的文件是可执行文件,那么会按照顺序做为插件命令输出;若是不是可执行文件,也会输出,可是同时会输出一个 Warning 的信息;编译

当前限制

虽然咱们能够自定义插件命令,可是有个限制就是你没法定义一个 kubectl 已经存在的命令去试图覆盖原命令的行为。例如 kubectl-version 这样的命令永远不会被执行,由于 kubectl 会优先执行内置的 version 命令。基于这样的缘由,你也没法给已有的命令增长额外的子命令。

使用插件

插件命令不须要安装,也不须要预加载任何东西。它继承 kubectl 命令的执行环境。kubectl 经过插件命令的名称来执行它。例如对于上面的名为 kubectl-hello 的命令,kubectl 就经过 $ kubectl hello 来执行它。

对于插件命令来说,它接收到的第一个参数老是它文件所在的全路径。对于上面的 kubectl-hello 命令,咱们稍做修改,用来打印全部的参数。

#include <stdio.h>
int
main(int argc, char *argv[])
{
    int        i = 0;
    printf("hello, i am a kubelet plugin command\n");
    printf("\n");
    for (; i < argc; i++) {
        printf("%s\n", argv[i]);
    }
}

输出以下:

$ kubectl hello kubernetes
hello, i am a kubelet plugin command

/Users/jemy/Bin/k8s-plugins/kubectl-hello
kubernetes

插件命名

对于插件的命令,必须了解的两点以下:

(1) 插件命令支持子命令,其格式必须为 kubectl-cmd-cmd1-cmd11 ,也就是每一个命令经过 - 分隔。这样在调用的时候可使用 $ kubectl cmd cmd1 cmd11 这样的方式来调用。
(2) 若是要在插件命令中使用多个单词构成一个命令,那么多个单词必须用 _ 进行分隔,例如对于 kubectl-hello_world 命令,能够经过 $ kubectl hello_world 这样的方式来调用。
(3) 插件命令必须自行解析全部传给该命令的选项参数,并进行相应的处理。

插件管理

鉴于 kubernetes 自己并无提供插件命令的包管理器用来安装和更新插件命令,咱们可使用 Kubernetes-sigs 项目中的 krew 来完成相关工做。

参考文档:https://kubernetes.io/docs/tasks/extend-kubectl/kubectl-plugins/

相关文章
相关标签/搜索