dck server プロトタイプ

16
Ver1.0 2013/08/08 Etsuji Nakai NII dodai-deploy2.0 project DCK Server プロトタイプ

Upload: etsuji-nakai

Post on 15-Jan-2015

507 views

Category:

Technology


0 download

DESCRIPTION

 

TRANSCRIPT

Page 1: DCK Server プロトタイプ

Ver1.0 2013/08/08Etsuji Nakai

NII dodai-deploy2.0 project

DCK Server プロトタイプ

Page 2: DCK Server プロトタイプ

2

NII dodai-deploy2.0 project

前回までのアイデア

Page 3: DCK Server プロトタイプ

3

NII dodai-deploy2.0 project

コンポーネントスタックの整理

IaaS Infra

dck

dckapp

libdck

dckemu

dcktool

libdck 本来はIaaS基盤が提供するべきだが、既存のIaaSでは未実装の機能を代替として提供するモジュール

AWS / OpenStack / Eucalyputus / Wakame VDCなどの既存の

IaaS基盤を前提とする

DCKを前提としたアプリケーション DCKを容易に利用するためのツール

Data Center Kernel本体

DCKを前提としたアプリケーション

DCKのAPIを呼び出すライブラリ

ユーザ

Page 4: DCK Server プロトタイプ

4

NII dodai-deploy2.0 project

dcinitとは?

複数VM間で連携するサービスを自立分散的に起動する仕組み dckが提供するインフラ機能を利用して、VM間の連携を実現する ここでは、dcinitを実現するために必要なdckのインフラ機能を考える

Page 5: 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に通知して負荷分散設定を変更する、など

の使い方ができる

Page 6: DCK Server プロトタイプ

6

NII dodai-deploy2.0 project

擬似コードイメージ

# dcinit web3tier start

fork apacheinstall apache

fork tomcatinstall apache

fork postgresqlinstall 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 tomcatadd_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}

postgres { install postgres shm_write(id, “postgres:hostname”, $HOSTNAME) shm_write(id, “postgres:ready”, true) event_loop}

Page 7: DCK Server プロトタイプ

7

NII dodai-deploy2.0 project

プロトタイプ実装DCK Server

Page 8: DCK Server プロトタイプ

8

NII dodai-deploy2.0 project

目的

とにかく一度、p.6のような擬似コードが実際に実行できる環境を作ってみる。

Page 9: DCK Server プロトタイプ

9

NII dodai-deploy2.0 project

構成

OpenStack

REST API

DCKサーバ

REST API

VMインスタンス

管理用PC

Page 10: DCK Server プロトタイプ

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)として使用します。

Page 11: DCK Server プロトタイプ

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)を停止・削除する

Page 12: DCK Server プロトタイプ

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 # dck-exec <親VM UUID> <新規VM名> <イメージID> <User Dataファイル> fork # dck-fork <親VM UUID> <新規VM名> ps # dck-ps / # dck-ps <UUID> ppid # dck-ppid <UUID> cpid # dck-cpid <UUID> poke # dck-poke <UUID> <key> <value> peek # dck-peek <UUID> / # dck-peek <UUID> <key> delete # dck-delete <UUID>

その他補助関数– JSONから特定キーの値を取り出す

# json_elem <key> <JSON>

Page 13: DCK Server プロトタイプ

13

NII dodai-deploy2.0 project

forkを利用した簡単なUser Dataの例#!/bin/bashcurl -s http://192.168.101.9:5000/dck/api/v1.0/libdck > /tmp/libdck.sh. /tmp/libdck.shpid=$( json_elem "uuid" "$(curl -s http://169.254.169.254/openstack/latest/meta_data.json )" ) # 自分のUUIDforked=$(dck-peek $pid "forked") # forkした子VMか判断するためのメタデータ

function child { # 子VMの場合の処理 echo "I'm child" > /etc/motd dck-poke $pid "child_setup" "true" # 処理完了を自身のメタデータに記録}

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}

# mainif [[ $forked == "true" ]]; then # 親VMと子VMで処理を分岐 childelse parentfiexit

Page 14: DCK Server プロトタイプ

14

NII dodai-deploy2.0 project

Forkを利用したスケールアウトWebサーバの例 (1/2)#!/bin/bashcurl -s http://192.168.101.9:5000/dck/api/v1.0/libdck > /tmp/libdck.sh. /tmp/libdck.shpid=$( 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 OffProxyPass /balancer_test balancer://mycluster lbmethod=byrequests timeout=1<Proxy balancer://mycluster>BalancerMember http://127.0.0.1 loadfactor=1EOF 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 webservers_bak=$webservers systemctl reload httpd.service fi sleep 10 done}

このUser DataでVMを起動するとロードバランサーとなる。

その後、このVMをforkすると、Webサーバーになって、ロードバランス対象に登録される。

Page 15: DCK Server プロトタイプ

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 { # 親VMは、ロードバランサーとして動作 prepare_httpd reload_lb # 子VMを定期的にチェックして、新規の子VMをロードバランス先に登録}

function child { # 子VMは、Webサーバとして動作 prepare_httpd   parent=$(dck-ppid $pid) ip=$(dck-pip $pid) dck-poke $parent "web-$ip" "$ip" # 親VMのメタデータの自身のIPアドレスを登録}

# mainif [[ $forked == "true" ]]; then childelse parentfiexit

Page 16: DCK Server プロトタイプ

Etsuji NakaiTwitter @enakai00

NII dodai-deploy2.0 project

Thank You!