使用外掛擴充套件 kubectl
本指南演示瞭如何為 kubectl 安裝和編寫擴充套件。透過將核心 kubectl
命令視為與 Kubernetes 叢集互動的基本構建塊,叢集管理員可以將外掛視為利用這些構建塊建立更復雜行為的手段。外掛透過新的子命令擴充套件 kubectl
,從而允許在 kubectl
主發行版中不包含新的自定義功能。
準備工作
你需要安裝一個可用的 kubectl
二進位制檔案。
安裝 kubectl 外掛
外掛是一個獨立的可執行檔案,其名稱以 kubectl-
開頭。要安裝外掛,將其可執行檔案移動到 PATH
中的任何位置。
你還可以使用 Krew 發現和安裝開源中可用的 kubectl 外掛。Krew 是由 Kubernetes SIG CLI 社群維護的外掛管理器。
注意
透過 Krew 外掛索引 可用的 Kubectl 外掛未經安全審計。你應該自行承擔安裝和執行第三方外掛的風險,因為它們是在你的機器上執行的任意程式。發現外掛
kubectl
提供了一個命令 kubectl plugin list
,該命令會在你的 PATH
中搜索有效的外掛可執行檔案。執行此命令會導致遍歷 PATH
中的所有檔案。任何可執行檔案且以 kubectl-
開頭的檔案都會在命令輸出中**按其在 `PATH` 中出現的順序**顯示。對於任何以 kubectl-
開頭但**不可執行**的檔案,將包含警告。對於任何名稱重疊的有效外掛檔案,也將包含警告。
你可以使用 Krew 從社群維護的外掛索引發現和安裝 kubectl
外掛。
建立外掛
kubectl
允許外掛透過在 PATH
中提供 kubectl-create-something
二進位制檔案來新增形如 kubectl create something
的自定義建立命令。
限制
目前無法建立覆蓋現有 kubectl
命令或擴充套件除 create
之外的命令的外掛。例如,建立外掛 kubectl-version
將導致該外掛永遠不會被執行,因為現有的 kubectl version
命令將始終優先於它。由於此限制,也**無法**使用外掛向現有 kubectl
命令新增新的子命令。例如,透過將外掛命名為 kubectl-attach-vm
來新增子命令 kubectl attach vm
將導致該外掛被忽略。
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 外掛機制提供了諸如 KUBECTL_PLUGINS_CURRENT_NAMESPACE
這樣的環境變數;現在不再這樣了。
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-bar
和 kubectl-foo-bar-baz
,kubectl
外掛機制將始終為給定的使用者命令選擇最長的外掛名稱。下面的一些示例進一步闡明瞭這一點
# 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 Runtime 倉庫中提供的工具的示例用法,請參閱示例 CLI 外掛。
分發 kubectl 外掛
如果你已經開發了一個供他人使用的外掛,你應該考慮如何打包、分發它以及向用戶提供更新。
Krew
Krew 提供了一種跨平臺的打包和分發外掛的方式。透過這種方式,你可以為所有目標平臺(Linux、Windows、macOS 等)使用單一的打包格式,並向用戶提供更新。Krew 還維護一個外掛索引,以便其他人可以發現並安裝你的外掛。
原生/平臺特定的包管理
或者,你也可以使用傳統的包管理器,例如 Linux 上的 apt
或 yum
,Windows 上的 Chocolatey,以及 macOS 上的 Homebrew。任何包管理器都適用,只要它能將新的可執行檔案放置在使用者的 PATH
中的某個位置。作為外掛作者,如果選擇此選項,你還需要承擔每個版本在多個平臺上更新 kubectl 外掛分發包的負擔。
原始碼
你可以釋出原始碼;例如,作為 Git 倉庫。如果你選擇此選項,想要使用該外掛的人必須獲取程式碼,設定構建環境(如果需要編譯),然後部署外掛。如果你還提供已編譯的包,或者使用 Krew,那將使安裝更容易。
下一步
- 檢視示例 CLI 外掛倉庫,瞭解用 Go 編寫的外掛的詳細示例。如有任何問題,請隨時聯絡 SIG CLI 團隊。
- 閱讀關於 Krew,一個 kubectl 外掛的包管理器。