多分すごく限られた層にだけ響くツール「kube-etcd-helper」を作りました。
kube-etcd-helper
は、kube-apiserverが利用しているetcdに直接アクセスし、
データのダンプや変更の検知を行うためのツールです。
kubernetesの全体のデータの動きを知りたい方や、kubernetesを開発プラットフォームとして利用するインフラエンジニアの方などは便利にお使いいただけると思います。
Kubernetesオブジェクトの中身を見るには
Kubernetesオブジェクトとは、Kubernetesのクラスタの状態を表す永続化されるエンティティのことです。
podとかserviceとかdeploymentなどですね。
これらは通常kube-apiserverによって公開されるAPIを通じて操作します。
kube-apiserverの背後ではetcdが動いており、エンティティの永続化に使われています。
手っ取り早くKubernetesオブジェクトの中身を確認するにはkubectl get
コマンドを利用するのが楽です。
例えばpodオブジェクトの中身を見るには以下のようなコマンドを実行します。
$ kubectl get pod <pod名>
NAME READY STATUS RESTARTS AGE
hello-world-55c844bc5b-544h6 1/1 Running 0 3d
より詳細に見るには-o yaml
や-o json
といったオプションをつければOKです。
よく使うコマンドですので馴染みのある方も多いですよね。
さらに、--watch
というオプションをつけることで、指定オブジェクトの変更を追い続けることも可能です。
# --watchオプションをつけると、オブジェクトの変更を検知できる
$ kubectl get pod <pod名> --watch
NAME READY STATUS RESTARTS AGE
hello-world-55c844bc5b-544h6 1/1 Running 0 3d
また、kube-apiserverが提供するREST APIを直接利用する方法でもオブジェクトの内容を確認できます。
# kubectl proxyを併用する場合
$ kube proxy --port=8080 &
$ curl http://localhost:8080/api/v1/namespaces/<ネームスペース>/pods/<pod名>
{
"kind": "Pod",
"apiVersion": "v1",
"metadata": {
"name": "<pod名>",
# 以下略
}
}
これらの方法以外にも、etcdctl
などのetcdクライアントツールで直接データの中身を覗く方法も取れそうなのですがこの方法には問題があります。
というのも、kubernetes 1.6以降はetcd v3がデフォルトとなりバイナリーフォーマット(protobuf)でシリアライズされたデータが格納されているため、
コマンドラインから覗いても(一部を除き)読めないデータとなっているからです。
ということで多くのケースではkubectl
またはREST APIを利用することになると思います。
問題となるケース
通常はkubectl
またはREST APIを利用すれば事足りると思いますが、いくつか面倒なケースというのもあります。
kubectl run
などの複数のオブジェクトにまたがる操作を追いたい場合- オブジェクトの変更履歴を比較し、どこが変わったのか確認したい場合
例えばkubectl run
を実行すると、Deployment/ReplicaSet/Podが作成されます。
これらの動きを追いたい場合--watch
オプションを利用することになるのですが、
現在はkubectl get all
に対しての--watch
オプションは残念ながらサポートされていないためそれぞれに対し個別にkubectl get --watch
しないといけません。
また、--watch
で変更履歴を追えますが、変更されるごとに個別のファイルに出力といったことはできないためどこが変わったのか比較するのがなかなかに面倒な作業です。
これらの問題を解決するためにkube-etcd-helper
を作りました。
kube-etcd-helperは何をするの?
kube-etcd-helper
は、kube-apiserverが利用しているetcdに直接アクセスしデータのダンプや変更の検知を行うためのツールです。
前述の通りkubectl
やREST APIからではネームスペース/オブジェクトを跨いだ全オブジェクトを追うのはなかなか手間ですが、kube-etcd-helper
を利用すれば簡単にできちゃいます。
kube-etcd-helperのインストール
kube-etcd-helper
はGoで書いているため、インストールは実行ファイルをダウンロードして実行権を付与するだけでOKです。
以下のGitHubリリースページからダウンロードしてください。
あとはetcdに接続できる環境で実行するだけです。
master上で直接kube-etcd-helper
を実行できる場合は問題ないですが、Docker for Macなどの直接etcdと通信できない環境の場合は
事前に以下のようにポートフォワードしておきます。
kubectl port-forward etcd-docker-for-desktop 2379:2379 --namespace=kube-system
なおデフォルトではlocalhost:2379
に対して通信しようとしますがオプションで変更も可能です。
同じく証明書の指定などもオプション指定可能です。
kube-etcd-helperの使い方
ダンプ
etcd内でのキー階層をそのままディレクトリ/ファイルにダンプが可能です。
# etcdのデータをoutディレクトリにダンプ
$ kube-etcd-helper dump -o out/ --pretty
変更の追跡(watch)
kubectl
の--watch
オプションと同じく、変更を検知するためのwatch
サブコマンドを用意しています。
これを利用すれば、全ネームスペースの全オブジェクトの動きを追うことが可能です。
# etcdのデータの変更を検知して標準出力に書き出し
$ kube-etcd-helper watch --pretty
watch
サブコマンドはディレクトリ/ファイルへの出力に対応しているため、diffコマンドなどを併用することでどこが変わったのかを追うことも容易です。
# ディレクトリ/ファイルへの出力
$ kube-etcd-helper watch -o out/ --pretty
この例はkubectl run
でhello-world
というdeploymentを作成した時の動きをwatch
サブコマンドで記録したところです。
deployment/replicaset/podそれぞれの配下にJSON形式で変更内容を保存しています。
diffコマンドなどを併用するとオブジェクトのどの値が変更されたのか確認できます。
この図はPodの作成〜schedulerがスケジューリングする部分ですね。Podのステータスがどう変わったのか一目瞭然です。
また、ファイル名はetcdのリビジョン番号を利用していますので、ファイル名順に並べればkubernetesがどの順番でetcdに対して操作を行なっているのか追うことも可能ですね。
その他のコマンド
その他にはlist
とget
サブコマンドがあります。
list
はetcdのキーのみを一覧表示します。get
は指定キーの内容を表示してくれます。
他にもいくつかオプションがありますので、詳細は--help
を参照してください。
終わりに
ということでkube-etcd-helper
の紹介でした。
カスタムのコントローラーを書く方やkubernetesの内部構造をもっと知りたいという方には便利だと思いますのでぜひご利用ください!!
以上です。