最近Apache CloudStackに試したい機能が色々と追加されているので、さくっと試せるようにVagrant+VirtualBoxでApache CloudStackを動かしてみます。
DevCloudとは
DevCloudはVagrantとVirtualBoxで簡単にApache CloudStackの環境を構築できるツールです。
DevCloud - Apache Cloudstack - Apache Software Foundation
DevCloud自体は数年前からあり以下のように紹介記事もあります。基本的な部分は大きく変わっていないですが、数年前の記事で変わっている部分もあるので今回は新しくやり直してみます。
Cloud OS「Apache CloudStack」をお手軽に使ってみる方法
DevCloudが作成する仮想マシン
DevCloudは管理サーバー(management)とホスト(xenserver)の2台の仮想マシンをVirtualBox上に作成します。
管理サーバーにはCloudStackの管理サーバーの他にもNFSやMySQLがインストールされます。
ホストにはXenServer 6.2がインストールされます。
この2台の仮想マシンにCloudStackの動作に必要なソフトウェアはほとんどインストールされているので、CloudStackの設定だけで様々な構成を試すことができます。
DevCloudを使ったCloudStack構築手順
作成する環境について
検証機
- Mac OS X 10.11.6 (El Capitan)
- プロセッサ 1.4GHz Intel Core i5
- メモリ 8GB 1600MHz DDR3
バージョン
- VirtualBox (5.0.26)
- Vagrant (1.8.5)
- vagrant-berkshelf (5.0.0)
- vagrant-omnibus (1.4.1)
- ChefDK (0.17.17)
CloudStack
今回はApache CloudStack 4.9 を使用します。
他のバージョンでも大きく手順は変わらないと思います。
CloudStack Packages | The CloudStack Company
ネットワーク構成
今回はAdvancedゾーンを作成します。
Marvinの設定ファイルを変更すればBasicゾーンも同じやり方で作成できると思います。
プライマリストレージ
デフォルトのMarvinの設定ファイルではプライマリストレージにホスト(xenserver)のローカルストレージを使用するようになっていますが、ローカルストレージとNFSでは使い方が異なるところがいくつかあるのでどちらも使えるように設定ファイルを書き換えて見ます。
必要なソフトウェアのインストールと設定
まず、以下のソフトウェアをインストールします。
DevCloudは仮想マシンをChefでプロビジョニングします。Chefでのプロビジョニングに必要となるプラグインをインストールします。
$ vagrant plugin install vagrant-berkshelf vagrant-omnibus
Marvinのインストール
ゾーンを構築する際に使用するMarvinをインストールします。次のようにJenkinsの成果物を使ってインストールするのが楽だと思います。MarvinがなくてもCloudStackのインストールはできるので、上手く行かなければとりあえずスキップしても良いです。
$ pip install http://cdn.mysql.com/Downloads/Connector-Python/mysql-connector-python-2.0.4.zip
$ curl -O https://builds.apache.org/job/cloudstack-marvin/lastBuild/artifact/tools/marvin/dist/Marvin*.tar.gz/*zip*/dist.zip
$ unzip -o dist.zip
$ pip install Marvin*.tar.gz
依存関係にあるcryptographyのインストールで失敗する場合は、下記リンクを参考にcryptographyをインストールしてから再度pip install Marvin*.tar.gz
するとうまくいくかもしれないです。
Installation — Cryptography 1.6.dev1 documentation
VirtaulBoxのネットワーク設定
Macの場合は下記のようにVirtualBoxのネットワーク設定を変更します。
(Windowsの場合はアダプタの名前が違うようです。READMEにしたがって設定してください。)
- VirtualBoxのメニューから「環境設定」を開きます。
- 「ネットワーク」タブの「ホストオンリーネットワーク」を開きます。
- vboxnet0, vboxnet1, vboxnet2をそれぞれ下記のように設定します。(DHCPサーバーは「DHCPサーバー」タブの「サーバーを有効化」のチェックを外してください)
- vboxnet0
- IPv4アドレス: 192.168.22.1
- IPv4ネットマスク: 255.255.0
- DHCPサーバー: 無効
- vboxnet1
- IPv4アドレス: 192.168.23.1
- IPv4ネットマスク: 255.255.0
- DHCPサーバー: 無効
- vboxnet2
- IPv4アドレス: 192.168.24.1
- IPv4ネットマスク: 255.255.0
- DHCPサーバー: 無効
Vagrant 1.8.5の不具合対応
Vagrantのバージョン1.8.5にはauthorized_keysのパーミッションが正しく設定されない不具合があるのでplugins/guests/linux/cap/public_key.rb
を探して(私の環境では/opt/vagrant/embedded/gems/gems/vagrant-1.8.5/plugins/guests/linux/cap/public_key.rb
)次のように修正します。
1.8.5以外のバージョンでは修正の必要はありません。
if test -f ~/.ssh/authorized_keys; then
grep -v -x -f '#{remote_path}' ~/.ssh/authorized_keys > ~/.ssh/authorized_keys.tmp
mv ~/.ssh/authorized_keys.tmp ~/.ssh/authorized_keys
+ chmod 0600 ~/.ssh/authorized_keys
fi
CloudStackのソースコードを取得
DevCloudのソースコードはCloudStackののレポジトリに含まれているのでgit clone
等で取得します。
$ git clone https://github.com/apache/cloudstack.git
Advancedゾーン用のファイルがあるディレクトリに移動します。
cloudstack/tools/devcloud4
にはBasicゾーン用の設定もあるので、Basicゾーンを構築する場合はそちらを使うと良いでしょう。
$ cd cloudstack/tools/devcloud4/binary-installation-advanced
Vagrantfileとchef_configuration.jsonの修正
Chefのバージョンをlatestに変更
元のVagrantfileでは仮想マシンにインストールするChefのバージョンに11.16.4
が指定されていますが、そのままだとエラーになるので:latest
に書き換えます。
- management.omnibus.chef_version = "11.16.4"
+ management.omnibus.chef_version = :latest
SyncedFolderを無効化
私の環境ではデフォルトのSyncedFolderを有効にしておくとエラーになったので無効にしておきます。
@@ -40,6 +40,7 @@ end
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
+ config.vm.synced_folder ".", "/vagrant", disabled: true
config.vm.define 'xenserver' do |xenserver|
xenserver.vm.box = 'duffy/xenserver'
Chefレシピの修正
そのままでは仮想マシンを起動時にMarvinのインストールに失敗するので../common/binary-installation/recipes/management_server.rb
からインストールの処理をコメントアウトします。
インストールしておいたローカルのMarvinでゾーンの作成を行うので、この処理は実行されなくても問題ありません。
@@ -17,7 +17,7 @@
# under the License.
#
-include_recipe 'cloudstack::marvin'
+# include_recipe 'cloudstack::marvin'
include_recipe 'cloudstack::management_server'
cloudstack_setup_database node['cloudstack']['db']['host'] do
仮想マシンのメモリサイズの変更
デフォルトのメモリサイズはxenserverが6GB、managementが2GBとなっていますが、使用するマシンによっては大きすぎて動かせないので調整します。
私の環境では以下のようにしました。
@@ -75,7 +75,7 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
v.customize ['modifyvm', :id, '--hostonlyadapter2', virtualbox_interface_0]
v.customize ['modifyvm', :id, '--hostonlyadapter3', virtualbox_interface_1]
v.customize ['modifyvm', :id, '--hostonlyadapter4', virtualbox_interface_2]
- v.customize ['modifyvm', :id, '--memory', 6144]
+ v.customize ['modifyvm', :id, '--memory', 2048]
end
## Tweak kernel
@@ -92,7 +92,7 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
management.vm.network 'forwarded_port', guest: 8080, host: 8080
management.vm.provider 'virtualbox' do |v|
- v.customize ['modifyvm', :id, '--memory', 2048]
+ v.customize ['modifyvm', :id, '--memory', 512]
v.customize ['modifyvm', :id, '--hostonlyadapter2', virtualbox_interface_0]
v.customize ['modifyvm', :id, '--hostonlyadapter3', virtualbox_interface_1]
end
CloudStackのバージョン変更
chef_configuration.json
のレポジトリとシステムVMテンプレートのURLを構築したいバージョンに合わせて変更します。
@@ -24,12 +24,11 @@
"path": "/exports/primary"
},
"hypervisor_tpl": {
- "xenserver": "http://packages.shapeblue.com/systemvmtemplate/4.5/systemvm64template-4.5-xen.vhd.bz2"
+ "xenserver": "https://packages.shapeblue.com/systemvmtemplate/4.6/systemvm64template-master-4.6.0-xen.vhd.bz2"
},
"configuration": "/vagrant/marvin.cfg.erb",
- "yum_repo": "http://packages.shapeblue.com/cloudstack/testing/centos/4.5/",
- "apt_repo": "http://packages.shapeblue.com/cloudstack/testing/debian/4.5/",
- "version": "4.5.0"
+ "yum_repo": "http://packages.shapeblue.com/cloudstack/main/centos/4.9/",
+ "version": "4.9.0"
},
"iptables": {
"lans": ["eth1", "eth2"]
CloudStack設定の初期値の変更
CloudStackインストール後にMarvinを使って設定を行うため8096番ポートを許可したり、CPUやメモリが少ない環境でも仮想マシンを起動できるようデフォルトのオファリングのスペックを変更したりします。
設定変更はprefill.sql
というファイルを使用して直接データベースを更新します。
SyncedFolderを無効にしたのでパスを修正しておきます。
@@ -110,6 +111,7 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
CHEF_CONFIGURATION = JSON.parse(Pathname(__FILE__).dirname.join('chef_configuration.json').read)
+ management.vm.provision :file, source: "./prefill.sql", destination: "/tmp/prefill.sql"
management.vm.provision :chef_solo do |chef|
chef.log_level = :debug
chef.run_list = CHEF_CONFIGURATION.delete('run_list')
@@ -15,7 +15,7 @@
"rootpassword": "password",
"management_server_key": "password",
"database_key": "password",
- "prefill": "/vagrant/prefill.sql"
+ "prefill": "/tmp/prefill.sql"
},
"secondary": {
"path": "/exports/secondary"
元のprefill.sql
はcloudstack/tools/devcloud4/prefill.sql
にあるのでコピーして必要な箇所を変更します。主な変更点は以下の2つです。
- NFS用のオファリングを追加
- オーバープロビジョニング係数と閾値を引き上げ
$ cp ../prefill.sql .
@@ -15,9 +15,12 @@
-- specific language governing permissions and limitations
-- under the License.
-REPLACE INTO `cloud`.`disk_offering` (id, name, uuid, display_text, created, use_local_storage, type, disk_size) VALUES (17, 'Devcloud4 offering', UUID(), 'Devcloud4 offering', NOW(), 1, 'Service', 0);
+REPLACE INTO `cloud`.`disk_offering` (id, name, uuid, display_text, created, use_local_storage, type, disk_size) VALUES (17, 'Devcloud4 offering - Local Storage', UUID(), 'Devcloud4 offering - Local Storage', NOW(), 1, 'Service', 0);
REPLACE INTO `cloud`.`service_offering` (id, cpu, speed, ram_size) VALUES (17, 1, 200, 256);
-REPLACE INTO `cloud`.`disk_offering` (name, uuid, display_text, created, use_local_storage, type, disk_size) VALUES ('Devcloud4 disk offering', UUID(), 'Devcloud4 disk offering', NOW(), 1, 'Disk', 1073741824);
+REPLACE INTO `cloud`.`disk_offering` (name, uuid, display_text, created, use_local_storage, type, disk_size) VALUES ('Devcloud4 disk offering - Local Storage', UUID(), 'Devcloud4 disk offering - Local Storage', NOW(), 1, 'Disk', 1073741824);
+REPLACE INTO `cloud`.`disk_offering` (id, name, uuid, display_text, created, use_local_storage, type, disk_size) VALUES (19, 'Devcloud4 offering', UUID(), 'Devcloud4 offering', NOW(), 0, 'Service', 0);
+REPLACE INTO `cloud`.`service_offering` (id, cpu, speed, ram_size) VALUES (19, 1, 200, 256);
+REPLACE INTO `cloud`.`disk_offering` (name, uuid, display_text, created, use_local_storage, type, disk_size) VALUES ('Devcloud4 disk offering', UUID(), 'Devcloud4 disk offering', NOW(), 0, 'Disk', 1073741824);
REPLACE INTO `cloud`.`configuration` (category, instance, component, name, value) VALUES ('Advanced', 'DEFAULT', 'management-server', 'integration.api.port', '8096');
REPLACE INTO `cloud`.`configuration` (instance, name,value) VALUE('DEFAULT','router.ram.size', '256');
REPLACE INTO `cloud`.`configuration` (instance, name,value) VALUE('DEFAULT','router.cpu.mhz','256');
@@ -31,4 +34,10 @@
REPLACE INTO `cloud`.`configuration` (instance, name, value) VALUE('DEFAULT', 'expunge.interval', '60');
REPLACE INTO `cloud`.`configuration` (instance, name, value) VALUE('DEFAULT', 'management.network.cidr', '0.0.0.0/0');
REPLACE INTO `cloud`.`configuration` (instance, name, value) VALUE('DEFAULT', 'secstorage.allowed.internal.sites', '0.0.0.0/0');
-UPDATE `cloud`.`vm_template` SET unique_name="Macchinina",name="Macchinina",url="http://dl.openvm.eu/cloudstack/macchinina/x86_64/macchinina-xen.vhd.bz2",checksum="30985504bc31bf0cd3b9d2c6ca7944d3",display_text="Macchinina" where id=5;
\ No newline at end of file
+REPLACE INTO `cloud`.`configuration` (instance, name, value) VALUE('DEFAULT', 'cluster.cpu.allocated.capacity.disablethreshold', '1');
+REPLACE INTO `cloud`.`configuration` (instance, name, value) VALUE('DEFAULT', 'cluster.memory.allocated.capacity.disablethreshold', '1');
+REPLACE INTO `cloud`.`configuration` (instance, name, value) VALUE('DEFAULT', 'pool.storage.allocated.capacity.disablethreshold', '1');
+REPLACE INTO `cloud`.`configuration` (instance, name, value) VALUE('DEFAULT', 'pool.storage.capacity.disablethreshold', '1');
+REPLACE INTO `cloud`.`configuration` (instance, name, value) VALUE('DEFAULT', 'storage.overprovisioning.factor', '3');
+REPLACE INTO `cloud`.`configuration` (instance, name, value) VALUE('DEFAULT', 'mem.overprovisioning.factor', '3');
+UPDATE `cloud`.`vm_template` SET unique_name="Macchinina",name="Macchinina",url="http://dl.openvm.eu/cloudstack/macchinina/x86_64/macchinina-xen.vhd.bz2",checksum="30985504bc31bf0cd3b9d2c6ca7944d3",display_text="Macchinina" where id=5;
仮想マシンの起動
vagrant up
を実行するとxenserver
とmanagement
の2台の仮想マシンが立ち上がります。
$ vagrant up
完了後にブラウザでhttp://192.168.22.5:8080/client/またはhttp://localhost:8080/client/にアクセスするとCluodStackのUIが開きます。
ユーザーネーム: admin、パスワード: passwordでログインできます。
(CloudStackのUIが見えるようになるまで完了してから数分かかるかもしれません。)
ゾーン作成
Marvinを使ってゾーンを作成します。
marvin.cfg.erb
をコピーして管理サーバーのIPアドレスを書き換えます。
$ cp marvin.cfg.erb marvin.cfg
@@ -109,15 +109,15 @@
},
"mgtSvr": [
{
- "mgtSvrIp": "<%= @management_server_ip %>",
- "port": <%= @management_server_port %>
+ "mgtSvrIp": "192.168.22.5",
+ "port": 8096
}
],
"dbSvr": {
- "dbSvr": "<%= @database_server_ip %>",
- "port": <%= @database_server_port %>,
- "user": "<%= @database_user %>",
- "passwd": "<%= @database_password %>",
- "db": "<%= @database %>"
+ "dbSvr": "192.168.22.5",
+ "port": 3306,
+ "user": "cloud",
+ "passwd": "cloud",
+ "db": "cloud"
}
次のコマンドを実行するとゾーンが作成されます。
$ python ../../../tools/marvin/marvin/deployDataCenter.py -i marvin.cfg
UIから「Infrastructure > System VMs」を確認して、2台のVM(SSVM, CPVM)が正常に起動していれば成功です。
仮想マシンの作成
動作確認のため仮想マシンを作成してみます。
基本的には通常通りに作成すれば良いのですが、普通のテンプレート、オファリングを使うと大きすぎてキャパシティの制限に引っかかったりするのでprefill.sql
で追加した以下のテンプレート、オファリングを使うと良いです。
- テンプレート: Macchinina
- Compute Offering
- Devcloud4 offering
- Devcloud4 offering - Local Storage
- Disk Offering
- Devcloud4 disk offering
- Devcloud4 disk offering - Local Storage
Macchinina
テンプレートから作成したVMには、ユーザー: root、パスワード: passwordでログインできます。
トラブルシューティング
システムVMが正常に起動しなかったり、仮想マシンの作成に失敗してしまう場合はmanagentにログインしてログを確認します。キャパシティの制限に引っかかっているケースが多いのではないかと思います。
$ vagrant ssh management
$ sudo less /var/log/cloudstack/management/management-server.log