複数Podでコマンドを実行できるツールを作った

Kubernetes の複数コンテナ上で、並列のコマンドを実行できるツール bow を作りました。 英語で bow は船首を意味します。

スクリーンショット

なぜ作ったの?

kubectl exec コマンドは、Kubernetes 上のアプリケーションのデバッグや、障害調査に役立てることができます。 しかし水平スケールが柔軟にできる Kubernetes では、特定のコンテナでコマンドを実行するというのはあまり適切ではありません。 規模によってはコンテナの数が数個から数十個になることもあります。 そういった環境でコンテナ 1 つずつkubectl execするのは大変だというのが容易に想像ができるでしょう。

また別のケースを考えてみます。 Kubernetes 上のアプリケーションは、標準出力 (STDOUT) に出したログは Kubernetes の仕組みを使って閲覧できます。 しかし時折、標準出力以外にログを出したい場合もあります。 そういったログを閲覧するには、kubectl logsコマンドではなく、kubectl execなどでログインして、cattail -Fで閲覧します。 この方法も、数十個のコンテナが実行している環境ではもはや通用しません。

そこで複数の Pod 上でコマンドを実行できるツールを作りました。 このコマンドのアイディアは、複数 Pod でログを閲覧できるsternから得ました。 Stern と同じような操作でkubectl execを実行できるツールを作りました。

使い方

Go のツールなので、go getでインストールできます。

$ go get -u github.com/ueokande/bow

Stern と同じように、第 1 引数に対象 Pod を指定します。

$ bow [OPTIONS] POD_SELECTOR -- COMMAND ARG...
Flags:
  -c, --container string    Container name when multiple containers in pod
  -h, --help                help for bow
      --kubeconfig string   Path to kubeconfig file to use
  -n, --namespace string    Kubernetes namespace to use.
      --no-hosts            Do not print hosts

例えば frontend にマッチする Pod(名前に含むか、ラベルの値に持つか)に対して、hostnameコマンドを実行するのは以下のとおりです。

$ bow frontend hostname
frontend-74bdf9b58d-542b9 sidecar| frontend-74bdf9b58d-542b9
frontend-74bdf9b58d-bgsmk sidecar| frontend-74bdf9b58d-bgsmk
frontend-74bdf9b58d-mkf2d php-redis| frontend-74bdf9b58d-mkf2d
frontend-74bdf9b58d-bgsmk php-redis| frontend-74bdf9b58d-bgsmk
frontend-74bdf9b58d-mkf2d sidecar| frontend-74bdf9b58d-mkf2d
frontend-74bdf9b58d-542b9 php-redis| frontend-74bdf9b58d-542b9

コンテナを指定しないと全てのコンテナで実行します。 実行するコンテナを明示的に指定するには-cオプションを使います。

$ bow frontend -c php-redis hostname
frontend-74bdf9b58d-bgsmk php-redis| frontend-74bdf9b58d-bgsmk
frontend-74bdf9b58d-542b9 php-redis| frontend-74bdf9b58d-542b9
frontend-74bdf9b58d-mkf2d php-redis| frontend-74bdf9b58d-mkf2d

ファイルのログをtail -Fするには以下のとおりです。 bowではなく実行するコマンドにオプションを渡すために、コマンドの直前に--を付けます。

$ bow frontend -c php-redis -- tail -F /var/log/apache2/access.log

まとめ

logbookに引き続き、Kubernetes 周辺ツールを作ってみました。 今回実装で一番苦労した点は、kubectl exec相当の API を Go から利用する点でした(詳しくは後日また改めて書きます)。 そこは公式のkubectlのソースコードを参考にしました。

業務で利用する Kubernetes クラスタがどんどん大きくなるにつれ、標準のkubectlではカバーできない事が多くなってきました。 Kubernetes API 自体も簡単なので、繰り返して入力してるコマンドや面倒と思ったことは、どんどんツール化してみようと思います。


Profile picture

Shin'ya Ueoka

B2B向けSaaSを提供する会社の、元Webエンジニア。今はエンジニアリング組織のマネジメントをしている。