❚ ベランダ発電、いよいよクラウド化 (このレビューの概要)
今回やりたいこと
太陽光発電システムの動作状況(発電電力、使用電力)をAzure*に作ったデータベースに記録して、インターネットに記録データを公開します。
ブラウザ上で数値とグラフで状況を示し、発電と使用状況の「見える化」を実現します。
本稿は、「クラウドな太陽光発電と蓄電をやってみよう!」の完結編にあたります。
太陽光発電システムは、この夏に製作したシステムです。Linuxが使えるマイコンボード(Intel Galileo)を中心に太陽光パネル1枚と鉛バッテリー1個を備えていて、完成以来順調に発電/蓄電しています。
*Azure:正式なサービス名は、「Microsoft Azure」ですが、本稿では「Azure」と記述させていただきます。
現状では、データベースへの記録は、発電システムからLAN内の別のLinuxマシンのSQLサーバーに対してリアルタイムに8秒間隔で1レコードずつ記録していて、LAN内ではブラウザをとおして参照できるようになっています。これをAzure経由でインターネットのどこからでもアクセスできるようにすることがこのレビューのゴールです。
・4つのグラフを表示できます。
(PWM値を含むリアルタイム値、日次、月次、年次それぞれの発電量と消費量)
実現するために行うこと
Azureで次の2点を実施します。(カッコ内は有料運用時の料金の見積)
- 仮想マシンを1台作成し、SQLサーバーとします。(1,365円/月)
Azureに作成する新規SQLサーバーは、ローカルにある既存のSQLサーバーと同期をとります。 - Webサイトを設置して、node.jsをwebサーバーとして上記SQLデータベースを読みつつ、HTMLを公開します。(無料)
このようなことを実現する場合、従来はローカル環境(オンプレミス*)で物理マシンを用意し、ポートを開いて直接ネットに公開する方法が広く行われていました。現在ではクラウドを利用して公開することが一般的となっており、今回はAzureをクラウドのプラットフォームとして進めます。
*オンプレミス:(on-premises)管理者自身が管理する設備内に導入、設置して運用すること。 クラウドに対する概念。
・今回やりたいこと:仮想マシンでクラスタMariaDB、WEBサイトでnode.js
現状の手元システム
現在稼働中のシステムのデータ保持は次のようになっています。
- CentOS6.5(仮想マシン)上の単一のMariaDBにすでに数カ月分のレコードがあります(1か月あたり約32万レコード)。
~ 物理マシンN54L内の仮想環境Hyper-Vに作成したCentOS6.5マシン
(開発当初、MariaDB5.5をCentOS7の仮想マシンで運用していましたが、完全同期型のレプリケーション機能を使用するためにMariaDB10.0に変更する必要があったのと、CentOS7からのコマンド体系に慣れていないため、仮想OSをCentOS6.5に戻して、移行しました。) - CentOS6.5(別の仮想マシン)にnode.js で動作するWebサーバーがあり、上記のレコードをグラフ化してブラウザから見ることができます。
~ 物理マシンWindows8.1内のVirtualBoxにVagrantで作成したCentOS6.5マシン
SQLデータベース
SQLデータベースは、MariaDBを使用します。
MariaDBは、コマンドがMySQLのコマンドと完全に互換性を保っており、かつレプリケーション*の仕組みが最も整っているからです。
特に、MariaDB10.0以降のレプリケーション機能は、「完全同期型」かつ「マスター/スレーブの区別がない」方式です。
つまり、2つ以上のサーバーをレプリケーションを行う設定にして起動しておけば、どれかのサーバー1つに対して読み書きを行うと、他のサーバーにも即座に反映されます。運用中にどれか1つのサーバーがダウンしても残りのサーバーが動き続け、ダウンした1台が復活したとき他のサーバーと同じ状態に保たれます。
運用中に、レプリケーションのために特別な操作の必要はなく、クラスタ内のどのノードも対等で、起動の前後も関係なく、ノードの停止・削除・追加も簡単に行え、更新系と参照系を分ける必要もありません。
*レプリケーション:データベースで、同じ内容の複製(レプリカ)を別のマシンに作成し、常に内容を同期させる機能。レプリケーションを行う複数のデータベースの集まりをクラスタ、クラスタ内の個々のデータベースをノードといいます。
データベースのレプリケーションの一般的な使用目的は、主としてデータを安全に保持することとサーバーの負荷を分散することです。負荷分散のためには、他のWebサーバーなどを含めて通信の入口部分にロードバランサーを設置してサーバー外から見かけ上1つのSQLサーバーとして扱える仕組みを作ります。
今回は、負荷分散の点は考えないことにしますので、ロードバランサーは設置しません。
ノードを2つ設定し、ノードの1つをローカル環境内(オンプレミス)に、もう1つをAzureに作ります。
構想として、太陽光発電システムからは、オンプレミスのSQLサーバーに書き込み、Web上にデータを公開するためにAzureに作ったSQLサーバーのレプリカから読み込むという役割分担します。
既存のGalileoのプログラム(node.js)を変更する必要なくクラウドをとおしてデータが公開できるはずです。LAN内で稼働している、SQLサーバーからデータを読んでグラフを表示するプログラム(node.js、HTML)も読み込み先を編集してAzureのWEBサイトにアップロードすれば公開できると見込んでいます。
データ公開を中止する場合は、Azureのサーバー(仮想マシン、WEBサイト)を終了するだけです。発電システム側からの書き込み手順などには影響なく運用できるはずです。
仮想マシンの作成を半自動化
Azure上に構築するマシンの設定にはVagrant(ベイグラント)とAnsible(アンシブル)を使用します。
ローカルの開発環境を整えるのに既にVagrantとAnsibleを使用しており、VagrantとAnsibleによる方法がAzureにも適用できれば工数の効率化が図れます。
また、マシンの構築だけでなく運用も含めてより汎用的な方法を取ることでクラウドプラットフォームの提供業者が異なっても、開発側はできるだけ一定の方法で運用していきたいという狙いもあります。たとえば、AWSで構築した環境をAzureで再現したり、またはその逆の作業も少ない手順で実現できます。
SQLサーバーのノード間はVPNで接続
オンプレミスとクラウドのSQLサーバーの結合手段として、VPN接続を使用します。VPN接続によって、異なるドメインのマシンをあたかも同一LAN内のマシンとして扱えるようになります。
VPN接続アプリケーションとして、今回はSoftEther VPNを使用しています。
公式サイト:
SoftEther VPN は、サポートしているOSとVPNプロトコルの種類が多く、ポート開放なしにファイヤーフォールを貫通する接続も確実に行なえます。丁寧なチュートリアルやドキュメントが完備されており、オープンソースで提供されています。
WEBサイトでnode.js のwebサーバー
AzureのWEBサイトではnode.jsが使用できますので、これをwebサーバーとして利用します。
既に、LAN内のGalileo、SQLサーバー、PC、スマホ・タブレット間でコマンドやデータの送受をnode.js とHTML+Javascriptを組み合わせて行っていて、作りやすく、堅牢な構成ができています。素性や挙動も確認できています。このオンプレミスで稼働している構成をできるだけ変更なく、Azureに移行してクラウド化していきます。
オープンソース*志向でいこう
クラウドプラットホームのAzure以外の構成要素には、オープンソースのプロダクトを活用します。
LinuxOS、MariaDB、構成ツールのVagrantやAnsible、SoftEtherVPN、node.jsとそのモジュールなどです。それぞれの開発者の技術と情熱に敬服するとともに感謝します。
したがって、このレビューに掲載する私のコード類もオープンソースとして共有します。
もし使ってくださる方があれば、コピーや模倣は歓迎します。その代わり、私のコード類を利用してさらに良いものができれば公開して共有してほしいと思っています。
そのような技術的な共有は、開発に関わる人や企業それぞれの成長の源であり、ICTやコンピューティングの技術全般が健全に発展し広く利用者に貢献できると考えています。
*オープンソース:プログラムのソースコードや回路図を公開する、頒布に対価を求めない、技術的中立性を保つことなど、定義にはいくつかの要素があります。技術の共有(わかちあい)という点でフリーソフトとは根本的に異なります。
❚ Azure に仮想マシンを作る
この項のGOAL
● Azure にMariaDBが使用できる仮想マシンを作成する
● Vagrant と ansilbe を使用して構成する
Vagrant経由でAzureの仮想マシンを作成
Azure に仮想マシンを作るには、いくつか方法があります。
1. Azureポータル(Azureの設定用のweb画面)からGUIで進める
2. azure-cli(コマンドラインツール)を利用する
3. Hyper-V(ローカルの仮想環境)で動作している環境を複製(レプリケーション)する
4. Vagrant (仮想環境構築ツール)を利用する
今回は、4. の方法を取ります。理由は、1. よりも詳細な設定ができ、インストールできるOSのイメージも選択肢が多く、一度設定ファイルを作成すると、いくつでも何度でも同じ環境がAzure上に再現できるからです。
そして、AnsibleやChefなど(構成管理ツール)を使用すると、マシンを作成した後のプロビジョニング(設定作業)まで自動化することができます。
マシンの作成後、Webサーバーやデータベースサーバーとして使用するために、用途に応じたプログラムをインストールするための詳細な構成が管理できるので、仮想環境でマシンの新規構成を頻繁に行う場合には便利です。
なお、2. は作成のたびにコマンドを何行も手入力する必要があるので、面倒な上、誤操作を誘発しそうです。3. は既に動作している環境があってまるごと移行したい場合には有効です。
仮想マシンの使い道について ~ 一般論
テストでは、同じ環境のマシンをチームごとフェーズごとに作ってテストしてその後マシンを破棄することを繰り返したりします。物理マシンでは台数や作業負荷に限度がありますが、仮想マシンでは何台作ってもスペースは不要で工数やコストの負担がは軽く済みます。その後本番用にも全く同じ構成の未使用のマシンが準備できます。
運用中の本番マシンでも更新時には既存マシンに手を加えるのではなくて、新しいマシンを新規作成して切り替えて使用することで、スムーズな移行手順が実現できます。
Azure のアカウントを作る
から行います。
サブスクリプションID(アカウント)が入手できれば、Azureポータル(webからAzureを操作するサイト)を開くことができます。
サブスクリプション入手時には、クレジットカードとショートメールが受け取れる携帯電話が必要となります。
初期登録時には1か月間有効の2万円分の利用権が付与されます(2014年10月現在)。
丁寧なガイダンス画面が続きますので、手続きに迷うことはありませんでした。
2万円分の利用権は、期間内ならどのサービスにも使用できますが、登録から1か月が過ぎると消滅します。ちなみに、AmazonのAWSの初期特典は、Azure同様に2万円付与されますが、サービスによって課金されるものもあるかわりに、1年間有効です。
以下、仮想マシンを操作する側のマシン(Host)で作業します。
Azureポータルを開いておいて状態の確認に使用しますが、画面が自動更新されないので、ブラウザでリロード操作をする必要があります。
Vagrant をインストールする
Vagrantは、仮想環境構築ツールです。Vagrant自体は仮想環境の実体を保持しません。必ずOSの実体を保持する仮想環境(プロバイダ)が必要です。ローカル環境で使用する場合は、VirtualBoxやVMwareなどを使用しますが、今回はこの部分でAzureを利用します。
http://www.vagrantup.com/downloads.html
Linuxの場合:
$ sudo rpm -ivh https://dl.bintray.com/mitchellh/vagrant/vagrant_1.6.5_i686.rpm
からダウンロードとインストールを行います。
LinuxとMacの場合、インストール後、Vagrantの操作は端末(ターミナル)から一貫して行えます。Windowsの場合は、Vagrantでマシンを作成したり起動終了などの操作はコマンドプロンプト(いわゆるDOS窓)から、作成したマシンへのSSH接続は別途接続用のアプリ(Teratermなど)からと、少し煩雑になります。
今回は、Windowsマシン内にVagrantでCentOS6.5のマシンを作り、別のWindowsマシンからSSHでその仮想マシンに接続し、その仮想マシン内で別のVagrantをインストール・起動してAzureに対する操作をしています。
azure-cli をインストールする
コマンドラインから、Azureを操作するツールです。
Vagrant からAzureを操作する場合には、内部的に azureコマンドを使用しますのでazure-cli のインストールが必要です。
http://azure.microsoft.com/ja-jp/documentation/articles/command-line-tools/
インストールに先立って、node.js(サーバー用のJavascript)とnpm(node.jsで使用するインストールツール) のインストールを済ませておきます。
Linuxの場合(既にnodo.jsとnpmとがインストールされているとして):
$ sudo npm install azure-cli -g
Azureポータルからサブスクリプションを元に設定ファイルをダウンロードしてLinuxのコマンドラインからazure-cli にファイルをインポートするとAzureにログインした状態になりazure コマンドが使用できるようになります。
azure コマンドでは、仮想マシンやWEBサイトの作成・設定などが行えます。
vagrant-azure をインストールする
https://github.com/MSOpenTech/vagrant-azure
VagrantでAzureが使用できるようにするアドインです。
提供者の「Microsoft Open Technologies」は、他にもツールを発行している様子で興味深いところです。
$ vagrant plugin install vagrant-azure
Ansible をインストールする
公式:
http://docs.ansible.com/index.html
Linuxにyumコマンドでインストールする場合:
$ sudo yum install ansible
※ インストール後、ローカル環境内で簡単な疎通テストを行っておきます。
鍵ファイルを作る
クラウドに関わる設定は、よりセキュアなので認証関係が厳重です。
たとえば、Azureの仮想マシンのSSHのログインは、パスワードによるログインは許されず、必ず秘密鍵と公開鍵の組み合わせによる認証が必要となります。
Azure.key(秘密鍵)と azure-cert.pem(公開鍵):
$ openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout azure.key -out azure-cert.pem
$ chmod 600 azure.key
(カレントディレクトリに生成されるので、都合のよい場所にコピーして使う。パーミッションを600に変えておく。ファイルの所有者、グループは、Hostを起動するアカウントに揃えておく。)
azure.pem(証明書):
$ azure account cert export -f azure.pem
myAzure.ppk:
PuTTY Key Generator* でAzure.key(秘密鍵)から変換生成(Vagrantfile では使用しないが、TeratermからSSH接続するときに必要です。パーミッションを600に変えておくことと、所有者・グループの設定は、上記の Azure.key と同様です。)
* :PuTTY Download Page
http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html
config ファイルを編集する
Host の ユーザカレントディレクトリ直下の .ssh ディレクトリに ファイル名「config」で次の編集をします。
SSH接続で必要になる場合があります。(下記 SSHの接続の2.の方法のとき)
Host *.cloudapp.net
user chiba-todo
IdentityFile /home/vagrant/.ssh/azure.key
Vagrantfile を編集する
# vi: set ft=ruby :
ENV['VAGRANT_DEFAULT_PROVIDER'] = 'azure'
Vagrant.configure('2') do |config|
# up中に共有ファイルが設定できず止まる(仮想マシンは起動できている)ので以下を手動で。 2014-11-09 6:53
# 「ssh azure」 で仮想マシンに入って、「sudo visudo」 で requiretty の行をコメントアウトする
# ついでに、
# ホストから「ssh-copy-id -i .ssh/id_rsa.pub azure」 で公開鍵転送
config.vm.provision 'ansible' do |ansible|
ansible.playbook = "./playbook_azure.yml"
# ansible.inventory_path = "./hosts"
end
config.vm.provider :azure do |provider, override|
provider.subscription_id = '541e47db-9e06-441d-b68b-xxxxxxxxxxx'
provider.mgmt_certificate = './azure.pem'
provider.mgmt_endpoint = 'https://management.core.windows.net/'
# vm settings
provider.vm_image =
'0b11de9248dd4d87b18621318e037d37__RightImage-CentOS-6.5-x64-v14.1.3'
provider.vm_user = 'chiba-todo' # defaults to 'vagrant' if not provided
provider.vm_location = 'Japan West'
provider.vm_size = 'ExtraSmall' # extrasmall ではダメ # Basic_A0 もダメ
provider.vm_name = 'chiba-todo01'
provider.cloud_service_name = 'chiba-todo01'
provider.tcp_endpoints = '3389:53389' # Remote Deaktop 用
provider.tcp_endpoints = '3306:3306' # MySQL 用 2014-11-08 22:07
provider.ssh_private_key_file = '.ssh/azure.key'
provider.ssh_certificate_file = './azure-cert.pem'
override.ssh.private_key_path = '.ssh/azure.key'
override.vm.box = 'azure'
override.vm.box_url = 'https://github.com/msopentech/vagrant-azure/raw/master/dummy.box'
end
config.ssh.username = 'chiba-todo' # the one used to create the VM # 仮想マシン起動後に必要
# config.ssh.pty= true # 2014-11-08 12:18 ⇦ 効き目なし
end
パラメータのうちのいくつかは、azureコマンドを実行して取得します。
Rubyの形式です。
マシン作成後、VagrantからAnsibleを起動してSQLサーバーのインストールを行うようにしています(config.vm.provision のブロック)。
AnsibleのPlaybookファイルを編集する
# playbook_azure.yml
---
- hosts: default
user: chiba-todo
sudo: yes
tasks:
- name: upgrade all packages
yum: name=* state=latest
# EPELリポジトリのインストール(socatがEPELリポジトリにあるため)
- name: repository prep
# command: sudo rpm -ivh http://ftp-srv2.kddilabs.jp/Linux/distributions/fedora/epel/6/i386/epel-release-6-8.noarch.rpm
yum: name=ca-certificates state=present
- name: repository install
yum: name=http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm state=present
# CentOS64 のとき
# - name: repository edit
# copy: src=/home/vagrant/epel.repo dest=/etc/yum.repos.d/epel.repo
# mysql-libsを消す
- name: del mysql-libs
yum: name=mysql-libs state=absent enablerepo=epel
# command: sudo rpm -e --nodeps mysql-libs
# # # 依存パッケージのインストール
- name: sub packages install
yum: name={{item}} state=latest enablerepo=epel
with_items:
- perl
- perl-DBI
- lsof
- rsync
- socat
- name: MariaDB repo copy
copy: src=/home/vagrant/MariaDB.repo dest=/etc/yum.repos.d/MariaDB.repo
- name: install MariaDB-10.0.14
yum: name={{item}} state=present
with_items:
- MariaDB-common
- MariaDB-compat
- MariaDB-client
- MariaDB-Galera-server
- galera
- name: copy server.cnf
# クラスタSQL用(クラスタとノードの設定は手動で編集)
copy: src=/home/vagrant/server.cnf dest=/etc/my.cnf.d/server.cnf
- name: port setting prep
copy: src=/home/vagrant/portSetting.sh dest=/vagrant/portSetting.sh mode=755
- name: port setting
shell: /vagrant/portSetting.sh >> portsettinglog.txt
YAML(ヤムル)形式です。(字下げが誤っていると実行できません)
基本的に、MariaDBをインストールする目的ですが、作業時点ではレポジトリを読み込む必要があったり、MariaDBをクラスタ対応とするために依存パッケージも同時にインストールすること、外部からのアクセスのためにポートを開放する操作、クラスタ対応用に編集したserver.cnf を転送する操作を記述しています。
Vagrantfile やPlaybookファイルは、編集と実行を何度も繰り返す必要がありました。
個々の環境やOSのバージョン、提供されるOSイメージの構成などによって、調整が必要です。
仮想マシンを作成するコマンドの実行
鍵ファイルを所定のディレクトリ(Vagrantfileの記述と合っていれば任意のディレクトリでよい。ファイル名も同様。)に置き、Vagrantfileを置いたディレクトリで次のコマンドを実行します。
$ vagrant up --provider=azure
$ VAGRANT_LOG=info vagrant up --provider=azure (実行ログを表示させる場合)
途中で手動作業が必要
3~5分くらいでAzureに仮想マシンが作られます。が、実行中に内部的にSSH接続しようとときにパスワードなしsudoが使用できないためにコマンドプロンプトに戻ってしまいます。
そのため、次のいずれかでSSHからAzureの仮想マシンに入って visudo コマンドで sudoが使用できるよう調整します。
- Host の Vagrant ssh コマンドを発行する
$ Vagrant ssh - Host の Linux コマンド のSSHを使う
$ ssh chiba-todo01.cloudapp.net
この時、.ssh/config ファイルにアカウント名と参照先を編集した鍵を使用します。 - 別に起動したTeratermから接続する
この時、前もって作成した myAzure.ppk を使用します。
そしてAzureの仮想マシンに入れたら(鍵やパスワードの確認があります)、
$ sudo visudo
として、
「Defaults requiretty」の行をコメントアウトします。
⇨「#Defaults requiretty」
仮想マシンを作成するコマンドを再開
$ VAGRANT_LOG=info vagrant reload
上書きではなく、続きから再開されます。
Ansibleがプロビジョニングする部分で時間がかかります(30分くらい)。
実行ログでエラーがないことを確認します。
ここまでで、クラスタ対応のMariaDBが使用可能な仮想マシンがAzureに作成されました。
❚ SoftEther VPNの設定
この項のGOAL
● オンプレのSQLサーバーマシンとAzure仮想マシンが 192.168.30.xxx のIPで疎通できること。
・SoftEtherVPN の設定は、Windows版ならGUIで設定できます
SoftEtherVPN Server のインストールと設定
常時起動しているマシンにインストールすべきですが、とりあえず、作業用のWindows機にWindows版をインストールしました。
GUIで操作できる「VPN サーバー管理マネージャ」で仮想HUB、仮想NAT、VPN Azure(Azureを利用したDDNSのようなもの)を設定、クライアントから接続するユーザーを登録してクライアントからの接続を待受けます。
VPNサーバーの疎通確認は、別のWindows機から行います。Windowsに標準で搭載されているVPN接続機能でこのVPNサーバーへ接続し、pingコマンドでレスポンスが正常なことを確認します。
SoftEtherVPN Client のインストールと設定、接続
今回、クライアントとしたいOSはLinuxですが、Linux用の SoftEtherVPN Client は、コマンドライン版のみで、しかもmakeが必要ですから、前もってgccをインストールする必要があります。
インストール後、vpnclient をスタートさせてからvpncmd を起動して設定を行います。
インストールしたディレクトリに移り、
$ sudo ./vpnclient start
$ sudo ./vpncmd
以下、vpncmd でコマンドによる設定です。
ユーザー名とパスワードはあらかじめVPNサーバーに登録してあります。
(adpVPNという名前のNICを作成)
>nicCreate adpVPN
(NICを有効化)
>nicenable adpVPN
(アカウントを作成)
>accountcreate accVPN /SERVER:xxxx.vpnazure.net:443 /HUB:VPN /USERNAME:xxxx /NICNAME:adpVPN
(パスワードの設定)
>AccountPasswordSet accVPN /PASSWORD:xxxx /TYPE:standard
(アカウントを仮想HUBに接続)
>accountConnect accVPN
(接続状態の確認 … Session Status が、Connection Completed (Session Established)となっていることを確認します。または、セッション接続状態 が 接続完了 (セッション確立済み)となっていること。)
>accountstatusget accVPN
(vpncmdを終了します)
>exit
自IPと相手IP(他のMariaDBのノードのIP)へのrouteを設定します。
$ sudo ifconfig vpn_adpvpn 192.168.30.2
$ sudo route add -net 192.168.30.3 metric 0 netmask 255.255.255.255 vpn_adpvpn
IPを変えて同じ設定を他のMariaDBのノードのマシンでも行い、ping疎通とMariaDBのクラスタ接続を確認します。
汎用性も永続性もない設定ですが、必要に応じて改良することとします。
VPN Client の設定も、Ansibleでプロビジョニングできるようにしておくと便利かもしれません。
❚ MariaDBの設定
この項のGOAL
● クラスタ設定した各ノードのMariaDBがエラーなく起動すること。
● オンプレのDBに書き込んだ内容が、Azure仮想マシンのDBに自動的に反映されていること。
server.cnfの編集
AnsibleでMariaDBをインストールする際に、下記のパートを加えたserver.cnf を上書きしていますので、IPの設定部分を編集します。全ノードのマシンでIPを変えて同様に編集します。
$ sudo vi /etc/my.cnf.d/server.cnf
:
:
wsrep_cluster_name=DBCLUSTER
wsrep_cluster_address=gcomm://192.168.30.3 (← 他のノードのIP)
wsrep_node_address=192.168.30.2 (←自分のIP)
wsrep_provider='/usr/lib/galera/libgalera_smm.so'
wsrep_sst_method=rsync
wsrep_slave_threads=4
:
:
クラスタMariaDBの起動確認
以下のコマンドで各ノードからMariaDBを起動します。
起動前にSELinuxを無効化しておきます。
$ sudo setenforce 0
他のノードが1つも起動していない場合
$ sudo service mysql start --wsrep_cluster_address=gcomm://
Starting MySQL...... SUCCESS! (← 成功!)
他のノードが起動している場合
$ sudo service mysql start
Starting MySQL....SST in progress, setting sleep higher....[ OK ] (← 成功!)
これらの起動操作をマシンの再起動時に自動的に行う場合は別途設定をします。
SELinuxを無効化しないでMariaDBを起動する方法があれば、そのようにしたいところです。
SQLに入り、レコードの同期ができているか確認します。
$ sudo mysql -u root -p
:
:
> use galileo_solar
:
> select * from 10sec_real order by created desc limit 10;
:
ここまでで、太陽光発電システム(Intel Galileo)で生成したデータがクラウド(Azure)に保存できるようになりました。
※ 実際に下記node.js経由でアクセスしてみると、パフォーマンスが悪かったり、クエリ結果が帰って来ないことがありました。
たとえば、Too many connections エラーの場合は、MariaDBの設定パラメータで、
max_connections を増やす、wait_timeout を減らす という調整をすると改善しました。
Too many connections エラーの対処(2015/02/14追記)
後述のグラフを描画する際にグラフが表示されず、ブラウザのコンソールに、
Uncaught TypeError: Cannot read property 'length' of null
(読みに行ったけれどデータが1件もない)エラーが発生していました。たどっていくと、
node.jsからSQLを読む部分で、
ER_CON_COUNT_ERROR: Too many connections
というエラーが発生していました。接続が多すぎると言われています。
調べると、SQLサーバーの設定パラメータで、max_connections と wait_timeout が関係しそうです。
max_connections パラメータは、データベースへの最大接続数です。接続には、データベースの内部からの接続も外部からの接続も含みます。デフォルト値は151です。
wait_timeout パラメータは、接続の継続時間です。クエリ結果にかかわらず(正常に完了しても、エラーでも、実行中でも)、この値で設定された一定時間は接続され、時間になると勝手に切れます。単位は秒で、デフォルト値は28800です。接続中に明示的に切るコマンドなどはありません。
「Too many connections」エラー中には、クラスタでつながっている別ノードのSQLサーバーもクエリが実行できなくなります。このような障害の場合は、クラスタにした効果はなさそうだとわかりました。
そこで、wait_timeoud = 600と短くしました。600秒=10分経過した接続から順次消去されます。極端に短くすると、クエリ結果が出力される前にタイムアウトになりますが、さすがに10分は長すぎるかもしれません。ただ、今のところ、8秒間隔のデータを最大で1年分読むようなクエリを実行する場合もあるので長めにしておきました。(サマリー(集計値専用)テーブルを作って、一度書き出しておき、毎回の処理ではそちらを読む方が速いことは明らかですし、フロントエンドの処理でユーザーを分の単位で待たせるのはありえないことなので、いずれそうすべきだと思っています。)
または、max_connectionを増やして対処することも可能です。しかし、接続を保存するためにはリソースが必要ですし、リソースを消費してパフォーマンスが落ちるのも避けたいので、こちらの方法は結局取りませんでした。とはいえ、100000接続まで設定できるようですので、1000とか2000くらいには増やしてよいのかもしれません。
SQLサーバーの設定パラメータを変更するには、具体的には、SQLのコマンドラインで、
> set global wait_timeout = 600;
として、
> show global variables like 'wait_timeout';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| wait_timeout | 600 |
+---------------+-------+
で設定されていることを確認します。値は、即座に動作に反映されます。
ただ、この方法ではSQLを再起動したときにデフォルト値に戻ってしまうので、
永続的設定にするには、設定ファイル /etc/my.cnf 内に以下を編集してSQLサーバーを再起動します。
[mysqld]
#max_connections = 151 # こちらはデフォルトのまま
wait_timeout = 600
なお、現在の接続の一覧を確認するには、SQLサーバーが稼働するLinuxのコマンドラインで、
$ mysqladmin processlist -u root -p
としてパスワードを入力するとリストが表示されます。
※ SQLサーバーで言う、接続(connection)、スレッド、プロセス の違いがイマイチよくわかっていません。
(追記ここまで)
他にも調整すると性能アップが期待できるパラメータがあるかもしれません。
❚ Azure WEBサイトでnode.js を使用してサイトを公開する
この項のGOAL
● オンプレで実行しているnode.js プログラムがWEBサイトからパブリックに公開できること。
● Azure仮想マシンのMariaDBから、HTMLのリクエストに応じてnode.jsがクエリした結果が表示できること。
Azure WEBサイト用にapp.js を一部変更
ローカルでnode.js のプログラム(app.js)が動作することを確認して、Azure WEBサイト用に次の2点を変更します。
・リッスンポート
var server = connect.createServer(
connect.static(__dirname)
).listen(3000); // ローカル用
↓
var server = connect.createServer(
connect.static(__dirname)
).listen(process.env.PORT || 8080); // azure用
・SQLサーバーのホスト名
mysql.createPool() 内の host: の定義を作成したAzure仮想マシンのIPアドレスに変更します。
var pool = mysql.createPool({
connectionLimit : 300,
host : '138.91.xxx.xxx', // azure用
database : 'galileo_solar',
user : 'netuser',
password : 'xxxx'
});
デプロイ*の手段
Azure にWEBサイトを作るには、いくつか方法があります。
1. Azureポータル(Azureの設定用のweb画面)からGUIで進める
2. azure-cli(コマンドラインツール)を利用する
node.jsを利用する場合は、git を使用してコンテンツをデプロイする方法がやりやすそうです。なので、WEbサイト作成の段階からコマンドラインで行うこととします。
事前に、デプロイする元のマシンでgit でソースコードが管理できるように設定しておきます。
*デプロイ:配備する、配置するなどの意味。単にアップロードするのではなく正しい位置に展開するとか足りないものを補う意味合いも含む。
WEBサイトの作成
※ 前もって、.publishsettingsファイルをダウンロード、自マシンのazureにインポートしておきます。インポートが成功すると以後Azureにログインした状態でazureコマンドを実行できます。
$ azure account download
:
$ azure account import xxxx.publishsett
(WEBサイト作成)
$ azure site create [サイト名] --git
git用のユーザー名やパスワードが求められることがあります。
作成が成功すると、サイトのURL、デプロイ先のgit用URLなどが返されます。
デプロイを行うソースのあるディレクトリに移動します。
(このディレクトリでgitを使う宣言)
$ sudo git init
$ sudo git add .
(ローカルでコミット)
$ sudo git commit
(デプロイ先を設定)
$ sudo git remote add azure https://chibatodo@xxxx.scm.azurewebsites.net:443/xxxx.git
(azureにpush)
$ sudo git push azure master
(WEBサイトでWebSocktが使えるようにする)
$ azure site set -w
node.jsでは、package.json というプロジェクトファイルのようなファイルを作ることができて、この中に登録したモジュールの一覧が書かれます。
デプロイする際にpackage.json が既に作られていて他のファイルとともにpushされれば、その内容に沿ってAzure側でモジュールの構成を整えてくれます。しかし、package.jsonがなくても、ローカルでnode.jsプログラムを作成した際にモジュールをグローバルにインストールしていなければ(モジュールをデフォルトであるローカルのnode_modulesディレクトリに置いていれば)単純にpushしただけでプログラムは正常にデプロイされ動作するようです。
WEBサイトでnode.jsを使用する場合のデバッグ
次のコマンドで、WEBサイトに対してモニタが始まります。
実行中に標準エラーが発生した場合SSH画面に表示されるので、不具合発見の手がかりになります。
$ azure site log tail [サイト名]
WEBサイトの確認
ブラウザから上記サイトのURL(xxxx.azurewebsites.net)にアクセスして、表示内容や動作を確認します。
・http://xxxxx.azurewebsites.net/ で公開できました
❚ その他こまごまとしたこと
Vagrantの共有フォルダができない問題(未解決)
仮想マシンとHostとの共有フォルダが設定できません。
(選択したLinux のイメージによるのかもしれません。今回のCentOSの6.5と7.0、Ubuntu14.04では設定できませんでした。)
Vagrantは、ゲストOSのユーザのホームディレクトリとHostのOSのVagrantfileがあるディレクトリが共有フォルダとして、ゲスト側Host側のどちらからも自由に読み書きできる機能があります。
Vagrantは、仮想マシンを構築していく過程のうち、共有フォルダの設定をするにあたり、仮想マシンでパスワードなしのsudo が使えることを前提としています。しかし、Azureで使用できるよう準備されたOSのイメージは必ずしもVagrantから使われることを前提としたものではないためこのことは保証されていません。また、vagrantの設定で「共有フォルダの作成を行わない」という設定にはできないので、どうしてもエラー終了となります。しかし、仮想マシンは正常に完成しています。
共有フォルダは仮想マシンの機能として必須ではないし、あとから手動で設定し直すことは可能です。
また、同様の理由(仮想マシンでパスワードなしのsudo が使えない)で、Vagrantfileに付加して設定する、provisioning の機能が使用できません。
したがって、Vagrant up 完了後に実施する、Ansible などの構成管理ツールもパスワードなしのsudo が必要なので、VagrantfileからAnsibleを呼び出し実行してすべて自動的に行うということはできません。
もし、VagrantからAzureに仮想マシンを作成する際に、ユーザが作成したパスワードなしのsudo がはじめから使えるイメージを使用できれば解決できそうですが、イメージを持ち込むことはちょっと難しいようです(Azureで作成したイメージを複製することはできるようですが、このイメージをVagrantから操作できるかどうかは不明です)。
課金されない状態にする
Azureポータルから仮想マシンを選択して [シャットダウン]の操作をすると、マシンは保存された状態でも時間課金はされなくなります。
vagrant halt コマンドも同様の効果があります。この時マシンの状態が、「停止済み (割り当て解除済み)」となります。
仮想マシンの終了、起動
Vagrant で構成した仮想マシンは、Azureポータルの[再起動]や[シャットダウン]を使用すると内容が破壊されるかもしれません。作成時に使用したHostマシンから「vagrant reload」「vagrant halt」を実行するほうが安全なようです。
スリープと再起動
Vagrant には suspend コマンド(スリープ状態に移行する)がありますが、Azureの仮想マシンは受け付けない仕様になっているらしく、発行してもエラーとなります(もっとも、使用する機会はありませんし、Azureポータルにもそのようなボタンは表れません)。
「停止済み (割り当て解除済み)」の仮想マシンに対して [開始]の操作をした場合、[開始中]、「開始中 (プロビジョニング)」、「実行中」と遷移して再び仮想マシンが使用できる状態となります。vagrant up コマンド を発行しても同様です。
「実行中」の仮想マシンに対して[再起動]の操作をすると、上記の[停止]と[開始]を連続して行うのと同じで、vagrant reload も同様です。
仮想マシンを破棄する
どんな操作で破棄しても、アクティブディレクトリは残ります。サブスクリプション(アカウント)の情報が保管されているようです。したがって、仮想マシン、クラウドサービス、ストレージの3項目が削除できれば、仮想マシンは完全に破棄できた状態になります。
Azureポータルからは1項目ずつ削除できますが、クラウドサービスを削除すると、仮想マシンとそのディスクが削除され、ストレージが残ります。
vagrant destroy による方法では、Azureポータルからクラウドサービスを削除したのと同じ結果になります。
なので、上記のいずれかを実行してストレージを個別に削除する方法が最少手順となります。
なお、ポータルから仮想マシンだけ削除してディスクが残った状態だとストレージは削除できません。
課金される料金がわかりにくい
Azureは、有料サービスで、しかも従量課金制なので、何をどのくらい使ったらいくらの請求が来るのかが気になります。
仮想マシンを1台作っただけでAzureポータルにはストレージアカウント、クラウドサービス、仮想マシン、ディレクトリの4項目が表示されていて、上から3つまでは従量課金制の表示があります。
はじめ、仮想マシンを作る場合は、1台あたりの課金だけだと思っていましたが、どうやら、仮想マシンには必ずディスクが必要なのでその容量によって課金もされるし、トラフィックにも量に応じて課金されるということのようです。
今回の程度の使用ではいきなり莫大な金額が請求されることもなさそうですが、何にいくらかかるのか、料金の体系がわかりにくいという印象は否めません。
マイクロソフトでは、わかりにくさをカバーするために、Web上の自動見積もりページや、人によるサポートを工夫しています。企業でAzureを導入したり顧客に勧める場合は、正確な金額の見積もりが必要となるので、こうした工夫は助かるところです。しかし、個人やSOHOの場合は、多少割高になったとしても、上限金額が決まったパッケージ料金が設定されるとさらに良いかと思います。アカデミック向けに無料枠を設ければ、さらにAzure利用の裾野が広がる気もします。
ライセンス料のこと
オンプレミスではMicrosoftの製品であるWindowsServer やWindowsOSを使用する場合、パッケージの購入が必要です。Azureの仮想マシンでWindowsServer を使用する場合では、ライセンス料などは不要で、仮想マシンに関わる料金だけで使用できます。これは良心的な設定といえるかもしれませんが、元々ライセンス料不要のLinux系OSを仮想マシンにインストールする場合にも仮想マシンの料金が同じというのでは割高感はあります。
なお、Azureで作成したWindows系仮想マシンをオンプレミスへレプリケーションする場合は、別途ライセンスが必要とのことです。
Azureポータルの画面
Vagrantを使って 仮想マシンの操作をしたとき(おそらく Azure-cliからのコマンドによる操作も)、Web経由のAzureポータルの画面にその結果や様子が反映されないので少し不便です。ブラウザの表示を手動で更新すれば確認できますが、Webから仮想マシンを操作した場合は即座に反映されるのですから、なんとかして欲しいところです。
WEBサイトのWebScketの接続数
無料で利用できるWEBサイトの範囲では、WebSocketの接続数は、5までです。
これは、テストにしか使えない数です。もし業務運用に供する場合は、有料プランを選択すれば接続数は増えますが、約6000円/月~となっていて気軽に利用できる金額ではありません。
WebSocketの管理に実際コストがかかるのか、戦略的な設定なのか不明ですが、今後の価格改定に期待することにします。
仮想マシン作成時のLAN帯域
仮想マシンを作成するためのHostになるローカルの仮想マシンを、Celeron Dual-Core T3100 1.9GHz、 Wi-fiが 11a/b/g のノートPCに設定しましたが、仮想マシン作成の Vagrant up コマンドが完走しないことがありました。
有線LANに変えたところ改善しましたので、Azureの仮想マシンを作成するためには思ったより多くのトラフィックが流れるようです。Hostの仮想マシンを別のPCから操作していますので、余計に通信が輻輳していたのかもしれません。
azure-cli がちょっと挙動不審
仮想マシンのスケール設定で、azureコマンドの取り得る引数とAzure本体のバリエーションが一致していません。
また、WEBサイトの構築中にログインできない状態になることがありました。
原因は突き止めきれていませんが、Azure本体の仕様とazure-cliの仕様でどこかに齟齬があるのかもしれないという印象を受けました。使用の際には気に留めておく必要がありそうです。
❚ まとめ
・テスト環境、オンプレ本番環境、Azure環境 (作成中に確認のために作ったチャートです)
使用感とコスパ
現在のたった1つの小さなソーラーシステムに対して1つのサーバーとデータベースという構成は永続運用するにはオーバースペックで、たいへんもったいない気はします。
けれど、そこはクラウド上の仮想環境なので、物理マシンを設置するわけでもなく、電気代もかからないので、テストフェーズとしては遠慮なく使用できました。
WEBサイトを有料プランに変更して、各機能の調整を十分にすれば、少なくとも数十台程度分のデータ管理やWeb公開は現状の仮想マシンのスペックでまかなえそうです。実運用では設定やスケールの選択を適切に行えば良いコストパフォーマンスが見込めます。
作ってみなければわからないこと
SQLサーバーのクラスタ化を初めて体験しましたが、クラスタ化によるパフォーマンスの低下はほとんど感じられませんでした(厳密に測定すれば、必ず低下が見られるはずですが)。ネット回線やクラウド環境、DBの性能の進化に驚きます。
反面、元々オンプレミスで効率よいDB操作のプログラムが書けていなければ、クラウドに移行したときに顕在化する問題もわかりました。クラウド用のチューニングというわけではなくて、スマートに動作するような作り込みを普段から心がけなければと再認識しました。
高まるクラウドへの期待
ベランダの発電状況がクラウド経由で確認できるしくみができました。
Galileoのようなマイコンを含むローカルのLinux機とクラウドの取り回しのしかたも見えてきました。
このことをどのように発展させるべきか、なんでもできるけれど何に使うと役に立つか、とか楽しくなるものができるのか、などということを考えはじめています。
たとえば、エネルギー関連で言えば、昨今の政策の動向をみるに、ユーザーサイドでエネルギーの統合的な管理が簡単にできるニーズはますます高まると感じています。そんな中、安定的かつスケーラブルにデータ管理ができるクラウドサービスは不可欠です。Azureもその選択肢のひとつになりそうです。
変更/更新履歴:
2015/02/14 MariaDB(MySQL)のチューニング について、追記しました。
ZIGSOWにログインするとコメントやこのアイテムを持っているユーザー全員に質問できます。