こんにちは。松浦です。
この記事は TECHSCORE Advent Calendar 2018 の9日目の記事です。
2018年の技術トレンドとして、 Kubernetes が大きな盛り上がりを見せたことについて異論はないかと思います。
TECHSCORE を運営する SynergyMarketing でも、 Kubernetes の運用を進めており、いくつかのアプリケーションがその上で動き出しています。
Kubernetes 上で動くアプリケーションを開発・運用する際には、kubectl をしばしば使うことになります。
kubectl には様々なサブコマンドが用意されていますが、場合によってはかゆいところに手が届かないことがあるかもしれません。
そのような時のためにも、kubectl には機能拡張を行うプラグイン機構が用意されています。
今回は、そのプラグイン機構を試してみることにします。
前提
プラグイン機構自体は kubectl 1.8 より alpha 版の機能として公式に導入されました。
しかし kubectl 1.12 にて、それまでのプラグイン機構が廃止され、新たなプラグイン機構が提供されることとなりました。
(kubectl 1.12 で alpha として取り入れられ、1.13 で beta となっています。)
以下の内容は、新しいプラグイン機構についてのものとなります。
なお、以下では kubectl 1.13.0 を用いています。 kubectl のバージョンアップにより挙動が変わる可能性がありますのでご注意ください。
kubectl plugin を試してみる
単純なプラグインを作ってみる
では、まずは単純なプラグインを作ってみて、どのように動くのか確認してみます。
kubectl のプラグイン機構では、 PATH 上の kubectl-
で始まる実行可能なファイルをプラグインとして認識するようになっています。
例えば kubectl-hello-world というファイルが PATH 上にある場合は、 kubectl hello world
が実行可能になります。
ということで、試してみましょう。
下記のような単純なシェルスクリプトを kubectl-hello-world という名前で作成します。
1 2 |
#!/bin/bash echo 'Hello, world!' |
このファイルに実行権限を付与し、PATH 上に移動させます。
使用可能なプラグインの一覧は kubectl plugin list
で確認できるので、実行してみます。
1 2 3 4 5 6 7 8 9 |
$ sudo chmod +x ./kubectl-hello-world && sudo mv ./kubectl-hello-world /usr/local/bin $ kubectl plugin list The following kubectl-compatible plugins are available: /usr/local/bin/kubectl-hello-world $ kubectl hello world Hello, world! |
kubectl-hello-world が検出され、 kubectl hello world
を使えるようになっていることが確認できました。
より複雑なことを試してみる
上記では、ごくごく単純なプラグインを作って、その動きを確認しました。
以下では、もう少し複雑なことを試しつつ、プラグイン機構の詳細な仕様も確認していきます。
kubectl hello-world を実行する
上記の例で見たように、 kubectl のプラグイン機構では、ダッシュ(-)を区切り文字としてサブコマンドが追加されます。
ただ、kubectl-
以降はダッシュの代わりにアンダースコア(_)で使用することもでき、その場合は呼び出し方が少し変わります。
例えば、 kubectl-hello_world というファイルを PATH 上に置くと、kubectl hello-world
が実行可能になります。
(kubectl hello_world
というコマンドも実行可能です)
1 2 3 4 5 6 7 |
$ sudo mv /usr/local/bin/kubectl-hello-world /usr/local/bin/kubectl-hello_world $ kubectl hello-world Hello, world! $ kubectl hello_world Hello, world! |
ダッシュでつながったサブコマンドを作りたい場合は、これを利用するとよいでしょう。
kubectl hello world version を実行する
より実用的なプラグインにする上では、引数やフラグを受け取って処理することも必要となると思います。
そこで、引数などがどのように渡ってくるかを試してみましょう。
上記で作成した kubectl-hello-world を修正して、 version という文字列が渡された場合に挙動が変わるようにします。
1 2 3 4 5 6 7 8 9 |
#!/bin/bash if [[ "$1" == "version" ]] then echo "1.0.0" exit 0 fi echo 'Hello, world!' |
この状態で kubectl hello world version
を実行してみると、 1.0.0 と出力されます。
1 2 |
$ kubectl hello world version 1.0.0 |
このように、プラグイン機構によって追加されたコマンド以降に設定されている文字列については、そのまま渡されるようになっています。
ところで、下記のようなシェルスクリプトを kubectl-hello-world-version というファイル名で作成してみます。
1 2 |
#!/bin/bash echo 'I am kubectl-hello-world-version.' |
このファイルに実行権限を与えて PATH 上に置いた上で kubectl hello world version
を実行してみると、以下のような出力が得られます。
1 2 3 4 |
$ sudo chmod +x ./kubectl-hello-world-version && sudo mv ./kubectl-hello-world-version /usr/local/bin $ kubectl hello world version I am kubectl-hello-world-version. |
kubectl のプラグイン機構では、実行されたコマンドの要素を可能な限りダッシュで結合した名前のファイルから探索を行い、マッチするものがなかった場合は、一番後ろの要素を省いたものを探索するようになっています。
(例えば kubectl foo bar baz --flag=val qux
を実行した場合は、 kubectl-foo-bar-baz から探索を行い、マッチするファイルがない場合は kubectl-foo-bar の探索を行います)
上記のケースでは kubectl-hello-world-version が先にマッチするため、そちらが実行されることとなりました。
このようなケースでは、常に一方しか実行されないようになってしまうので注意が必要です。
kubectl create hello world は実行できない
現行の kubectl のプラグイン機構では、既存の kubectl のサブコマンドを上書きすることはできません。
(この制限のために、既存のサブコマンドに機能を追加することもできません)
そのため、 PATH 上に kubectl-version や kubectl-create-hello-world といったファイルが存在したとしても、実行されません。
ちなみに、そのようなファイルが存在する場合、 kubectl plugin list
を実行すると、警告が出るようになっています。
1 2 3 4 5 6 7 8 9 |
$ sudo mv /usr/local/bin/kubectl-hello-world /usr/local/bin/kubectl-create-hello-world $ kubectl plugin list The following kubectl-compatible plugins are available: /usr/local/bin/kubectl-create-hello-world - warning: kubectl-create-hello-world overwrites existing command: "kubectl create" error: one plugin warning was found |
あとがき
ということで、kubectl のプラグイン機構を一通り試してみました。
新たなプラグイン機構はシンプルな構造をしているので、手を出しやすいと思います。
追加したい機能がある場合は試してみてはいかがでしょうか。