Kubernetes 1.12 新的外掛機制
Kubernetes 1.12 新的外掛機制
在很久以前的版本研究過 kubernetes 的外掛機制,當時弄了一個快速切換namespace
的小外掛;最近把自己本機的 kubectl 升級到了 1.12,突然發現外掛不能用了;擼了一下文件發現外掛機制徹底改了…
一、外掛編寫語言
kubernetes 1.12 新的外掛機制在編寫語言上同以前一樣,可以以任意語言編寫,只要能弄一個可執行的檔案出來就行
,外掛可以是一個bash
、python
指令碼,也可以是Go
等編譯語言最終編譯的二進位制;以下是一個 Copy 自官方文件的bash
編寫的外掛樣例
#!/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"
二、外掛載入方式
2.1、外掛位置
1.12 kubectl 外掛最大的變化就是載入方式變了,由原來的放置在指定位置,還要為其編寫 yaml 配置變成了現在的類似 git 擴充套件命令的方式:
只要放置在 PATH 下,並以kubectl-
開頭的可執行檔案都被認為是kubectl
的外掛
;所以你可以隨便弄個小指令碼(比如上面的程式碼),然後改好名字賦予可執行許可權,扔到 PATH 下即可
2.2、外掛變數
同以前不通,
以前版本的執行外掛時,kubectl
會向外掛傳遞一些特定的與kubectl
相關的變數,現在則只會傳遞標準變數;即kubectl
能讀到什麼變數,外掛就能讀到,其他的私有化變數(比如KUBECTL_PLUGINS_CURRENT_NAMESPACE
)不會再提供
並且新版本的外掛體系,所有選項(flag
) 將全部交由外掛本身處理,kubectl 不會再解析,比如下面的--help
交給了自定義外掛處理,由於指令碼內沒有處理這個選項,所以相當於選項無效了
還有就是
傳遞給外掛的第一個引數永遠是外掛自己的絕對位置,比如這個test
外掛在執行時的$0
是/usr/local/bin/kubectl-test
2.3、外掛命名及查詢
目前在外掛命名及查詢順序上官方文件寫的非常詳盡,不給過對於普通使用者來說,實際上命名規則和查詢與常規的 Linux 下的命令查詢機制相同,只不過還做了增強;增強後的基本規則如下
PATH -
PATH
優先匹配原則跟傳統的命令查詢一致,即當多個路徑下存在同名的外掛時,則採用最先查詢到的外掛
當你的外掛檔名中包含-
,並且kubectl
在無法精確找到外掛時會嘗試自動拼接命令來嘗試匹配;如下所示,在沒有找到kubectl-test
這個命令時會嘗試拼接引數查詢
由於以上這種查詢機制,
當命令中確實包含-
時,必須進行轉義以_
替換,否則kubectl
會提示命令未找到錯誤
;替換後可直接使用kubectl 外掛命令(包含-)
執行,同時也支援以原始外掛名稱執行(使用_
)
在複雜外掛體系下,多個外掛可能包含同樣的字首,此時將遵序最精確查詢原則;即當兩個外掛kubectl-test-aaa
、kubectl-test-aaa-bbb
同時存在,並且執行kubectl test aaa bbb
命令時,優先匹配最精確的外掛kubectl-test-aaa-bbb
,
而不是將bbb
作為引數傳遞給kubectl-test-aaa
外掛
2.4、總結
外掛查詢機制在一般情況下與傳統 PATH 查詢方式相同,同時kubectl
實現了智慧的-
自動匹配查詢、更精確的命令命中功能;這兩種機制的實現主要為了方便編寫外掛的命令樹(外掛命令的子命令…),類似下面這種
$ ls ./plugin_command_tree kubectl-parent kubectl-parent-subcommand kubectl-parent-subcommand-subsubcommand
當出現多個位置有同名外掛時,執行kubectl plugin list
能夠檢測出哪些外掛由於 PATH 查詢順序原因導致永遠不會被執行問題
$ 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
三、Golang 的外掛輔助庫
由於外掛機制的變更,導致其他語言編寫的外掛在實時獲取某些配置資訊、動態修改kubectl
配置方面可能造成一定的阻礙;為此 kubernetes 提供了一個ofollow,noindex" target="_blank">command line runtime package
,使用 Go 編寫外掛,配合這個庫可以更加方便的解析和調整kubectl
的配置資訊
官方為了演示如何使用這個cli-runtime
庫編寫了一個namespace
切換的外掛(自己白寫了…),倉庫地址在Github
上,基本編譯使用如下(直接go get
後編譯檔案預設為目錄名cmd
)
➜~ go get k8s.io/sample-cli-plugin/cmd ➜~ sudo mv gopath/bin/cmd /usr/local/bin/kubectl-ns ➜~ kubectl ns default ➜~ kubectl ns --help View or set the current namespace Usage: ns [new-namespace] [flags] Examples: # view the current namespace in your KUBECONFIG kubectl ns # view all of the namespaces in use by contexts in your KUBECONFIG kubectl ns --list # switch your current-context to one that contains the desired namespace kubectl ns foo Flags: --as stringUsername to impersonate for the operation --as-group stringArrayGroup to impersonate for the operation, this flag can be repeated to specify multiple groups. --cache-dir stringDefault HTTP cache directory (default "/Users/mritd/.kube/http-cache") --certificate-authority stringPath to a cert file for the certificate authority --client-certificate stringPath to a client certificate file for TLS --client-key stringPath to a client key file for TLS --cluster stringThe name of the kubeconfig cluster to use --context stringThe name of the kubeconfig context to use -h, --helphelp for ns --insecure-skip-tls-verifyIf true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure --kubeconfig stringPath to the kubeconfig file to use for CLI requests. --listif true, print the list of all namespaces in the current KUBECONFIG -n, --namespace stringIf present, the namespace scope for this CLI request --request-timeout stringThe length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") -s, --server stringThe address and port of the Kubernetes API server --token stringBearer token for authentication to the API server --user stringThe name of the kubeconfig user to use
限於篇幅原因,具體這個cli-runtime
包怎麼用請自行參考官方寫的這個sample-cli-plugin
(其實並不怎麼 “simple”…)
本文參考文件:
轉載請註明出處,本文采用CC4.0 協議授權