serverspecでconfigファイルを複数行まとめてテストする
configファイルの記述の正当性をserverspecでテストするときは、ヒアドキュメントを使うといいかも、という話です。
configファイルを普通にテストする
serverspecで、configファイルの記述をテストするとき、普通はits(:content)
matcherを使います。
describe file('/etc/httpd/conf/httpd.conf') do its(:content) { should match /ServerName www.example.jp/ } end
が、configの記述が1行では意味をなさず、複数行にわたって「ブロック」として記載されていたとき、昔はits(:content)
matcherをひたすら繋げて書いていました。
describe file('/etc/td-agent/td-agent.conf') do its(:content) { should match %r{^[[:blank:]]*<source>} } its(:content) { should match %r{^[[:blank:]]*type monitor_agent} } its(:content) { should match %r{^[[:blank:]]*bind 0.0.0.0} } its(:content) { should match %r{^[[:blank:]]*port 24220} } its(:content) { should match %r{^[[:blank:]]*</source>} } end
例はtd-agent.conf
のテストです。
この記述のダメなところは、結局行単位で評価しているので、前後関係が全く意味を成さないところです。それぞれの行をconfig内のどこにどういう順番で書こうが、そのconfigが実際には無効な記述だったとしても、serverspecのテストは通ります。
素直にits(:content)
をまとめて書く
一応、最初から最後までまとめて1つのmatcherで繋げて書くことはできます。
describe file('/etc/td-agent/td-agent.conf') do its(:content) { should match %r{<source>\n type monitor_agent\n bind 0.0.0.0\n port 24220\n</source>} } end
この記述の良くないところは、仮にテストがfailedしたときに、どこが間違っているのかわかりづらいところです。
2) File "/etc/td-agent/td-agent.conf" content should match /<source>\n type monitor_agent\n bind 0.0.0.0\n port 24220\n<\/source>/ On host `localhost' Failure/Error: its(:content) { should match %r{<source>\n type monitor_agent\n bind 0.0.0.0\n port 24220\n</source>} } expected "<match debug.**>\n type stdout\n</match>\n\n<source>\n type monitor_agent\n bind 0.0.0.0\n port 24222\n</source>\n\ninclude /etc/td-agent/conf.d/*.conf\n\n" to match /<source>\n type monitor_agent\n bind 0.0.0.0\n port 24220\n<\/source>/ Diff: @@ -1,2 +1,12 @@ -/<source>\n type monitor_agent\n bind 0.0.0.0\n port 24220\n<\/source>/ +<match debug.**> + type stdout +</match> + +<source> + type monitor_agent + bind 0.0.0.0 + port 24222 +</source> + +include /etc/td-agent/conf.d/*.conf
上記はport番号を24222とわざと間違って書いているのですが、ブロック全体が誤っていると捉えられます。というか、いちいちテストコードを書くのも、わざわざ改行を¥n
で書かなければいけなかったりと面倒です。
ヒアドキュメントを使う
test-monitor_agent = <<"EOS" <source> type monitor_agent bind 0.0.0.0 port 24220 </source> EOS describe file('/etc/td-agent/td-agent.conf') do its(:content) { should match test-monitor_agent } end
もしテストがfailedしても、その部分を判別してくれます。
1) File "/etc/td-agent/td-agent.conf" content should match "<source>\n type monitor_agent\n bind 0.0.0.0\n port 24220\n</source>\n" On host `localhost' Failure/Error: its(:content) { should match test } expected "<match debug.**>\n type stdout\n</match>\n\n<source>\n type monitor_agent\n bind 0.0.0.0\n port 24222\n</source>\n\ninclude /etc/td-agent/conf.d/*.conf\n\n" to match "<source>\n type monitor_agent\n bind 0.0.0.0\n port 24220\n</source>\n" Diff: @@ -1,6 +1,12 @@ +<match debug.**> + type stdout +</match> + <source> type monitor_agent bind 0.0.0.0 - port 24220 + port 24222 </source> + +include /etc/td-agent/conf.d/*.conf
普通に書く
普通に書いても動きます。(これ昔はできなかったと思ったのですが…昔から動いてましたっけ?)
describe file('/etc/td-agent/td-agent.conf') do its(:content) { should match " <source> type monitor_agent bind 0.0.0.0 port 24220 </source>" } end
当たり前ですがテストfailed時もヒアドキュメントと同じ表示になります。
一番簡単なのはこれですが、テストコードとconfigの記載が混在するので見づらいという問題はあります。好みですが、自分ならヒアドキュメントで変数化して使うかなという印象です。
そう考えると、configファイルをどこまで厳密にチェックするかは考えものです。
そこまでやるなら、もうconfigファイルの最初から最後までまるっとspecファイルに書いてテストすればいいんじゃないかとか、そもそもそれやるならもうserverspecじゃなくて、正しいconfigとのdiff
でいいんじゃないかとか思ったりもします。configファイルのテストはある程度妥協して、あとは正しく動くのかというinfratasterの範疇になるかもしれません。
CheckInstallでruby 2.2.0のrpmパッケージを作成する
前回CentOS6にCheckInstallを導入したので、今回はCheckInstallを使ってruby-2.2.0をrpm化してみます。
以下を参考にしました。
CentOSにRubyをcheckinstallでRPMにしてインストールする。 - オープンソースこねこね
# wget http://cache.ruby-lang.org/pub/ruby/2.2/ruby-2.2.0.tar.gz # tar -zxvf ruby-2.2.0.tar.gz # cd ruby-2.2.0 # ./configure --enable-shared --prefix=/usr
注意点としては、configure
時に--enable-shared
と--prefix=/usr
を指定することです。
--enable-shared
は、指定しないとインストールの途中でライブラリが足りなくなってエラーになります。
libffi-devel
をyumでインストールすればよいという記事もありましたが、自分の環境だとそれでもエラーになります。
また、--prefix=/usr
については、指定しないとデフォルトで--prefix=/usr/local
を指定していることになり、
最終的にrpmパッケージをインストールするときに依存パッケージであるlibrubyが/usr/bin/ruby
を参照しようとしてエラーになります。
# make # cp -p ruby bin/ # checkinstall --fstrans=no
ruby
バイナリをbin/
配下にコピーしている理由は、最初のリンクの通りです。
最終的なcheckinstallコマンド実行時は、最後に余計なディレクトリをパッケージングするか確認を求められるので、
含めないようにしてください。
あとはrpmパッケージができるので、インストールするだけ。
CentOS6にcheckinstallを導入する
ruby-2.2.0のrpmを作成したかったので、checkinstallをCentOS6 (64bit)に導入しました。
CheckInstallとは
ソースコードからmake
, make install
によってインストールするソフトウェアについて、rpmなどのパッケージングを自動で行ってくれるソフトです。
これがないと、spec
ファイルを自分で書かなければならず、非常に手間がかかりますが、checkinstall
によって比較的簡単にrpmパッケージを作成することができます。
(作成できるのはrpmパッケージだけではありませんが)
導入手順
基本的に以下に従って導入しました。
CentOS 6.3 に checkinstall をインストールする - パンダのメモ帳
CentOSにcheckinstallをgitからインストールする - オープンソースこねこね
手順
基本的にrootユーザで実行しています。
必要パッケージ導入
# yum -y install git gcc make gettext rpm-build
CheckInstall導入前準備
# cd /var/tmp # git clone http://checkinstall.izto.org/checkinstall.git # cd checkinstall/ # sed -i 's:CONFDIR=$(PREFIX)/lib/checkinstall:CONFDIR=$(PREFIX):g' Makefile # sed -i 's:EXCLUDE="":EXCLUDE="/selinux":g' checkinstallrc-dist # sed -i 's:LIBDIR=$(PREFIX)/lib:LIBDIR=$(PREFIX)/lib64:g' installwatch/Makefile
CheckInstall rpmパッケージ作成
導入前に、CheckInstall自体のrpmパッケージを作成します。
# make # make install # mkdir -p /root/rpmbuild/SOURCES # checkinstall --install=no
途中でいろいろと質問がありますが、rpmを指定するくらいでほとんど気にする必要はありません。
checkinstall 1.6.3, Copyright 2010 Felipe Eduardo Sanchez Diaz Duran This software is released under the GNU GPL. The checkinstallrc file was not found at: /usr/local/lib/checkinstall/checkinstallrc Assuming default values. Please choose the packaging method you want to use. Slackware [S], RPM [R] or Debian [D]? R ************************************** **** RPM package creation selected *** ************************************** This package will be built according to these values: 1 - Summary: [ CheckInstall installations tracker, version 1.6.2 ] 2 - Name: [ checkinstall ] 3 - Version: [ 20150207 ] 4 - Release: [ 1 ] 5 - License: [ GPL ] 6 - Group: [ Applications/System ] 7 - Architecture: [ x86_64 ] 8 - Source location: [ checkinstall ] 9 - Alternate source location: [ ] 10 - Requires: [ ] 11 - Provides: [ checkinstall ] Enter a number to change any of them or press ENTER to continue: Installing with make install... ========================= Installation results =========================== 中略 Copying files to the temporary directory...OK Stripping ELF binaries...OK Compressing man pages...OK Building file list...OK Building RPM package...OK NOTE: The package will not be installed Erasing temporary files...OK Writing backup package...OK Deleting temp dir...OK ********************************************************************** Done. The new package has been saved to /root/rpmbuild/RPMS/x86_64/checkinstall-20150207-1.x86_64.rpm You can install it in your system anytime using: rpm -i checkinstall-20150207-1.x86_64.rpm **********************************************************************
CheckInstall導入
# cd /root/rpmbuild/RPMS/x86_64 # rpm -ivh checkinstall-20150207-1.x86_64.rpm Preparing... ########################################### [100%] 1:checkinstall ########################################### [100%]
インストールの確認
# rpm -qi checkinstall Name : checkinstall Relocations: (not relocatable) Version : 20150207 Vendor: (none) Release : 1 Build Date: Sat 07 Feb 2015 08:00:05 PM UTC Install Date: Sat 07 Feb 2015 08:01:58 PM UTC Build Host: localhost Group : Applications/System Source RPM: checkinstall-20150207-1.src.rpm Size : 460811 License: GPL Signature : (none) Packager : checkinstall-1.6.3 Summary : CheckInstall installations tracker, version 1.6.2 Description : CheckInstall installations tracker, version 1.6.2 CheckInstall keeps track of all the files created or modified by your installation script ("make install" "make install_modules", "setup", etc), builds a standard binary package and installs it in your system giving you the ability to uninstall it with your distribution's standard package management utilities.
インストールできました。
次回、CheckInstallでruby-2.2.0をrpm化してみます。
consulをdockerで動かすときにホストからアクセスするときのメモ
以下の方法でconsulを検証していたのですが、1個だけハマったのでメモ。
Dockerを使って軽くConsulを触ってみる - さくらのナレッジ
基本的に上記方法に従います。
構成
Mac -> CoreOS(VM) -> docker container
docker container上でconsulを起動し、それをmacからアクセスして確認しました。
設定
- Vagrantfile (途中略)
config.vm.network "forwarded_port", guest:28400, host:28400 # consul(remote rpc) config.vm.network "forwarded_port", guest:28500, host:28500 # consul web api config.vm.network "forwarded_port", guest:28600, host:28600 # consul dns
- Dockerfile (途中略)
# consul EXPOSE 8400 EXPOSE 8500 EXPOSE 8600
- 起動時
core@core-01 ~ $ docker run -itd --name="consul-agent1" --hostname="consul-agent1" -p 20022:22 -p 28400:8400 -p 28500:8500 -p 28600:8600 test core@core-01 ~ $ docker run -itd --name="consul-agent2" --hostname="consul-agent2" -p 30022:22 -p 38400:8400 -p 38500:8500 -p 38600:8600 test core@core-01 ~ $ docker run -itd --name="consul-server1" --hostname="consul-server1" -p 40022:22 test core@core-01 ~ $ docker run -itd --name="consul-server2" --hostname="consul-server2" -p 50022:22 test core@core-01 ~ $ docker exec -it consul-server1 /bin/bash [root@consul-server1 /]# consul agent -data-dir=/tmp/consul -server -bootstrap-expect 2 -client=`hostname --ip-address` & [root@consul-server1 /]# exit core@core-01 ~ $ docker exec -it consul-server2 /bin/bash [root@consul-agent1 /]# consul agent -data-dir=/tmp/consul -server -join=10.1.0.3 -client=`hostname --ip-address` & [root@consul-server2 /]# exit core@core-01 ~ $ docker exec -it consul-agent1 /bin/bash [root@consul-agent1 /]# consul agent -data-dir=/tmp/consul -join=10.1.0.3 -client=`hostname --ip-address` & [root@consul-agent1 /]# exit core@core-01 ~ $ docker exec -it consul-agent2 /bin/bash [root@consul-agent2 /]# consul agent -data-dir=/tmp/consul -join=10.1.0.3 -client=`hostname --ip-address` & [root@consul-agent2 /]# exit
ここでは、consul-server1
のIPアドレスは10.1.0.3としています。
これで、docker container上では8400,8500,8600のポートが、CoreOS(VM)上では28400,28500,28600へ変換され、さらにMac上ではPortForwardingにより28400,28500,28600へ変換されます。
接続
mac上から、以下で繋がります。
$ consul members -rpc-addr=127.0.0.1:28400 Node Address Status Type Build Protocol consul-agent1 10.1.0.2:8301 alive client 0.4.1 2 consul-server2 10.1.0.4:8301 alive server 0.4.1 2 consul-server1 10.1.0.3:8301 alive server 0.4.1 2 consul-agent2 10.1.0.5:8301 alive client 0.4.1 2 $ curl -s localhost:28500/v1/catalog/nodes | jq "." [ { "Address": "10.1.0.2", "Node": "consul-agent1" }, { "Address": "10.1.0.5", "Node": "consul-agent2" }, { "Address": "10.1.0.3", "Node": "consul-server1" }, { "Address": "10.1.0.4", "Node": "consul-server2" } ]
ハマったこと
consul agent
コマンド実行時に、-client
オプションを入れないと、localhostからのアクセスしか受け付けません。従って、mac上からipを叩いても結果を取得できません。
例えば、以下のように-client
オプションなしだと、localhost以外からconsulコマンドでアクセスしてもエラーになります。
[root@consul-agent1 /]# consul agent -data-dir=/tmp/consul -join=10.1.0.3 &
普通に、consul agent
コマンドのオプションに書いてあるんですけどね…
-client=127.0.0.1 Sets the address to bind for client access. This includes RPC, DNS and HTTP
zabbixで運用していた人間がsensuを触ってみた感想
zabbixでシステム運用に関わっている人間が、sensuを使った運用にチャレンジした話です。
結論としては、運用に本格的に入る前に、sensuの導入を断念しました。
sensuとは
sensuは、クラウド環境に親和性の高い監視・モニタリングソフトウェアです。
http://sensuapp.org/
大まかなポイントは以下だと思います。
- Chefやpuppetで簡単に導入できる
- community pluginが豊富
- 設定が全てコードで記載されている。変更するときもjsonファイルの書き換え
- クライアント側からサーバへ通知して監視が始まる(サーバ側にクライアントの定義が必要ない) → AWS EC2のようなImmutableに扱う環境で便利
詳細は以下の記事が詳しいです。
【DevOpsDays Tokyo 2013】クラウド時代のモニタリングツール、UNIXの思想が息づくsensuチュートリアル
監視ソフトをNagiosからSensuに切り替えて2ヶ月経ったのでまとめた
使ってみた状況
- オンプレミス環境でzabbixを使い、数ヶ月の運用を行っていた
- AWS環境を利用するにあたって、sensuの導入を検討した
- 監視+モニタリングが要件 なので、必然的にgraphiteも導入した
- AWS環境ではBlue Green Deploymentを導入。従って頻繁にEC2インスタンスを作り替える
感想
sensu(とgraphite)が物凄く使いづらい印象を受けました。以下、sensuを使ってみた感想です。
導入が容易じゃない
確かに、基本インストールは簡単です。chef-soloで導入しましたが、erlangのインストールトラブルはあったものの、割とすんなり入れることができます。
ただ、簡単なのはあくまで基本インストールのみで、実際に使うためにはほとんどの場合は以下を行うことになります。
- community pluginの導入
subscribers
(クライアントを役割別に分けるグループ名) の設定- モニタリング用にgraphiteの導入
特に面倒なのが後半2つです。
subscribers
の設定は、クライアントごとにどうやって名前を定義するか?それをいかに自動的に設定するか?のベストプラクティスがまだ確立されていない気がします。そのため、色々な方法はあるものの、ある程度アーキテクチャを自分で考えて作りこむ必要があります。なおchef-serverで導入する場合は、role
名が自動で割り当たるらしいので、それほど大変ではないみたいですが…。
graphiteはそもそもsensuではないので、自動的にはインストールされません。なので、chefに組み込むところから始まります。後述しますが、必要となるソフトウェアも多く、Django
に馴染みがないならなおさら大変です。
メンテナンスが容易じゃない
sensuを導入すると、(自動でインストールされるとはいえ)以下の面倒を見る必要が生じます。
- sensu本体
- rabbitmq
- redis
ということは、障害発生時は上記をチェックする必要があるということです。 そして、sensu-adminを導入すると、更に…
が増えます。
graphiteも導入すると、更に増えます。
sensuはRuby、sensu-adminはRuby on Rails、graphiteはpython (Django)というのもちぐはぐで、なんだかなぁという感じ。
ちなみにzabbixなら
- zabbix本体 (zabbix-server, zabbix-agent)
- データベース
で済みます。面倒を見なければならないソフトウェアは少ないほうがいいかと。
使用感もあんまり
sensuは監視ソフトウェア、graphiteはグラフ化のソフトウェアなので、監視とモニタリングでいちいち画面遷移しなければいけません。少なくとも素のsensu管理画面はかなり簡素なので、機能は必要最低限しかないように思います。シンプルという見方もできますが。
設定がjson形式だから見やすい、という見方もあるにはあるのですが、所詮ファイルなので、いろんな軸で見る、という多面的な見方はできません。
また、graphiteは完全なグラフ化ソフトウェアなので、"メトリクス取得のための"ソフトウェアではありません。そのため、いろんなサーバで横断的に見るとか複数のグラフを並べるとか、そんな気の利いたことはできません。これはsensuの問題ではありませんが。
ほとんどの機能はzabbixでもできる
もともとの触れ込みである"クライアント側からサーバへ通知して監視が開始"の仕組みも、zabbixではディスカバリ機能を使うことでほぼ同様のことができます。
sensuはapiを提供しているので独自の仕組みを作りやすい、という意見も、zabbixだってAPIを提供しています。
逆に、zabbixでできてsensuでできないことは多いです。sensu管理画面自体の認証とか、メンテナンス機能(一時的にアラートを抑止する機能)とか。後者はsensu-adminを導入すれば可能かもしれません。
community pluginが動かない…ものもある
1ヶ月くらい前に触ってみた当初は、elasticsearchのpluginが最新バージョンに対応していなかったり、別のプラグインで引数を用意しているくせに動かない(純粋なバグ)というものもありました。pull requestしろよっていう感じかもしれませんが…。幸いコード自体は簡単なので、修正することはできます。ただ、いちいちpluginくらいで信用しないことを前提にバグとか検証で時間を取っていられないし、動くことを前提としたかったなぁというのはあります。
ただ、zabbixだとユーザパラメータとか外部スクリプトとかでプラグイン相当の仕組みはあるにはあるのですが、communityとしてまとまっているわけではないので、その都度ネット上から探す(もしくは一から作る)必要があります。基本的なプロセス、ポート、リソース監視などだけで済むなら考える必要はありませんが、新しいソフトウェアがAPIを提供していて、API経由で新しいメトリクスを取得できるとすると、その仕組みに追従できるのはsensuの方が可能性があるかもしれません。
コードベースの変更管理
これは完全に志向の問題ですが、設定が全てjsonで記載されているということは、GUIからポチポチ設定を変更できないということです。変更履歴をコードベースで管理できるので、例えばgithubなんかで管理すると、いつ誰が設定を変更したかは分かりやすいと思います。
一方で、GUIでカジュアルに変更したいという志向のチームだと、かなり敷居が高いでしょう。設定を変更するだけで、その都度git pull → コード変更 → コミットしてpush → デプロイ となるので。変更履歴を取るか、カジュアルに設定変更できることを取るかはチームによると思います。
まとめ
最初に挙げた特徴の反対意見として、以下のように感じました。
- Chefやpuppetで簡単に導入できる
→ただし、簡単なのは基本インストールまでで、追加設定まで行うとそれなりに面倒 - community pluginが豊富
→community pluginでいろんなソフトウェアに対して簡単に監視が行えるし、今後もきっと追加されていくだろう
ただし、バグが多い - 設定が全てコードで記載されている。変更するときもjsonファイルの書き換え
→確かに1側面では見やすい。ただ、色々な軸で横断的に見るのには向いていない。
設定変更履歴をgitなどで取ることができるのは便利 - クライアント側からサーバへ通知して監視が始まる(サーバ側にクライアントの定義が必要ない)
→確かにそうですがzabbixでもできる
さらに…
- そもそもsensuを利用するために様々なソフトウェアを導入する必要があり、それらをメンテナンスする必要がある
- 色々なソフトウェア、サービスと連携できるという触れ込みだが、例えばグラフ化はgraphiteという以外にそんなに選べるほど選択肢がある状況でもない
ちなみにリソースに関しては、長期間で運用したわけではないので評価できません。
sensuを利用するのに適した状況
なので、sensuを使いたいという場合は、以下になると思います。
- sensu apiを利用して、一から手に馴染む監視サービスを作る覚悟がある
- GUIで設定変更とか軟弱なことはしない、もしくは変更履歴をしっかり取ることが求められる
- もともとrabbitmqやredis, graphiteなど関わりのあるソフトウェアを利用している
- 今後も新しいソフトウェアをどんどん導入していく予定で、それを監視する予定
そう考えると、zabbixはやっぱり監視・モニタリング用によく考えられているのだなぁと思います。
外部(からの)アクセスに便利なsshポートフォワーディング
社内から社外へは接続できるけれども、社外から社内へは自由にアクセスできない…というのがよくあるセキュリティだと思いますが、この方法を使うことで、セキュリティ設定を変更せずに外部からアクセスが可能になります。
最初にこの方法を教えてもらった時に、感動しました。
条件
以下のマシンがあることが条件です。
- 内部ネットワーク→インターネットへ接続できるサーバが内部にあり、インターネット側へsshできること(
踏み台2
とします) 踏み台2
は最終的に繋ぎたい内部システム(例ではinternal:80
)などへアクセスできること- 最終的なアクセス元となる環境→インターネット上のサーバへssh接続できる環境があること(AWSなど)(
踏み台1
とします)
接続イメージ
説明する方法で、自分の端末の任意のポートが、内部ネットワークのアクセス先とマッピングされます。
localhost:20080
が、まるで内部ネットワークのinternal:80
に繋がるようなイメージです。
方法
- 内部ネットワーク(
踏み台2
)→外部(踏み台1
)へ接続する
踏み台2
から以下のコマンドを実行します。
ssh –N –R 10080:internal:80 user@x.x.x.x
これで、踏み台1
の10080
番ポートと踏み台2の先のinternal:80
が繋がります。
この時点で、x.x.x.x:10080
にアクセスするだけで、外部から内部へアクセスできます。
が、この場合は外部から内部ネットワークが丸見えになる危険性があります。Public IPとポート番号さえ分かってしまえば、外部からアクセスできてしまいます。(AWSの場合はSecurityGroupなどで制御することも可能ですが…)
そこで、自分の端末からだけ内部ネットワークにアクセスできるようにします。
- 自分の端末→外部(
踏み台1
)へ接続する
自分の端末から以下のコマンドを実行します。
ssh –N –L 20080:localhost:10080 user@x.x.x.x
これで、自分の端末の20080
番ポートが踏み台1の10080
番ポートと繋がりました。
1.と2.を組み合わせることで、自分の端末の20080番ポートが、内部ネットワークのinternal:80
に繋がることになります。
例えば内部ネットワーク上のwebシステムであれば、外部からでもhttp://localhost:20080/
でアクセスできるようになります。
仕組み
踏み台2
のコマンド:
ssh –N –R 10080:internal:80 user@x.x.x.x
-R
は、ssh接続先のポート番号と繋ぎたい先をマッピングするためのオプションです。
この場合は、x.x.x.x:10080
とinternal:80
をマッピングしています。
-N
は、リモートコマンドを発行しないオプションです。ポートフォワーディング用に指定するものと思ってください。
cron
などで、万が一切れてしまったら自動的に繋ぎ直すようにしておけばより安心です。
- 自分の端末のコマンド:
ssh –N –L 20080:localhost:10080 user@x.x.x.x
-L
は、自分自身のポート番号と繋ぎたい先をマッピングするためのオプションです。
この場合は、自分の端末の20080番ポートとx.x.x.x:10080
をマッピングしています。
-R
の時は、ssh接続先のポート番号を指定していましたが、-L
の場合はssh接続元のポート番号を指定しています。
また、コマンド中に出てくるlocalhost:10080
は、あくまで踏み台1
(x.x.x.x)から見たlocalhost
であることに注意してください。
ですので、ほぼ以下のコマンドと同義です。
ssh –N –L 20080:x.x.x.x:10080 user@x.x.x.x
最終的には、以下のようなイメージになります。
<自分の端末>:20080 → 踏み台1(x.x.x.x):10080 → 踏み台2 → internal:80
sshポートフォワーディングは、あくまでホスト:ポート同士をsshを通じてトンネリングしているだけなので、上記でいう踏み台1
は、sshのポートしか開放する必要がありません。
ですので、ある程度のセキュリティをは担保できることになります。公開鍵による認証にすれば、より安心だと思います。
使い方によってはリスクになりうる方法ですので、理解した上でご利用ください。
Chefからsensuをインストールする時にerlang導入で失敗する
sensuをChefでインストールしようとすると、途中でエラーになって止まります。
Sensu | An open source monitoring framework
Recipe: erlang::package * package[erlang] action install ================================================================================ Error executing action `install` on resource 'package[erlang]' ================================================================================ Chef::Exceptions::Exec ---------------------- returned 1, expected 0 Resource Declaration: --------------------- # In /root/chef-repo/cookbooks/erlang/recipes/package.rb 46: package 'erlang' 47: end Compiled Resource: ------------------ # Declared in /root/chef-repo/cookbooks/erlang/recipes/package.rb:46:in `from_file' package("erlang") do action :install retries 0 retry_delay 2 package_name "erlang" version "R16B03-0.2.el6" cookbook_name :erlang recipe_name "package" end
そこで、以下の記事を見つけたので、それを試してみました。
CentOS 6.5でChefからSensuをインストールしようとするとRabbitMQでコケる回避策 - さよならインターネット
こちらの記事ではRabbitMQ起動時に失敗するとのことでしたが、自分の環境ではインストール時に失敗します。
そして、上記の記事の通り、以下のようにrecipeを書き換えて実行…しても、止まってしまいました。
diff --git cookbooks/erlang/recipes/package.rb cookbooks/erlang/recipes/package.rb index 19f9fce..6cec68f 100644 --- cookbooks/erlang/recipes/package.rb +++ cookbooks/erlang/recipes/package.rb @@ -43,5 +43,9 @@ when 'rhel' include_recipe 'yum-erlang_solutions' end - package 'erlang' + execute "yum install -y erlang-R16B02" do + user "root" + command "yum install -y erlang-R16B02" + not_if { File.exists? "/usr/bin/erl" } + end end
そこで結局取ったのは、上記erlang
インストールに入る前に、そもそもインストールしてしまうという強引な方法…。
以下のコードをcookbooks/sensu/recipes/default.rb
に記載します。
include_recipe "yum-epel" package "erlang" do action :install options "--enablerepo=epel" end
これで、Chefでインストールが通るようになりました。
これ、結局ryuzeeさんの方法なんですよね。
ryuzeeさんがなぜwrapperのcookbookを作って、わざわざerlang
を先にインストールしているのかがようやく分かりました。
Sensuを使って自由度の高い監視システムの構築を行う方法 | Ryuzee.com
https://github.com/ryuzee-cookbooks/sensu-server-wrapper