[AWS] EC2 で OpenVPN サーバを起動する

OpenVPN サーバ作る必要があったので、作業メモ

OpenVPN サーバのローンチ

MarketPlace に AMI があるので、それから作るのが簡単です。
Launch on EC2: OpenVPN Access Server
上のリンクからローンチすればセキュリティグループも作ってくれるけど、自分でセキュリティグループ作りたい場合は、インバウンドで最低限以下を許可するように設定。

Connection Method Protocol Port Range Source (IP or Group)
SSH tcp 22 Anywhere or IP Range
HTTPS tcp 443 Anywhere
tcp 943 Anywhere
udp 1194 Anywhere

起動したら EIP 割り当てておけば、後々便利。

しばらくすると EC2 起動してくるので、ssh 接続してイニシャルセッティングする。

$ ssh -i ~/.ssh/openvpn.pem openvpnas@xxx.xxx.xxx.xxx
Welcome to OpenVPN Access Server Appliance 2.1.4b

To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

user-data not available: HTTP Error 404: Not Found: util/ec2:12,util/ec2:7,python2.7/urllib2:154,python2.7/urllib2:437,python2.7/urllib2:550,python2.7/urllib2:475,python2.7/urllib2:409,python2.7/urllib2:558 (urllib2.HTTPError)

          OpenVPN Access Server
          Initial Configuration Tool
------------------------------------------------------
OpenVPN Access Server End User License Agreement (OpenVPN-AS EULA)
 ()

Please enter 'yes' to indicate your agreement [no]: yes

Once you provide a few initial configuration settings,
OpenVPN Access Server can be configured by accessing
its Admin Web UI using your Web browser.

Will this be the primary Access Server node?
(enter 'no' to configure as a backup or standby node)
> Press ENTER for default [yes]: yes

Please specify the network interface and IP address to be
used by the Admin Web UI:
(1) all interfaces: 0.0.0.0
(2) eth0: 192.168.0.1
Please enter the option number from the list above (1-2).
> Press Enter for default [2]: 2

Please specify the port number for the Admin Web UI.
> Press ENTER for default [943]: 943

Please specify the TCP port number for the OpenVPN Daemon
> Press ENTER for default [443]: 443

Should client traffic be routed by default through the VPN?
> Press ENTER for default [no]: no

Should client DNS traffic be routed by default through the VPN?
> Press ENTER for default [no]: yes

Use local authentication via internal DB?
> Press ENTER for default [yes]: yes

Private subnets detected: ['19.168.0.0/16']

Should private subnets be accessible to clients by default?
> Press ENTER for EC2 default [yes]: yes

To initially login to the Admin Web UI, you must use a
username and password that successfully authenticates you
with the host UNIX system (you can later modify the settings
so that RADIUS or LDAP is used for authentication instead).

You can login to the Admin Web UI as "openvpn" or specify
a different user account to use for this purpose.

Do you wish to login to the Admin UI as "openvpn"?
> Press ENTER for default [yes]: yes 
(admin ユーザ名変えたい時は、ここで no 答えて、次の質問で変えたい名前を入力)

Type the password for the 'openvpn' account:
Confirm the password for the 'openvpn' account:

> Please specify your OpenVPN-AS license key (or leave blank to specify later): 


Initializing OpenVPN...
Adding new user login...
useradd -s /sbin/nologin "openvpn"
Writing as configuration file...
Perform sa init...
Wiping any previous userdb...
Creating default profile...
Modifying default profile...
Adding new user to userdb...
Modifying new user as superuser in userdb...
Getting hostname...
Hostname: xxx.xxx.xxx.xxx
Preparing web certificates...
Getting web user account...
Adding web group account...
Adding web group...
Adjusting license directory ownership...
Initializing confdb...
Generating init scripts...
Generating PAM config...
Generating init scripts auto command...
Starting openvpnas...

NOTE: Your system clock must be correct for OpenVPN Access Server
to perform correctly.  Please ensure that your time and date
are correct on this system.

Initial Configuration Complete!

You can now continue configuring OpenVPN Access Server by
directing your Web browser to this URL:

https://xxx.xxx.xxx.xxx:943/admin
Login as "openvpn" with the same password used to authenticate
to this UNIX host.

During normal operation, OpenVPN AS can be accessed via these URLs:
Admin  UI: https://xxx.xxx.xxx.xxx:943/admin
Client UI: https://xxx.xxx.xxx.xxx:943/

See the Release Notes for this release at:
   http://www.openvpn.net/access-server/rn/openvpn_as_2_1_4b.html

openvpnas@openvpnas2:~$ sudo apt-get update && sudo apt-get upgrade

これで https://{public IP Address}:943/admin にアクセスすることで、ローンチした OpenVPN サーバの管理パネルに接続できます。
(自己署名証明書による HTTPS 接続なので、セキュリティ例外追加しないと接続できないので注意)

OpenVPN サーバで接続用のユーザ作成

https://{public IP Address}:943/admin から管理パネルにログインして [User Management] の [User Permitions] でユーザを追加。
[Allow Auto-login] にチェックしておくと、ユーザの設定が簡略化されるのでオススメ。

他の設定とか諸々はドキュメント参照。

OpenVPN クライアントのインストールと設定

Tunnelblick あたりをインストールしておけばいいです。
上の設定で VPN 接続用のユーザを作成してあるのであれば https://{public IP Address}:943/ にログイン。
Screen Shot 2017-02-22 at 12.54.03.png

すると、以下のような画面が表示されるので [Yourself (autologin profile)] ってリンクから ovpn ファイルをダウンロード。
Screen Shot 2017-02-22 at 12.54.13.png

ダウンロードした ovpn ファイルをダブルクリックすると Tunnelblick が起動して、よしなに設定してくれます。

iPhone とかでも VPN 接続したい場合は iPhoneやiPad (iOS) でOpenVPNを使ってみよう! を参考にしてみましょう。

MarketPlace にある AMI 使うと簡単にできて便利すなぁ。

参考 URL

続きを読む

AWS E2 G2インスタンス上にKeras環境を構築する 2017年2月版

はじめに

Deep Learningをやろうと思ったらでかい計算資源が必要なのが当たり前なのだけど、手持ちのPCのスペックで十分とかそうそうありはしないので、EC2のGPUインスタンスをささっと立てて使うのも手だと思う。

FrameworkはKerasでバックエンドはTensorFlow GPUバージョン。それをpyenv仮想環境でセットアップする構成とした。先日TensorFlow 1.0がリリースされてtf.kerasが実装されたみたいだけどまだ試してないので普通にKeras使うことにする。

環境構築についてはこちらを参考にさせていただいた。
AWSのGPUインスタンスでTensorFlowを動かす

インスタンスの作成

EC2 Instance: クイックスタートにある Ubuntu Server 16.04 LTS (HVM), SSD Volume Type
Type : g2.2xlarge
ストレージなどはとりあえず標準構成(メモリ15GB, ストレージ8GB)

セットアップ

まずはSSHでログインする

ssh -i ~/[ec2key].pem ubuntu@[Instance IP]

エフェメラルストレージを作業ディレクトリにするためシンボリックリンクを作成する

CUDAとかけっこうでかいので作業の途中で空き容量が足りなくなる。/mnt/tmp/へのシンボリックリンクを作成してエフェメラルストレージを作業領域に使う。

sudo mkdir /mnt/tmp
sudo chmod 777 /mnt/tmp
sudo rm -rf /tmp
sudo ln -s /mnt/tmp /tmp
cd /tmp

Ubuntuを最新にアップグレードする

sudo apt-get update
sudo apt-get upgrade -y

ロケールを設定する

upgrade後ロケール関係のwarningが出てうざいので

sudo apt-get install language-pack-ja
sudo update-locale LANG=ja_JP.UTF-8

セットアップに必要なモジュールをインストールする

sudo apt-get install python
sudo apt-get install -y build-essential python-pip python-dev git python-numpy swig python-dev default-jdk zip zlib1g-dev ipython

NVIDIAドライバとの衝突をさけるため、Nouveauのブラックリストを追加する

echo -e "blacklist nouveau\nblacklist lbm-nouveau\noptions nouveau modeset=0\nalias nouveau off\nalias lbm-nouveau off\n" | sudo tee /etc/modprobe.d/blacklist-nouveau.conf
echo options nouveau modeset=0 | sudo tee -a /etc/modprobe.d/nouveau-kms.conf
sudo update-initramfs -u
sudo reboot

再起動後、ログインしてlinux-image-extra-virtualをインストールする。

ssh -i ~/[ec2key].pem ubuntu@[Instance IP]
sudo apt-get install -y linux-image-extra-virtual
sudo reboot

再起動後、ログインしてlinux-headersをインストールする。

ssh -i ~/[ec2key].pem ubuntu@[Instance IP]
sudo apt-get install -y linux-source linux-headers-`uname -r`

CUDA Toolkit v8 をセットアップする

現時点での最新バージョンは 8.0。
ダウンロードしてインストールする

cd /tmp
wget https://developer.nvidia.com/compute/cuda/8.0/prod/local_installers/cuda_8.0.44_linux-run
chmod +x cuda_8.0.44_linux-run
./cuda_8.0.44_linux-run  -extract=`pwd`/nvidia_installers
cd nvidia_installers/
sudo ./NVIDIA-Linux-x86_64-367.48.run
# Acceptを選択する。kernelセットアップはプログレスバーが100%になってからしばらく時間がかかる
# OK を選択する
# OK を選択する
# Yes を選択する
# OK を選択する
sudo modprobe nvidia
sudo ./cuda-linux64-rel-8.0.44-21122537.run
# Readmeが表示されるので q で終了する
# accept と入力してエンター
# install Path: default
# shortcut?: default

cuDNN をセットアップ

https://developer.nvidia.com/cudnn からcuDNNを一度ローカルにDownloadする
cuDNNはDeveloperサインアップしないと落とせないため。仕方がない。

ローカルのターミナルからダウンロードしたcuDNNをEC2インスタンスに転送する

scp -i [ec2key].pem cudnn-8.0-linux-x64-v5.1.tgz ubuntu@[Instance IP]:/tmp

EC2インスタンスにもどる

cd /tmp
tar -xzf cudnn-8.0-linux-x64-v5.1.tgz
sudo mv ./cuda/lib64/* /usr/local/cuda/lib64/
sudo mv ./cuda/include/* /usr/local/cuda/include/

~/.bashrcに以下を追記する

# cuDNN
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/cuda/lib64"
export CUDA_HOME=/usr/local/cuda
source ~/.bashrc

Python 仮想環境の構築

python -V
Python 2.7.12
sudo apt-get install git gcc make openssl libssl-dev libbz2-dev libreadline-dev libsqlite3-dev
git clone https://github.com/yyuu/pyenv.git ~/.pyenv
git clone https://github.com/yyuu/pyenv-virtualenv.git ~/.pyenv/plugins/pyenv-virtualenv

~/.bash_profileを作成して以下を記載する

# pyenv
export PYENV_ROOT=$HOME/.pyenv
export PATH=$PYENV_ROOT/bin:$PATH
eval "$(pyenv init -)"
# virtualenv
eval "$(pyenv virtualenv-init -)"
export PYENV_VIRTUALENV_DISABLE_PROMPT=1
source ~/.bash_profile

Keras用仮想環境をつくる

pyenv install 3.5.3
pyenv virtualenv 3.5.3 keras
pyenv activate keras
python -V
Python 3.5.3

Tensorflowをインストールする

pip install tensorflow-gpu

TensorFlowのバージョンを確認してみて以下のようになってたらGPUが使えるようになっている。

python -c 'import tensorflow as tf; print(tf.__version__)'
I tensorflow/stream_executor/dso_loader.cc:135] successfully opened CUDA library libcublas.so.8.0 locally
I tensorflow/stream_executor/dso_loader.cc:135] successfully opened CUDA library libcudnn.so.5 locally
I tensorflow/stream_executor/dso_loader.cc:135] successfully opened CUDA library libcufft.so.8.0 locally
I tensorflow/stream_executor/dso_loader.cc:135] successfully opened CUDA library libcuda.so.1 locally
I tensorflow/stream_executor/dso_loader.cc:135] successfully opened CUDA library libcurand.so.8.0 locally
1.0.0

Kerasをインストールする

pip install pillow
pip install h5py
pip install matplotlib
pip install keras

keras examplesを実行してみる

cd /tmp
git clone https://github.com/fchollet/keras.git
cd keras/examples

とりあえずMNISTをCNNで解くやつを実行してみる

python mnist_cnn.py
Using TensorFlow backend.
I tensorflow/stream_executor/dso_loader.cc:128] successfully opened CUDA library libcublas.so locally
I tensorflow/stream_executor/dso_loader.cc:128] successfully opened CUDA library libcudnn.so locally
I tensorflow/stream_executor/dso_loader.cc:128] successfully opened CUDA library libcufft.so locally
I tensorflow/stream_executor/dso_loader.cc:128] successfully opened CUDA library libcuda.so.1 locally
I tensorflow/stream_executor/dso_loader.cc:128] successfully opened CUDA library libcurand.so locally
Downloading data from https://s3.amazonaws.com/img-datasets/mnist.pkl.gz
X_train shape: (60000, 28, 28, 1)
60000 train samples
10000 test samples
Train on 60000 samples, validate on 10000 samples
Epoch 1/12
I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
I tensorflow/core/common_runtime/gpu/gpu_device.cc:885] Found device 0 with properties: 
name: GRID K520
major: 3 minor: 0 memoryClockRate (GHz) 0.797
pciBusID 0000:00:03.0
Total memory: 3.94GiB
Free memory: 3.91GiB
I tensorflow/core/common_runtime/gpu/gpu_device.cc:906] DMA: 0 
I tensorflow/core/common_runtime/gpu/gpu_device.cc:916] 0:   Y 
I tensorflow/core/common_runtime/gpu/gpu_device.cc:975] Creating TensorFlow device (/gpu:0) -> (device: 0, name: GRID K520, pci bus id: 0000:00:03.0)
60000/60000 [==============================] - 13s - loss: 0.3770 - acc: 0.8839 - val_loss: 0.0932 - val_acc: 0.9709
Epoch 2/12
60000/60000 [==============================] - 11s - loss: 0.1363 - acc: 0.9603 - val_loss: 0.0632 - val_acc: 0.9801
Epoch 3/12
60000/60000 [==============================] - 11s - loss: 0.1064 - acc: 0.9687 - val_loss: 0.0509 - val_acc: 0.9835
Epoch 4/12
60000/60000 [==============================] - 11s - loss: 0.0900 - acc: 0.9736 - val_loss: 0.0443 - val_acc: 0.9857
Epoch 5/12
60000/60000 [==============================] - 11s - loss: 0.0769 - acc: 0.9775 - val_loss: 0.0405 - val_acc: 0.9865
Epoch 6/12
60000/60000 [==============================] - 11s - loss: 0.0689 - acc: 0.9795 - val_loss: 0.0371 - val_acc: 0.9870
Epoch 7/12
60000/60000 [==============================] - 11s - loss: 0.0649 - acc: 0.9803 - val_loss: 0.0361 - val_acc: 0.9881
Epoch 8/12
60000/60000 [==============================] - 11s - loss: 0.0594 - acc: 0.9823 - val_loss: 0.0356 - val_acc: 0.9886
Epoch 9/12
60000/60000 [==============================] - 11s - loss: 0.0547 - acc: 0.9841 - val_loss: 0.0321 - val_acc: 0.9889
Epoch 10/12
60000/60000 [==============================] - 11s - loss: 0.0525 - acc: 0.9841 - val_loss: 0.0320 - val_acc: 0.9889
Epoch 11/12
60000/60000 [==============================] - 11s - loss: 0.0506 - acc: 0.9850 - val_loss: 0.0323 - val_acc: 0.9892
Epoch 12/12
60000/60000 [==============================] - 11s - loss: 0.0471 - acc: 0.9856 - val_loss: 0.0314 - val_acc: 0.9897
Test score: 0.0314083654978
Test accuracy: 0.9897

実行時間は: 2:23 (データのダウンロード時間除く)。手持ちのMBAでは35分ほどかかったので10倍以上速い。
1epochあたり10秒くらいかよ。

調子に乗ってIMDBのLSTMという重たそうなやつもやってみた。

python imdb_cnn_lstm.py
Using TensorFlow backend.
I tensorflow/stream_executor/dso_loader.cc:128] successfully opened CUDA library libcublas.so locally
I tensorflow/stream_executor/dso_loader.cc:128] successfully opened CUDA library libcudnn.so locally
I tensorflow/stream_executor/dso_loader.cc:128] successfully opened CUDA library libcufft.so locally
I tensorflow/stream_executor/dso_loader.cc:128] successfully opened CUDA library libcuda.so.1 locally
I tensorflow/stream_executor/dso_loader.cc:128] successfully opened CUDA library libcurand.so locally
Loading data...
25000 train sequences
25000 test sequences
Pad sequences (samples x time)
X_train shape: (25000, 100)
X_test shape: (25000, 100)
Build model...
Train...
Train on 25000 samples, validate on 25000 samples
Epoch 1/2
I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
I tensorflow/core/common_runtime/gpu/gpu_device.cc:885] Found device 0 with properties: 
name: GRID K520
major: 3 minor: 0 memoryClockRate (GHz) 0.797
pciBusID 0000:00:03.0
Total memory: 3.94GiB
Free memory: 3.91GiB
I tensorflow/core/common_runtime/gpu/gpu_device.cc:906] DMA: 0 
I tensorflow/core/common_runtime/gpu/gpu_device.cc:916] 0:   Y 
I tensorflow/core/common_runtime/gpu/gpu_device.cc:975] Creating TensorFlow device (/gpu:0) -> (device: 0, name: GRID K520, pci bus id: 0000:00:03.0)
   30/25000 [..............................] - ETA: 1397s - loss: 0.6936 - acc: 0.4333I tensorflow/core/common_runtime/gpu/pool_allocator.cc:247] PoolAllocator: After 3811 get requests, put_count=2890 evicted_count=1000 eviction_rate=0.346021 and unsatisfied allocation rate=0.530307
I tensorflow/core/common_runtime/gpu/pool_allocator.cc:259] Raising pool_size_limit_ from 100 to 110
  360/25000 [..............................] - ETA: 160s - loss: 0.6935 - acc: 0.4833I tensorflow/core/common_runtime/gpu/pool_allocator.cc:247] PoolAllocator: After 2156 get requests, put_count=2374 evicted_count=1000 eviction_rate=0.42123 and unsatisfied allocation rate=0.373377
I tensorflow/core/common_runtime/gpu/pool_allocator.cc:259] Raising pool_size_limit_ from 256 to 281
  870/25000 [>.............................] - ETA: 94s - loss: 0.6925 - acc: 0.5287I tensorflow/core/common_runtime/gpu/pool_allocator.cc:247] PoolAllocator: After 4249 get requests, put_count=4491 evicted_count=1000 eviction_rate=0.222668 and unsatisfied allocation rate=0.192281
I tensorflow/core/common_runtime/gpu/pool_allocator.cc:259] Raising pool_size_limit_ from 655 to 720
25000/25000 [==============================] - 63s - loss: 0.3815 - acc: 0.8210 - val_loss: 0.3519 - val_acc: 0.8456
Epoch 2/2
25000/25000 [==============================] - 60s - loss: 0.1970 - acc: 0.9238 - val_loss: 0.3471 - val_acc: 0.8534
24990/25000 [============================>.] - ETA: 0sTest score: 0.347144101623
Test accuracy: 0.853440059948

実行時間: 2:25 (データのダウンロード時間除く)。MBAでこれも40分以上かかったやつなので圧倒的。

さらに調子に乗ってもっと重たそうなやつをやってみる。mnist_acgan.pyはMNISTをACGAN(Auxiliary Classifier Generative Adversarial Network)というやつで解くみたい。DCGANの親戚か?詳しくはここに載ってるみたいだけど難しいので後回しにする。
とりあえずGANなので重いだろう。どんなもんだろうか。

python mnist_acgan.py
Using TensorFlow backend.
I tensorflow/stream_executor/dso_loader.cc:128] successfully opened CUDA library libcublas.so locally
I tensorflow/stream_executor/dso_loader.cc:128] successfully opened CUDA library libcudnn.so locally
I tensorflow/stream_executor/dso_loader.cc:128] successfully opened CUDA library libcufft.so locally
I tensorflow/stream_executor/dso_loader.cc:128] successfully opened CUDA library libcuda.so.1 locally
I tensorflow/stream_executor/dso_loader.cc:128] successfully opened CUDA library libcurand.so locally
Epoch 1 of 50
  0/600 [..............................] - ETA: 0sI tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
I tensorflow/core/common_runtime/gpu/gpu_device.cc:885] Found device 0 with properties: 
name: GRID K520
major: 3 minor: 0 memoryClockRate (GHz) 0.797
pciBusID 0000:00:03.0
Total memory: 3.94GiB
Free memory: 3.91GiB
I tensorflow/core/common_runtime/gpu/gpu_device.cc:906] DMA: 0 
I tensorflow/core/common_runtime/gpu/gpu_device.cc:916] 0:   Y 
I tensorflow/core/common_runtime/gpu/gpu_device.cc:975] Creating TensorFlow device (/gpu:0) -> (device: 0, name: GRID K520, pci bus id: 0000:00:03.0)
W tensorflow/core/common_runtime/bfc_allocator.cc:217] Ran out of memory trying to allocate 3.74GiB. The caller indicates that this is not a failure, but may mean that there could be performance gains if more memory is available.
599/600 [============================>.] - ETA: 1s   
Testing for epoch 1:
component              | loss | generation_loss | auxiliary_loss
-----------------------------------------------------------------
generator (train)      | 3.88 | 1.49            | 2.39 
generator (test)       | 3.36 | 1.04            | 2.32 
discriminator (train)  | 2.11 | 0.53            | 1.58 
discriminator (test)   | 2.12 | 0.70            | 1.43 
Epoch 2 of 50
 44/600 [=>............................] - ETA: 732s

1epoch終わるのに 15分ほどかかった。あと48epochある。。果てしないしお金かかるので途中でやめた。まあでも半日回せば結果出そう。すごいな。

作業後のディスク空き状況

df -k
Filesystem     1K-blocks    Used Available Use% Mounted on
udev             7679880       0   7679880   0% /dev
tmpfs            1539900    8800   1531100   1% /run
/dev/xvda1       8117828 6149060   1533492  81% /
tmpfs            7699496       0   7699496   0% /dev/shm
tmpfs               5120       0      5120   0% /run/lock
tmpfs            7699496       0   7699496   0% /sys/fs/cgroup
/dev/xvdb       66946696 3017852  60521484   5% /mnt
tmpfs            1539904       0   1539904   0% /run/user/1000

システムディスクの使用量は81%。エフェメラルストレージはインスタンスがstopすると揮発するのでデフォルトの8GBが不安ならストレージ要領を拡張しとくとよい。

AMIにしてからg2.xlargeインスタンスを作成してみたらエラーになる

構築できたインスタンスのスナップショットをとって、AMIからg2.xlargeインスタンスを作成してみた。ちゃんと動くか試行。

pyenv activate keras
python -V
 Python 3.5.3
python -c 'import tensorflow as tf; print(tf.__version__)'
Traceback (most recent call last):
  File "/home/ubuntu/.pyenv/versions/keras/lib/python3.5/site-packages/tensorflow/python/__init__.py", line 61, in <module>
    from tensorflow.python import pywrap_tensorflow
  File "/home/ubuntu/.pyenv/versions/keras/lib/python3.5/site-packages/tensorflow/python/pywrap_tensorflow.py", line 28, in <module>
    _pywrap_tensorflow = swig_import_helper()
  File "/home/ubuntu/.pyenv/versions/keras/lib/python3.5/site-packages/tensorflow/python/pywrap_tensorflow.py", line 24, in swig_import_helper
    _mod = imp.load_module('_pywrap_tensorflow', fp, pathname, description)
  File "/home/ubuntu/.pyenv/versions/3.5.3/lib/python3.5/imp.py", line 242, in load_module
    return load_dynamic(name, filename, file)
  File "/home/ubuntu/.pyenv/versions/3.5.3/lib/python3.5/imp.py", line 342, in load_dynamic
    return _load(spec)
ImportError: libcudart.so.8.0: cannot open shared object file: No such file or directory

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/home/ubuntu/.pyenv/versions/keras/lib/python3.5/site-packages/tensorflow/__init__.py", line 24, in <module>
    from tensorflow.python import *
  File "/home/ubuntu/.pyenv/versions/keras/lib/python3.5/site-packages/tensorflow/python/__init__.py", line 72, in <module>
    raise ImportError(msg)
ImportError: Traceback (most recent call last):
  File "/home/ubuntu/.pyenv/versions/keras/lib/python3.5/site-packages/tensorflow/python/__init__.py", line 61, in <module>
    from tensorflow.python import pywrap_tensorflow
  File "/home/ubuntu/.pyenv/versions/keras/lib/python3.5/site-packages/tensorflow/python/pywrap_tensorflow.py", line 28, in <module>
    _pywrap_tensorflow = swig_import_helper()
  File "/home/ubuntu/.pyenv/versions/keras/lib/python3.5/site-packages/tensorflow/python/pywrap_tensorflow.py", line 24, in swig_import_helper
    _mod = imp.load_module('_pywrap_tensorflow', fp, pathname, description)
  File "/home/ubuntu/.pyenv/versions/3.5.3/lib/python3.5/imp.py", line 242, in load_module
    return load_dynamic(name, filename, file)
  File "/home/ubuntu/.pyenv/versions/3.5.3/lib/python3.5/imp.py", line 342, in load_dynamic
    return _load(spec)
ImportError: libcudart.so.8.0: cannot open shared object file: No such file or directory


Failed to load the native TensorFlow runtime.

See https://github.com/tensorflow/tensorflow/blob/master/tensorflow/g3doc/get_started/os_setup.md#import_error

for some common reasons and solutions.  Include the entire stack trace
above this error message when asking for help.

TensorFlowがエラーを吐く。よくわからないけどCUDA関係か?
AMI化ができるかどうかはあとで検討が必要かも。断続的に使う場合はインスタンスをstopして置いとくのがいいかもしれない。

まとめ

上記Kerasの環境構築までは一時間以内でできる。インスタンスstopして置いとくのもいいけど、使いたい時にサラから構築してもそんなに手間ではない。
使用頻度とかケースに応じて考えるのがいいだろう。つーかTensorFlow GPUの環境構築以前と比べてめっちゃ楽になったな。

続きを読む

[AWS] EC2+RDS開発環境設定 Apache2.2+PHP+MySQL+WordPress+phpMyAdmin

インフラ初心者がAWSに以下の環境を構築するまでの流れを実施したので、備忘録として残しておこうと思います。

(0)AWSの設定
(1)Apache2.2+PHP7+MySQL5.6+WordPress4.7+phpMyAdmin4.6 ← 本エントリの内容
(2)Nginx+Unicorn+RubyOnRails(詳細は後ほどUP予定)

実施事項
◎EC2の設定
◎RDSの設定
◎WordPressの設定
◎phpMyAdminの設定

【ご一読いただくにあたって】
・EC2、RDS等々の設定は済ませておいて下さい。
 まだの方はこちらから → AWSの設定
・間違いがありましたらコメントにて教えて下さい。(まだまだ勉強中です。)
・専門用語の深い解説はしておりません。

EC2の設定

アップデート、ユーザ追加等の下準備

sshでEC2へアクセスした状態


       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|___|___|

https://aws.amazon.com/amazon-linux-ami/2016.09-release-notes/
3 package(s) needed for security, out of 6 available
Run "sudo yum update" to apply all updates.
[ec2-user@ip-10-0-1-107 ~]$ sudo yum update

~アップデート~

総ダウンロード容量: 51 M
Is this ok [y/d/N]: y
(途中、確認されますが[y]を入力)

完了しました!
[ec2-user@ip-10-0-1-107 ~]$ sudo su - #スーパーユーザへ切替
[root@ip-10-0-1-107 ~]# useradd myname #ユーザ追加
[root@ip-10-0-1-107 ~]# passwd myname #ユーザパスワード設定
Changing password for user myname.
New password: (パスワード入力)
Retype new password: (再入力)
passwd: all authentication tokens updated successfully. #成功
[root@ip-10-0-1-107 ~]# sudo visudo #追加したユーザに権限付与

=ファイル編集画面=

## Allow root to run any commands anywhere
root    ALL=(ALL)       ALL
myname  ALL=(ALL)       ALL  (←rootの下に追加)

===============

[root@ip-10-0-1-107 ~]# exit #スーパーユーザ ログアウト
logout
[ec2-user@ip-10-0-1-107 ~]$ su - myname #追加したユーザに切替
パスワード:
[myname@ip-10-0-1-107 ~]$

Apache2.2 インストール

[myname@ip-10-0-1-107 ~]$ sudo yum -y install httpd
[sudo] password for myname: (パスワード入力) 

~インストール~

Complete!
[myname@ip-10-0-1-107 ~]$ httpd -version #バージョン確認
Server version: Apache/2.2.31 (Unix)
[myname@ip-10-0-1-107 ~]$ sudo /sbin/chkconfig httpd on #自動起動をonに変更
[myname@ip-10-0-1-107 ~]$ sudo service httpd start #Apache起動
Starting httpd: httpd: apr_sockaddr_info_get() failed for ip-10-0-1-107
httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName
                                                           [  OK  ]
#サーバーは起動しているもエラーが表示

[myname@ip-10-0-1-107 ~]$ sudo service httpd stop #Apache停止

エラーをググってみると設定ファイルの修正が必要とのこと。
Apacheエラーの原因と解決方法
Apacheのエラー

networkファイルの修正

[myname@ip-10-0-1-107 ~]$ sudo vi /etc/sysconfig/network
===
HOSTNAME=localhost.localdomain
        ⬇︎
#HOSTNAME=localhost.localdomain
HOSTNAME=13.112.XXX.XXX ← (EC2のパブリックIP)追加
===

hostsファイルの修正

[myname@ip-10-0-1-107 ~]$ sudo vi /etc/hosts
===
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
           ⬇︎
127.0.0.1   13.112.XXX.XXX localhost localhost.localdomain localhost4 localhost4.localdomain4 ← (EC2のパブリックIP)追加
===

httpd.confファイルの修正

[myname@ip-10-0-1-107 ~]$ sudo vi /etc/httpd/conf/httpd.conf
===
#ServerName www.example.com:80
ServerName 13.112.XXX.XXX ← (EC2のパブリックIP)追加
===

再度起動

[myname@ip-10-0-1-107 ~]$ sudo service httpd start
Starting httpd:                                            [  OK  ]

http://13.112.XXX.XXXにアクセス

スクリーンショット 2017-02-10 20.29.48.png

OK!!

PHP7 インストール

標準リポジトリで利用できないパッケージのインストールを可能にするEPELリポジトリを有効化

[myname@ip-10-0-1-107 ~]$ sudo vi /etc/yum.repos.d/epel.repo #epel.repoの編集

=ファイルの中=

enabled=0
   ⬇︎
enabled=1 に変更

=ファイルの中終わり=

[myname@ip-10-0-1-107 ~]$ sudo rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm #Remiレポジトリのインストール
[myname@ip-10-0-1-107 ~]$ sudo yum -y install libwebp --disablerepo=amzn-main --enablerepo=epel #libwebpのインストール
[myname@ip-10-0-1-107 ~]$ sudo yum -y install libmcrypt libtool-ltdl libtidy libXpm libtiff gd-last autoconf automake #amzn-main.repoから各ライブラリをインストール
[myname@ip-10-0-1-107 ~]$ sudo yum -y install --disablerepo=amzn-main --enablerepo=remi-php70 php php-opcache php-devel php-mbstring php-mcrypt php-phpseclib-crypt-blowfish php-pecl-apc php-gd php-mysqlnd php-xml #phpインストール

Complete!
[myname@ip-10-0-1-107 ~]$ php -v #バージョン確認
PHP 7.0.15 (cli) (built: Jan 17 2017 17:20:32) ( NTS )
Copyright (c) 1997-2017 The PHP Group

AWSナレッジセンター
yum が便利になる RPMforge、Remi、EPEL とは一体何なのか
【yum入門】epel, remiなどのレポジトリをyumに追加する方法
libwebp の概要
Amazon LinuxでYUMを使う時に気をつけるポイント
php-opcache
php-devel
この辺はまだまだ勉強中です。

WordPress4.7.2インストール

Apacheのドキュメント・ルートのディレクトリは”/var/www/html”とのこと。
今回はhttp://13.112.XXX.XXX/wordpressでアクセスした時にWordPressのトップ画面が表示されるように設定
(wordpressディレクトリはWP展開時に自動生成)

[myname@ip-10-0-1-107 ~]$ cd /var/www/html #htmlへ移動
[myname@ip-10-0-1-107 html]$ sudo wget http://ja.wordpress.org/latest-ja.tar.gz ~/ #最新のWordPressをダウンロード (20170210時点では、4.7.2)
[myname@ip-10-0-1-107 html]$ sudo tar zxvf latest-ja.tar.gz

~インストール~
(wordpressディレクト生成)

[myname@ip-10-0-1-107 html]sudo chown -R apache:apache wordpress #オーナー変更

http://13.112.XXX.XXX/wordpress
にアクセスすると
http://13.112.XXX.XXX/wordpress/wp-admin/setup-config.php
にリダイレクトされる

wp1.png

wp2.png

項目
データベース名 db_qiita
ユーザー名 db_qiita_user
パスワード ********
ホスト名 db-id-for-qiita.xxxxxxxxx.ap-northeast-1.rds.amazonaws.com(RDSエンドポイント)

※RDSインスタンス生成時に設定した値を入力

wp3.png

[インストール実行]

wp4.png

項目
サイトのタイトル wp_site_qiita(任意)
ユーザー名 wp_qiita_user(任意)
パスワード ********
メールアドレス your_mail@address.com(任意)

wp5.png

インストール成功 → ログイン画面

wp6.png

ダッシュボード画面

wp7.png

サイトトップ画面(WordPress4.7.2の場合)

phpMyAdminのインストール

今回はhttp://13.112.XXX.XXX/phpMyAdminでアクセスした時にphpMyAdminのトップ画面が表示されるように設定

[myname@ip-10-0-1-107 html]$ sudo wget https://files.phpmyadmin.net/phpMyAdmin/4.6.6/phpMyAdmin-4.6.6-all-languages.tar.gz #phpMyAdminをダウンロード
[myname@ip-10-0-1-107 html]$ sudo tar xzvf phpMyAdmin-4.6.6-all-languages.tar.gz #展開
[myname@ip-10-0-1-107 html]$ sudo mv phpMyAdmin-4.6.6-all-languages phpMyAdmin #リネーム
[myname@ip-10-0-1-107 html]$ cd phpMyAdmin #移動
[myname@ip-10-0-1-107 phpMyAdmin]$ cp config.sample.inc.php config.inc.php #設定ファイルをコピー
[myname@ip-10-0-1-107 phpMyAdmin]$ sudo vi config.inc.php #設定を編集

=ファイルの中=
/* Server parameters */
$cfg['Servers'][$i]['host'] = 'localhost';
                   ⬇︎
$cfg['Servers'][$i]['host'] = 'db-id-for-qiita.xxxxxxxxx.ap-northeast-1.rds.amazonaws.com';
============

http://13.112.XXX.XXX/phpMyAdmin へアクセス

スクリーンショット 2017-02-13 11.05.55.png

項目
ユーザー名 db_qiita_user
パスワード xxxxxxxxx

※RDSインスタンス生成時に設定したユーザ名とパスワード
pma1.png

ログイン成功!

以上です。

後ほど別のEC2にNginx+Unicorn+RubyOnRailsの開発環境を設定予定です。

参考にさせていただきました。
【AWS】WordPressのインストールとRDS、S3の連携
EC2にphpMyAdminを設置しRDSに接続する

続きを読む

IPsecの基礎知識を身につけつつ、AWSのVPN接続設定を読む

概要

  1. IPv4におけるIPsecについて調べる
  2. AWSのVPNサービスで提供されているルータの設定テンプレートを読み解く

IPsecについて

概要

  • Security Architecture for the Internet Protocol

    • IPsecとは特定のプロトコルを指すものではない。いくつかの要素をもとに成り立つ、IPのセキュリティ設計。

      • AH, ESP, IKE, SA(それぞれ後述)
  • IP通信を透過的にセキュア化する
    • アプリケーションプロトコル(HTTPなど)を変更することなしに利用できる
    • cf. SSL/TLS
  • IPsecは「トンネリング」と「暗号化」の機能をもつため、VPNで利用される

RFC

  • RFCを読むなら、まずこれに目を通したほうがいい. IPsec関連のRFCの見通しをよくするための”Road Map”

バージョン

  • IPsec-v1, IPsec-v2, IPsec-v3がある
  • 現在使われているのは. IPsec-v2とIPsec-v3
  • ただし、これらのバージョンはIETF的には非公式とのこと。(wikipediaより)

IPsecの2つのモード

トランスポートモード

  • ホスト間で使用される
  • パケットのIPヘッダは変更しない
  • 既存のIPヘッダの後ろにAH/ESPヘッダを挿入する

トンネルモード

  • ルータ間(セキュリティゲート間)で使用される
  • AWSのVPN接続はこちらのモード
  • もとのパケットに新たにIPヘッダを付加してパケットを転送する
  • ホスト(PC)はIPsecを意識しない

構成する要素

AH(Authentication Header)

  • 認証機能

ESP(Encapsulated Security Payload)

  • ペイロード部の暗号化
  • 改ざん防止のAHか機密性保護のESPかを選択する。現在広く使われているのはESPらしい。
  • VPNでは暗号化が必須なのでESPを使う

IKE(Internet Key Exchange)

  • 鍵交換
  • 動的なSAの構築で利用される
    • 詳細は『3分間ネットワーク』へ

    • SAの構築のために、セキュアにパラメータを交換するためのSAを別に構築する。(ISKAMP SA)
      • IKEフェーズ1でISKAMP SAを構築し、IKEフェーズ2でSA(IPsec SA)を構築する

SA(Security Association)

それぞれの関連

AWSのVPN設定用テンプレート

  • AWSのマネジメントコンソールにおけるVPCサービスの画面より「VPN接続」を設定すると、自分の環境に合わせた機器(ルータのOS)の設定テンプレートがダウンロードできる。

    • 基本的にはそのままコピペすれば設定が完了するくらい出来上がったもの
  • そのうち、vyatta用のテンプレートをダウンロードし、一つ一つの設定を見ていく。
    • もともとあったコメントは大きく削除し、解説用のコメント私のほうで追加した

      • NW詳しくないので、ある程度疑いの目で見て欲しい
    • 一部の情報(主に環境に依存しているIPアドレス)はマスクした
! --------------------------------------------------------------------------------
! IPSec Tunnel #1 (トンネル1と2を設定する必要がある)
! --------------------------------------------------------------------------------

! #1: Internet Key Exchange (IKE) Configuration
! もともとのコメント文にも書いてあったが、「AES128, SHA1, and DH Group 2」の最小限の要求を満たす設定のため、適宜修正すること。そしてNATトラバーサルを利用するには、UDP PORT 4500を開放しておくこと。

! IKEフェーズ1で作成されたキーの持続期間を28800sec(8時間)にする. これを超えるとIKE フェーズ1のネゴシエーションが発生する
! "AWS"はグループ化された設定の識別名
set vpn ipsec ike-group AWS lifetime '28800'

! フェーズ1のネゴシエーション時に使用する、Diffie-Hellman交換のパラメータ。DHグループ2を指定している
! "proposal 1"は、IPsecの接続を開始するイニシエータにおいて、IKEフェーズ1で使用するパラメータのうち最も優先度の高い「提案」
set vpn ipsec ike-group AWS proposal 1 dh-group '2'

! AES128の暗号方式を使用する(AWSというIKE設定グループのプロポーザル1において)
set vpn ipsec ike-group AWS proposal 1 encryption 'aes128'
! 説明は省略
set vpn ipsec ike-group AWS proposal 1 hash 'sha1'

! 対向のVPNゲートウェイの認証方式にpre-shared-secret(事前共有秘密)を使用する。
! "xxx.xxx.xxx.xxx"は対向のVPNゲートウェイのアドレス
set vpn ipsec site-to-site peer xxx.xxx.xxx.xxx authentication mode 'pre-shared-secret'

! pre-shared-secretの内容(マスクしている)
set vpn ipsec site-to-site peer xxx.xxx.xxx.xxx authentication pre-shared-secret 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'

! 対向のVPNゲートウェイの説明文
set vpn ipsec site-to-site peer xxx.xxx.xxx.xxx description 'VPC tunnel 1'

! 対向のVPNゲートウェイと'AWS'IKE設定グループをひもづける
set vpn ipsec site-to-site peer xxx.xxx.xxx.xxx ike-group 'AWS'

! 対向のVPNゲートウェイに送られるパケットの送信元IPアドレス(yyy.yyy.yyy.yyy) を指定する
set vpn ipsec site-to-site peer xxx.xxx.xxx.xxx local-address 'yyy.yyy.yyy.yyy'

! IPsecのVPNトンネルを仮想トンネルインタフェースにバインドする
set vpn ipsec site-to-site peer xxx.xxx.xxx.xxx vti bind 'vti0'

! IPsecのVPNトンネルに設定するESP設定グループを指定する
set vpn ipsec site-to-site peer xxx.xxx.xxx.xxx vti esp-group 'AWS'


! #2: IPSec Configuration
! eth0でIPsec VPNを有効にする
set vpn ipsec ipsec-interfaces interface 'eth0'

! 説明は省略
set vpn ipsec esp-group AWS compression 'disable'

! 3600sec(1時間)を超えるとIKEフェーズ2のネゴシエーションが行われる
set vpn ipsec esp-group AWS lifetime '3600'

! (トランスポートモードではなく、)IPsecのトンネルモードを使用する
set vpn ipsec esp-group AWS mode 'tunnel'

! PFS(Perfect Forward Secrecy)というものがあるらしい
set vpn ipsec esp-group AWS pfs 'enable'

! 説明は省略
set vpn ipsec esp-group AWS proposal 1 encryption 'aes128'
! 説明は省略
set vpn ipsec esp-group AWS proposal 1 hash 'sha1'

! VPNトンネルが到達不能になったときに、VPNトンネルをリスタートする
set vpn ipsec ike-group AWS dead-peer-detection action 'restart'
! IKEキープアライブの送信間隔(sec)
set vpn ipsec ike-group AWS dead-peer-detection interval '15'
! 対向ゲートウェイが応答しない場合に、actionが実行される期間(sec)
set vpn ipsec ike-group AWS dead-peer-detection timeout '30'


! #3: Tunnel Interface Configuration
! vtiインタフェース(vti0)の設定。IPアドレス、説明文、MTU
set interfaces vti vti0 address 'zzz.zzz.zzz.zzz/zz'
set interfaces vti vti0 description 'VPC tunnel 1'
set interfaces vti vti0 mtu '1436'

! #4: Border Gateway Protocol (BGP) Configuration
! AS番号65000(自分のAS)に、BGPネイバー(nnn.nnn.nnn.nnn)のAS番号10124を指定
set protocols bgp 65000 neighbor nnn.nnn.nnn.nnn remote-as '10124'
set protocols bgp 65000 neighbor nnn.nnn.nnn.nnn soft-reconfiguration 'inbound'
set protocols bgp 65000 neighbor nnn.nnn.nnn.nnn timers holdtime '30'
set protocols bgp 65000 neighbor nnn.nnn.nnn.nnn timers keepalive '10'

! アドバタイズするネットワーク。AWSのテンプレートのデフォルトは下記の通りだが、自身が所属するNWを指定するほうがよいと思われる
set protocols bgp 65000 network 0.0.0.0/0


! --------------------------------------------------------------------------------
! IPSec Tunnel #2
! --------------------------------------------------------------------------------
! ここからTunnel2の設定になるが、内容はTunnel1とほとんど変わらないので割愛する。

参考にしたサイト

続きを読む

異なるリージョン同士をVPNつなごうとしたけど、できなかった話

追記

構成と設定を見直したところ、疎通できました。

近日中に記事にします。


概要

異なるリージョン(東京とソウル)をVPNで接続したかったが、失敗した。(理由もわかっていない)

詳しい方、分かる方、いらっしゃったらぜひ教えてください。

構成図

WG4PUQ8PwpjtRAPT-8B8DF.png

やりたかったこと(ゴール)

  • 東京リージョンのEC2インスタンス(10.0.0.128/28)からソウルリージョンのEC2インスタンス(10.0.1.192/28)にPINGが通る

結果(失敗)

  • 東京リージョンEC2インスタンスを”t1″、ソウルリージョンEC2インスタンスを”s1″とすると、疎通確認の結果は以下の通り

    • t1 -> vyos : PING疎通成功
    • vyos -> s1 : PING疎通成功
    • t1 -> s1 : PING疎通失敗
      • s1のパケットキャプチャの結果より、パケットがs1に届いていない
    • vyos -> t1 : PING疎通失敗
      • t1のパケットキャプチャの結果より、パケットは届いているが、応答(t1->vyos)がvyosに届いていない
  • 問題は2点?

    • vyosがルーティングをしていない
    • t1 -> vyos(vyos -> t1の戻りの経路)で何かが起こっている
      • t1上のパケットキャプチャの結果では、PINGの応答は、”10.0.0.xxx(t1のローカルIPアドレス) -> 169.xxx.xxx.xxx”となっていた。(マスクしているのは忘れたから)

構成を簡単に説明

  • 東京リージョンとソウルリージョンそれぞれにVPCを作成
  • 仮想プライベートゲートウェイは東京リージョンに置き、カスタマーゲートウェイはソウルリージョンに置く。カスタマーゲートウェイは、EC2でたてたvyosにする

参考にしたサイト

上記のサイトは、自分がやりたかったことをほぼ同じ構成で実現している。細かい部分で違いはあるが(ネットワークアドレスが違う、デフォルトのVPCを使用している、vyosのバージョンが違うなど)、それが原因とは思いづらい…。

やったこと

実際に作業した順番で書いていく(順番の記憶違いはあるかも)
BGPのAS番号はすべての箇所で65000にしています。(どこで設定しているか忘れたのでここに書いた)

東京リージョン

  • VPCを作成
  • 上記VPC内にサブネットを作成。構成図の通り2つのサブネットを作成し、アベイラビリティゾーンは分けている。
  • インターネットゲートウェイを作成し、VPCにアタッチ
  • 仮想プライベートゲートウェイを作成し、VPCにアタッチ
  • ルートテーブルを設定
    • サブネットを関連付ける
    • ルートを設定
      • 送信先:0.0.0.0/0、ターゲット:インターネットゲートウェイ
      • 送信先:10.0.1.0/24、ターゲット:仮想プライベートゲートウェイ(もしかしたら設定していないかも。vyosからアドバタイズされたものが載っていたかも)
  • 作成したVPC内に疎通確認用のEC2インスタンスを1台たてる(Amazon Linux)
    • セキュリティグループはすべてのトラフィックを許可

ソウルリージョン

  • VPCを作成
  • 上記VPC内にサブネットを作成。構成図の通り2つのサブネットを作成し、アベイラビリティゾーンは分ける。
  • インターネットゲートウェイを作成し、VPCにアタッチ
  • ルートテーブルを設定
    • サブネットを関連付ける
    • ルートを設定
      • 送信先:0.0.0.0/0、ターゲット:インターネットゲートウェイ
  • 作成したVPC内にEC2インスタンスを2つ作成。1つはvyos用、もう1つはPing疎通確認用。サブネットはそれぞれ別のものを指定する。(つまりアベイラビリティゾーンも別)
  • vyosの構築内容
    • AMIは、コミュニティAMIから”VyOS(HVM)1.1.7″を選択
    • EIPを付与
    • セキュリティグループはすべてのトラフィックを許可
    • 「送信元と宛先のチェック」は無効に設定
  • Ping疎通確認用インスタンスの構築内容
    • AMIは、Amazon Linuxを選択.
    • セキュリティグループはすべてのトラフィックを許可

東京リージョン

  • ソウルリージョンで付与したEIPのグローバルIPアドレスをもとに、カスタマーゲートウェイを作成
  • このカスタマーゲートウェイと先ほど作成した仮想プライベートゲートウェイから、「VPC接続」を作成、ルーティングは動的
  • vyatta用のコンフィグをダウンロード

ソウルリージョン

  • ダウンロードしたコンフィグをもとにvyosを設定

    • 変更した箇所は下記の2点.(クラスメソッドさんの記事を丸パクリ。http://dev.classmethod.jp/event/soracom-door/)
    • “10.0.1.0/24″の箇所は、試行錯誤の中で”10.0.1.128/28″、”0.0.0.0/0″も試したが、すべて疎通は上手く行かなかった
(変更前)
set vpn ipsec site-to-site peer ***** local-address [VyOSのEIP]
set protocols bgp 65000 network 0.0.0.0/0

(変更後)
set vpn ipsec site-to-site peer ***** local-address [VyOSのプライベートIP]
set protocols bgp 65000 network 10.0.1.0/24
  • ルートの設定で、10.0.0.0/24 宛のターゲットは、vyosに付与したEIPを指定

確認作業

  • マネジメントコンソールのVPC設定画面(東京リージョン)で、「VPN接続」の1つのトンネルがUPしていることを確認
  • 東京リージョンのVPCのルーティングの設定で、ソウルリージョン宛は仮想プライベートゲートウェイになっていることを確認
  • ソウルリージョンのVPCのルーティングの設定で、東京リージョン宛はvyosのEIPになっていることを確認

失敗した原因究明として、他に試せそうなこと

  • リージョンを変える。東京<->シンガポールとか
  • vyosのバージョンを変える
    • 昔、特定のバージョンのvyattaにて、今回と同様の構成でルーティングに失敗する不具合があったらしい
    • ソウルリージョンには1.1.7のバージョンしかなかったので、リージョンごと変える必要がある
  • 片方のリージョンで172.x.x.xのデフォルトのVPCを使ってみる
  • アベイラビリティゾーンをなるべく分けずにやってみる
  • ルーティングやNWの構成を見直す?

最後に…

  • VPNやIPsec、VPCを学んで、出直してきます。

続きを読む

AWS のデータセンターに侵入する(妄想で)

AWS の中身はどうなっているの?

 AWS インスタンスを立ち上げたとき、なんとなく Virtual Machine 上で 仮想OSが立ち上がっているんだろうなーというのは分かるけど、実際の物理層はどうなっているんでしょうか。データセンターはどこにあって、何台くらいのサーバが動いていて、どのラックのどの VM 上にインスタンスができるんでしょう。
 そんなこと知らなくてもサーバ立てることはできるし、障害にも強いらしいし、知らなくてもいいことなんだけど。でも、わたし気になります!

ナイショです

 AWS はデータセンターの場所は非公開、どこにあるか教えてくれません。物理層の内部仕様も非公開で re:invent でチョイ出しする程度です。
 ここはささやかな抵抗として、物理構成を想像で補完し、妄想によるデータセンターへの侵入を試みます。

こんな構成で構築しました

 手始めにサーバ 1台、ボリューム 1台の構成でサーバを構築してみました。データセンターに侵入しこのときの物理的な情報を見ていくとともに、対障害性の向上を検討します。
SEKKEI.png

  • インスタンスタイプ:t2.micro (1vCPU/1GiB)
  • VPC:1つ
  • サブネット:1つ
  • AZ:ap-northeast-1a

AWS データセンターに来ました

 データセンターは地震や洪水といった自然災害が少なく、安定した土地に立てられるものなので、どのあたりに建っていそうかはある程度予想がつきます。洪水・液状化などあらゆるハザードマップを見ながら捜索範囲は東京だけでなく関東全域に及び、埼玉県某市にあるという妄想に至りました。
 こちらのビルです、写真をご覧ください。

DC
 これが ap-northeast-1a の実物です、10年以上経過しているにしてはきれいな外見ですね。表には看板すら出ておらず、ぱっと見データセンターだとわかりません。警備員やビルから出てきた人間にインタビューしても、社名すら教えてくれません、さすがにしっかりしています。1

侵入に成功しました

 入館認証、入室認証、監視カメラ、静脈認証、等々の超厳重なセキュリティを忍術により突破しサーバルームへ侵入。物理構成を念力で透視することにより、前述のインスタンスとボリュームの可視化に成功しました。
 前置きが長かったですが、次からが本編になります。

サーバ構成

image

解説

インスタンス

 AWS ではハイパーバイザに Xen をカスタマイズしたものを使用しているそうです。大量の Xen Server があり、その1台の上にゲスト OS としてインスタンスがいました(オレンジ)。
 物理ホストの電源喪失、ハイパーバイザの障害、H/W 障害はインスタンスに波及することになります、それを監視してくれるのが Cloud Watch であり、EC2 ステータスでよく見る Check Status 2/2 ですね。
 EC2 インスタンスは起動するたびに別の物理ホスト上で立ち上がります(薄いオレンジ)。EC2 メンテナンス時に再起動依頼のメールが届きますが、物理ホストからどいてもらうためのオペレーションです。起動したままホストを移動する Live Migration はできないようです。Auto Recovery もこれと同じ仕組みで、別筐体に移すことでリカバリが行われます。
 ハイエンドなブレードサーバに何百台もサーバがあるわけではなく、ローエンドなブレードサーバに数十台のインスタンスが起動できる設計がされており、安価で大量にというモデルです、t2.micro を選びましたが、高 GPU だったり、HPC なインスタンスを選べば別の筐体に起動されることでしょう。

 障害時には再起動でリカバリできることはわかりましたが、現状の構成ではデータセンター全体が壊れると復旧できませんので、EC2 インスタンスは Multi-AZ 構成にしたほうがよさそうです。

ネットワーク(SDN Layer)

 だいぶ想像ですが、各ハイパーバイザは巨大な SDN(Software Defined Network)で接続されています。今回の VPC / Subnet(黄色)が見つけられます 。 2
 VPC やサブネットを構築したとしても SDN 上で論理的なネットワークが構成されるだけで、物理的なネットワーク構成とは関係ありません。ネットワーク機器のメンテナンスは利用者まで波及せず、自動で SDN 上の論理構成が変更された上でネットワーク機器のメンテナンスが行われるものと思われます。3

ボリューム(SAN Layer)

 EBS ボリュームも巨大な SAN のなかにいました(赤色)。仮想ディスクであるため、物理ディスクをまるっとマウントしているわけではないですね。EBS ボリュームは自動的に同一 AZ にレプリケートされているので(ピンク)耐久性も高いし故障率も低くなっています。ネットワーク的には直接サーバに SCSI マウントされているわけではなく、iSCSI(SCSI over IP) や FCoE(FiverChanner over Ethernet)が使われており IP で接続されています。4
 
 耐久性が高いことはわかりましたが、現状の構成ではやはりデータセンターが逝くと復旧できませんので、定期的に EBS Snapshot をとることにしましょう。EBS Snapshot は バックグラウンドでは S3 を使用しており、3つ以上の AZ にレプリケートされます。

構成の改善点まとめ

  • Multi-AZ 構成にしよう
  • EBS Snapshot を定期的に取ろう

 なんか聞いたことのある結論ですが、物理層から見ても一般的なプラクティスと同じ結論に至るということでしょう。

おわりに

 いかがでしたか?
 利用者の目には見えない物理レイヤーを妄想してみるのは、なかなか楽しいですね。
 結果的には大きめなデータセンターらしい普通な構成ですが、物理レイヤーを意識することでボトルネックへの気付きにもつながりました。
 また、インフラについて詳しくないところ調べながらで記事を書いたので、個人的に勉強になりました。

注意事項

  • 想像なので、実際の構成とは大いに異なると思います
  • 想像なので、NDA に抵触する情報は含まれていません
  • 知識不足により、図や用語には間違いが含まれると思われます

参考書籍


image
クラウドを支える技術 ―データセンターサイズのマシン設計法入門 (WEB+DB PRESS plus) 単行本(ソフトカバー) – 2014/9/26

記事を書いていたらデータセンターの設計にすこし興味が出てきたため、読みました。

参考サイト

製品の詳細 – Amazon EC2 | AWS
製品の詳細 – Amazon Elastic Block Store(EBS) | AWS
製品の詳細 – Amazon VPC | AWS
How did they build that — EC2 Enhanced Networking | Cloudier Than Thou
Windows Insider用語解説:Software-Defined Network(SDN)とは何か? – @IT
AWS箇条書きナレッジ – Qiita
Awsの質問に何でも答えます
AWS re:Invent 2016現地レポート – 通信すら飲み込むAmazon、ルーター用半導体も自社開発と公表:ITpro


  1. 関東に限らず大阪や北海道にあるやもしれません。1b や 1c でなく 1a にたどり着けたのはご都合主義である為です。 

  2. 1台構成なので繋がりがいまいち表現できていません。ネットワークは二重化されていますが、記載省略しています。 

  3. SDN コントローラーの記載も省略しています。実際にはもっとかっこいいメッシュネットを構成しているでしょう。 

  4. データとチェックディジットがストライピングにより分散した上でレプリケートしていると思うので、データはもっと分散しているはずですが、省略。 

続きを読む

ひとつのEC2インスタンスで複数のIPアドレスを使った環境を構築する(EC2 + ENI + unicorn + nginx + rails)

背景

  • ひとつのEC2インスタンス上に複数の開発環境を作りたい。
  • それぞれの環境に違ったIPアドレスを割り当てたい。
  • インフラ関連の知識が少なく自信がない:innocent:

間違いありましたら、指摘お願い致します。

前提条件

EC2上で動くrailsアプリケーションが構築済みである事。
VPC、EC2、セキュリティグループ、サブネットの設定は既にされているものとして説明します!

大まかな手順

今回は環境1、環境2、環境3と3つの環境を作ります。

  1. ネットワークインターフェイス(ENI)を設定する
  2. 3環境分、EC2のプライベートIPアドレスを用意する
  3. 3環境分、グローバルIPアドレスを用意する
  4. プライベートIPアドレスとグローバルIPアドレスを紐付ける
  5. ネットワークインターフェイスをOSに認識させる
  6. nginxの設定(バーチャルホストの設定)

ネットワークインターフェイス(ENI)の設定

※ネットワークインターフェイスはVPC内で実行中のインスタンスでしか使用できないので注意。

EC2 > ネットワークインターフェイス > ネットワークインターフェイスの作成。
サブネットを選択すると、選択可能なセキュリティグループが表示されます。
選択完了後、[作成する]をクリックします。

スクリーンショット 2017-02-03 21.12.39.png

作成したネットワークインターフェイスが一覧に表示されます。
作成したネットワークインターフェイスを選択して[アタッチ]をクリックします。
アタッチするEC2インスタンスを選択します。

スクリーンショット 2017-02-03 21.04.42.png

これでネットワークインターフェイスがEC2にアタッチされました!

プライベートIPアドレスの設定

ネットワークインターフェイスにプライベートIPアドレスを追加します。

作成したネットワークインターフェイスを選択し
アクション > Manage IP Addresses を選択します。

スクリーンショット 2017-02-03 21.19.14.png

今回は3つの環境を作成するので「新しいIPの割り当て」を3回クリックします。
「更新する」をクリックすると新しいプライベートIPアドレスが割り当てられます。
プライベートIPアドレスは未入力状態だと自動的に割り当てられます。
特に決まっていない場合は未入力で大丈夫です。

スクリーンショット 2017-02-03 21.20.11.png

環境分のプライベートIPアドレスが取得できました!

Elastic IPの取得

今回は環境を3つる為、3つのグローバルIPを取得します。

EC2 > Elastic IP > 新しいアドレスの割り当て を選択します。

スクリーンショット 2017-02-03 20.25.20.png

何も指定するところがないウィンドウが出てきます。
このまま[割り当て]をクリックします

スクリーンショット 2017-02-03 20.34.30.png

一覧に作成した Elastic IPが表示されているので選択します。
アクション > アドレスの関連付け を選択します。

aaaa.jpg

リソースタイプは「ネットワークインターフェイス」を選択します。
ネットワークインターフェイス、プライベートIPは作成したものを選択します。
作成したIPの数分、作業を繰り返します。

スクリーンショット 2017-02-03 20.38.11.png

※起動中のEC2に紐づいていないElastic IPは料金が発生するので注意!

休憩

ここまではAWSのコンソール上で操作するので、スムーズにいくかと思います。
ここから先はEC2にコンソールからログインして設定を行います。
サーバの設定に慣れていないと、いろいろハマる・・・と思いますので気を引き締めていきましょう!
(実際にいろいろハマりました)

ネットワークインターフェイスをOSに認識させる

まずは、先ほど作成したプライベートIPアドレスがeth0に追加されている事を確認します。
※今回作成したプライベートIPアドレスを仮に 21.0.1.123, 21.0.1.124, 21.0.1.125 とします。

$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu qdisc noqueue state UNKNOWN group default qlen 1
        (省略)
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu qdisc mq state UP group default qlen 1000
    inet 21.0.1.201/24 brd 21.0.1.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet 21.0.1.123/24 brd 21.0.1.255 scope global secondary eth0
       valid_lft forever preferred_lft forever
    inet 21.0.1.124/24 brd 21.0.1.255 scope global secondary eth0
       valid_lft forever preferred_lft forever
    inet 21.0.1.125/24 brd 21.0.1.255 scope global secondary eth0
       valid_lft forever preferred_lft forever
    (省略)

プライベートIPアドレスは登録されていますが、OSに認識されていない状態ですので
OSに認識させるためのネットワーク設定ファイルを作成します。

ファイル名ですが「ifcfg-」の後にインタフェース名を記載します。
また名前は一意である必要があります。
今回追加したネットワークインターフェイスはeth0、3つの環境を作成するのでそれぞれ番号を振っています。

ifcfg-eth0
$ cd /etc/sysconfig/network-scripts
$ touch ifcfg-eth0:1
$ vi ifcfg-eth0:1
 (ifcfg-eth0:1に以下を設定する)
DEVICE=eth0:1
BOOTPROTO=static
BROADCAST=21.0.0.255
IPADDR=21.0.1.123
NETMASK=255.255.255.0
NETWORK=21.0.0.1
ONBOOT=yes

この設定ファイルにはプライベートIPアドレスを設定します。
同様にifcfg-eth0:2, ifcfg-eth0:3 のファイルも作成します。
設定が完了したらネットワークのサービスを再起動します。

$ sudo service network reload
Shutting down interface eth0:                              [  OK  ]
Shutting down loopback interface:                          [  OK  ]
Bringing up loopback interface:                            [  OK  ]
Bringing up interface eth0:
Determining IP information for eth0... done.

Determining IPv6 information for eth0... done.
Determining if ip address 21.0.1.123 is already in use for device eth0...
RTNETLINK answers: File exists
Determining if ip address 21.0.1.124 is already in use for device eth0...
RTNETLINK answers: File exists
Determining if ip address 21.0.1.125 is already in use for device eth0...
RTNETLINK answers: File exists
                                                           [  OK  ]

上記のように全OKが出れば完了です。
設定に誤りがある場合はエラーが出るので修正します。
下記はエラーの一部です(同じIPアドレスが設定されていると怒られました)

error in ifcfg-eth0:2: already seen ipaddr 21.0.1.125 in ifcfg-eth0:1

nginxの設定

uniconは環境ごとに起動する必要があります。
listenにはプライベートIPアドレスを指定します。


$ cd /etc/nginx/conf.d/
$ cat virtual.conf
upstream unicorn {
  server unix:/home/test-user/app/dev1/project/tmp/sockets/unicorn.sock;
}

server {
  listen 21.0.1.123;
  server_name dev1;
  root /home/test-user/app/dev1/project;
  index index.html;
  charset utf-8;
  (省略)
}

upstream unicorn-dev2 {
  server unix:/home/test-user/app/dev2/project/tmp/sockets/unicorn.sock;
}

server {
  listen 21.0.1.124;
  server_name dev2;
  root /home/test-user/app/dev2/project;
  index index.html;
  charset utf-8;
}

upstream unicorn-dev3 {
  server unix:/home/test-user/app/dev3/project/tmp/sockets/unicorn.sock;
}

server {
  listen 21.0.1.125;
  server_name dev3;
  root /home/test-user/app/dev3/project;
  index index.html;
  charset utf-8;
}

listenにはプライベートIPアドレスを指定します。

大事な事なので2回書きました・・・。
グローバルIPアドレスを設定していて、悩みました。
オンプレミスでの運用が長い方はハマりやすいと思います・・・:pray:

設定が完了したらnginxを再起動します。

$ sudo service nginx restart

これで完了です!
各環境にアクセスして繋がるか確認してください!

続きを読む

Deep Security Manager 9.6 SP1 + AWS RDS構築

はじめに

AWSでのセキュリティは責任共有モデルで示しているように、OSより上位レイヤーの設定についてはお客様の責任となります。そのOSより上位のセキュリティ対策としてTrend Micro社のDeep Securityがいいらしい。

ということで、早速試してみました。
以下Deep Securityの構築ステップを記載します。Windows版のインストールガイドはWeb上探せば出てくるのですが、Linux版はあまり情報ないため、Linux版のインストールステップを記載します。
なおデータベースはAWS環境ということでRDSを採用しております。

ちなみに、Trend Micro社はAWS上でDeep Security as a ServiceとしてDeep Securityのサービスを提供していますが、今回はEC2インスタンスを立てそこにDeep Security Managerを導入する構成を組みました。

構成

構成はこんな感じ。
構成サンプル.png
EC2インタンス上にDSMサーバーとしてDeep Security Manager(移行DSM)とDeep Security Agent(移行DSA)を導入しRelayを有効化。クライアントサーバーにはDSAのみ導入。データベースにはOracleのRDSを使用。

DSMバージョン:Deep Security Manager 9.6 SP1 Patch1 Update4

作ってみた

1. 前提はこちら参照

2. インストーラーダウンロード
DSM:こちらのサイトのDeep Security Managerをクリックし、Linux版(Manager-Linux-9.6.xxxx.x64.sh)をダウンロードします。
DSA:上記サイトのLinux 版 Deep Security Agent / Relayをクリックし、対象OS用のインストーラー(RHELならAgent-RedHat_EL7-9.6.x-xxxx.x86_64.zip)をダウンロードします。

3. 応答ファイル(dsm.properties)準備
今回はOSはREHL7.2を使用したため、インストールはCLIで実施します。応答ファイルは自分で作成します。
RDSを使用する場合はDB接続先として下記情報を記載します。(DBのHostnameにRDSを指定するだけです)
DatabaseScreen.DatabaseType=Oracle
DatabaseScreen.Hostname=xxxxxx.ap-northeast-1.rds.amazonaws.com
DatabaseScreen.DatabaseName=<db_name>
DatabaseScreen.Transport=TCPV
DatabaseScreen.Username=<db_user_name>
DatabaseScreen.Password=<db_user_password>
Relay有効化のため、RelayScreen.Install=Trueの1行もお忘れなく(※)

最低限の構成を導入するため、使用した応答ファイル(dsm.properties)はこちらです。

dsm.properties
CredentialsScreen.Administrator.Username=<user_name>
CredentialsScreen.Administrator.Password=<password>
DatabaseScreen.DatabaseType=Oracle
DatabaseScreen.Hostname=xxxxxx.ap-northeast-1.rds.amazonaws.com
DatabaseScreen.DatabaseName=<db_name>
DatabaseScreen.Transport=TCP
DatabaseScreen.Username=<db_user_name>
DatabaseScreen.Password=<db_user_password>
RelayScreen.Install=True

(※)Relay有効化できずにハマったはなしはこちら

4. DSMのインストール実行
インストーラーを配置したディレクトリで下記実行するだけです。

[root@DSM DSM]# ./Manager-Linux-9.6.4072.x64.sh -q -conasole -varfile ./dsm.properties  
Unpacking JRE ...
Starting Installer ...
The physical memory on this machine is less than what is recommended for a production environment. Unless you are installing Deep Security Manager 
for demonstration or evaluation purposes only, it is strongly recommended that you cancel this installation and install on a more powerful machine. 
See the system requirements in the Installation Guide for more information.
Stopping Trend Micro Deep Security Manager Service...
Checking for previous versions of Trend Micro Deep Security Manager...
Upgrade Verification Screen settings accepted...
The installation directory has been set to /opt/dsm.
Database Screen settings accepted...
License Screen settings accepted...
Address And Ports Screen settings accepted...
Credentials Screen settings accepted...
Security Update Screen settings accepted...
Software Update Screen settings accepted...
Smart Protection Network Screen settings accepted...
All settings accepted, ready to execute...
Extracting files ...
Setting Up...
Connecting to the Database...
Creating the Database Schema...
Creating dsmadmin Account...
Recording Settings...
Creating Temporary Directory...
Installing Reports...
Installing Modules and Plug-ins...
Creating Help System...
Validating and Applying Activation Codes...
Configure Localizable Settings...
Setting Default Password Policy...
Creating Scheduled Tasks...
Creating Asset Importance Entries...
Creating Auditor Role...
Optimizing...
Importing Software Packages...
Configuring Relay For Install...
Importing Performance Profiles...
Recording Installation...
Clearing Sessions...
Creating Properties File...
Creating Shortcut...
Configuring SSL...
Configuring Service...
Configuring Java Security...
Configuring Java Logging...
Cleaning Up...
Starting Deep Security Manager...
u Finishing installation ...
[root@DSM DSM]# echo $?
0

あっさり完了。

5. DSAインストール
ダウンロードしたzipを解凍し、RPMをインストールします。

[root@DSM DSM]# rpm -qoivh Agent-Core-RedHat_EL7-9.6.2-7599.x86_64.rpm
Preparing... 

:

Starting ds_agent (via systemctl):  [  OK  ]
[root@DSM DSM]# echo $?
0

こちらもあっさり完了。

以上で、DSM、DSAのインストールが完了です。

あとはブラウザでコンソールにアクセスし、諸々設定し完了ですが、それはまた別の機会に。

その他

DSM、DSAのサービス名は次の通りです。これらのサービスが自動起動していればインストールは成功です。

DSM:dsm_s.service
DSA:ds_agent.service

参考

Trend Micro Deep Security インストール手順

続きを読む

モニタリングサービス(Mackerel、Datadog、New Relic)入門!

はじめに

  • モニタリングサービスMackerelDataDogNewRelicについて簡単にまとめてみました。
  • サーバのリソース監視、ログ、プロセス監視ができれば良かったので、今回はAWSインテグレーション機能などについてはあっさりとしか触れてません。
  • どのサービスも、監視対象のサーバーを用意した状態で、15分あれば無料でサーバのリソースがモニタリングできるところまでいけます(そしてクレジットカードなどの登録は不要)ので、是非はじめてみてはどうでしょうか。

サービスの紹介

Mackerel(マカレル)

  • 「株式会社はてな」が提供しているサーバ管理・監視ツール
  • 監視/メトリクス

    • デフォルトで様々なメトリクスが取得されており、閾値を設定して監視することができる。(CPU,Network,Disk,Memory)
    • プロセスやログ監視などはサーバー上の設定ファイルに設定を追加することでとても簡単に実現できる。
    • プラグインを利用することでかなりの種類のミドルウェアのメトリクス可視化が可能
  • 通知

    • Email、Slack、HipChat、ChatWork、Lineなど幅広い通知先に対応
  • 料金

    • Standardで1ホスト1800円
  • Freeアカウント

    • Trialは14日でStandard相当の機能が利用可能。制約はあるが無料でも使い続けられる。
  • 気になった機能

    • http/httpsの外形監視が可能
    • AWSインテグレーション機能

      • MackerelのホストとしてAWSのサービスを登録できる。
      • 現在の対応サービスはEC2、ELB (CLB)、ALB、RDS、ElastiCache・Redshift。EC2だけではなくマネージドなサービスを監視できる。
  • 雑感

    • 日本語であることを差し引いてもマニュアルが親切で、試しているときに3つの中で一番躓かなかった
    • 設定がとてもシンプルでわかり易い(ログ監視、プロセス監視もDatadogみたいにpythonのスクリプト書かなくてもよい。)
    • 外形監視はMackerelしかない機能。
    • AWSインテグレーションは今日現在対応サービスがそんなにあるわけではないので、不足分はCloudWatchで補っていくのかな。

Datadog

  • Datadogが提供しているリソース管理・監視サービス
  • 監視/メトリクス

    • デフォルトで様々なメトリクスが取得されており、閾値などで監視が可能(CPU,Network,Disk,Memory)
    • プロセスの監視についてはサーバー上の設定ファイルに設定を追加し、実現する。
    • ログの監視は標準のログのフォーマット以外はカスタムのログのパーサをpythonで記載する必要がある。(後述)
    • HTTPの監視については外部からの監視ではなく、あくまでAgentからの監視のよう。
  • 通知

    • Email、HipChat、Pagerduty(インシデントとして登録)
    • 本文はカスタマイズ可能。日本語も使えました。
  • 料金

  • Freeアカウント

    • 14日間特に制限なしで利用可能(クレジットカードの登録不要)
  • 気になった機能

  • 雑感

    • マニュアルが揃っており、始めやすくUIも直観的。
    • インテグレーション機能が強烈
    • 異常値の検出機能など高度なモニタリングができ、今後の機能拡張も期待できそう
    • 日本語の情報源も多く、利用しているユーザも多そう。マニュアルも全部ではありませんが日本語で提供されている。

NewRelic Infrastructure

  • NewRelicが提供するモニタリングサービス

  • 監視/メトリクス

    • デフォルトで様々なメトリクスが取得されており、閾値で監視が可能(CPU,Network,Disk,Memory)
    • プロセスの監視もUIからできる。ログの監視についてはやり方が見つけられなかった。
  • プラン・料金

    • 30日間のFreeアカウントプランとEssential,Proという3つの体系
    • EssentialとProの違いはデータの保持期間(3日と13日)とEC2以外のモニタリングができるか否かのようです。
    • こちらのページを見て計算してみたのですが、インスタンスタイプや年払い、月払いで料金が異なるようです。
  • Freeアカウント

    • 14日間特に制限なしで利用可能(クレジットカードの登録不要)
  • 雑感

    • 製品ラインナップが多くて調べ始めたら混乱した。
    • Infrastructure単体で使うというよりAPMとセットで使うイメージがしっくりくる。サーバの監視はMackerelやDatadog、アプリケーションの監視としてピンポイントでAPMを導入するという形になる気がする。
    • Qiitaやブログの記事がDatadog,Mackerelと比べると少ない。販売代理店のページで翻訳されているマニュアルがある。

ためしてみる

Mackerel(マカレル)

セットアップ

  • ホストへのagentのインストールはすごく簡単

    • スタートガイドにURLがあるのでコピペします。
    • rpm,tar.gz,windows installerとか色々対応してます。
curl -fsSL https://mackerel.io/file/script/amznlinux/setup-all-yum.sh | MACKEREL_APIKEY='xxxxxxxxxxxxxxxxx' sh
  • 数秒後にホストの一覧を見てみると・・・

image

  • サービスとロールを設定してみる

    • サービスとは○○システムという単位
    • ロールというのはWEBサーバ、DBサーバというホストの役割を表すもの。
    • 今回はオンプレとAWSのホストをdemo-appというロールでまとめてみました。
  • CPU、メモリの状況などがロール単位にまとめてみることができます。

image

ログ監視

  • 今回の目的であるログ監視をやってみます。
  • ログ監視は公式サイトによるとプラグインを入れて設定するもののようです。

  • プラグインをインストールします

yum -y install mackerel-check-plugins
  • 設定を追加します
/etc/mackerel-agent/mackerel-agent.conf
[plugin.checks.test_log]
command = "check-log --file /home/ec2-user/test.log --pattern FATAL --return"
  • 設定を反映するためにエージェントを再起動します。
[root@ip-10-0-0-24 ec2-user]# service mackerel-agent restart
Stopping mackerel-agent:                                   [  OK  ]
Starting mackerel-agent:                                   [  OK  ]
[root@ip-10-0-0-24 ec2-user]#
  • FATALというメッセージを出してみましょう
echo "FATAL:message" >> /home/ec2-user/test.log
  • 正しく検知できました!(Alertは自動でCloseされるようです)

image

  • メモとか残せるのは気が利いていていいですね

image

プロセス監視

  • ログ監視と同じ感じで正規表現でプロセス名を指定します。
/etc/mackerel-agent/mackerel-agent.conf
[plugin.checks.check_demo_app]
command = "check-procs --pattern java8"
  • ちょっと待つとホストの表示画面の右側に現れます。

image

  • プロセスを切ってみると・・・ちゃんと検知します

image

  • プロセスを上げると自動でCloseされます

image

外形監視

  • warning,criticalにするレスポンスタイムや、アラートが発生している期間に一定の時間間隔で通知を再送する設定などかなり気が利いてる印象

image

  • 設定した内容は一覧で見ることができます。

image

  • サイトを停止して、ちょっと待つとアラートに引っかかります。復旧後自動でCloseされます。

image

Datadog

セットアップ

  • すごく簡単
  • Distributionとかツールを選ぶとスクリプトがでてくるのでコピペするだけです。

image

DD_API_KEY=xxxxxxxxxxxxxxxxxx bash -c "$(curl -L https://raw.githubusercontent.com/DataDog/dd-agent/master/packaging/datadog-agent/source/install_agent.sh)"
  • シンプルなホストの一覧。タグがつけられるのはどこも一緒

    • デフォルトのタイムゾーンをみて時間を表示してくれます。意外と嬉しい。

image

  • ホストを選択するとメトリクスをみれます

image

  • Metrics Explorerを使うとタグをつけたhostのメトリクスをまとめて見れたりします。ここはすごく柔軟でいいですね

image

プロセス監視

  • サンプルがあるのでコピーして使います
cp /etc/dd-agent/conf.d/process.yaml.example /etc/dd-agent/conf.d/process.yaml
  • sshとjavaのプロセスを監視してみます
/etc/dd-agent/conf.d/process.yaml
init_config:

instances:
- name: ssh
  search_string: ['ssh', 'sshd']

- name: demo-app
  search_string: ['java']
  • agentを再起動します
[root@ip-10-0-0-24 ec2-user]# service datadog-agent restart
Stopping Datadog Agent (using killproc on supervisord):    [  OK  ]
Starting Datadog Agent (using supervisord):                [  OK  ]
[root@ip-10-0-0-24 ec2-user]#
  • 以下のコマンドで取得できていることを確認します。
[root@ip-10-0-0-24 conf.d]# service datadog-agent info
====================
Collector (v 5.10.1)
====================
・・・・
  Checks
  ======

    process
    -------
      - instance #0 [OK]
      - instance #1 [OK]
      - Collected 12 metrics, 0 events & 2 service checks
  • Monitors -> Processを選択して監視を追加しましょう

    • メール通知するタイトルやメッセージは自由に変えられますし、日本語でも問題なく送信できました。

image

  • Javaのプロセスが死ぬとメールが飛んできて、画面もこんな感じになります

image

ログ監視

  • ログ監視を行うにはこちらを参照。
  • apacheのログとかアプリケーションのログのようなDatadog標準のフォーマットではないものについてはpythonでparseしてから送信する必要があるとのこと。
  • まずはこんなログをparseしてみます。
127.0.0.1 - - [31/Jan/2017:00:57:59 +0000] ERROR hogehogehoge
127.0.0.1 - - [31/Jan/2017:00:58:00 +0000] SUCCESS hogehogehoge
  • parserをpythonで書いて用意します。(見様見真似で書いたのでイケてるのかがわかりません)
/opt/datadog-agent/agent/checks/libs/test_log_parser.py
from time import strftime
import re
import time

def test_log_parser(log, line):

    regex = '([(\d\.)]+) - - \[(.*?)\] (.*?) (.*?)'
    parsed = list(re.match(regex, line).groups())

    event = {}
    event["aggregation_key"]  = "test.log-monitor"
    event["timestamp"] = int(time.time())
    event["msg_title"] = "Test log monitor / Log Level: " + parsed[2]
    event["msg_text"] = "message: " + parsed[3]

    if re.match('^ERROR$', parsed[2]):
        event["alert_type"] = "ERROR"
        event["event_type"] = "event.error"
    else:
        event["alert_type"] = "INFO"
        event["event_type"] = "event.info"

    return [event]
  • Datadogの設定に食べさせて、agentを再起動します。
/etc/dd-agent/datadog.conf
dogstreams: /var/log/test.log:/opt/datadog-agent/agent/checks/libs/test_log_parser.py:test_log_parser
[root@ip-10-0-0-24 libs]# service datadog-agent restart
Stopping Datadog Agent (using killproc on supervisord):    [  OK  ]
Starting Datadog Agent (using supervisord):                [  OK  ]
  • こんなログが出てればOK
/var/log/datadog/collector.log
2017-01-31 01:46:32 UTC | INFO | dd.collector | checks.collector(datadog.py:143) | Instantiating function-based dogstream
2017-01-31 01:46:32 UTC | INFO | dd.collector | checks.collector(datadog.py:150) | dogstream: parsing /var/log/test.log with <function test_log_parser at 0x7f7bb5bcc410> (requested /opt/datadog-agent/agent/checks/libs/test_log_parser.py:test_log_parser)
  • ログを流してあげるとEventのページに表示されます
echo "127.0.0.1 - - [31/Jan/2017:00:58:05 +0000] SUCCESS hogehogehoge5" >> /var/log/test.log
echo "127.0.0.1 - - [31/Jan/2017:00:57:59 +0000] ERROR hogehogehoge" >> /var/log/test.log

image

  • NewMonitor -> Eventから監視を設定します

画面上部にイベントが表示されていて、Select events to countの値を変更するとフィルタされた値が表示されています。

image

  • ERRORの時にちゃんとアラートが飛びました。

image


NewRelic Infrastructure

セットアップ

  • DataDog,Macherelと違って少しだけ手順を踏みます。

    • アクセスキーの登録
    • yumリポジトリの設定
    • yumでのインストール
  • 少し待って画面上部の「INFRASTRUCTURE」をクリックするとモニター画面が現れます。
    • タイムゾーンはデフォルトタイムゾーンで表示してくれます。残念ながらAlertsは対応がまだのようでUTC or PSTの表示になります。

image

  • Alertの設定

image

APM(蛇足)

ついでにAPMも試してみようと思ったのですが、今回使っているJavaのアプリケーションはSpringBootで作っておりますが、ApplicationServerのルートディレクトリがないものには対応していないようでした。残念。

公式ドキュメントを参考にすればイメージがつくかと思います。

続きを読む

mackerelでAmazonElasticsearchServiceのメトリクス収集

概要

mackerelはAWSインテグレーションでAWSのいくつかのサービスのメトリクスを自動で収集してくれるのですがAmazonElasticsearchServiceは対応していないので自分でメトリクスを収集する必要があります。

プラグイン自体は既に存在しているのでそれを使えば簡単にメトリクスは収集出来るのですが、単純に何らかのインスタンスのmackerel-agentの設定に入れてしまうとそのホスト自身のメトリクスとして収集されてしまいます。

それを防ぐためmackerelのcustom_identifierの機能を使ってElasticsearchServiceをインスタンスとしてメトリクスを収集する方法をまとめました。

空のインスタンス設定作成

まず、mackerel側に空のインスタンスを作成します。

API_KEY='XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'

curl https://mackerel.io/api/v0/hosts -H "X-Api-Key: ${API_KEY}" -H "Content-Type: application/json" -X POST -d '
{
  "name": "xxxxxxxxxxxxx.ap-northeast-1.es.amazonaws.com",
  "meta": {
    "network": {}
  },
  "status": "standby",
  "roleFullnames": [
    "<サービス>:<ロール>"
  ],
  "customIdentifier": "xxxxxxxxxxxxx.ap-northeast-1.es.amazonaws.com"
}'

<サービス>:<ロール>は事前に作成しておく必要があります
customIdentifierとnameはElasticsearchServiceのエンドポイントのドメインを指定していますが、分かりやすいものを指定しても問題ありません。

mackerel-agentの設定

次にmackerel-agentを設定します。
プラグインはmackerel-plugin-aws-elasticsearchを使用します。

mackerel-agent.conf
[plugin.metrics.aws-elasticsearch]
command = '''
  /usr/local/bin/mackerel-plugin-aws-elasticsearch 
    -domain=<ElasticsearchService作成時に指定したdomain> 
    -client-id=12345678901 
    -region=ap-northeast-1 
    -access-key-id=XXXXXXXXXXXXXXXXXXXX
    -secret-access-key=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
'''
custom_identifier = "xxxxxxxxxxxxx.ap-northeast-1.es.amazonaws.com"

指定するIAMに最低限必要な権限はcloudwatch:GetMetricStatisticsです。
custom_identifierには先程のcustomIdentifierと同じものを指定して下さい。

mackerel-agentを再起動してしばらくするとmackerelでメトリクスが参照出来るようになります。

参考

http://qiita.com/Hanyu/items/474dbdc4f4da87f25e1b

続きを読む