Backup ExecでHyper-V仮想マシンバックアップ/リストア時にGRT用テンポラリディレクトリは使われるのか?


Backup ExecではHyper-V/vSphereの仮想マシンバックアップを仮想レイヤーの方からバックアップを行った場合、その仮想マシンの上でWindowsが動いている場合は、ファイル単位でのリストアを行えるGRT機能というのをサポートしている。

で・・・Backup Execの設定を見ていくと、全体設定の中に
・Granular Recover Technology
  バックアップ時にBackup Execが一時的にデータを保存するパス C:\TEMP
  リストア時にBackup Execが一時的にデータを保存するパス   C:\TEMP
というものがある。

仮想マシンバックアップ時にC:\TEMPを観察してみたけど、使用している様子が見受けられない。
不思議に思って調べてみた

Veritas Backup Exec 管理者ガイド「Granular Recovery Technology」の「Granular Recovery Technology を使うバックアップ用の推奨デバイス」

ディスクデバイス、重複排除デバイス、およびディスクカートリッジデバイスに送信された GRT 対応のバックアップジョブの暗号化を有効にすると、Backup Exec は詳細バックアップセットを暗号化された形式でディスクに格納しません。GRT 非対応のバックアップソースのバックアップセットのみが暗号化型式で格納されます。 クラウド、OpenStorage、およびテープデバイスに送信されるバックアップジョブのすべてのバックアップセットは、暗号化型式で格納されます。

ファイルサイズの制限があるボリューム上でディスクストレージデバイスを使う必要がある場合、Backup Exec ではステージングの場所が必要です。 Backup Exec はバックアップジョブの実行中に少しのメタデータをステージングの場所に一時的に格納します。 バックアップが終了したら、ステージングの場所からデータを削除します。 ただし、ファイルサイズの制限がないボリューム上のディスクストレージデバイスを宛先として使う場合、ステージングの場所は必要ありません。

ステージングの場所のデフォルトのパスは C:\temp です。

テープ装置などを使っている場合はステージングの場所が必要。
ローカルのNTFSディスクやCIFS共有を使っている場合は、「ファイルサイズの制限に制限がないボリューム」なので、ステージングの場所は不要。

というわけで、今回テストした環境は、CIFS共有をバックアップ保存先としていたため、ステージング領域が不要であった。ということのようでした。

BackupExec / NetBackupでWinPEを使った起動ディスクで仮想マシンをリカバリするとNIC設定が消える場合がある


BackupExec 20.1を使ってHyper-V上のWindows Serverのバックアップを行った。
最初、Hyper-V経由で仮想マシンとしてのバックアップにしようと考えていたのだが、BackupExecでは特定のドライブのバックアップを取らないという設定が出来ず、必ず全ドライブをバックアップする必要があることが分かった。
このため、対象サーバにBackupExec Agentをインストールして、エージェント経由でのバックアップを取ることにした。

で、Windows ADKを使用したSDR起動ディスクを作って、フルリストアのテストを行ったところ問題発生。
NICが2つついている場合、片側につけたIPアドレス設定がリカバリされない。

いろいろ条件をかえて試してみたけど、必ず発生している。

どうやら仕様らしい。

Veritasのサイト上だとNetBackup / vSphere環境での話として、「After restore a Windows Virtual Machine to original or alternate location, Virtual NIC settings may be changed or lost.」というのが掲載されている。

回避方法はなく、手動で再設定しろ、だそうな

ESXi 6.5でVMDirectPath I/Oが設定できるけど使えない


ESXi6.5環境において、16Gb FC HBAのQLogic QLE2662に対して、VMDirectPath I/Oで仮想マシンから直接使える様にパススルー設定をした。
設定は問題なくできたものの、仮想マシンを起動してみると、全然認識してくれない。

よく、パススルー設定で選択できない、という話は聞くが、今回は、設定は出来ている。

ためしに8GbのFC HBA QLE2540 を使ってみると、同様の手法で設定でき、仮想マシンからちゃんと認識している。

ここら辺に糸口があるな、と調査。


<調査過程は省略>

結論からすると「VMware vSphere VMDirectPath I/O:プラットフォームとデバイスの要件」(英語版:VMware vSphere VMDirectPath I/O: Requirements for Platforms and Devices)の「PCI 機能リセット」設定の問題だった。

パススルー設定したPCIeデバイスは、物理サーバ起動時に初期化しているが、接続されている仮想マシンが起動する毎にPCIeデバイスの初期化を行う必要がある。
この初期化手法をどういう風に行うか、という設定を適切に行わないと、仮想マシン側で認識できないようだ。

設定はESXi上の /etc/vmware/passthru.map で行われている。

うまく動いたQLE2540のVender ID/Product IDを「esxcfg-info」コマンドで確認すると「1077」「2523」。
これは /etc/vmware/passthru.map で「1077 2532 default false」という定義で設定されている。
意味は、初期化手法がdefaultで、fptShareableがfalseなので全体初期化になる、というもの。
全体初期化であるため、1枚に複数ポートがある場合、別の仮想マシンに割り当てることができず、同じ仮想マシンに全部のポートを割り当てる必要がある、ということになる。

動かなかったQLE2662の方は「1077」「2031」。
記載が無いので、適切な初期化方法を見つけて追加する必要がある。
KBに「PCI ホスト ブリッジ直下の PCI 機能を VMDirectPath I/O で使用するには、FLR または D3Hot リセットをサポートする必要があります」とあるため「flr」の場合と「d3d0」の場合をそれぞれ実験。
結果、「d3d0」の時のみ仮想マシン側でもデバイスを認識してくれた。

ということで、/etc/vmware/passthru.mapの最終行に「1077 2031 d3d0 default」という記載を追加した。

なお、 passthru.map の修正を行った後は、ESXiを再起動する必要がある。

# cd /etc/vmware/passthru.map
# passthrough attributes for devices
# file format: vendor-id device-id resetMethod fptShareable
# vendor/device id: xxxx (in hex) (ffff can be used for wildchar match)
# reset methods: flr, d3d0, link, bridge, default
# fptShareable: true/default, false

# Intel 82579LM Gig NIC can be reset with d3d0
8086  1502  d3d0     default
# Intel 82598 10Gig cards can be reset with d3d0
8086  10b6  d3d0     default
8086  10c6  d3d0     default
8086  10c7  d3d0     default
8086  10c8  d3d0     default
8086  10dd  d3d0     default
# Broadcom 57710/57711/57712 10Gig cards are not shareable
14e4  164e  default  false
14e4  164f  default  false
14e4  1650  default  false
14e4  1662  link     false
# Qlogic 8Gb FC card can not be shared
1077  2532  default  false
# QLogic QL45604 cards need to be reset with "link" and cannot be shared
1077  1634  link     false
1077  1629  link     false
1077  1636  link     false
1077  1656  link     false
1077  1644  link     false
1077  1654  link     false
# LSILogic 1068 based SAS controllers
1000  0056  d3d0     default    
1000  0058  d3d0     default
# NVIDIA
10de  ffff  bridge   false
# for QLE2662
1077  2031  d3d0     default
#

CephのOSD毎のPlacement Groupの数を確認する



Cephのテスト環境を構築してみた。

シナリオ通りに構築を進めていき、とりあえずは問題なくは終わった。
終わったんだけど、最後にステータスでも確認してみるかとceph healthを実行してみたところHEALTH_WARNが・・・

[root@ceph01 ~]# ceph health
HEALTH_WARN too many PGs per OSD (480 > max 300)
[root@ceph01 ~]#

OSDにたくさんのPGが割り当てられてる、といってるけど、具体的にはどれくらいあるんだろう?

と調べていくと、stackoverflowにある、下記のPGとOSDの関係性に関する質問を発見
Ceph too many pgs per osd: all you need to know

そこで紹介されている「Get the Number of Placement Groups Per Osd」に、OSD毎のPG数をコマンドで確認する手法が掲載されていた。

「ceph pg dump」の出力結果を整形して見やすいようにしている、というものだった。

ceph pg dump | awk '
BEGIN { IGNORECASE = 1 }
 /^PG_STAT/ { col=1; while($col!="UP") {col++}; col++ }
 /^[0-9a-f]+\.[0-9a-f]+/ { match($0,/^[0-9a-f]+/); pool=substr($0, RSTART, RLENGTH); poollist[pool]=0;
 up=$col; i=0; RSTART=0; RLENGTH=0; delete osds; while(match(up,/[0-9]+/)>0) { osds[++i]=substr(up,RSTART,RLENGTH); up = substr(up, RSTART+RLENGTH) }
 for(i in osds) {array[osds[i],pool]++; osdlist[osds[i]];}
}
END {
 printf("\n");
 printf("pool :\t"); for (i in poollist) printf("%s\t",i); printf("| SUM \n");
 for (i in poollist) printf("--------"); printf("----------------\n");
 for (i in osdlist) { printf("osd.%i\t", i); sum=0;
   for (j in poollist) { printf("%i\t", array[i,j]); sum+=array[i,j]; sumpool[j]+=array[i,j] }; printf("| %i\n",sum) }
 for (i in poollist) printf("--------"); printf("----------------\n");
 printf("SUM :\t"); for (i in poollist) printf("%s\t",sumpool[i]); printf("|\n");
}'

これをテスト環境で実行してみると下記の様な出力を得られた

[root@ceph01 ~]# ceph pg dump | awk '
BEGIN { IGNORECASE = 1 }
 /^PG_STAT/ { col=1; while($col!="UP") {col++}; col++ }
 /^[0-9a-f]+\.[0-9a-f]+/ { match($0,/^[0-9a-f]+/); pool=substr($0, RSTART, RLENGTH); poollist[pool]=0;
 up=$col; i=0; RSTART=0; RLENGTH=0; delete osds; while(match(up,/[0-9]+/)>0) { osds[++i]=substr(up,RSTART,RLENGTH); up = substr(up, RSTART+RLENGTH) }
 for(i in osds) {array[osds[i],pool]++; osdlist[osds[i]];}
}
END {
 printf("\n");
 printf("pool :\t"); for (i in poollist) printf("%s\t",i); printf("| SUM \n");
 for (i in poollist) printf("--------"); printf("----------------\n");
 for (i in osdlist) { printf("osd.%i\t", i); sum=0;
   for (j in poollist) { printf("%i\t", array[i,j]); sum+=array[i,j]; sumpool[j]+=array[i,j] }; printf("| %i\n",sum) }
 for (i in poollist) printf("--------"); printf("----------------\n");
 printf("SUM :\t"); for (i in poollist) printf("%s\t",sumpool[i]); printf("|\n");
}'
dumped all in format plain

pool :  4       5       6       7       8       9       10      11      12      13      14      1       2       15      3       | SUM
----------------------------------------------------------------------------------------------------------------------------------------
osd.4   39      29      25      36      27      24      35      34      30      28      34      33      35      29      32      | 470
osd.5   36      35      28      31      21      29      27      37      37      30      32      36      37      27      37      | 480
osd.6   38      37      30      35      30      24      37      33      32      31      27      32      33      31      27      | 477
osd.7   33      34      30      31      25      34      35      42      32      33      21      30      31      28      33      | 472
osd.8   29      32      39      35      28      39      31      34      36      35      38      34      35      24      21      | 490
osd.9   32      34      33      33      37      38      39      27      30      31      28      29      27      26      26      | 470
osd.10  39      31      34      24      35      36      35      40      34      37      37      45      32      31      37      | 527
osd.11  25      26      30      33      36      42      27      30      42      31      28      32      28      35      31      | 476
osd.0   27      39      38      29      35      24      34      26      28      31      38      23      33      31      32      | 468
osd.1   29      30      29      28      43      24      34      30      22      34      30      37      34      44      29      | 477
osd.2   27      32      35      33      31      38      21      24      30      26      37      26      26      36      33      | 455
osd.3   30      25      33      36      36      32      29      27      31      37      34      27      33      42      46      | 498
----------------------------------------------------------------------------------------------------------------------------------------
SUM :   384     384     384     384     384     384     384     384     384     384     384     384     384     384     384     |
[root@ceph01 ~]#

また、NAKAMURA Minoru’s Home Pageにある「RADOS の概略 (RADOS と CRUSH と Placement Group の関係)」は、Cephの理解に役に立った

OpenStack上の仮想インスタンスを物理サーバ間移動(マイグレーション)させる手法について


2022/04/20追記

このページに記載しているのはOpenStack Pike(16番目のリリース)ぐらいまでの話です。

それ以降のOpenStackについては関わっていないので不明です。


OpenStackで仮想インスタンスを動かしている場合に、物理サーバ間を移動させる手法について、いまいちまとまっているものがなかったので、メモ。

・物理サーバを指定して仮想インスタンスを起動

→ 不可能

アベイラビリティーゾーン(availability-zone)というサーバをまとめたグループ(雑な表現)を指定して起動することまでしかできない

・仮想インスタンスを稼働中に物理サーバを移動させる

→ 可能

例えば起動ディスクを含めcinderボリュームを使っている場合、下記コマンドで実施できる

# openstack server migrate --live 移動先ComputeNode --block-migration 仮想インスタンスUUID --wait

なぜか「migrate」と「migration」の2つの単語が混じっている、という不親切なつくりなので、惑わされないこと。

上記だと、移動が終わるまでコマンドが終了しない。「–wait」を抜いた場合、下記の様な形でマイグレーションの進捗状況を確認することが出来る

# openstack server migrate --live 移動先ComputeNode --block-migration 仮想インスタンスUUID
# nova server-migration-list
# nova server-mgirationshow 仮想インスタンスUUID マイグレーション番号

「openstack sevrer show 仮想インスタンスUUID」では進捗のパーセンテージのみ確認可能。

それに対して、「nova server-mgirationshow 仮想インスタンスUUID マイグレーション番号」では、全体で何バイト転送する必要があり、現在何バイト転送が終了しているか、といった詳細を確認することができる。

参考資料
 nova Migrate instances
 nova Live-migrate instances

・止まってる物理サーバ上にあった仮想インスタンスを他の物理サーバで起動させる

→ nova evacuateコマンドで可能

# nova evacuate 仮想インスタンスUUID 移動先ComputeNode

nova evacuateは、元々起動していた物理サーバ上の「nova-compute」と通信が取れない場合に実行できる。

nova-computeと通信が取れる状態だとエラーになる・・・無理矢理実行したいのであれば、該当サーバ上のnova-computeを落とせばできなくもない。

参考資料
 nova Evacuate instances
 nova Recover from a failed compute node

・ERRORステータスになっててmigrateが出来ない

「nova reset-state 仮想インスタンスUUID」を実行することで、ステータスがリセットできる。

参考資料
 nova Troubleshoot Compute