2014-09 / 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
[2013-05-19-1]にインストールしたUbuntu 12.04はうっかり32bit版でし
た。。仕方がないのでUbuntu 14.04へのアップグレードがてら、クリーン
インストールすることにしました。
管理画面からポチポチしてOSのインストールは完了。Cookはあらかじめ
VirtualBoxとEC2で確認していたので万全です(キリッ
と思いきや、いつまでたってもRecipeが処理されません...。
$ knife solo cook masutaka.net
Running Chef on masutaka.net...
Checking Chef version...
Uploading the kitchen...
Generating solo config...
Running Chef...
Starting Chef Client, version 11.16.2
(ここでダンマリ)
これまた仕方がないので、サーバ側の
/opt/chef/embedded/lib/ruby/gems/1.9.1/gems以下をprintfデバッグ(と
いうかpデバッグか)で調べたところ、Chefがサーバ情報を取得するときに
使うOhaiのGCEプラグインから返ってこないことがわかりました。GCEとは
Google Compute Engineです。なんでChefが?
で、結論から言うと、GCEプラグインをOFFにしたら解決しました。
knife solo prepareのあとに/opt/chefが作られるので、
/opt/chef/embedded/lib/ruby/gems/1.9.1/gems/ohai-7.4.0/lib/ohai/config.rb
を以下のように修正。あとはknife solo cookするだけです。knife solo
bootstrapは出来ないことになります。
default :disabled_plugins, []
↓
default :disabled_plugins, [:GCE]
knife soloはchef-soloをリモートから実行するコマンドで、
/opt/chef/embedded/bin/ruby /usr/bin/chef-solo -c /home/masutaka/chef-solo/solo.rb -j /home/masutaka/chef-solo/dna.json
のようなchef-soloコマンドを実行します。root権限だったかな?
この/home/masutaka/chef-solo/solo.rbに
Ohai::Config[:disabled_plugins] = [:GCE]
を書き、前述のchef-soloコマンドを実行すれば/opt/chef以下を修正する
必要はありませんが、残念ながらこのファイルはknife solo cook時に自動
生成されます。
ローカルの.chef/knife.rbに書いても無視されました。残念。そういうわ
けで、今はprepareをした後はサーバにログインしてファイルを書き換え、
そのあとにcookというイマイチなことをしています。
ではなぜ、さくらのVPSだけダンマリになるのか?
/opt/chef/embedded/lib/ruby/gems/1.9.1/gems/ohai-7.4.0/lib/ohai/mixin/gce_metadata.rbの
ここに違いがありました。
def can_metadata_connect?(addr, port, timeout=2) t = Socket.new(Socket::Constants::AF_INET, Socket::Constants::SOCK_STREAM, 0) saddr = Socket.pack_sockaddr_in(port, addr) # さくらはこの行に来る。 connected = false
portは80、addrはmetadata.google.internalです。
さくら以外はおそらくSocket.pack_sockaddr_inで例外が発生して、それ以
降処理されないのでしょう。さくらはそれ以降処理され、無限ループに入
り込んでしまいます。
irbでも再現出来ました。さくら以外は例外が発生しています。
さくらは壊れた文字列が返ってきます。
# さくら以外(Cookできる)
$ irb -r socket
irb(main):001:0> Socket.pack_sockaddr_in(80, 'metadata.google.internal')
SocketError: getaddrinfo: nodename nor servname provided, or not known
from (irb):1:in `pack_sockaddr_in'
from (irb):1
from /Users/masutaka/.rbenv/versions/2.1.2/bin/irb:11:in `<main>'
# さくら(Cookでダンマリ)
$ irb -r socket
irb(main):001:0> Socket.pack_sockaddr_in(80, 'metadata.google.internal')
=> "\x02\x00\x00PE\xAC\xC9\xD0\x00\x00\x00\x00\x00\x00\x00\x00"
irb(main):002:0> require 'nkf'
irb(main):003:0> NKF.nkf('-w8', Socket.pack_sockaddr_in(80, 'metadata.google.internal'))
=> "\u0002\u0000\u0000PEャノミ\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"
pingでも違いあり。
# さくら以外(Cookできる)
$ ping metadata.google.internal
ping: cannot resolve metadata.google.internal: Unknown host
# さくら(Cookでダンマリ)
$ ping metadata.google.internal
PING metadata.google.internal.net (69.172.201.208) 56(84) bytes of data.
さくらのDNSサーバはさくら奨励の133.242.0.3と133.242.0.4を指定。
Google Public DNS(8.8.8.8と8.8.4.4)に変えても変わらず。
ここで調査は行き詰まり。cookが面倒になってしまったのは残念。
ブラジルの人も困っていました。
GCE Plugin infinite loop · Issue #382 · opscode/ohai
追記(2016-07-19):
職場の同僚が EC2 で同じ現象でハマっていて、この記事の方法で回避で
きたそうです。
2014-09 / 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30