こんにちは、@ueokandeです。 この記事はKubernetes Advent Calendar 2021の 8 日目の記事です。
Pod 内のアプリケーションをトラブルシュートするとき皆さんどうしていますか? 本日は Kubernetes Pod 内にあるディレクトリを、ローカルファイルシステムにマウントする kubectl プラグインを作ったお話をします。
kubectl-mount プラグイン
Pod 内のアプリケーションをトラブルシュートするとき皆さんどうしていますか?
設定ファイルを参照したりログを閲覧したいときは、 kubectl exec
で Pod 内のシェルを立ち上げることがありますよね。
しかし Kubernetes Pod にはエディタやページャーなどの高級なツールはないので、 cat
や tail
などでファイルの中身を見ることになるかと思います。
kubectl-mount
は Pod のファイルシステムをローカルディレクトリにマウントする kubectl プラグインです。
sshfsのように、Pod 内のディレクトリやファイルを、あたかもローカルのコマンドからアクセスできます。 たとえばログファイルを閲覧するためにページャーを使ったり、設定ファイルをエディタで開いてシンタックスハイライトを有効にして閲覧できます。
プラグインは go install
でインストールできます。
$ go install github.com/ueokande/kubectl-mount@latest
使い方
プラグインのインストール後は、 kubectl mount
サブコマンドでマウントできるようになります。
たとえば nginx
Pod のログディレクトリをマウントするには以下のように実行します。
$ mkdir -p /tmp/nginx-logs
$ kubectl mount nginx:/var/log /tmp/nginx-logs
/tmp/nginx-logs
以下に Pod 内の /var/log
以下がマウントされます。
NGINX のアクセスログは以下のコマンドから閲覧できます。
$ less /tmp/nginx-logs/nginx/access.log
しくみ
kubectl-mount
は、FUSE (Filesystem in Userspace) という Linux カーネルの機能を使っています。
FUSE はファイルシステムのインターフェイスであり、このインターフェイスを実装するプログラムを記述することでファイルシステムを実装できます。
物理デバイスやネットワークストレージはもちろんのこと、プログラムを書いて任意のファイルシステムを実装できるので、リモートホストのファイルシステムや、/proc のような論理的なファイルシステムも実装できます。
sshfs も FUSE の機能を使った実装の 1 つです。
go-fuseは Go で FUSE の実装ができるライブラリで、 kubectl-mount
もこのライブラリを使っています。
また go-fuse は macOS 上で FUSE の機能を使える OSXFUSE もサポートしています。
kubectl-mount
は Pod 内のファイルを取得、閲覧するために、Kubernetes exec
API を実行します。
ファイル一覧を取得するときには、Pod 上で ls
コマンドを実行して、その出力結果が FUSE に返します。
同じようにファイル作成日や更新日などの情報を得るには、 Pod 内で stat
コマンドを実行して、その出力結果をパースして FUSE に返します。
制約
Read-only ファイルシステム
Pod 上のファイルの作成や更新はできません。
Kubernetes exec
API と FUSE 経由でファイルの更新もできそうですが、安全な書き込み方法が確立できてないので現在はまだ未サポートです。
Pod 内のファイルを保護するために、 kubectl-mount
は Read-only ファイルシステムとしてマウントされます。
Linux ディストリビューションの要件
kubectl mount
は Pod 内で以下のコマンドを実行します。
find
またはls
stat
cat
つまり scratch コンテナなどこれらのユーティリティがない Pod 内のフィルシステムはマウントできません。