Mais conteúdo relacionado
Semelhante a DCK Server プロトタイプ (20)
Mais de Etsuji Nakai (20)
DCK Server プロトタイプ
- 5. NII dodai-deploy2.0 project
VM間の連携方法
一般的な分類
– Fork
• 新しいVMを起動して、実行中コードの指定関数の実行を開始する
– Messaging
• pub/subモデルでイベント情報を交換する
– Shared memory
• 複数VM間で情報共有するWhite Board機能
• hostnameなどの基本情報をVM間で共有することができる
– Signal
• 指定VMのイベントハンドラを起動する
• Tomcatが追加されたらApacheに通知して負荷分散設定を変更する、など
の使い方ができる
5
- 6. NII dodai-deploy2.0 project
擬似コードイメージ
# dcinit web3tier start
fork apache
install apache
fork tomcat
install apache
fork postgresql
install apache
main {
global id = $$ # Uniq job ID
shmget(id)
shm_write(id, “controller:hostname”, $HOSTNAME)
fork apache
fork tomcat
fork postgresql
shm_read(id, “apache:ready”) # Blocking read
shm_read(id, “tomcat:ready”) # Blocking read
shm_read(id, “postgres:ready”) # Blocking read
while (1) {
fork tomcat if scaleout_is_required
}
}
apache {
install apache
shm_write(id, “apache:hostname”, $HOSTNAME)
shm_write(id, “apache:reday”, true)
event_loop
}
# signal handler to modify apache conf for new tomcat
add_tomcat {
tomcat_hosts=shm_read(id, “tomcat:hostlist”)
update_apache_config(tomcat_hosts)
}
tomcat {
install tomcat
shm_append(id, “tomcat:hostlist”, $HOSTNAME)
pgsql=shm_read(id, “pgsql:hostname”)
apache=shm_read(id, “apache:hostname”)
notify “add_tomcat” $apache
shm_write(id, “tomcat:ready”, true)
event_loop
}
6
postgres {
install postgres
shm_write(id, “postgres:hostname”, $HOSTNAME)
shm_write(id, “postgres:ready”, true)
event_loop
}
- 10. NII dodai-deploy2.0 project
「User Data」「メタデータ」「UUID」について
OpenStackでは、VM起動時にテキストの「User Data」を受け渡すことができま
す。特にスクリプトファイルを渡すと、ゲストOS起動後に自動実行されます。
– DCK Serverでは、「User Data」を利用して、VM連携処理の「ブートスト
ラップ」を実施しています。
OpenStackでは、各VMに対して、「Key=Value」形式のメタデータを複数セッ
トすることができます。
– DCK Serverでは、VM間でメタデータを相互参照することで、VM間のメッ
セージ伝達を行います。
OpenStackでは、起動中のVMにユニークなUUIDがアサインされます。
– DCK Serverでは、UUIDをVMの識別子(プロセスID)として使用します。
10
- 11. NII dodai-deploy2.0 project
DCK ServerがREST APIで提供する機能
exec
– 新規VMを起動する。
• 親VMのUUID、OSイメージ、User Dataを指定する。
fork
– 既存VMの「User Data」を再利用して、新規VMを起動する。
• forkされたVMは、メタデータに「forked=true」がセットされる。
ps
– 起動中VMの情報を取得する
ppid
– 指定VMの親VMのUUIDを取得する
cpid
– 指定VMの子VMのUUID(複数)を取得する
poke
– 指定VMに指定のメタデータをセットする
peek
– 指定VMのメタデータを取得する
delete
– 指定VM(および、子VM)を停止・削除する
11
- 12. NII dodai-deploy2.0 project
libdck.shについて
DCK ServerのREST APIを簡便なコマンドで利用するためのライブラリ(シェルスクリプトの関数群)
– User Dataなどから次のようにインクルードして使用する。
– # curl -s http://<dckserver>:5000/dck/api/v1.0/libdck > /tmp/libdck.sh
– # . /tmp/libdck.sh
exec
fork
# dck-exec <親VM UUID> <新規VM名> <イメージID> <User Dataファイル>
ps
ppid
# dck-ps / # dck-ps <UUID>
cpid
poke
# dck-cpid <UUID>
peek
delete
# dck-peek <UUID> / # dck-peek <UUID> <key>
# dck-fork <親VM UUID> <新規VM名>
# dck-ppid <UUID>
# dck-poke <UUID> <key> <value>
# dck-delete <UUID>
その他補助関数
– JSONから特定キーの値を取り出す
# json_elem <key> <JSON>
12
- 13. NII dodai-deploy2.0 project
forkを利用した簡単なUser Dataの例
#!/bin/bash
curl -s http://192.168.101.9:5000/dck/api/v1.0/libdck > /tmp/libdck.sh
. /tmp/libdck.sh
pid=$( json_elem "uuid" "$(curl -s http://169.254.169.254/openstack/latest/meta_data.json )" ) # 自分のUUID
forked=$(dck-peek $pid "forked")
# forkした子VMか判断するためのメタデータ
function child {
echo "I'm child" > /etc/motd
dck-poke $pid "child_setup" "true"
}
# 子VMの場合の処理
# 処理完了を自身のメタデータに記録
function parent {
# 親VMの場合の処理
for i in 1 2; do
result=$(dck-fork $pid "child$i")
# 子VMをfork
cpids[i]=$(json_elem "pid" "$result")
done
for cpid in ${cpids[@]}; do
# 子VMの処理完了をループで待つ
while [[ ! $(dck-peek $cpid "child_setup") == "true" ]]; do
sleep 10
done
done
echo "I'm parent" > /etc/motd
}
# main
if [[ $forked == "true" ]]; then # 親VMと子VMで処理を分岐
child
else
parent
fi
exit
13
- 14. NII dodai-deploy2.0 project
Forkを利用したスケールアウトWebサーバの例 (1/2)
#!/bin/bash
curl -s http://192.168.101.9:5000/dck/api/v1.0/libdck > /tmp/libdck.sh
. /tmp/libdck.sh
pid=$( json_elem "uuid"
"$(curl -s http://169.254.169.254/openstack/latest/meta_data.json )" )
forked=$(dck-peek $pid "forked")
function reload_lb {
webservers_bak=""
while [[ true ]]; do
# 自身のメタデータから子VMのIPを取得して、ロードバランサに登録
webservers=$(dck-peek $pid | awk -F ': ' '/^ +"web/ { print $2 }' | sed 's/[",]//g')
if [[ $webservers != $webservers_bak ]]; then
cat <<EOF > /etc/httpd/conf.d/proxy.conf
<IfModule proxy_module>
ProxyRequests Off
ProxyPass /balancer_test balancer://mycluster lbmethod=byrequests timeout=1
<Proxy balancer://mycluster>
BalancerMember http://127.0.0.1 loadfactor=1
EOF
for s in $webservers; do
echo "BalancerMember http://$s loadfactor=1" >> /etc/httpd/conf.d/proxy.conf
done
cat <<EOF >> /etc/httpd/conf.d/proxy.conf
</Proxy>
</IfModule>
EOF
このUser DataでVMを起動するとロードバラン
webservers_bak=$webservers
サーとなる。
systemctl reload httpd.service
fi
その後、このVMをforkすると、Webサーバー
sleep 10
done
になって、ロードバランス対象に登録される。
}
14
- 15. NII dodai-deploy2.0 project
Forkを利用したスケールアウトWebサーバの例 (2/2)
function prepare_httpd {
setenforce 0
yum install -y httpd
systemctl stop iptables
systemctl start httpd.service
hostname > /var/www/html/index.html
}
function parent {
prepare_httpd
reload_lb
}
# 親VMは、ロードバランサーとして動作
# 子VMを定期的にチェックして、新規の子VMをロードバランス先に登録
function child {
# 子VMは、Webサーバとして動作
prepare_httpd
parent=$(dck-ppid $pid)
ip=$(dck-pip $pid)
dck-poke $parent "web-$ip" "$ip" # 親VMのメタデータの自身のIPアドレスを登録
}
# main
if [[ $forked == "true" ]]; then
child
else
parent
fi
exit
15