Running Kubernetes Cluster on AWS

Following this guide https://kubernetes.io/docs/getting-started-guides/kops/, set up Kubernetes cluster on AWS using kops.

1. Install kops

According to the guide, kops is:

kops helps you create, destroy, upgrade and maintain production-grade, hig… 続きを読む

クラウドの力を借りて無限収入システムを構築する(はずだった)

目的

 ビットコイン等の仮想通貨の採掘をして不労所得チャリンチャリンというのは夢がありますよね。私もチャレンジしようと思ったのですが、手元の貧相な PC では電気代すらペイできないのは明らかです。
 ではクラウドの力を借りて、GPU でやってみたらどうなのか。スポット価格をうまく使えば、もしかしてクラウド利用料を賄えて夢の無限収入システムを構築できるのではないか、というチャレンジをしてみたので、その記録です。
 なお、実際に稼げるとは思ってなくて、AWS スポットインスタンス使ってみる、GPUインスタンスを使ってみる、ブロックチェーンに触れてみる、など一石三鳥なお勉強をすることが目的です。

概念図

 インスタンス利用料が安いときに仮想通貨をマイニングすれば黒字転嫁するのでは、というアイデアです。
image.png

結果

 すごい赤字になる。スポットインスタンスを活用しても インスタンス利用料の半分まかなえる程度の採掘量にとどまり利益が生まれることはなかった、通貨マイナーの世界はきびしい。
 FPGA 使えれば結果は変わるのかなー。

構築の流れ

採掘環境構築~試しに採掘まで

環境情報

  • 採掘対象

    • Ethereum
  • OS 1
    • Ubuntu Linux 16.04 / 64bit
  • インスタンスタイプ
    • g3.4xlarge or p2.xlarge
  • リージョン
    • us-east-1(インスタンス費用がたぶんいちばん安いので)
  • マイナークライアント
    • Claymore’s Dual GPU Miner 9.7
  • ウォレット
    • coincheck

ウォレットの準備

  • Coincheck にアカウント作成

    • その他、大手のbitFlyer、Zaif 等なんでもよさそうです、手数料や取り扱い通貨が違います
  • 身分証明書を送り取引可能な状態にする
    • 最大2営業日必要との記載ですが、今回は数時間で本人確認が完了しました
  • Ether入金用のアドレスを作成 する

    • アドレス:0x0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X

マイニング用AMIを作成する

Ubuntu インスタンスを作成、Calymore9.7 を導入する。

console
$ wget https://github.com/nanopool/Claymore-Dual-Miner/releases/download/v9.7/Claymore.s.Dual.Ethereum.Decred_Siacoin_Lbry_Pascal.AMD.NVIDIA.GPU.Miner.v9.7.-.LINUX.tar.gz
$ mkdir Calymore9.7
$ tar xvzf Claymore.s.Dual.Ethereum.Decred_Siacoin_Lbry_Pascal.AMD.NVIDIA.GPU.Miner.v9.7.-.LINUX.tar.gz -C ./Calymore9.7/
$ cd Calymore9.7/

不足しているライブラリをインストール

console
sudo apt-get install ocl-icd-opencl-dev
sudo apt-get install libcurl3

nvidiaのドライバをインストール

console
sudo apt-get install -y nvidia-367

以下のshを作成

Claymore9.7/miningStarter.sh
#!/bin/sh

workername1=`hostname`
workername2=`date +"%y%m%d%H%M%S"`

#export GPU_FORCE_64BIT_PTR=0 # must be comment out for amdgpu-pro
export GPU_MAX_HEAP_SIZE=100
export GPU_USE_SYNC_OBJECTS=1
export GPU_MAX_ALLOC_PERCENT=100
export GPU_SINGLE_ALLOC_PERCENT=100

export ETH_ADDR=0x0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X # Ether入金アドレス
export ETH_WORKER_NAME=$workername1$workername2 # ワーカーの名前=ホスト名+起動日時
export ETH_POOL_HOST=us1.ethermine.org:4444 #AWSリージョンと同じusを指定

cd /home/ubuntu/Claymore9.7/ #SHおいたとこ

./ethdcrminer64 
  -epool $ETH_POOL_HOST 
  -ewal $ETH_ADDR.$ETH_WORKER_NAME 
  -epsw x 
  -mode 0 
  -ftime 10 
  -etha 2 
  -allpools 1 
  -wd 0 
  -eres 4 
  -gser 2

で、sh 起動、なんかうごく。

console
sudo bash miningStarter.sh

image.png

こちらで Ethereum入金アドレス で検索すると、進捗が確認できる。
ethermine.org – The fastest way to mine Ether

ためしに採掘&オンデマンドでの結果

数時間後…
image.png

ちゃんと掘れてるみたいですが、いくらになったんでしょう…

  • AWS利用料(g3.xlarge@us-east-1)

    • $1.14 / H = $27.4 / Day
  • マイニング結果 23
    • 0.002659 ETH/Day (10 MH/s) = $0.8 / Day
  • 収支
    • -98%($-26.56/Day)の赤字

 オンデマンドインスタンス価格では赤字を垂れ流す結果となりました。自動起動設定をしたあと、AMI をとっておきます。

/etc/rc.local
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

bash /home/ubuntu/Claymore9.7/miningStarter.sh #SHのありか

exit 0
  • AMI-ID

    • ami-0X0X0X0X

スポットインスタンスで起動まで

 バージニア北部のここ一週間のスポットインスタンスの価格設定履歴より、スポットの最安値とオンデマンド比の割引率を求めました。4

インスタンスタイプ オンデマンド($/H) スポット最安($/H) 割引率
g3.4xlarge 1.14 0.23 80%
g3.4xlarge 2.28 0.4 82%
g3.4xlarge 4.56 1.04 77%
p2.xlarge 0.9 0.1 89%
p2.8xlarge 7.2 1 86%
p2.16xlarge 14.4 2.2 85%

 g3とp2はどちらがマイニングに適しているのか計測しないとわかりませんが、とりあえず「p2.xlarge」でいいかなと感覚で決め、自動入札とAutoScaleの設定をします。この割引率を見る限り、負けが見えていますが。。。

  • 起動設定:MiningLaunchConfig

    • インスタンスタイプ

      • p2.xlarge
    • スポット価格
      • $ 0.1
    • AMI ID
      • ami-0X0X0X0X
  • AutoScalingGroup設定:MiningAutoScaleGroup

    • 起動設定

      • MiningLaunchConfig
    • 希望
      • 3
    • 最小
      • 3
    • 最大
      • 3

 これで、スポットインスタンスが 0.1 以下の場合自動で入札し、その価格帯であれば常時3台 起動する設定ができました。

勝手に起動する!
image.png

勝手に採掘する!
image.png

無限にお金が、、、!!

最終結果

  • AWS利用料(p2.xlarge@us-east-1)

    • $0.098 / H = $2.35 / Day
  • マイニング結果(1台あたり)
    • 0.003244 ETH/Day (12.2 MH/s) = $ 0.97 / Day
  • 収支
    • -59%($-1.38/Day)の赤字

 無限にお金が減っていく!
 残念ながら、スポットインスタンスでも無限の収入は実現できませんでした。もっと値下げしてくれれば黒字転換するんですが、そんなうまい話ないですよね。
 無念!!

参考リンク

イーサリアムを効率良くマイニングできるClaymore’s Dual Minerの使い方・設定 | トレードステーションと株・FX自動売買で暮らす
技術者向け Ethereumの基礎知識 (イーサリアム、エセリウム) – Qiita
【2017年度版】イーサリアム(ETH)でお金を稼ごう! ~マイニング編~ | デジモノ達人
イーサリウムを GPU マイニングしてみる(2017/04/21 時点) – Qiita
GPU関連でよく使うコマンドまとめ – Qiita
ETH-USD電卓:ETH/USD Ethereum Price Calculator | CoinGecko
Mining収支電卓:Ethereum Mining Profitability Calculator
採掘量確認:Balances – ethermine.org – The fastest way to mine Ether

構築時エラー集

ocl-icd-opencl-dev ないとエラー

ethdcrminer64
./ethdcrminer64: error while loading shared libraries: libOpenCL.so.1: cannot open shared object file: No such file or directory

libcurl3 ないとエラー

ethdcrminer64
./ethdcrminer64: error while loading shared libraries: libcurl.so.4: cannot open shared object file: No such file or directory

nvidiaのドライバ ないとエラー

ethdcrminer64
ETH: 1 pool is specified
Main Ethereum pool is asia1.ethermine.org:4444
DCR: 4 pools are specified
Main Decred pool is pasc-eu2.nanopool.org:15555
AMD OpenCL platform not found 
No NVIDIA CUDA GPUs detected.
No AMD OPENCL or NVIDIA CUDA GPUs found, exit

補足


  1. GPU は Windows に最適化されているものが多く、マイナーの世界では Windows を使うのがメジャーみたいです 

  2. 1 ETH = $ 299.96 で計算しています 

  3. 数時間しか稼働させていないので、インスタンスタイプにおける MH/s は正しい平均値が取れていません 

  4. 2017/8 時点 

続きを読む

EC2(スポット)インスタンス上でChainerMNのマルチノード分散学習

EC2(スポット)インスタンスでChainerMNを使う(マルチノード分散学習)

概要

  • EC2(スポット)インスタンスでChainerMNのマルチノード分散学習をする方法

    • 環境変数の設定方法
    • sshにStrictHostChecking noを追加
    • セキュリティグループの設定(VPC内からの全アクセスを許可)
  • EC2上でマルチノード分散学習する場合の注意点
    • p2.xlargeを使ってマルチノード分散学習は性能がでない
    • g3.4xlargeを利用すると良い
  • マルチノード学習した際の性能の簡単な評価
    • ImageNetの学習ではp2.8xlargeを使う時と同等かそれ以上のコストパフォーマンス

やりたかったこと

スポットインスタンスの価格が比較的安いGPU1個のインスタンス(p2.xlargeg3.4xlarge)を複数使って、ディープラーニングの学習を高速化させたかった。

学習を高速にする手段としては、マルチノードで分散する以外に、そもそも1台あたりのGPU数を増やす、という選択肢もある。
しかし、GPUを複数個積んでいるEC2のインスタンスはどれも高いし、スポットインスタンスで価格を抑えられないことがある。例えば、p2.8xlargeはオンデマンドインスタンスの場合、\$7.2/hかかる。スポットインスタンスの価格は、ここ1週間くらいはp2.8xlargeが\$2.5/h弱のようだが、ちょっと前は\$72/hに張り付いていた。
あるいは、自前で学習用計算機用意する手もあるが、GPU複数台積むマシンとなるとかなり高くつくことになる。個人の趣味の範囲内だと、電気代を抜いてもAWSを使うより高くなる可能性が高そう。

なので、p2.xlargeなどのスポットインスタンスでの値段が低め(〜\$0.3/h)で抑えられているインスタンスを複数利用して、学習を高速化させるという方針に至った。オンデマンドのp2.8xlargeと比べて、スポットインスタンスのp2.xlargeg3.4xlargeは1GPU当たりの値段で1/3ほどなので、マルチノードの分散学習の複雑さや効率の悪さはGPUの台数で補えるという目論見。

ChainerMNを使った分散学習 in AWS

環境の準備

ChainerMNのインストール

ChainerMNをインストールする方法自体は、もう多数の記事・情報があるので、詳細は省く。自分はここChainerMNのチュートリアルを参考にした。
やったことを列挙すると、以下の通り。

  • CUDA 8.0のインストール
  • cuDNN 6.0のインストール
  • NCCL 1.xのインストール
    • GitHubのページにはno longer maintainedとあるが、まだNCCL2は使えかった
  • OpenMPIのビルド・インストール
  • Chainer、ChainerMNのインストール

この作業はGPUを積んでいる中で安いインスタンス(p2.xlarge)を利用すると良い。

環境変数の設定

sshに非対話モードで入った時に、CPATHLD_LIBRARY_PATHが適切な値(具体的にはcudaのパスを含む)になっていないと学習スクリプトがうまく動かない。
/etc/bash.bashrcを以下のようにした。

/etc/bash.bashrc
export PATH=/usr/local/cuda-8.0/bin:${PATH}
export LD_LIBRARY_PATH=/usr/local/cuda-8.0/lib64:${LD_LIBRARY_PATH}
export CPATH=/usr/local/cuda-8.0/targets/x86_64-linux/include:${CPATH}

以下のコマンドを叩いた時、PATHLD_LIBRARY_PATHが適切に設定されていれば良い。

$ ssh localhost 'env'

sshの設定

マルチノード分散学習をする際、インタラクティブな操作なしに別ノードへsshで接続できる必要がある。したがって、鍵認証の設定をする。また、デフォルトでは最初に接続しようとすると、Are you sure you want to continue connecting (yes/no)?のメッセージが出て、yes/noの入力を求められるので、手間を考えるとこれも対処する必要がある。

まず、鍵認証の設定をする。

$ ssh-keygen #パスフレーズなし、~/.ssh/id_rsaに置く
$ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys

次に、.ssh/configを以下のとおりにして、yes/no入力をなくす

~/ssh/.config
Host *
    StrictHostKeyChecking no

どちらもセキュリティ上良いとは言えないが、最終的にはAWSのセキュリティグループで外部ネットワークからのインバウンドを遮断して運用すれば許容範囲と思っている。

ENAの有効化

必要なのかはわからないが、UbuntuはデフォルトではENAが有効になっていないようだったので、有効にする。最新の手順はここにあるので、これの通りに行う。
やるべきことは以下の3つ

  1. インスタンス上で、ENAのモジュールを追加
  2. インスタンスを停止
  3. ローカルからaws CLIでENAを有効化

AWS上のリソースの準備

1. VPC、サブネット、プレイスメントグループの準備

それぞれ適当な名前で準備する。VPCとサブネットは一度EC2インスタンスを起動すればついでにできるし、プレイスメントグループは、EC2のコンソールから、ネットワーク&セキュリティ → プレイスメントグループのページに行って作成すれば良い。
なお、プレイスメントグループはいるのかどうか分からないが、ネットワークの帯域幅をフルに出すには必要らしいので自分は作成した。

2. 学習ノード用のセキュリティグループの準備

セキュリティグループの準備も必要。インバウンドルールでは、「すべてのトラフィック・すべてのポート範囲へのVPCからのアクセス」を許可する。本来はもっと絞りこめると思うが、調べるのが面倒だったのでVPC内に全部公開した。
EC2コンソール上では、すべてのトラフィック すべて 0-65535 カスタム <VPCのCIDR>となっていれば良い。

3. (Optional) AMIの作成

必要はないが、ここまで終えた時点でAMIを作っておくと別のことをしたい時に無駄な出費を防げる。
AMIの作成方法は省略。

学習スクリプトなどの準備

最後に、学習用のスクリプト、データセットなどを準備する。

今回、自分はchainermnについているImageNetのサンプルを使った。
git clone --depth 1 https://github.com/chainer/chainermn.gitとして、chainermnのソースを落とすとchainermn/examples/imagenetの下にImageNetのサンプルがあるのでこれを用いる。また、自分の場合、models_v2/nin.pyをchainerのexamples/imagenet/nin.pyに置き換えないと動かなかったので、chainerのソースも落としてきてcpした。

次に、データセットを準備する。データセットの準備方法は、ここここなどが参考になる。

ここまで終えたら、インスタンスを止めてAMIを作成する。

実行方法(1ノード)

テストも兼ねて1ノードで学習を走らせる場合は、インスタンスを起動した後、sshでログインして、

$ mpiexec -n 1 python3 ~/chainermn/examples/imagenet/train_imagenet.py train.txt test.txt

などとすれば良い。ここで、train.txt、test.txtはそれぞれ準備したデータセットのパス

参考: ChainerMN チュートリアル

実行方法(マルチノード)

上で作成した学習スクリプトの入ったAMIを利用し、スポットインスタンスを適当に何個か立ち上げる。この時、VPC、プレイスメントグループ、セキュリティグループは上で準備したものを忘れず利用する。
なお、別にスポットインスタンスでなくてもいいが、費用を抑えて実験してみたいだけならスポットインスタンスの方が適していると思う。ただし、スポットインスタンスが突然中断するリスクを減らすため、高めに価格を設定しておくと安心。

また、多少値段は上がるが、p2.xlargeでなく、g3.4xlargeを使うと良い (理由は”注意点”で後述)。

以下では、2台のg3.4xlargeインスタンスを立ち上げ、それぞれのプライベートIPが172.31.41.13172.31.41.14となったとする。
まず、どちらか1台(以下では172.31.41.13の方とする)にsshでログインする。ログインしたら、以下の内容のホストファイルを~/hostfileに作成する(パスはどこでも良い)。

~/hostfile
172.31.41.13 cpu=1
172.31.41.14 cpu=1

(プライベートIPは、その時立ち上げたスポットインスタンスを見て適宜修正する必要あり。)

次に、以下のコマンドを叩くと、2台のマシンで分散学習される。

$ mpiexec -n 2 --hostfile ~/hostfile python3 ~/chainermn/examples/imagenet/train_imagenet.py train.txt test.txt

参考: ChainerMN チュートリアル

注意点(ネットワークの帯域幅を考慮する必要あり)

GPU付きインスタンスの中ではp2.xlargeが値段は安いのだが、ネットワークの帯域幅が小さく、性能が出なかった。iperfを使ってはかった結果では、1.44Gbps。一方、g3.4xlarge10Gbpsでるというスペックだし、実際iperfではかると10Gbpsでた(情報提供:https://twitter.com/grafi_tt/status/895274632177000449 )。

いくら安く分散学習させたいと言っても、p2.xlargeだと性能向上が見られなかったので、g3.4xlargeを使う方が良いと思う。

性能確認

学習が高速化できるのか確認するため簡単な性能測定をした。なお、どれも1回しか計測してないし、真面目に条件を揃えたわけではないので、数字は参考程度に。

以下のパターンで、ImageNetの学習にかかる時間を測定した。

  1. g3.4xlarge1台で、ChainerMNを利用
  2. g3.4xlarge複数台(2, 4, 6, 8, 10, 12)で、ChainerMNを利用
  3. p2.8xlarge(8GPU)で、ChainerMNを利用

結果

以下の通り。
分散すればちゃんと高速化されるし、p2.8xlargeと比べても安いまたは同等程度の値段でほぼ同じ性能を出せている。ただ、この辺は学習させるネットワークやデータセットによって色々異なるんだろうな。

表1: 1エポック当たりの時間

条件 1エポックあたりの平均時間 (sec)
g3.4xlarge*1 34.4
g3.4xlarge*2 21.8
g3.4xlarge*4 12.5
g3.4xlarge*6 9.2
g3.4xlarge*8 7.9
g3.4xlarge*10 6.3
g3.4xlarge*12 5.2
p2.8xlarge 7.9

ちゃんと分散するにつれて短い時間で学習できている。


表2: 値段 – 総実行時間

条件 値段 (\$/h) 総実行時間 (sec)
g3.4xlarge*1 0.3 344.3
g3.4xlarge*2 0.6 217.8
g3.4xlarge*4 1.2 125.2
g3.4xlarge*6 1.8 92.4
g3.4xlarge*8 2.4 79.2
g3.4xlarge*10 3.0 63.0
g3.4xlarge*12 3.6 51.7
p2.8xlarge 7.2(オンデマンド) / 2.5(スポットインスタンス利用時) 79.1

備考:g3.4xlargeのスポットインスタンスの値段は\$0.3/hとして計算

p2.8xlargeをオンデマンドで利用する場合に比べると、より安く高速な学習ができる。p2.8xlargeがスポットインスタンスの場合と比べても、ほぼ同等の性能が今回の例では出た。


グラフ1: epoch – elapsed_time
graph1.png


グラフ2: epoch-validation/main/accuracy
graph2.png

epochが少なすぎてわかりやすいデータにならなかったが、分散させるほど同エポックでの精度は悪化する傾向にあるらしい。直感的にもそんな気はする。とはいえ、マルチノードの場合とp2.8xlargeでノード内で分散した場合では大きな精度の差は見つけられない。分散学習するなら、エポックを大きめに設定する必要があるようだが、それはマルチノード分散学習の問題というより、現在のChainerMN全体の問題の可能性が高い。


その他備考
分散学習では、最初の1回のmpiexecは時間がかかるらしい。上記計測は、2回目のmpiexecで行っている。原因は、ノード間の接続を確立する時間が追加されているからではないかと思うが、詳細は不明。ただし、学習時間が長くなるにつれて、その時間は無視できるものになると思われる。

まとめとか

少なくともImageNetでは、マルチノードの分散学習でも相当の学習時間の短縮が見込める。また、8/7からChainerMNを初めて5日でここまでできたので、非常に難しい作業が必要というわけでもない。
そのため、AWS上でのディープラーニング学習を高速化させたい時、選択肢に入れる価値はあると思う。最初に書いたような、複数GPUを積んだスポットインスタンスが高い時にも使えるし、あるいはp2.8xlargeを複数使ってさらに高速化する、という使い方もマルチノードの分散学習はできるはず。

一方で、データセットが増えた時どうなるのか、モデルが複雑になった時どうなるのか、などは調べてない。実際に使ってみるとたいして高速化されなかった、みたいなケースはありそう。

要改善点

とりあえずテストするだけなら上記手順でもできたが、実際にディープラーニングを利用するプロジェクトに組み込むとなると以下の点を改善しないといけない。

学習スクリプトの実行方法

本来は、aws CLIとかSDKからスポットインスタンスを立ち上げて、自動で学習を回したい(ここみたいに)。
そのためには、UserDataのスクリプトで学習スクリプトを実行する必要があるが、以下の点に注意が必要。

  1. mpiexecをするインスタンスの決定方法
  2. ホストファイルの作成方法
  3. すべてのインスタンスが立ち上がるまでの待ち合わせ処理

1については、特定のタグを全インスタンスに付けておき、aws ec2 describe-instancesで全インスタンスのプライベートIPを取得、辞書順最小のインスタンスでmpiexecすれば解決しそう。
2は、describe-instancesした時に全部のプライベートIPがわかるんだからホストファイルもついでに生成できる。
3は、ポーリングなりなんなりでやればできるはず。この時、ついでに学習パラメータの環境変数への展開やS3からデータセットのダウンロードも待ち合わせ処理すると色々便利そう。

中断時の対処

スポットインスタンスなので、たまに強制終了させられることがある。

  1. 定期的なS3へのスナップショットアップロード(systemd-timer)
  2. 1台でも終了したら全台終了して無駄な出費の削減
  3. 学習開始時にスナップショットがあればそれを読み込み

の3つの対処が必要。

続きを読む

JavaによるLambdaをCodepipelineで自動リリースする最小構成サンプル

TL;DR

以下の文書では、node.js でのLambda関数のリリースを自動化する例が出ています。
http://docs.aws.amazon.com/ja_jp/lambda/latest/dg/automating-deployment.html

本文書では、これとほぼ同じようなアプリをJavaで書き、そのリリースを自動化します。それぞれの要素の意味や役割の説明は最低限に留めます。 (筆者もよくわかってません。えっへん。) 最小の動作サンプルの例示を行います。

本文書ではマネージメントコンソール上で色々手作業で設定を入れさせています。今後のUIの変更で、手順が変わっているかもしれません。ご容赦を。

前提

  • githubにコードが配置してあること。
  • 更新を検出するブランチが決めてあること。
  • Gradleでビルドを行います。
  • 中間ファイルを置くためのS3バケットがあること。例として、auto-release-sampleとします。

準備

ロールの作成

IAM マネージメントコンソールを開き、以下のようにロールを作成します。

項目 備考
名前 cloudformation-lambda-execution-role
ロールタイプ AWS CloudFormation 作成時は「AWS サービスロール」から選択する。作成後のロールの画面では、信頼関係 タブに表示される
アタッチされたポリシー AWSLambdaExecute ロールの画面では、アクセス許可 タブ=>管理ポリシー に表示される

一度ロールを作った後、作成したロールをマネージメントコンソールで開き、アクセス許可 タブ ->インラインポリシー にて、作成するには、ここをクリックしてください。をクリックする。  カスタムポリシー -> 選択 と進んだ後下記内容を記載する。ポリシー名は適宜設定する。

{
    "Statement": [
        {
            "Action": [
                "s3:GetObject",
                "s3:GetObjectVersion",
                "s3:GetBucketVersioning"
            ],
            "Resource": "*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "s3:PutObject"
            ],
            "Resource": [
                "arn:aws:s3:::codepipeline*"
            ],
            "Effect": "Allow"
        },
        {
            "Action": [
                "lambda:*"
            ],
            "Resource": [
                "*"
            ],
            "Effect": "Allow"
        },
        {
            "Action": [
                "iam:GetRole",
                "iam:CreateRole",
                "iam:DeleteRole"
            ],
            "Resource": [
                "*"
            ],
            "Effect": "Allow"
        },
        {
            "Action": [
                "iam:AttachRolePolicy",
                "iam:DetachRolePolicy"
            ],
            "Resource": [
                "*"
            ],
            "Effect": "Allow"
        },
        {
            "Action": [
                "iam:PassRole"
            ],
            "Resource": [
                "*"
            ],
            "Effect": "Allow"
        },
        {
            "Action": [
                "cloudformation:CreateChangeSet"
            ],
            "Resource": [
                "*"
            ],
            "Effect": "Allow"
        }
    ],
    "Version": "2012-10-17"
}

注:必要最低限の権限になってはいないかもです。今後の本記事の更新でなるべく削って行きたいです。

githubにファイルを配置する

アプリケーションのソースコードをgithubに保存します。

具体的なファイルの中身はサンプルリポジトリを参照してください。
https://github.com/kazurof/minimum-java-lambda-with-codepipeline
ファイルのディレクトリ構成を記載しておきます。

│  build.gradle
│  buildspec.yml
│  gradlew
│  gradlew.bat
│  minimum-lambda-java-model.yaml
│
│
├─gradle
│  └─wrapper
│          gradle-wrapper.jar
│          gradle-wrapper.properties
│
└─src
    └─main
        └─java
            └─codepipelinesample
                    Main.java

補足

buildspec.yml には、利用するS3リポジトリ名が記載されます。(先に、auto-release-sampleとしたもの。)実際に動かしてみる場合は適宜あなたが用意したリポジトリ名に変更してください。

CodePipeline の作成

AWS CodePipeline のマネージメントコンソールを開き、パイプラインを以下のように作成する。

パイプライン名

パイプライン名はわかればなんでも良い。

ソース

項目 備考
ソースプロバイダ GitHub GitHubを選択すると、GitHubリポジトリのURLとブランチを指定し、OAuth認証を行い、CodePipelineから指定したGitHubのリポジトリにアクセスできるようにする。
アクションカテゴリー ソース 作成時は入力を求められない。自動でつけられるものでOK
アクション名 Source 作成時は入力を求められない。自動でつけられる名前でOK
出力アーティファクト名 MyApp 作成時は入力を求められない。自動でつけられる名前でOK

ビルド

項目 備考
ビルドプロバイダ AWS CodeBuild
アクションカテゴリー ビルド 作成時は入力を求められない。
アクション名 CodeBuild 作成時は入力を求められない。

CodeBuildの新しいプロジェクトを作るを選択する。プロジェクト名はわかればなんでも良い。

ビルドプロジェクトの作成

項目
ビルド環境 Ubuntu Java8
ビルド仕様 ソースコードのルートディレクトリの buildspec.yml を使用

注:
– この時、AWS CodeBuild のサービスロールがユーザーに代わり自動的に作成されます。code-build-<ビルドプロジェクト名>-service-role という形になります。
– このビルドのアクションにおいて、以下項目が以下のように自動設定されます。

項目
入力アーティファクト MyApp
出力アーティファクト MyAppBuild

「ビルドプロジェクトの保存」を押下、「次のステップ」を押下してください。

デプロイ

項目 備考
デプロイプロバイダ AWS CloudFormation
アクションモード 変更セットの作成または置換
スタックの名前 MyBetaStack
変更セット名 MyChangeSet
テンプレートファイル packaged-minimum-lambda-java-model.yaml
Capabilities(特徴) CAPABILITY_IAM
ロール名 cloudformation-lambda-execution-role この作業手順の先頭で作ったロールを指定する。
アクションカテゴリー デプロイ 自動で設定される

AWS サービスロールの作成

ロールを新たに作ります。

当該画面の文言を転載:
「AWS CodePipeline がアカウントでリソースを使用するアクセス許可を付与するため、IAM にサービスロールを作成します。」

  • 「ロールの作成」を押下。
  • 「許可」を押下。
  • 「次のステップ」を押下。

ロール名は、「AWS-CodePipeline-Service」になるはずです。(すでにある場合はインラインポリシーに追加される挙動の様子。未確認です。)

パイプラインの確認

今まで入力した内容の確認画面が表示される。「パイプラインの作成」を押下します。

サービスロールを修正

Codebuild 向けに作成されたサービスロールが、用意したS3バケット(auto-release-sample)にアクセスできるように修正する。

今までの手順で、code-build-<ビルドプロジェクト名>-service-roleなるロールが生成されているのでそれを修正する。

  • IAM マネジメントコンソールから、ロール を選択する。
  • code-build-<ビルドプロジェクト名>-service-role を選択する。
  • アクセス許可=> インラインポリシー=> 「表示するインラインポリシーはありません。作成するには、ここをクリックしてください。」 をクリックする。
  • 「Policy Generator」 を選択して 「Select」 を選択する。
  • 「AWS Service」 で、「Amazon S3」 を選択する。
  • 「Actions」 で、「PutObject」 を選択する。
  • 「Amazon Resource Name (ARN)」 に arn:aws:s3:::auto-release-sample* と入力する。(末尾のアスタリスク必要!)
  • 「ステートメントを追加」 を選択して 「Next Step」 を選択する。
  • 「ポリシーの適用」 を選択する。

CodePipelineにLambdaを更新するステップを追加する

  • AWS CodePipeline マネジメントコンソールに移動 =>作成したpipelineを選択
  • 編集ボタンをクリック
  • Stagingの鉛筆アイコンをクリック
  • 既存のアクションの最後にある [+ Action] アイコンを選択する。
  • 以下のように入力
項目
アクションカテゴリー デプロイ
アクション名 execute_cs (わかればなんでも良い)
デプロイプロバイダ AWS CloudFormation
アクションモード 変更セットの実行
スタックの名前 MyBetaStack
変更セット名 MyChangeSet
  • 「更新」を押して保存
  • 「パイプラインの変更を保存」を押してパイプライン全体を保存

自動リリースとLambdaの実行

以上でCodepipeline 作成は終了です。gitリポジトリのmasterブランチに何か修正を入れてみてください。Codepipelineのマネジメントコンソールで、パイプラインが動作するところを確認できます。

正しく終了したら、Lambdaのマネージメントコンソールを開いてください。JavaによるLambda関数が作成されているはずです。テスト実行ができます。

感想

関係する要素技術多いせいか、手順長いですね。。。:sweat_smile:

続きを読む

Ubuntu16.04にnvidia-dockerをインストールする方法

はじめに

dockerのversionも大分上がったので再度インストール設定をまとめました。
AWS EC2 P2インスタンスで確認

nvidiaドライバインストール

アップデート

sudo apt update -y
sudo apt upgrade -y

unable to resolve hostと言われた場合実行(今回は言われた)

sudo sh -c 'echo 127.0.1.1 $(hostname) >> /etc/hosts'

Repositoryを追加して、ドライバインストール。
ドライバのVersionはそれぞれのGPUで異なるので要確認

sudo add-apt-repository ppa:xorg-edgers/ppa
sudo apt-get update
apt-cache search 'nvidia-[0-9]+$'
sudo apt-get install nvidia-375
sudo reboot

dockerインストール

基本的に公式サイトに従う。

sudo apt-get install 
   apt-transport-https 
   ca-certificates 
   curl 
   software-properties-common

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

sudo apt-key fingerprint 0EBFCD88

sudo add-apt-repository 
  "deb [arch=amd64] https://download.docker.com/linux/ubuntu 
  $(lsb_release -cs) 
  stable"

sudo add-apt-repository 
  "deb [arch=armhf] https://download.docker.com/linux/ubuntu 
  $(lsb_release -cs) 
  stable"

sudo apt-get -y update

sudo apt-get -y install docker-ce

sudo usermod -aG docker $USER
# ログインし直すとsudoしなくてもdockerコマンドが使える

nvidia-dockerインストール

sudo apt-get install nvidia-modprobe
wget -P /tmp https://github.com/NVIDIA/nvidia-docker/releases/download/v1.0.1/nvidia-docker_1.0.1-1_amd64.deb
sudo dpkg -i /tmp/nvidia-docker_1.0.1-1_amd64.deb
docker volume create -d nvidia-docker --name nvidia_driver_375.66
docker volume ls

動作確認

nvidia-docker run -it nvidia/cuda nvidia-smi

+-----------------------------------------------------------------------------+
| NVIDIA-SMI 375.66                 Driver Version: 375.66                    |
|-------------------------------+----------------------+----------------------+
以下略

続きを読む

EC2(Linux) awslogs/ssm-agent 自動起動設定

通常の制御だからか需要が無いからか、公式ドキュメント上での自動起動設定制御の記載は確認できませんでした。
ディストリビューション、バージョンによって違いがあるのでまとめておきます。

環境

  • Amazon Linux AMI 2017.03
  • CentOS release 6.9
  • CentOS Linux release 7.3.1611
  • Ubuntu 14.04.5 LTS
  • Ubuntu 16.04.2 LTS

awslogs

操作 AmazonLinux CentOS6 CentOS7 Ubuntu14 Ubuntu16
インストール yum setup.py setup.py setup.py setup.py
起動/停止 service service systemctl(service) service systemctl(service)
自動起動 chkconfig chkconfig systemctl(chkconfig) sysv-rc-conf(update-rc.d) (*1) systemctl(sysv-rc-conf/update-rc.d) (*1)
  • (*1) sysv-rc-conf は環境によっては要インストール

cron.d と logrotate.d

インストール時に毎分の起動チェックとログローテートの cron が格納されます。
必要に応じて以下のファイルの退避(削除)も行います。
尚、yum でインストール(AmazonLinux)した場合、awslogs_log_rotate は作成されません。

/etc/cron.d/awslogs
/etc/cron.d/awslogs_log_rotate
/etc/logrotate.d/awslogs

AGENT_ETC_DIR

awslogs.conf 等の設定ファイル格納場所です。
yum でインストール(AmazonLinux)した場合と setup.py(AmazonLinux以外)とで格納場所が異なります。

インストール ディレクトリ
yum /etc/awslogs/
setup.py /var/awslogs/etc/

amazon-ssm-agent

操作 AmazonLinux CentOS6 CentOS7 Ubuntu14 Ubuntu16
インストール yum(rpm) yum(rpm) yum(rpm) apt(deb) apt(deb)
起動/停止 initctl (*1) initctl (*1) systemctl(service) initctl(service) (*1) systemctl(service)
自動起動 (upstart) (*2) (upstart) (*2) systemctl (upstart) systemctl
  • (*1) initctl は省略可
  • (*2) upstart はファイル退避/コメントアウト/manual記入等で無効化

    • /etc/init/amazon-ssm-agent.conf

続きを読む

Amazon Inspectorを試してみた

Amazon Inspectorとは

EC2で実行されているアプリケーションのセキュリティ状態をテストできるものです。

利用可能なリージョン

us-east-1,us-west-2,eu-west-1,ap-northeast-1

利用可能なOS

Amazon Inspector でサポートされているオペレーティングシステムとリージョン

Amazon Linux (2015.03、2015.09、2016.03、2016.09、2017.03)
Ubuntu (14.04 LTS、16.04 LTS)
Red Hat Enterprise Linux (6.2、6.3、6.4、6.5、6.6、6.7、6.8、6.9、7.2、7.3)
CentOS (6.2、6.3、6.4、6.5、6.6、6.7、6.8、6.9、7.2、7.3)

設定

EC2にエージェントインストール

今回はAmazon Linuxで試しました。

$ cat /etc/system-release
Amazon Linux AMI release 2017.03

ダウンロードしてインストールします。
リンクの手順に沿ってやるだけです:point_up::dizzy:
AWS エージェントをインストールするには

$ wget https://d1wk0tztpsntt1.cloudfront.net/linux/latest/install

$ sudo bash install

Inspectorの設定

  1. サービスから「Inspector」を選択
  2. 左ペインから「評価ターゲット」を選択し、「作成」をクリック
  3. 名前とキーを入力して「保存」
    スクリーンショット 2017-08-01 10.13.44.png

  4. EC2にタグ付けする
    スクリーンショット 2017-08-01 13.16.58.png

  5. Inspectorで先ほど作成した評価ターゲットの左にある矢印をクリックして、「プレビュー」をクリックするとタグ付けされたEC2が出力されます
    スクリーンショット 2017-08-01 13.19.39.png
    →これが評価ターゲットになります。

  6. 左ペインから「評価テンプレート」をクリックして「作成」をクリックします。

  7. ターゲット名は先ほど作成した評価ターゲットを選択します。
    ルールパッケージは以下から選択可能です。今回はCVEを選択してみました。
    Amazon Inspector のルール パッケージとルール
    ・ 共通脆弱性識別子(CVE)
    ・ Center for Internet Security (CIS) ベンチマーク
    ・ セキュリティのベストプラクティス
    ・ 実行時の動作の分析
    所要時間は長ければ長いほど、より精密な結果が得られるとのことです。
    AWS推奨は1時間。
    SNSと連携してメール飛ばせたりしますが、ここでは省略。
    「作成および実行」を押すと調査が始まります。

スクリーンショット 2017-08-01 13.34.48.png

結果

スクリーンショット 2017-08-01 13.47.29.png
指定した時間が経過すると、調査結果が出力されます。
重要度の左にある矢印をクリックすると詳細が確認で、CVEのページのリンクも載っています。

脆弱性が自分のインスタンスに影響しているのか否か判断できて便利ですね:baby:

料金

料金は月あたり 1 エージェント 1 評価あたり 0.30 USD から始まり、従量制割引により月あたり 1 エージェント 1 評価あたり 0.05 USD の低価格でご利用いただけます。

Amazon Inspector料金

Amazon Inspectorの価格体系について

評価実行中のインスタンスへの影響

評価実行プロセス中のパフォーマンスへの影響を最小限に抑えるように設計されています
Amazon Inspector のよくある質問

CloudWatchで確認してみましたが、CPU使用率が高騰することはありません(上がっても1%未満)でした。

関連資料

BlackBelt

Amazon Inspector とは

Amazon Inspector のよくある質問

続きを読む

AWS EC2のスポットインスタンスでGPU版tensorflowを動かす

最近tensorflow使い始めました:smile: 手元のMacBook Proだと学習にとっても時間がかかるので、AWS EC2のGPUインスタンスを使ってみることに.
EC2を安価に使うにはスポットインスタンス♪と思ったのですが、なんと、スポットインスタンスだとCUDAとかがセットアップされたNVIDIAのAMIが選択できないじゃないですか:scream: どうやら素のOSの上に自力で環境構築しないといけないっぽい. でも1回環境作ってしまえば再利用は可能.

というわけで、GPU版tensorflowを動かすまでの手順をまとめます. 構築する環境は
Ubuntu 16.04 LTS + CUDA + cuDNN + python3.6 + tensorflow-gpu
です.

EC2インスタンスの作成

EC2コンソールから「スポットインスタンスのリクエスト」でインスタンスを作成します.

  • AMI: Ubuntu 16.04 LTS
  • インスタンスタイプ: p2.large
  • EBS ボリューム: デフォルト8GBなので適当に増やす. 32GBとか.

インスタンスタイプはp2.8xlargeやp2.16xlargeでもいいですが、セットアップはp2.largeで行っておいて、学習時に8xlargeや16xlargeに切り替えてもいいかも.

EC2インスタンスが起動したら各モジュールを最新版にアップグレードし、最低限の開発環境をインストール.

$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo apt-get install libffi-dev libssl-dev gcc make

pyenvを使ってpython環境を整える

まずpyenvをgit cloneする.

$ git clone https://github.com/yyuu/pyenv.git ~/.pyenv

.bashrc に以下追加.

PYENV_ROOT=$HOME/.pyenv
PATH=$PYENV_ROOT/bin:$PYENV_ROOT/shims:$PATH
eval "$(pyenv init -)"

編集した.bashrcを読み込んでおく.

$ source ~/.bashrc

続いてpythonのインストール. 今回はpython 3.6を入れる.

$ pyenv install --list|grep 3.6
  3.3.6
  3.6.0
  3.6-dev
  3.6.1
  3.6.2rc1
$ pyenv install 3.6.1
$ pyenv global 3.6.1
$ which pip3
/home/ubuntu/.pyenv/shims/pip3  # pyenvが使われているのを確認
$ pip3 install aws  # ついでに入れておく

CUDAのインストール

CUDAのダウンロードサイトでdebファイルのダウンロード先を調べる.

  • OS:Linux,
  • Architecture: x86_64,
  • Distribution:Ubuntu,
  • Version: 16.04,
  • Installer Type: dev(local)

を選べば良い. URLが分かったら, wgetで取得してインストール.

$ wget https://developer.nvidia.com/compute/cuda/8.0/Prod2/local_installers/cuda-repo-ubuntu1604-8-0-local-ga2_8.0.61-1_amd64-deb
$ sudo dpkg -i cuda-repo-ubuntu1604-8-0-local-ga2_8.0.61-1_amd64-deb
$ sudo apt-get update
$ sudo apt-get install cuda

cuDNNのインストール

cuDNNのダウンロードサイトから cuDNN v6.0 Library for Linux を取得してインストールすれば良いのだが、ユーザ登録してログイン後のページからしかダウンロード出来ず、wgetでURL指定で簡単にダウンロード出来ない.
一度macに保存してscpでEC2に送り込むことにした.

# scpでローカルのMacからEC2にdevファイルをコピー. pemファイルのパスとIPは適宜変更.
$ scp -i aws.pem ~/Downloads/cudnn-8.0-linux-x64-v6.0.tgz ubuntu@12.34.56.789:~/
$ tar xzf cudnn-8.0-linux-x64-v6.0.tgz
$ sudo cp -a cuda/lib64/* /usr/local/lib/
$ sudo cp -a cuda/include/* /usr/local/include/
$ sudo ldconfig

tensorflowのインストール

CPU版のtensorflowが入っている場合はuninstallしてからGPU版を入れる. ついでによく使うライブラリも入れておく.

$ sudo apt-get install libcupti-dev
$ pip3 uninstall tensorflow
$ pip3 install tensorflow-gpu
$ pip3 install keras sklearn matplotlib scipy librosa

サンプルを動かして動作確認

今回はkerasのmnist-mlpで動作確認. git cloneでサンプルを取得して実行.

$ git clone https://github.com/fchollet/keras.git
$ cd keras/examples
$ $ python mnist_mlp.py 
Using TensorFlow backend.
...
Test loss: 0.118156189926
Test accuracy: 0.9811
$

動いた:sunglasses:

続きを読む

JAWSUG HPC: AWS Batch x OpenFoam HandOn

JAWSUG HPC支部 第10回勉強会 AWS Batch x OpenFoam Hand-On
https://jawsug-hpc.connpass.com/event/61919/

元ネタ:http://qiita.com/porcaro33/items/0b6cf3e2c2a0f88fc305

OpenFoam x AWS Batch ハンズオン環境
image

1. Build Infrastructure

Prerequisites

まずはAWSにログイン https://console.aws.amazon.com/
Oregonリージョンに移動、ログインしたユーザがEC2, S3, Batch, ECR, Cloudformation, IAM等を操作できる権限であることを確認してください。

Create KeyPair

Bastion Serverにアクセスするのに使用するKeyPairを作成します。
後ほどCloudFormationを実行するときにKeyNameを入力するのでメモしといてください。

AWS Console -> EC2 -> Key Pairs -> Create Key Pair -> Enter key name -> Create
image

Run CloudFormation

Docker Imageのビルド環境としてUbuntuサーバをAWS上にたてます。このハンズオンではCloudFormationで必要な環境を構築してしまいます。
– VPC
– Subnet
– SecurityGroup
– Bastion EC2 (Ubuntu16.06)
– SpotFleet Role
– AWS Batch Role
– Batch Job Role
– S3 Bucket
– Container Repo

CloudFormationテンプレートをGithubからダウンロード
https://raw.githubusercontent.com/porcaro33/openfoam-docker/master/aws_batch_base.yml

CloudFormation -> Create New Stack -> Choose File -> Next
image

Enter Stack Name and KeyPair Name -> Next
image

Next -> checkin at “I acknowledge that AWS CloudFormation…” -> Create
image

CloudFormaitonが収束したら、Outputsを見てください。ここの情報をBatch Jobを設定するスクリプト編集するときに使います。このBrowser Tabは残しておいてください。
image

2. Docker Build and Push

Bastion Server

CloudFormationで作成したUbuntuサーバにログインします。お好きなssh clientでログインしてください。ユーザ名は”ubuntu”です。

ssh -i <path_to_keypair> ubuntu@<IP_from_CF_OUTPUT>

ここから先は必要なスクリプト類はgithubに準備したので、git cloneで持ってきてください。

git clone https://github.com/porcaro33/openfoam-docker.git

openfoam-dockerフォルダに移動し、bastion_setup.shを実行してください。docker-ceとawscliをインストールします。

cd openfoam-docker
./bastion_setup.sh

docker build/push

Dockerfileはgithubからダウンロードしてあるので、いきなりビルド!

sudo docker build -t openfoam-batch:latest .

ビルドが終わったらECRにdocker imageをpushします。

aws --region us-west-2 ecr get-login --no-include-email

返り値の”docker login -u AWS -p ….”をコピー、sudoを前につけて、ペーストして実行。
“Login Succeeded”と表示されたらOK。

次はtagをつけて、pushします。

sudo docker tag openfoam-batch:latest <account-id>.dkr.ecr.us-west-2.amazonaws.com/openfoam-batch:latest
sudo docker push <account-id>.dkr.ecr.us-west-2.amazonaws.com/openfoam-batch:latest

3. Create Batch Environment

Batchを実行する上で必要な、Job Definition, Compute Environment, Job Queueを作成していきます。CloudFormationのOutputsをもとに3つのjsonファイル編集して、AWCCLIを実行していきます。

job_definition.json

sudo vi job_definition.json

imageにはarnではなくURIを入力する必要があるので、一度ECSの画面にいってURIをコピーしてjsonに貼り付ける。
image

compute_environment.json

sudo vi computing_env.json

image

job_queue.json

sudo vi job_queue.json

特に変更点なし、内容だけ確認してください。

create job definition, compute enmvironment, job queueのCLI実行。それぞれ返り値を確認しながら実行してください。

aws --region us-west-2 batch register-job-definition --cli-input-json file://job_definition.json
aws --region us-west-2 batch create-compute-environment --cli-input-json file://computing_env.json
aws --region us-west-2 batch create-job-queue --cli-input-json file://job_queue.json

5.Submit Jobs

これでOpenFoamを実行する環境は準備できました。最後にジョブを実行します。AWSCLIをつかって10回ジョブを実行して、その結果をS3に保存していきます。

./submit_batch.sh

ジョブが実行されると、BatchのDashboardで各ジョブのstatusが次々を変わっていくのが見えます。ジョブがない場合はECS Clusterのコア数を0に設定しているので、ジョブに合わせてEC2 Instanceを起動していくのも見えます。

Batch Dashboard
image

EC2
image

最後にS3にファイルが保存されているのを確認しください。

6.Close this environment

Batch環境を消すには、作成とは逆の順番で消していく必要があります。
– disable/delete job queue
– disable/delete compute environment
– disable/delete job definition

Batchを消したら、S3内の結果ファイルも消してください。バケットを空にしないとCloudFormationの削除でfailします。
– delete s3 objects
– delete container repo
– delete cloudformation stack

fin!

続きを読む

コマンド1つで作れる!かんたん自宅Amazon S3互換環境!

Amazon S3って?

ざっくりというとAmazonが提供している”ファイルサーバーのようなもの”です.

公式ドキュメントによると

Amazon Simple Storage Service はインターネット用のストレージサービスです。また、ウェブスケールのコンピューティングを開発者が簡単に利用できるよう設計されています。

引用:Amazon S3 とは何ですか?

厳密にはAmazon S3はオブジェクトストレージの一種で,

オブジェクトストレージはデータをファイル単位やブロック単位ではなく、オブジェクトという単位で扱います。オブジェクトにはストレージシステムのなかで固有のID(URI)が付与され、データとそれを扱うためのメタデータによって構成されています。 メタデータは通常のファイルシステムでも作成日や作成者などの情報を持っていましたが、オブジェクトではデータの種類、保存期間やコピー回数など、より多くの情報を付加できます。

引用:オブジェクトストレージとは何か

というものです.

S3のイメージを私なりに,すごく粗い言い方をすると,「RESTFullなAPIを備えたKVSのようなファイルサーバー」と,とらえています.
基本的には,KVSと同じで,固有のキー(ID)を持ってて,そこに対し,ファイルのデータが入ります.それがCurlのようなHTTPリクエストでファイルをアップロードしたり,ダウンロードしたりすることが出来る.一方で,普通のファイルシステムのように階層構造を作ったりすることはしないストレージ.というイメージでしょうか.

Minioって?

https://www.minio.io/

image.png

Go言語で作られたAmazon S3互換のオブジェクトストレージのシステムです.
ライセンスはApache License 2.0で,Lambda Functionsにも対応しているようで,Amazon Lambdaとの連携もできるようです.今回はこのMinioを導入してみようと思います.

他にもAmazon S3互換を謳うオープンソースのプロダクトはあるのですが,一時期のマストドンブームの際に,

Mastodon のインスタンス作成時につまづいたところメモ

という記事を読んで,「Amazon S3も互換品ならオンプレミスで動かせるんだ!」と気づき,やってみようと思いました.Minioに関する記事は非常に少ないですが,読んでみると,かなり簡単に導入が出来たので,私も紹介したくなりました.

事前に必要な環境

Minioを一番簡単に使える方法はdockerです.そのため,事前にdockerが入っていることが前提です.そのため,ubuntuであれば

$ sudo apt-get install docker.io

の導入が必要です.

インストール方法

今回作るMinioのインスタンスは,

設定する変数
Access Key AKIAIOSFODNN7EXAMPLE
Secret Key wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

という設定で,8080ポートでサービスします.

$ sudo docker run --rm -p 8080:9000 -it 
       -e MINIO_ACCESS_KEY=AKIAIOSFODNN7EXAMPLE 
       -e MINIO_SECRET_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY 
       minio/minio server /export

これで自宅にAmazon S3互換環境構築完了です!!

上手く起動すると,このような表示になります.

$ sudo docker run --rm -p 8080:9000 -it -e MINIO_ACCESS_KEY=AKIAIOSFODNN7EXAMPLE   -e MINIO_SECRET_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY   minio/minio server /export
Created minio configuration file successfully at /root/.minio

Endpoint:  http://172.17.0.2:9000  http://127.0.0.1:9000
AccessKey: AKIAIOSFODNN7EXAMPLE 
SecretKey: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY 

Browser Access:
   http://172.17.0.2:9000  http://127.0.0.1:9000

Command-line Access: https://docs.minio.io/docs/minio-client-quickstart-guide
   $ mc config host add myminio http://172.17.0.2:9000 AKIAIOSFODNN7EXAMPLE wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

Object API (Amazon S3 compatible):
   Go:         https://docs.minio.io/docs/golang-client-quickstart-guide
   Java:       https://docs.minio.io/docs/java-client-quickstart-guide
   Python:     https://docs.minio.io/docs/python-client-quickstart-guide
   JavaScript: https://docs.minio.io/docs/javascript-client-quickstart-guide
   .NET:       https://docs.minio.io/docs/dotnet-client-quickstart-guide

Drive Capacity: 87 GiB Free, 96 GiB Total

今回は,簡単に導入するため,永続化やコンテナの使いまわしは,無視しています.

WebUIでの動作確認

Minioは標準でWebUIを持っています.先ほどのコマンドから,8080ポートで稼働しているのでwebブラウザで確認してみます.

image.png

このような画面で,Access KeyとSecret Keyを求められるので,先ほどのキーを入れるとログインできます.

image.png

ログインするとこんな感じの画面になります.右下の赤い+マークの部分から,「バケットの作成」「ファイルのアップロード」が出来ます.

awscliからMinioを使う

awscliとは

説明不要かもしれませんが,AWSを使うためのコマンドラインツールで,Amazonが公式に作っています.MinioはAmazon S3互換なので,このツールのS3の部分の機能が使えます.
公式の説明は,

AWS Command Line Interface は、AWS のサービスを管理するための統合ツールです。ダウンロードおよび設定用の単一のツールのみを使用して、コマンドラインから複数の AWS サービスを制御し、スクリプトを使用してこれらを自動化することができます。

引用:AWS Command Line Interface とは

awscliの導入・設定

awscliのインストールもすごく簡単です.

$ sudo apt-get install python-pip
$ sudo pip install awscli

それに加えて,awscliの設定もします.基本的には,先ほどのAccess KeyとSecret Keyの2つを設定します.

$ aws configure
AWS Access Key ID [****************MPLE]: AKIAIOSFODNN7EXAMPLE
AWS Secret Access Key [****************EKEY]: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Default region name [None]: 
Default output format [None]:

これで準備は完了しました!

awscliでの動作確認

少しだけAmazon S3について解説すると,最初にバケットと呼ばれるものを作ります.これがイメージとしてはフォルダに近くて,これにファイルをアップロードしていきます.しかし,フォルダとは違って階層的にフォルダを掘っていくことはできません.1フォルダに全ファイルを突っ込んでいく形で運用していきます.

awscli自体の使い方は,S3で使う時とほぼ同じです.しかし,1つだけオプションを付け加える必要があります.
それが–endpoint-urlという引数で,ここに自分が建てたMinioのサーバーを指定します.

バケットの作成
$ aws --endpoint-url http://localhost:8080 s3 mb s3://miniotest
make_bucket: miniotest
バケットの一覧表示
$ aws --endpoint-url http://localhost:8080 s3 ls
2017-07-23 17:17:04 miniotest
ファイルのアップロード
$ aws --endpoint-url http://localhost:8080 s3 cp testfile s3://miniotest/testfile_from_local
upload: ./testfile to s3://miniotest/testfile_from_local
ファイルのダウンロード
$ aws --endpoint-url http://localhost:8080 s3 cp s3://miniotest/testfile_from_local testfile_from_s3
download: s3://miniotest/testfile_from_local to ./testfile_from_s3
ファイルの削除
$ aws --endpoint-url http://localhost:8080 s3 rm s3://miniotest/testfile_from_local
delete: s3://miniotest/testfile_from_local
バケット内のファイルの一覧表示
$ aws --endpoint-url http://localhost:8080 s3 ls s3://miniotest
2017-07-23 17:19:00          0 testfile_from_local
バケットの削除
$ aws --endpoint-url http://localhost:8080 s3 rb s3://miniotest
remove_bucket: miniotest

まとめ

この土日に思い立って作ってみましたが非常に簡単でした.
私自身,AWSの経験がなく,既に自分でサーバーを借りているのに,追加で借りるのもなー.と思っていました.その中で,こんなに簡単にS3環境が建てられるのはうれしかったです.
また,今回はawscliの使い方を勉強するのも目的でした.最初は,「互換品だから公式のツールじゃまともに動いてくれないかな・・・」と若干不安な点もありましたが,動作には問題は出なかったので,非常に楽でした.そう考えると,MinioはよくできたS3互換環境なのかな.と思いました.
「会社内でS3使いたいけど,パブリッククラウドだとセキュリティが・・・」とか,「S3を勉強がてら軽く使ってみたいな.」という人には,Minioは簡単に建てられるのでおススメです.

続きを読む