hyperledger/fabricをEC2で動かす

SPAJAM仙台予選でブロックチェーンでアセット監視システムを作ったが
その時hyperledger/fabricをEC2で動かそうとして結構はまったのでセットアップをまとめた。

Docment

Docs
prerequisites

Environment

  • AWS EC2 t2.micro
  • Ubuntu Server 14.04 LTS (HVM)
  • Storage 50GB
    環境に19GBほど使うのでデフォルトだと動かない

Foundation

基本的なもの。

sudo apt-get update -qq
sudo apt-get dist-upgrade -qqy
sudo apt-get -y upgrade
sudo apt-get -y install git
sudo apt-get -y install gcc
sudo apt-get -y install g++
sudo apt-get -y install make
sudo apt-get -y install unzip
sudo apt-get -y install autoconf
sudo apt-get -y install build-essential libtool

Add required library

Fabricで使うライブラリ

sudo apt-get -y install zlib1g-dev  
sudo apt-get -y install libsnappy-dev  
sudo apt-get -y install libbz2-dev  

Install go

goの環境を作る。今回は1.6.2を使用した

cd /tmp
wget https://storage.googleapis.com/golang/go1.6.2.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.6.2.linux-amd64.tar.gz
echo 'export PATH=$PATH:/usr/local/go/bin' >>  $HOME/.bash_profile

mkdir $HOME/go
mkdir $HOME/work

echo 'export GOROOT=$HOME/go' >> $HOME/.profile
echo 'export PATH=$PATH:$GOROOT/bin' >>  ~/.profile
echo 'export GOPATH=$HOME/work' >> $HOME/.bash_profile
. $HOME/.bash_profile

Install rocksdb

"virtual memory exhausted: Cannot allocate memory"を回避するための設定

t2.microとか激弱い鯖だといる。金の力でここを省略できる

sudo dd if=/dev/zero of=/swapfile bs=1024 count=256k
sudo mkswap /swapfile
sudo swapon /swapfile
sudo sh -c 'echo "/swapfile       none    swap    sw      0       0 " >> /etc/fstab'
echo 10 | sudo tee /proc/sys/vm/swappiness
echo vm.swappiness = 10 | sudo tee -a /etc/sysctl.conf
sudo chown root:root /swapfile 
sudo chmod 0600 /swapfile 

rocksdbをインストール

masterを使うと互換性がなくエラーを吐く内容 ので一つ前のもの(v4.5.1)を入れる

cd /tmp
wget https://github.com/facebook/rocksdb/archive/v4.5.1.tar.gz
tar xzvf v4.5.1.tar.gz
cd rocksdb-4.5.1
make
sudo make install

Install docker

dockerをインストールする

sudo apt-get install apt-transport-https ca-certificates
sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D
sudo sh -c "echo 'deb https://apt.dockerproject.org/repo ubuntu-trusty main' >> /etc/apt/sources.list.d/docker.list"
sudo apt-get update
sudo apt-get install -y linux-image-extra-$(uname -r)
sudo apt-get purge lxc-docker
sudo apt-cache policy docker-engine
sudo apt-get -y install apparmor
sudo apt-get -y install docker-engine

dockerの権限を変更

一度ログアウトしてもう一度ログインする。

sudo gpasswd -a $USER docker
echo 'Please login once more!!!'
exit

Prevent [java] <defunct>

デフォルトだとストレージドライバーがaufsで上のエラーが出てしまうので(Issues) ストレージドライバーをdevicemapperに変更する

sudo service docker stop
sudo docker daemon --storage-driver=devicemapper &
sudo docker run hello-world

Grpc

# First install protoc
cd /tmp
git clone https://github.com/google/protobuf.git
cd protobuf
git checkout v3.0.0-beta-3
#unzip needed for ./autogen.sh
./autogen.sh
./configure --prefix=/usr

Node

公式に準拠して0.12.7を入れる

cd  /tmp
NODE_VER=0.12.7
NODE_PACKAGE=node-v$NODE_VER-linux-x64.tar.gz
TEMP_DIR=/tmp
SRC_PATH=$TEMP_DIR/$NODE_PACKAGE

ディレクトリ作成

sudo mkdir /var/hyperledger
sudo chown -R $USER:$USER /var/hyperledger

Fabric

cd $GOPATH/src
mkdir -p github.com/hyperledger
cd github.com/hyperledger
git clone https://github.com/hyperledger/fabric.git
cd work/src/github.com/hyperledger/fabric
sudo chown -R $USER:$USER /var/hyperledger

ゴミ取り

apt-get -y autoremove
apt-get clean
rm -rf /var/lib/apt/lists/* /tmp/*

Sample

make peer
cd build/bin/peer
./peer node start

Result

$ ./peer node start
04:52:51.925 [crypto] main -> INFO 001 Log level recognized 'info', set to INFO
04:52:51.927 [main] serve -> INFO 002 Security enabled status: false
04:52:51.928 [main] serve -> INFO 003 Privacy enabled status: false
04:52:51.928 [chaincode] NewChaincodeSupport -> INFO 004 Chaincode support using peerAddress: 0.0.0.0:30303
04:52:51.929 [eventhub_producer] start -> INFO 005 event processor started
04:52:51.948 [state] loadConfig -> INFO 006 Loading configurations...
04:52:51.949 [state] loadConfig -> INFO 007 Configurations loaded. stateImplName=[buckettree], stateImplConfigs=map[numBuckets:%!s(int=1000003) maxGroupingAtEachLevel:%!s(int=5) bucketCacheSize:%!s(int=100)], deltaHistorySize=[500]
04:52:51.949 [state] NewState -> INFO 008 Initializing state implementation [buckettree]
04:52:51.949 [buckettree] initConfig -> INFO 009 configs passed during initialization = map[string]interface {}{"numBuckets":1000003, "maxGroupingAtEachLevel":5, "bucketCacheSize":100}
04:52:51.949 [buckettree] initConfig -> INFO 00a Initializing bucket tree state implemetation with configurations &{maxGroupingAtEachLevel:5 lowestLevel:9 levelToNumBucketsMap:map[6:8001 4:321 7:40001 3:65 2:13 0:1 9:1000003 8:200001 5:1601 1:3] hashFunc:0xb37d00}
04:52:51.949 [buckettree] newBucketCache -> INFO 00b Constructing bucket-cache with max bucket cache size = [100] MBs
04:52:51.949 [buckettree] loadAllBucketNodesFromDB -> INFO 00c Loaded buckets data in cache. Total buckets in DB = [0]. Total cache size:=0
04:52:51.949 [genesis] loadConfigs -> INFO 00d Loading configurations...
04:52:51.949 [genesis] loadConfigs -> INFO 00e Configurations loaded: genesis=map[chaincodes:<nil>], mode=[], deploySystemChaincodeEnabled=[false]
04:52:51.949 [genesis] func1 -> INFO 00f No genesis block chaincodes defined.
04:52:51.950 [consensus/controller] NewConsenter -> INFO 010 Creating default consensus plugin (noops)
04:52:51.950 [consensus/noops] newNoops -> INFO 011 NOOPS consensus type = *noops.Noops
04:52:51.950 [consensus/noops] newNoops -> INFO 012 NOOPS block size = 500
04:52:51.950 [consensus/noops] newNoops -> INFO 013 NOOPS block timeout = 1s
04:52:51.951 [main] serve -> INFO 014 Starting peer with id=name:"jdoe" , network id=dev, address=0.0.0.0:30303, discovery.rootnode=[[]], validator=true
04:52:51.951 [rest] StartOpenchainRESTServer -> INFO 015 Initializing the REST service on 0.0.0.0:5000, TLS is disabled.

感想

t2.microでやるのはきつい SPAJAMは完敗。