第6回ICTSCトラブルシューティングコンテストで優秀賞をもらった&writeupのようなもの

2016-09-15 "感想とか" の下辺りに成績表やメンバーのブログなどを追記しました

8月27,28日に大阪で開催された第6回トラブルシューティングコンテストにチームWCDIとして参加してきました。
今回もひっそりと記録を書き残しておきたいと思います。

icttoracon.net

今回で4回目の参加です。前回と同じくサーバサイドを担当しました。

ちなみに第5回の記事↓
blog.hnron.net

今見たら前回の記事があまりにも適当だったので今回は割と真面目に書きます。

今年のメンバー

前回のメンバーから3年生が1人抜けて代わりに1年生が1人入りました。
3年2人、2年2人、1年1人の構成です。

役割分担ですが、今回はサーバサイド2人、ネットワークサイド2人、フルスタック1人にし、
サーバとネットワークでどちらかに問題が偏った場合に、片方に負荷がかかりすぎないような構成にしました。

戦略とか色々

前回までの反省から戦略は色々と考えていました。

役割分担とか

(今年は色々と事情が変わりましたが、)
例年通りなら問題は、「1日目午前、1日目午後、2日目午前、2日目午後」の4つの区切りに分けて出題されます。
基本的には午前から午後、1日目から2日目とまたいで問題が出題されることはなく、制限時間はからなず各区切り内で終わるように設定されていました。
また、問題はだいたい3問ずつ出題され、サーバとネットワークの比率が 2:1 or 1:2 になるように出題されています。

前回まではサーバ3人ネットワーク2人のように分けていたため、人数が少ない方に高難易度の問題が集中すると負荷が偏ってしまうことがありました。
これを踏まえ今回の役割分担ではフルスタック枠を1人分用意しました。

結果として2日目午前までは安定して問題を解くことが出来ました。
しかし、2日目の午後は例年とは違った形で出題されました。午前からまたいで出題された問題が1問 + 午後新たに出題された問題が5問の計6問を2時間で解くことになりました。
かなり異例の問題ラッシュでしたが、問題が解けたかは置いておいて1人フルスタック構成がいい感じに機能し1人1問を上手く割り振れました。
(問題を解いている最中はサーバ問題4問ネットワーク問題2問だと思っていた)

範囲とか

いままでの反省から全員が同じ範囲を勉強するよりも、手分けして出来るだけ広範囲をカバーしたほうが安定するような気がしたので勉強内容がかぶらないよう担当範囲を調整しました。

また当日のタスク振りをスムーズにするために、勉強会ごとにどの技術をどのくらい学習したか(構築してトラブル事例を調べた、ドキュメント読んだだけなど)をslackにあげて共有しました。

slackといえば当日の情報共有は今までownCloudなどを用意していたのですが、slackだけでよくね?となったので今回はslackのみです。

問題の解き方とか(サーバサイド)

結構前からこのスタイルだったのですが、一番最初にトラブルの原因を見つけた人がそのまま解答提出まで一人で行うという感じで問題を解いています。

もう少し詳しく説明すると
問題が出題されたら誰がどの問題を解くかを割り振ります。(基本的にはその人が解きたい問題)
問題に割り振られた人が一人なら問題ないのですが、もし複数人が割り振られた場合は原因究明までは協力して行います。
ただし、トラブルの解決と報告は基本的に誰か一人だけで行うという感じです。

これは複数人でトラブルシュートしている際の「あれ?誰か今何かした?」などの "やらかした" 系を出来る限り防ぐためです。
本来であればコミュニケーションや情報共有をしっかり行っていれば "やらかした" は起こらないはずですが、 当日緊張していたりテンパったりするとわりと "やらかす" 場合が結構あったりするので自然とこのスタイルで問題を解くようになっていました。

気になってること

他のチームが2日目午後でどんな感じにメンバーにタスクを振ったのかが気になってます。
他には、さっき書いた問題の解き方で「トラブルの解決と報告は一人で行う」という方法ですが、他のチームはどういうふうに問題を解いてるかも気になっています。

結果

結果は優秀賞(2位)でした。
430点中、1位は219点、私達は175点でした。

2日目午前までの段階で9問中7問ぐらい解けていたのでそれなりに自信があったのですが、
2日目午後を6問中5問ほど落としてしまっているはずなので、そこができていたらと思うと結構悔しいです。

感想とか

今回も楽しかったです。
スコアサーバや出題パターンの変更など、新要素がいくつかあって新鮮味がありました。
個人的には2日目午後がいい感じに緊張感と絶望感があって楽しかったです。
また、いくつか新たな反省点も出てきたので次回はこれを踏まえて戦略を立てたいと思います。

チーム的には結構安定してきたように思います。 第3回大会ではボロ負けでしたが、第4回で最優秀賞、第5回で5位、第6回で優秀賞と安定して上位を取れるようになってきました。
サーバ問題は大体解けるようになってきたのでネットワーク側で確実に点が取れるように強化したいです。

次回は最優秀賞取ります (でも次回運営募集してたら運営もやってみたかったり)


2016-09-15 【追記】
追記その1
成績表が送られてきたので公開しておきます。
2日目午後、落とした問題が6問中5問だと思ってたら全問落としてた
あとやっぱり運営OBつよい

追記その2
最優秀賞のチームの方がブログでこの記事を紹介してくれてました。(ありがとうございます)

biraprog.hatenablog.jp

追記その3
あと後輩が残りのwritewpを書いてくれました。

blog.acqn.xyz


writeup的な

以下writeupです
自分が触った問題だけです
答えがあってるかは保証できません
多分今年も公式で解答を出すと思うのでそんなに詳しくは書きません

Q3(1日目午前) 移行したアプリケーションが動かない!

アプリケーションはエラーログが表示されない仕様だったのでMySQLの設定とかログとか見てました。
書き込みが文字化けしていたので文字コードかなと思い色々探ってましたが特に問題はなし。(今考えたら文字化けはわざとでミスリードを狙ってたのかも)

後輩がおもむろにループバックアドレスに対してtcpdumpしたところ、MySQLのパケットを拾えたのでそこからエラーメッセージを拾ってきて原因を突き止めました。

ちなみにそのエラーメッセージ↓

In aggregated query without GROUP BY, expression #1 of SELECT list contains nonaggregated column 'dengon.message.id'; this is incompatible with sql_mode=only_full_group_by  

後は後輩がやってくれました。

ちなみに提出した解答

ご依頼にありました件につきまして、サーバの更新によりMySQLのバージョンが変わってしまったのが原因でした。  
新しいバージョンのMySQLは、「sql_mode」によるSQL文の判定条件が変わっており、以前より厳密に判定されるようになっていました。  
tcpdumpでパケットを見て確認したところ、今回の伝言板アプリケーションはこの厳密な規格にそぐわない形式でgroup by句が使われているため、SQLでエラーが発生して投稿に失敗しておりました。  
今回のプログラムはELFファイル(実行ファイル)だったため、ソースコードの変更は不可能だと判断し、MySQLサーバの設定の変更を行いました。そのため、以下のファイルを追加したしました。  
  
/etc/mysql/conf.d/mysqld.cnf  
> [mysqld]  
> sqlmode=NOENGINE_SUBSTITUTION  
  
以上の操作により正常に投稿が出来ることを確認いたしました。  
以上、よろしくお願いいたします。  

Q6(1日目午後) VMがネットワークにつながらない!

片方のVMにはアクセス出来るがもう片方にはアクセスできないという現象が発生してました。
arpingしたところ、どうやらmacアドレスが被っていたようなので、それをそのまま報告しました。
また、つながらない方のVMと同じIPアドレスを使用しているコンピュータがもう1台いるみたいだったのでそれも報告しておきました。

正式な解答?はVMをコピーしたらmacアドレスがそのままコピーされてしまってmacアドレスがコンフリクトした、だそうです。

最初はGARPでイタズラされてるのかなとも思い判断に悩みましたが、tcpdumpの結果や、
1年の後輩が勉強会中にVirtualBoxで同じことをやらかしていたのを思い出し、macアドレスが被っただけかなぁと判断しました。

Q7(1日目午後) 自動マウントをしてくれない!

/etc/security/pam_mount.conf.xml ファイルを見てみたら普通にRead-Onlyの設定になっていました。

他にトラブルになりそうなものだと /etc/skel/private ファイルが作成されていました。
ディレクトリに作成し直そうとしたのですが、root権限で消せなかったので lsattr したところ、案の定「i」フラグが設定されていたので chattr でフラクを削除、ファイルをディレクトリに作成し直しました。

あとは pam_mount.conf.xml 内の mountpoint を修正しました。

mountpoint="home"
↓
mountpoint="/home"

その後 test01〜test05 ユーザを作成し、privateディレクトリがちゃんと配布されていることと、自動マウントが正常に出来ていることを確認しました。

解答文は長いので原文は載せませんが、

  • /etc/skel/ディレクトリにprivateディレクトリを作成
    • /etc/skel/private ファイルを chattr -i して削除したあと、privateディレクトリを作成した。
  • ユーザを作成
  • pam_mount.conf.xmlの編集
  • ファイルが作成できるか確認テスト

をやったことをコマンド付きで解答に書いて送りました

Q9(2日目午前) レプリケーションが出来ない!

一瞬NoSQLを期待しましたが普通にMySQLでした。(そろそろNoSQL系の問題が出てもいい気がする

$ show slave status\G コマンドから得た情報と、MySQLのエラーログから原因を突き止めていきました。

MySQLのログとか
接続先が無いと怒ってるっぽい

# MySQLのログファイル  
160828  7:40:50 [ERROR] Slave I/O: error connecting to master 'repl@192.168.5.5:3306' - retry-time: 60  retries: 86400, Error_code: 2013  
  
# show slave status\G の結果  
error connecting to master 'repl@192.168.5.5:3306' - retry-time: 60  retries: 86400  

レプリケーションの設定情報
なんかmasterのIPが間違ってる

mysql> show slave status\G  
    *************************** 1. row ***************************  
            Slave_IO_State: Connecting to master  
                Master_Host: 192.168.5.5 ← !!! masterのIPが間違ってる !!!  
                Master_User: repl  
                Master_Port: 3306  

masterのIP修正

mysql> STOP SLAVE;  
mysql> change master to MASTER_HOST='192.168.11.3';  
mysql> start slave;  

記憶が正しければこの時点でiptablesの tcp/3306 が空いていないことに気づいて開けたはずです。

MySQLのエラーログを確認する。
まだどこかが間違っているみたい

160828 11:19:14 [ERROR] Slave I/O: error connecting to master 'repl@192.168.11.3:3306' - retry-time: 60  retries: 86400, Error_code: 1130  

ユーザ情報を確認してみたらreplユーザのHostの設定が間違ってました。

$ mysql -u root --password=password -e "select Host, User, Password from mysql.user;"  
+--------------------+------+-------------------------------------------+  
| Host               | User | Password                                  |  
+--------------------+------+-------------------------------------------+  
| localhost          | root | *139..................................... |  
| problem11-template | root | *139..................................... |  
| 127.0.0.1          | root | *139..................................... |  
| 192.168.5.%        | repl | *22F..................................... |  
+--------------------+------+-------------------------------------------+  

replユーザの設定を修正

mysql> rename user 'repl'@'192.168.5.%' to 'repl'@'192.168.11.%';  

この後MySQLのログかなんかで server-id が被っていると怒られたので修正しときました。

server-id=100  
この行を以下のように変更  
server-id=101  

とりあえず分かった原因は

  1. tcp/3306 が空いていない
  2. slaveのMySQLの設定で、指定されたmasterのIPアドレスが間違っている
  3. master側のMySQLのユーザ設定で、replユーザのログイン可能Hostが「192.168.5.%」(正しくは192.168.11.%)と誤った設定がされている
  4. masterとslaveでserver-idが被っていたため、slaveが止まってしまう

解決方法

  1. master側のiptablesで tcp/3306 を開ける
  2. slaveのMySQLの設定で、masterのIPを正しく変更する
  3. masterのMySQLで、replユーザの設定を正しく変更する
  4. slaveのserver-idを変更する
  5. 一度DBを削除し、レプリケーションし直した

これに叩いたコマンドの詳細を添付してレプリケーションが出来ることを確認したと運営に報告しました。

他の問題(自分が触ってないやつで覚えているもの)

前回運営がIP電話でトラブっていたので今回SIPが出そう!と予想して対策してましたがダメでした...
IPv6問題は対策でv6のルーティングプロトコルや相互運用について調べたり構築したりしていて、指定された機材にNAT64の機能が無いことを知っていたので騙されずに済みました。
ここら辺の話はきっと後輩が書いてくれるはず