仮想マシンのリソース制限 日本 OpenStack ユーザ会第 17 回勉強会 2014/01/20 株式会社日立製作所横浜研究所運用管理システム研究部クラウドサービスプロジェクト 西島直
Contents 1. クラウドにおけるディスク I/O の問題点 2. 仮想マシンのリソース制限 3. リソース制限した結果 1
1. クラウドにおけるディスク I/O の問題点 2
1-1 クラウドにおけるディスク I/O の問題点 仮想マシンの I/O 性能が一定ではない 昨日と今日で I/O 性能が違う I/O の途中で極端に性能が悪くなる I/O を発行するタイミングによって性能にばらつきができる 仮想マシンの性能見積もりが難しい 理由は様々な要因が絡んでる ホストマシンの I/O 帯域を共有しているので他の仮想マシンが I/O を発行している場合に影響がでる 仮想マシンだけでなくホストがログの書き込みなど I/O を発行している I/O スケジューラにより仮想マシンの I/O を公平にしようとしている 3
Mb/s 1-2 クラウドにおけるディスク I/O の実験 Fedora19 + RDO havana(all in one) でディスク I/O の性能実験 Xeon(R) CPU E3-1220 の 4 コア / メモリ 16G/1TB(SATA600 7200rpm) fio で計測 direct I/O で 10MB のファイルをシーケンシャルに 60 秒間書き込む vm02 は 20 秒から vm03 と vm04 は 40 秒から書き込み開始 35 vm01 vm02 vm03 vm04 30 25 20 15 1VM で約 25MB/s 4VM 合計で約 10MB/s 10 5 0 0 5 10 15 20 25 30 35 40 45 50 55 仮想マシンの I/O 性能を一定にしたい 秒 4
2. 仮想マシンのリソース制限 5
2-1 Instance Resource Quota Yaguang Tang 氏のパッチによって libvirt がもつリソースチューニング機能を利用したフレーバーごとに CPU や disk I/O, network のリソース制限が Grizzly から利用できるようになった commit 082c4ca417705975b8ef3672ce6ed40661d0f019 Author: Yaguang Tang <yaguang.tang@canonical.com> Date: Fri Feb 15 22:12:58 2013 +0800 Add libvirt XML schema support for resource tuning parameters Extend the libvirt XML config classes to support for CPU, disk IO, network traffic tuning parameters. Libvirt のリソースチューニング機能とは? https://wiki.openstack.org/wiki/instanceresourcequota Libvirt は仮想マシンの制御を抽象化したライブラリ 様々なハイパーバイザをサポートする 仮想マシンをドメインと呼び ドメインを構成するファイルを XML で記述している XML にはドメインの定義に必要なオプションや 使用するリソースなどがあり その機能の一部として cgroups や QEMU の機能を用いた CPU Tuning や Block I/O Tuning などがある http://libvirt.org/formatdomain.html#elementscputuning http://libvirt.org/formatdomain.html#elementsdisks 6
2-2 CPU のリソース制限 cpu_shares CPU を利用する時間の比重を指定する 他の VM の設定に基づく相対的な尺度なので値に単位はない 例えば vm01 に 2048 の値が設定され vm02 に 1024 の値が設定されているとき 前者は後者より 2 倍の CPU 時間を利用する cpu_period CPU を利用する時間の間隔 ( マイクロ秒単位 ) を指定する 値は 1000~ 1000000 が利用可能 cpu_quota CPU の最大帯域幅 ( マイクロ秒単位 ) を指定する 値は 1000~ 18446744073709551 を指定する マイナスの値は帯域幅制御されないことを意味する 実行例 : vm01 1 サイクル 2 : 1 vm02 vm01 600msec 1000msec nova-manage flavor set_key --name m1.small --key quota:cpu_shares --value 1024 nova-manage flavor set_key --name m1.small --key quota:cpu_period --value 500000 nova-manage flavor set_key --name m1.small --key quota:cpu_quota --value 1000000 Quota:600msec Period:1000msec 7
2-3 Network Traffic のリソース制限 inbound_average, inbound_peak, inbound_burst inbound の平均ビットレート (kbps) を指定する Average は必須項目でその他は任意の項目 Peak はそのインターフェースが送信可能な最大帯域幅で burst はピーク時にバーストできるバイト量を指定する outbound_average, outbound_peak, outbound_burst outbound の平均ビットレート (kbps) を指定する Average は必須項目でその他は任意の項目 Peak はそのインターフェースが受信可能な最大帯域幅で burst はピーク時にバーストできるバイト量を指定する 実行例 : nova-manage flavor set_key --name m1.small --key quota:vif_inbound_average --value 10240 nova-manage flavor set_key --name m1.small --key quota:vif_outbound_average --value 10240 注意 Wikiのページは間違っている修正しました inboud_* ではなくvif_inbound_* パッチの説明はvif_inbound_* となっている 8
2-4 Disk I/O のリソース制限 total_bytes_sec 1 秒間に利用可能な Disk I/O のスループット量を指定する read_bytes_sec や write_bytes_sec と同時に利用することはできない read_bytes_sec, write_byte_sec 1 秒間に利用可能な Disk I/O の読み込み ( 書き込み ) スループット量を指定する total_iops_sec 1 秒間に利用可能な Disk I/O の IOPS を指定する read_iops_sec や write_iops_sec と同時に利用することはできない read_iops_sec, write_iops_sec 1 秒間に利用可能な Disk I/O の読み込み ( 書き込み )IOPS を指定する 実行例 : nova-manage flavor set_key --name m1.small --key quota:disk_read_bytes_sec --value 1024000 nova-manage flavor set_key --name m1.small --key quota:disk_write_bytes_sec --value 1024000 注意 Wiki のページは間違っている 正しくは disk_* と disk_* が必要 IOPS せ設定する場合も disk_ が必要 パッチの説明は disk_* となっている 修正しました 9
2-5 リソース制限したフレーバーの作成方法 読み込み 書き込みを 1MB/s に制限したフレーバーを作成する # nova flavor-create q1.small <flavor-id> 2048 20 1 # nova-manage flavor set_key --name q1.small --key quota:disk_read_bytes_sec --value 1024000 Key quota:read_bytes_sec set to 1024000 on instance type q1.small # nova-manage flavor set_key --name q1.small --key quota:disk_write_bytes_sec --value 1024000 Key quota:write_bytes_sec set to 1024000 on instance type q1.small Horizon からでも設定が可能 10
2-6 リソース制限した仮想マシンの制限を確認 仮想マシンの XML を確認 # nova boot --flavor <flavor-id> --image <image-id> --key-name <key-name> 1mb_limited # cat /var/lib/nova/<uuid>/libvirt.xml <devices> <disk type="file" device="disk"> <driver name="qemu" type="qcow2" cache="none"/> <source file="/var/lib/nova/instances/3dfed148-c592-4da0-bfe8-753be30528b0/disk"/> <target bus="virtio" dev="vda"/> <iotune> <read_bytes_sec>1024000</read_bytes_sec> <write_bytes_sec>1024000</write_bytes_sec> </iotune> </disk> 読み込み 書き込み制限を確認 # virsh blkdeviotune instance-00000016 vda total_bytes_sec: 0 read_bytes_sec : 1024000 write_bytes_sec: 1024000 total_iops_sec : 0 read_iops_sec : 0 write_iops_sec : 0 1024kb の制限を確認 <iotune> が追記された 11
3. リソース制限した場合の実験結果 12
Mb/s 3-1 リソース制限の実験 以下の制限を課して性能測定した vm01 は 10MB/s, vm02 は 1MB/s, vm3 は 1MB/s, vm04 は 2MB/s の write 制限 12 vm01 vm02 vm03 vm04 10 8 6 4 2 0 0 5 10 15 20 25 30 35 40 45 50 55 write 性能が制限の通りになることが確認できた 4VM で 14MB/s になり 制限なしより 40% 効率的に利用できた 秒 13
Mb/s Mb/s 3-2 リソース制限の課題 (1) 帯域幅を動的に変更することができない リソースが余っているときは多くの帯域幅を利用したい 例えば 0 秒から 20 秒は他の VM がいないので帯域を 25MB/s 利用し他の VM の I/O が開始された場合は帯域を制限する等 vm01 vm02 vm03 vm04 35 30 25 20 vm01 vm02 vm03 vm04 15 10 5 15 10 5 0 0 5 10 15 20 25 30 35 40 45 50 55 秒 0 0 5 10 15 20 25 30 35 40 45 50 55 秒 14
Kb/s 3-3 リソース制限の課題 (2) 物理リソースの最大 I/O 帯域幅以上に設定が可能 全ての仮想マシンに I/O 帯域の制限が必要 左の図はすべての VM に制限を施した 右の図は vm1 だけ制限を課していない場合 (or 物理リソース以上の帯域に設定した場合 ) vm1 だけ I/O 帯域を確保し他の VM は I/O 帯域が確保できない limited vm1 is no limit 6000 6000 5000 5000 4000 3000 2000 vm1 vm2 vm3 vm4 4000 3000 2000 vm1 vm2 vm3 vm4 1000 1000 0 0 時間 時間 15
3-4 その他 Havana で Cinder Volume の帯域制限が可能になった ( らしい ) Volume Type に対応付ける Hypervisor か back-end もしくは両方で QoS を実施する 確かにソースにはそれらしきものがある [root@havana ~(keystone_admin)]# less nova/virt/libvirt/volume.py def connect_volume(self, connection_info, disk_info): # Extract rate_limit control parameters if 'qos_specs' in data and data['qos_specs']: tune_opts = ['total_bytes_sec', 'read_bytes_sec', 'write_bytes_sec', 'total_iops_sec', 'read_iops_sec', 'write_iops_sec'] specs = data['qos_specs'] if isinstance(specs, dict): for k, v in specs.iteritems(): if k in tune_opts: new_key = 'disk_' + k setattr(conf, new_key, v) Cinderのコマンドでqos_specsが設定できる cinder qos-create <name> write_bytes_sec=102400 consumer=front-end cinder qos-associate <qos_specs> <volume_type_id> 実行してみる 反映されない 16
END 仮想マシンのリソース制限 2014/01/20 株式会社日立製作所横浜研究所運用管理システム研究部クラウドサービスプロジェクト 西島直 17