kvmでストレージパスを変更してのライブマイグレーション
やりたいことがタイトルで表現できているかどうか謎ですが、概要は以下の通りです。
目次
何をやりたいのか
- KVM Host A(以下HA)からKVM Host B(以下HB)にGuest X(以下、GX)をライブマイグレーションしたい
- その際、ストレージパス(ディスクパス)を変更したい
- 例えば以下のようなケース
- HAではGXのストレージが/path/to/gx.imgだったとする
- HBではGXのストレージを/path/to/gx2.imgとしたい、というケース
- ストレージパスが変わる、ということはつまり(ほとんどの場合は)「共有ストレージを用いたライブマイグレーションを行わない」ということ
- 例えば以下のようなケース
上記ができると何がうれしいのか?
例えば
とか。
アプローチ
具体的な手順
冒頭の「何をやりたいのか」の例を当てはめつつ説明します。
1. 移行先ホストで、移行先ストレージを用意する
例では以下になります。
- HB上で/path/to/gx2.imgを用意する
2. 移行元ホストで移行対象の仮想マシン定義を出力、移行先用に書き換える
例では以下になります。
- HA上でGAの仮想マシン定義をdumpする(virsh dumpxml 仮想マシン名 > ダンプ先ファイル名)
- 移行先用に仮想マシン定義を編集する(上記の「ダンプ先ファイル名」で指定したファイルを編集する)
- 編集内容は「ストレージパスの書き換え」
- 例えば以下のようなこと
(snip) <domain type='kvm' id='X'> (snip) <devices> (snip) <disk type='block' device='disk'> (snip) - <source dev='/path/to/ga.img'/> + <source dev='/path/to/ga2.img'/> (snip) </disk> (snip) </devices> (snip) <domain type='kvm' id='X'>
ここでは「ダンプ先ファイル名」をga.xmlとします。
3. マイグレーション!
例では以下になります。
コマンドにするならこんな感じ
HA# virsh migrate --live --persistent --copy-storage-all --verbose --xml ga.xml GuestA qemu+ssh://HB/system
これでライブマイグレーションできるはず。
注意点
いろいろ問題点があります。
- 長い時間、ストレージとネットワークに負荷がかかり続ける
- ストレージ内容をネットワーク経由で全部コピーすることになるので、シンプルにやるならこの特性はやむなし
こんなもんだろうか…。
しかしとりあえず、時間がかかっても「止めずに、別ストレージパスに移行できる」というのはかなりメリットな気がする。
drupal8のインストールが途中で振り出しに戻る
drupalのインストールをしていたのですが、表記の事象に遭遇。 ちなみに振り出しに戻る、というのはリダイレクトでブラウザでのインストールの最初の画面に飛ばされる、という意味です。
前提
- Ubuntu 14.04 LTSにdrupal8.0.6をインストールする
- 前段にリバースプロキシが存在する←結論を言うとこいつが原因
事象
drupalのインストールは概ね以下の手順になります。
- OSをインストール
- 必要なパッケージ(apache, php, mysqlとその関連)
- drupalのダウンロード&展開&Apacheから見えるようにする
- ブラウザで当該サーバにアクセス、設定が進んでいく
どこで表記の事象が起きるかというと、ブラウザで当該サーバにアクセスした後。具体的には以下。
- 言語の選択
- プロフィールの選択
- 必要条件の検証
- データベースのセットアップ←このステップの次で「言語の選択」に戻される
- サイトのインストール
- 翻訳のセットアップ
- サイトの環境設定
- 翻訳の完了
対処
drupalのパッケージを展開した後、sites/default/default.settings.php
を以下のとおり編集する
(snip) -# $settings['reverse_proxy'] = TRUE; +$settings['reverse_proxy'] = TRUE; (snip) -# $settings['reverse_proxy_addresses'] = array('a.b.c.d', ...); +$settings['reverse_proxy_addresses'] = array('a.b.c.d');
ちなみに上記のa.b.c.d
は、drupalが実際に動いているサーバから見える、リバースプロキシのIPアドレスと思われる。
原因
もはや対処で解決しちゃった人は興味がないと思いますが、原因の推測。 ちゃんと追いきっていませんので内容は薄っぺらです。
どうやらインストーラはリダイレクトとかを巧みに使っているようで、 リバースプロキシが存在すると、それがうまく動かない模様。 エラー時にphpが「header already sent」的なエラーを吐いていました。
ちなみに、かなりハマった…。いろいろ調べた。
- phpのエラーログを有効にしてみた
- エラーで特定したファイル・行を確認してみた
- ある箇所Bでヘッダ出力しようとしたとき、ある箇所Aですでにヘッダ出力されていることはわかった
- しかし、それがなぜだかわからない…
- サーバとかクライアントでパケットキャプチャしてみた
- 手元のVirtualBoxでdrupalをインストールしてみた
- うまくいった
- VirtualBoxと問題が起きている環境でインストール時のパケットキャプチャをして比べてみた
- 失敗しているほうはTCPのRSTが頻発。これがリバースプロキシの有無と関連しているかどうかは不明
- ためしに問題が起きている環境でリバースプロキシをはずしてみた
- うまくいった
- ようやく以下にたどりつく
やっと解決。ちなみに関連エラーは以下のとおり。
振り出しに戻される(リダイレクトされる)ときにphpのエラーログに出力される内容
RuntimeException: Failed to start the session because headers have already been sent by "/path/to/drupal-8.0.6/vendor/symfony/http-foundation/Response.php" at line 1151. in /path/to/drupal-8.0.6/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php on line 144
これはもはやdrupalとは関係なくなってきていて、罠。この先に答えは見つけられませんでした。
振り出しに戻されたあと、再度インストールを進めた際に途中でブラウザに表示される内容
Error The website encountered an unexpected error. Please try again later. Drupal\Core\Config\UnmetDependenciesException: Configuration objects (block.block.bartik_account_menu, block.block.bartik_branding, block.block.bartik_breadcrumbs, block.block.bartik_content, block.block.bartik_footer, block.block.bartik_help, block.block.bartik_local_actions, block.block.bartik_local_tasks, block.block.bartik_main_menu, block.block.bartik_messages, block.block.bartik_page_title, block.block.bartik_powered, block.block.bartik_search, block.block.bartik_tools, block.block.seven_breadcrumbs, block.block.seven_content, block.block.seven_help, block.block.seven_local_actions, block.block.seven_login, block.block.seven_messages, block.block.seven_page_title, block.block.seven_primary_local_tasks, block.block.seven_secondary_local_tasks, block_content.type.basic, comment.type.comment, contact.form.feedback, core.entity_form_display.block_content.basic.default, core.entity_form_display.comment.comment.default, core.entity_form_display.node.article.default, core.entity_form_display.node.page.default, core.entity_form_display.user.user.default, core.entity_view_display.block_content.basic.default, core.entity_view_display.comment.comment.default, core.entity_view_display.node.article.default, core.entity_view_display.node.article.rss, core.entity_view_display.node.article.teaser, core.entity_view_display.node.page.default, core.entity_view_display.node.page.teaser, core.entity_view_display.user.user.compact, core.entity_view_display.user.user.default, editor.editor.basic_html, editor.editor.full_html, field.field.block_content.basic.body, field.field.comment.comment.comment_body, field.field.node.article.body, field.field.node.article.comment, field.field.node.article.field_image, field.field.node.article.field_tags, field.field.node.page.body, field.field.user.user.user_picture, field.storage.node.comment, field.storage.node.field_image, field.storage.node.field_tags, field.storage.user.user_picture, filter.format.basic_html, filter.format.full_html, filter.format.restricted_html, node.type.article, node.type.page, rdf.mapping.comment.comment, rdf.mapping.node.article, rdf.mapping.node.page, rdf.mapping.taxonomy_term.tags, taxonomy.vocabulary.tags) provided by standard have unmet dependencies in Drupal\Core\Config\UnmetDependenciesException::create() (line 89 of core/lib/Drupal/Core/Config/UnmetDependenciesException.php). Drupal\Core\Config\UnmetDependenciesException::create('standard', Array) (Line: 465) Drupal\Core\Config\ConfigInstaller->checkConfigurationToInstall('module', 'standard') (Line: 136) Drupal\Core\ProxyClass\Config\ConfigInstaller->checkConfigurationToInstall('module', 'standard') (Line: 146) Drupal\Core\Extension\ModuleInstaller->install(Array, ) (Line: 87) Drupal\Core\ProxyClass\Extension\ModuleInstaller->install(Array, ) (Line: 1560) install_install_profile(Array) (Line: 648) install_run_task(Array, Array) (Line: 526) install_run_tasks(Array) (Line: 116) install_drupal(Object) (Line: 39)
これはこれでぐぐるとそこそこ情報が出てきてしまい、罠。この先に答えは見つけられませんでした。
おまけ
自分のサーバは非力でインストールにすごく時間がかかります。 結果的に途中でHTTPがタイムアウトしてインストールが失敗してしまいました。
リクエスト処理時間が数時間? - HTTPサーバのタイムアウト設定について - — ありえるえりあ
上記を参考にいろいろ調べたところ、タイムアウトが発生しているのはクライアントとリバースプロキシの間。 つまり、バックエンドのWebサーバからの返事が遅すぎるので、リバースプロキシがクライアントにタイムアウトを返しちゃっている、ということのようです。
そんなわけで、リバースプロキシのタイムアウト設定を変更。
https://httpd.apache.org/docs/2.2/ja/mod/mod_proxy.html#proxytimeout
これでプロキシ時のタイムアウトを長くして問題が発生しなくなった。
2016/04/04頃にWindowsの時刻が1時間くらい進んだ件の対処方法
目次
あらまし
に書いた件の関連。 原因特定までは至っていませんが、自分のように
という場合、関係者は自分かMicrosoftさんしかいないわけで、しかも自分は特別何か時刻同期について設定をいじっているわけでもないので、 Microsoftさん側の問題なのかな、というところで落ち着いています。
対処方法
さて、対処方法。 何に対する対処か、ですが、2つ考えられると思っています。
- (応急対応)とりあえずずれた時計を直す
- (再発防止)時刻同期先サーバを変更する
A. とりあえずずれた時刻を修正する
まずはさておき、直しましょう。 直し方は2パターン。 Windows 7を前提に説明しますが、ほかでも似たような方法で対処できると思います。
Aa. 手動で時刻設定を行う
- タスクトレイの時刻をクリック、「日付と時刻の設定の変更」をクリック(もしくは、「コントロールパネル」→「時計、言語、および地域」→「日付と時刻の設定」をクリック)
- 「日付と時刻の変更(D)...」ボタンを押下、時刻設定を行う
Ab. 時刻同期サーバとの再同期を強制的に行う
- タスクトレイの時刻をクリック、「日付と時刻の設定の変更」をクリック(もしくは、「コントロールパネル」→「時計、言語、および地域」→「日付と時刻の設定」をクリック)
- 表示されたウィンドウ上部の「インターネット時計」タブをクリック
- 表示されたタブ内の「設定の変更(C)...」をクリック
- 表示されたウィンドウ内の「今すぐ更新(U)」をクリック
これで直らなければ、「Aa. 手動で時刻設定を行う」か、Bの対処を検討してください。
B. 時刻同期先サーバを変更する
今回発生した事象とまったく同じ事象が、同じ原因に基づいて発生したとき、同じように時間が1時間ほど進んでしまうことを防ぎます。 これは「今回の事象はMicrosoftさんの時刻同期サーバであるtime.windows.comが原因」という前提に立っています。 もしそうでない場合、同じ原因であれば同じように1時間ほど進んでしまうことがあるかもしれません。
変更先は「国立研究開発法人 情報通信研究機構(通称NICT)」が運営する、公開NTPサーバがおすすめです。
以下、変更方法です。 (NICTの公開NTPサーバ以外に設定する場合は、「ntp.nict.jp」を適宜読み替えてください。)
- タスクトレイの時刻をクリック、「日付と時刻の設定の変更」をクリック(もしくは、「コントロールパネル」→「時計、言語、および地域」→「日付と時刻の設定」をクリック)
- 表示されたウィンドウ上部の「インターネット時計」をクリック
- 表示されたタブ内の「設定の変更(C)...」をクリック
- 表示されたウィンドウ内のサーバ欄に「ntp.nict.jp」と全部半角で入力、OKをクリック(OKをクリックする前に、「今すぐ更新(U)」を押してテストすることをおすすめします)
NTPうんちく
NTPとは
NTP(Windowsでは「インターネット時刻」という言葉が近しい意味だと思います)というのは、ネットワーク越しに時刻を同期させるための仕組みです。 サザンオールスターズの「今何時?」「そうね大体ね」よろしく、ネットワーク越しにNTPサーバに時刻を教えてもらいます。
NTPの精度
ところでNTPを使った時刻同期では、どのくらいの精度で時刻を同期できるのでしょうか? 答えは「NTPサーバとのネットワークの安定性に依存する」です。
ネットワークの安定性というのは、具体的には「今何時?」と聞いてから「そうね大体ね」と返事が来るまでの時間の「ゆらぎ」です。 返事が来るまでの「時間(返事が早い、遅い)」ではないですよ、「時間のゆらぎ」です。専門用語では「ジッタ(jitter)」といいます。 ちなみに、返事が来るまでの時間は「遅延」とか「RTT(Round Trip Time)」といったりします。
(以下、概念的な話で正確なNTPプロトコルの動作を説明していません。詳細は参考文献を参照ください。)
例えば何回「今何時?」と聞いても、確実に1.00秒後に回答が返ってくるようなネットワークの安定性だった場合、 返ってきた答えから1.00秒を引いた時刻を設定すれば、NTPサーバと誤差0.01秒以内で設定できることになります。
例えば「今何時?」と聞いた際、1回目は0.01秒後に、2回目は0.10秒後、3回目は0.01秒後に返ってきたとします。さて、返ってきた答えから何秒引いた時刻を設定しましょう?
0.01秒とか0.20秒とか早く答えを返してくれるよりも、10.00秒かかったとしてもゆらぎ(ジッタ)が小さい方が正確な時刻設定ができるんですね。
参考文献
2016年4月版 CMSトレンド(簡易版)
とあるWebサイトを作ることになりそうで、CMSについていろいろ調査中。 調べれはすぐわかることばかりだけど、簡単に整理しておきます。
目次
CMSとは?
「Contents Management System」の略で、要するにWebサイト(ホームページ)を簡単に更新する仕組みのこと。
2016年4月版 CMSトレンド(簡易版)
多く使われているのは以下の3つの模様。
それぞれ特徴があるが、記事にできるほどちゃんと理解していないので、詳細は別記事にて。
現時点での自分の理解は以下の通り。 ※ちゃんと使い込んでいるわけではないので、推測をかなり含みます。
WordPress
- シェアNo.1
- 情報が多い
- ブログ向き
Joomla!
Drupal
- シェアNo.3
- 大企業サイトでの採用率が上がっている(WordPressとの差が縮まっている)
- 動作が軽快
- カスタマイズの幅がJoomla!に比べて広い(簡単かどうかは別の話)
- 管理画面がそこそこ使いやすい
- 多機能なので大規模なWebサイトに向いている
蛇足
自分が今回作るサイトはJoomla!が向いてそうだけど、 自分とお客様との関係性を考えると、ノウハウとして持っておいたほうがいいのはDrupalのような気がするので、自分はDrupalを掘り下げてみようと思う。
2016年3月22日に発生したANAのシステム障害について、ANAが日本ユニシスへの損害賠償を検討している
表記の件を考察してみる。
例によって、ANAさんとか特定のSIerさん、ベンダーさん、メーカーさんとかを批判する意図はありません。 不幸にも社会的インパクトがあったシステム障害について、 エンジニアとしてどう向き合うべきかの糧にしたい、という思いで書いています。 (というわけで、今更ですが表記が気持ち悪くならない範囲で個別の社名は書かないことにします。)
参照した記事は以下。
目次
損害賠償の根拠・理由
損害賠償というからには「U社さんがとある債務を履行しなかったことが今回のシステム障害の原因であり、ANAが損害を被った原因である」という論法になるはず。
もはやここから先はANAとU社さんの個別の契約の話なので、私のような第三者がとやかく言う内容ではないわけですが、
- ANAは上場企業であり、世界中に数多くの株主が存在する
- 会社は法律を遵守した上で、株主の利益を最優先に考える
- ANAは株主の利益を守るために、行うべきことは行わなければいけない
- でないと、役員が株主から「債務不履行」で損害賠償請求をされてしまう
こんな事情があると思われるので、ANAも株主に「ちゃんと株主利益考えてますよアピール」としての「損害賠償請求の検討」をいわなければいけなかったと推測。
U社が履行すべきだった債務とは?
個別の契約の話なので超推測ですが、帰着するのは「なんで冗長化してたのにシステム全体が止まっちゃったの?」という点だと思われる。
2016年3月22日に発生した、全日本空輸株式会社(ANA)の国内線システム障害についての考察 - わかりやすい
にも書いた内容に少し関連するけど、
- 設計が悪かった←設計者の瑕疵
- 設計は適切だったけど、設計を実現する機器の選定を誤った←機器選定者の瑕疵
- 機器が、設計どおりに動くための要件を満たしていなかった(今回の機器を選定したのが悪かった)
- 設計は一見適切だが、設計を実現する機器が世の中に存在しない←設計者の瑕疵でもあり、「そんな要件満たす機器はありません」と指摘できなかった機器選定者の瑕疵でもあると思われる
- 「故障機が故障シグナルを送信することでフェイルオーバーさせる」は、故障機に何かしら動作を期待している時点であやしい
ほかにも「運用が悪い(障害が長期化したのは、構築時に想定していた復旧手順を適切に履行しなかったことが原因である)」、という主張も出てくるかもしれませんね。
教訓
仮定(推測)の上に教訓もへったくれもないですが、
- 無理が通れば道理が引っ込む
- 「絶対止めるな」に対しては「コスト」か「納期」か「嘘(実は止まっちゃう)」で責任を取ることになる
- システム要件は現実的なものを定義しましょう
- 設計はシステム要件を最低限満たす、シンプルなものにしましょう
- 機器選定は、設計要件を最低限満たす、稼動実績の高いものにしましょう
- 実は運用が一番大事ですよね
- 運用してシステムとしての役割を果たさせる(目的)ために構築する(手段)のであって、「作った(目的)ものを動かし続けなければいけない(尻拭い)」ではないはず
- 無理・誤りに気づき、適切なレールに戻せると幸せですね
- だいたいシステム作るときには、予算と納期(下手すると採用すべき機器まで)が決まっているのに、要件はぜんぜん決まっていない、なんてことがよくあるので、まぁ、難しいですよね…。
ITによって世の中がもっと便利になりますように。 また、それを支える側にも適切な責任と利益が与えられますように…。
2016/04/04頃にWindowsの時刻が1時間くらい進んだ?
(2016/04/05 10:00 対処方法の記事を書きました。) 2016/04/04頃にWindowsの時刻が1時間くらい進んだ件の対処方法 - わかりやすい
Windows標準のNTPクライアントはtime.windows.comを向いてた。 最終同期時刻は2016/04/04 01:00だったはず。再同期したら直ってしまった。
調べてみると、似たような症状に合ってる方がちらほら。
Windows機の時間がいつの間にか1時間進んでた
— バカ.exe (@ahiru3net) April 3, 2016
艦これ できない で検索して、この人のツイートを見て確認したら俺も時間1時間ズレてるからWindowsの不具合なのかな
— ラ・ムスクロ (@LaMusculo) April 3, 2016
windowsの日本時間サマータイム化、デフォルトのNTPサーバがバグったのか?
— じゅんじ (@tuba_kun) April 3, 2016
少なくとも自分の環境が原因ではなさそう。
適当なデスクトップだから時刻が対象ずれるのはかまわないけど、Windows Serverとか大丈夫なんだろうか? 自分が面倒を見てるWindows Serverは幸いにもtime.windows.comを向いたものはなかったから確認できず。
2016年3月22日に発生した、全日本空輸株式会社(ANA)の国内線システム障害についての考察
表記の件について、エンジニア目線で考察してみる。
なお、原文は以下。 www.ana.co.jp
ちなみにANAさんの発表は株主や顧客に対してできる限りの説明責任を果たすためのものであって、 世のエンジニアに何が起きたのかを教えるためのものではないので、 今のANAさんの発表内容を批判する意図の記事ではないです。
目次
システムの構成
ANAさんが公表している構成図 www.ana.co.jp を参照。ポイントは以下。
- DBサーバが4台あり、同期が必要
- DBサーバにはAPサーバとの通信用通信路以外に「同期通信用の通信路」がある
- 同期通信用の通信路を「ネットワーク中継機」が実現している
- ネットワーク中継機には予備機が存在し、ネットワーク中継機が故障した際は予備機がその機能を引き継ぎ、DBサーバ間の同期通信が正常に行える状態になる
何が起きたのか
- ネットワーク中継機(他の報道によると、シスコシステムズ合同会社のCatalyst 4948E)が故障したにも関わらず、予備機が正常にその機能を引き継がず、DBサーバ間の同期が正常に行えなくなった
- 結果的にアプリケーションが正常に動作しなくなった
考察したいポイント
- 今回の事象(ネットワーク中継機の故障)が発生した際、具体的にどのように予備機に切り替わる想定だったのか
- 今回なぜそのように動かなかったのか
どのように予備機に切り替わる想定だったのか
ANAさんの発表から部分引用
本来であれば、ネットワーク中継機が故障すると「故障シグナル」を発信し、予備機に自動的に切り替わる設計になっておりますが、
- (故障したネットワーク中継機が?それ以外が?主体不明)「故障シグナル」を発信する
- (ネットワーク中継機の予備機が?それ以外が?主体不明)「故障シグナル」を受信し、予備機に自動的に切り替わる
ここがキモですが、主体不明なので切り替えのメカニズムがいまひとつ見えてきません。
今回なぜ、想定どおりに動かなかったのか
今回は故障しているにも関わらず「故障シグナル」を発信せず、予備機に自動的に切り替わりませんでした。
ここは前段のメカニズムが明らかになれば、ある程度納得できそう。
もっと知りたい点
故障シグナルを発信する主体は誰(どの機器)で、何をもって故障と判断するのか
- 誤検知(false positive)や見逃し(false negative)は起こりうるのか?
- 仮に故障シグナルの発信主体が故障機自体だとすると、見逃しは簡単に起こりそう。(例えば電源断とか)
故障シグナルを受信するのは誰(どの機器)で、受信後どのように振舞うことで、全体として動作継続するのか
- (発信主体による見逃しも含め)故障シグナルの受信に失敗したらどうなるのか
- 発信主体の誤検知による故障シグナルを受信したらどうなるのか
「2.再発防止策」の「(1)同一事象の検知」について
同一事象が再発し、ネットワーク中継機が「故障シグナル」を出さない場合でも、データベースサーバーからネットワーク中継機の故障を検知できる改善を実施しました。(2016年3月24日に実施しました)
- 故障シグナルの受信者はデータベースサーバーなのか?
- 故障を検知(他の3台のデータベースサーバーと同期が正常に行えないことを把握)したデータベースサーバーはどう振舞うのか?その際、システム全体として処理が継続できるのか?
「2.再発防止策」の「(2)メーカーによる改善策」について
不具合のあった機器は、製造メーカーにおいて解析を実施し、故障個所が判明しております。 現在、製造メーカーにて改善策を検討中です。
- 故障箇所は具体的にどのレベルまで判明しているのか?
- ハードウェア?
- ソフトウェア?
- OS?
- その他何らかの機能?(例えばVRRPとか)
- 問題のあった振る舞い?(例えば「Masterが居なくなった際に自身(Backup)がMasterに昇格する振る舞い」とか)
不具合の発生条件
※このセクションは3/31 15:20頃追記しました
中継機の故障内容は以下の2点とされています。
- 中継機能の故障
- トラフィックの転送そのものができなくなった、ということと推測
- 「故障シグナル」の発信機能の故障
- 聞いたことのない機能なので、詳細不明
これらの故障の原因(トリガー)が気になる。
上記には
「本番環境と同等の作りにしてあるテスト環境にスイッチを持ち込んでテストしたところ、不具合が再現した」(ANA広報)
とあるので、トリガーは判明していると思われる。
まとめ
正直エンジニアとしてはこの内容ではさっぱりわからない。 続報があれば記事の修正なり別記事を書くなりしたいと思います。
この記事の改定履歴
- 2016/03/31 15:20頃
- もっと知りたい点に「不具合の発生条件」を追記
- ANAさんの報告ページのURLが変わっていたので差し替え