tkuchikiの日記

新ブログ https://blog.tkuchiki.net

Mackerel のホスト名を ssh の補完候補リストに出力する

この記事は、Mackerel Advent Calendar 2015 8日目の記事です。

Mackerel に登録しているホストに ssh するとき、
補完できたら楽かもしれないと思い、その実現方法を模索してみました。
補完機能を一から書くのは大変なので、
bash-completion を使います。
動作環境は Linux です。

※紹介する方法は、ローカルマシンからの ssh で補完する方法ではなく、
リモートマシンからリモートマシンへ ssh する際に補完する方法です。

bash-completion

bash-completion は、bash の補完機能を拡張するものです。
細かく説明されている記事がいくつもあると思いますので説明は省きます。
以下のようにインストールできます。

yum

yum install -y epel-release
yum install -y --enablerepo=epel bash-completion

apt-get

apt-get install -y bash-completion

補完

consul membersの結果でbash補完する - Qiita を参考に、
_known_hosts_real() を上書きして補完できるようにします。
consul の場合は DNS の機能があるので、
dnsmasq などと組み合わせることで、ホスト名で名前解決できます。
そのため、consul members でホスト名一覧を取ることができれば、
ssh に使うことができます。
しかし、今回のケースでは、ホストの一覧を取るだけでは、
ssh することができません。
bash-completion の補完は、
/etc/hosts, ~/.ssh/config, ~/.ssh/known_hosts を使うようですので、
/etc/hosts, ~/.ssh/config に自動で設定を追加することで、
補完できるようにする方法を考えます。
Mackerel の /api/v0/hosts.json を parse するのに jq を使いますので、
yum, apt-get もしくは source build してインストールしてください。

/etc/hosts を使う

_known_hosts_real() を使うと書いておきながら、
/etc/hosts に設定を追加する場合、
root 以外は書き込めないので使えなさそうです。
仕方がないので cron で定期的に更新します。
以下のようなスクリプトになりました。

ssh で入れるホストには mackerel-agent が入っていると思いますので、
mackerel-agent.conf から apikey を取得して使っています。
curlhttps に対して Request を送ると dentry_cache が肥大化してしまうので、
export NSS_SDB_USE_CACHE=yes することをおすすめします。
cron の場合、普通に使えば毎分より短い間隔では実行できないので、
Mackerel のサーバへの負荷もそれほど高くないと思いますが、
台数に応じて実行間隔をばらつかせる、実行間隔を伸ばすなどしましょう。

実行例

Mackerel に、

  • server01 192.168.1.100
  • server02 192.168.1.110
  • server03 192.168.1.120
  • server04 192.168.1.130

というホストが登録されていると仮定します。

$ ssh s[Tab]
$ ssh server0[Tab]
server01  server02    server03  server04

といった具合に補完されます。

/etc/hosts には以下のように設定が追記されます。

192.168.1.100 server01 # mackerel
192.168.1.110 server02 # mackerel
192.168.1.120 server03 # mackerel
192.168.1.130 server04 # mackerel

# mackerel を検索して追記に利用していますので、
事前に /etc/hosts に色々な設定が書いてあっても、
影響することはありません。
また、追記する前に古い設定を削除していますので、
同じような設定が無限に追記されていくことはありません。

~/.ssh/config を使う

/etc/hosts の場合、root 以外は書き込めないので
_known_hosts_real() を使えませんでしたが、
~/.ssh/config であれば、自分の権限で書き込むことができます。
/etc/bash_completion_known_hosts_real() を、
以下のコードで上書きすると ~/.ssh/config に動的に設定を追加することができます。

ファイルの更新間隔をチェックして、
interval で設定した秒数経過するまで api を叩かないようにしています。
こちらも同時に使用するユーザ数に応じてばらつかせたり、
間隔を伸ばしたりしましょう。

実行例

補完のされ方は /etc/hosts のときと同じです。

~/.ssh/config には以下のように追記されます。

Host server01 # mackerel
Hostname 192.168.1.100
Host server02 # mackerel
Hostname 192.168.1.110
Host server03 # mackerel
Hostname 192.168.1.120
Host server04 # mackerel
Hostname 192.168.1.130

こちらも # mackerel を検索して追記に利用していますので、
~/.ssh/config に色々設定していた場合でも影響はありませんし、
設定が無限に追記されていくこともありません。

まとめ

ssh する際に Mackerel のホストを補完する方法を紹介しました。
かなり無理やりな方法ですので、もっと良い方法をご存知でしたら教えて下さい...
また、ローカルホストから ssh するときにも使えれば良いと思ったのですが、
複数オーガニゼーションで運用している場合、
apikey の切り替えが難しそうでしたので諦めてしまいました。

9日目の担当は、@norisu0313 さんの、
http://qiita.com/norisu0313/items/8e66f6b6adae60279d5f です!