Fabric1.0已經正式發布一段時間了,官方給出的單機部署的腳本也很完備,基本上傻瓜式的一鍵部署,直接運行官方的network_setup.sh up即可。但是在實際生產環境,我們不可能把所有的節點都放在一台機器中,所以必然會遇到多級部署的問題。下面我們就來講講怎么實現多機部署和測試官方的ChainCode。
1.環境准備
我們要部署的是4Peer+1Orderer的架構,也就是官方的e2c_cli架構。為此我們需要准備5台機器。我們可以開5台虛擬機,也可以購買5台雲服務器,不管怎么樣,我們需要這5台機器網絡能夠互通,而且安裝相同的系統,我們用的是Ubuntu 16.04版。為了方便,我建議先啟用1台虛擬機,在其中把准備工作做完,然后基於這台虛擬機,再復制出4台即可。這里是我用到5台Server的主機名(角色)和IP:
orderer.example.com | 10.174.13.185 |
peer0.org1.example.com | 10.51.120.220 |
peer1.org1.example.com | 10.51.126.19 |
peer0.org2.example.com | 10.51.116.133 |
peer1.org2.example.com | 10.51.126.5 |
接下來我們需要准備軟件環境,包括Go、Docker、Docker Compose,我在之前的單機部署的博客中也講到過具體的方法,這里再復述一下:
1.1 Go的安裝
Ubuntu的apt-get雖然提供了Go的安裝,但是版本比較舊,最好的方法還是參考官方網站,下載最新版的Go。具體涉及到的命令包括:
wget https://storage.googleapis.com/golang/go1.8.3.linux-amd64.tar.gz sudo tar -C /usr/local -xzf go1.8.3.linux-amd64.tar.gz
接下來編輯當前用戶的環境變量:
vi ~/.profile
添加以下內容:
export PATH=$PATH:/usr/local/go/bin export GOROOT=/usr/local/go export GOPATH=$HOME/go export PATH=$PATH:$HOME/go/bin
編輯保存並退出vi后,記得把這些環境載入:
source ~/.profile
我們把go的目錄GOPATH設置為當前用戶的文件夾下,所以記得創建go文件夾
cd ~
mkdir go
1.2 Docker安裝
我們可以使用阿里提供的鏡像,安裝也非常方便。通過以下命令來安裝Docker
curl -sSL http://acs-public-mirror.oss-cn-hangzhou.aliyuncs.com/docker-engine/internet | sh -
安裝完成后需要修改當前用戶(我使用的用戶叫fabric)權限:
sudo usermod -aG docker fabric
注銷並重新登錄,然后添加阿里雲的Docker Hub鏡像:
不同的版本添加方法是不一樣的,官方的文檔如下:
https://cr.console.aliyun.com/#/accelerator
當然覺得阿里雲鏡像不好用,喜歡用DaoClound的也可以用DaoClound的鏡像。
1.3 Docker-Compose的安裝
Docker-compose是支持通過模板腳本批量創建Docker容器的一個組件。在安裝Docker-Compose之前,需要安裝Python-pip,運行腳本:
sudo apt-get install python-pip
安裝完成后,接下來從DaoClound安裝Docker-compose,運行腳本:
curl -L https://get.daocloud.io/docker/compose/releases/download/1.10.1/docker-compose-`uname -s`-`uname -m` > ~/docker-compose sudo mv ~/docker-compose /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose
1.4 Fabric源碼下載
我們可以使用Git命令下載源碼,也可以使用go get命令,偷懶一點,我們直接用go get命令獲取最新的Fabric源碼:
go get github.com/hyperledger/fabric
這個可能等的時間比較久,等完成后,我們可以在~/go/src/github.com/hyperledger/fabric中找到所有的最新的源代碼。
由於Fabric一直在更新,所有我們並不需要最新最新的源碼,需要切換到v1.0.0版本的源碼即可:
cd ~/go/src/github.com/hyperledger/fabric git checkout v1.0.0
1.5 Fabric Docker鏡像的下載
這個其實很簡單,因為我們已經設置了Docker Hub鏡像地址,所以下載也會很快。官方文件也提供了批量下載的腳本。我們直接運行:
cd ~/go/src/github.com/hyperledger/fabric/examples/e2e_cli/ source download-dockerimages.sh -c x86_64-1.0.0 -f x86_64-1.0.0
這樣就可以下載所有需要的Fabric Docker鏡像了。
2.docker-compose 配置文件准備
在Fabric的源碼中,提供了單機部署4Peer+1Orderer的示例,在Example/e2e_cli文件夾中。我們可以在其中一台機器上運行單機的Fabric實例,確認無誤后,在該機器上,生成公私鑰,修改該機器中的Docker-compose配置文件,然后把這些文件分發給另外4台機器。我們就以orderer.example.com這台機器為例
2.1單機運行4+1 Fabric實例,確保腳本和鏡像正常
我們先進入這個文件夾,然后直接運行
./network_setup.sh up
這個命令可以在本機啟動4+1的Fabric網絡並且進行測試,跑Example02這個ChainCode。我們可以看到每一步的操作,最后確認單機沒有問題。確認我們的鏡像和腳本都是正常的,我們就可以關閉Fabric網絡,繼續我們的多機Fabric網絡設置工作。關閉Fabric命令:
./network_setup.sh down
2.2生成公私鑰、證書、創世區塊等
公私鑰和證書是用於Server和Server之間的安全通信,另外要創建Channel並讓其他節點加入Channel就需要創世區塊,這些必備文件都可以一個命令生成,官方已經給出了腳本:
./generateArtifacts.sh mychannel
運行這個命令后,系統會創建channel-artifacts文件夾,里面包含了mychannel這個通道相關的文件,另外還有一個crypto-config文件夾,里面包含了各個節點的公私鑰和證書的信息。
2.3設置peer節點的docker-compose文件
e2e_cli中提供了多個yaml文件,我們可以基於docker-compose-cli.yaml文件創建:
cp docker-compose-cli.yaml docker-compose-peer.yaml
然后修改docker-compose-peer.yaml,去掉orderer的配置,只保留一個peer和cli,因為我們要多級部署,節點與節點之前又是通過主機名通訊,所以需要修改容器中的host文件,也就是extra_hosts設置,修改后的peer配置如下:
peer0.org1.example.com: container_name: peer0.org1.example.com extends: file: base/docker-compose-base.yaml service: peer0.org1.example.com extra_hosts: - "orderer.example.com:10.174.13.185"
同樣,cli也需要能夠和各個節點通訊,所以cli下面也需要添加extra_hosts設置,去掉無效的依賴,並且去掉command這一行,因為我們是每個peer都會有個對應的客戶端,也就是cli,所以我只需要去手動執行一次命令,而不是自動運行。修改后的cli配置如下:
cli: container_name: cli image: hyperledger/fabric-tools tty: true environment: - GOPATH=/opt/gopath - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock - CORE_LOGGING_LEVEL=DEBUG - CORE_PEER_ID=cli - CORE_PEER_ADDRESS=peer0.org1.example.com:7051 - CORE_PEER_LOCALMSPID=Org1MSP - CORE_PEER_TLS_ENABLED=true - CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.crt - CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.key - CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt - CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer volumes: - /var/run/:/host/var/run/ - ../chaincode/go/:/opt/gopath/src/github.com/hyperledger/fabric/examples/chaincode/go - ./crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ - ./scripts:/opt/gopath/src/github.com/hyperledger/fabric/peer/scripts/ - ./channel-artifacts:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts depends_on: - peer0.org1.example.com extra_hosts: - "orderer.example.com:10.174.13.185" - "peer0.org1.example.com:10.51.120.220" - "peer1.org1.example.com:10.51.126.19" - "peer0.org2.example.com:10.51.116.133" - "peer1.org2.example.com:10.51.126.5"
在單擊模式下,4個peer會映射主機不同的端口,但是我們在多機部署的時候是不需要映射不同端口的,所以需要修改base/docker-compose-base.yaml文件,將所有peer的端口映射都改為相同的:
ports: - 7051:7051 - 7052:7052 - 7053:7053
2.4設置orderer節點的docker-compose文件
與創建peer的配置文件類似,我們也復制一個yaml文件出來進行修改:
cp docker-compose-cli.yaml docker-compose-orderer.yaml
orderer服務器上我們只需要保留order設置,其他peer和cli設置都可以刪除。orderer可以不設置extra_hosts。
2.5分發配置文件
前面4步的操作,我們都是在orderer.example.com上完成的,接下來我們需要將這些文件分發到另外4台服務器上。Linux之間的文件傳輸,我們可以使用scp命令。
我先登錄peer0.org1.example.com,將本地的e2e_cli文件夾刪除:
rm e2e_cli –R
然后再登錄到orderer服務器上,退回到examples文件夾,因為這樣可以方便的把其下的e2e_cli文件夾整個傳到peer0服務器上。
scp -r e2e_cli fabric@10.51.120.220:/home/fabric/go/src/github.com/hyperledger/fabric/examples/
我們在前面配置的就是peer0.org1.example.com上的節點,所以復制過來后不需要做任何修改。
再次運行scp命令,復制到peer1.org1.example.com上,然后我們需要對docker-compose-peer.yaml做一個小小的修改,將啟動的容器改為peer1.org1.example.com,並且添加peer0.org1.example.com的IP映射,對應的cli中也改成對peer1.org1.example.com的依賴。這是修改后的peer1.org1.example.com上的配置文件:
version: '2' services: peer1.org1.example.com: container_name: peer1.org1.example.com extends: file: base/docker-compose-base.yaml service: peer1.org1.example.com extra_hosts: - "orderer.example.com:10.174.13.185" - "peer0.org1.example.com:10.51.120.220" cli: container_name: cli image: hyperledger/fabric-tools tty: true environment: - GOPATH=/opt/gopath - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock - CORE_LOGGING_LEVEL=DEBUG - CORE_PEER_ID=cli - CORE_PEER_ADDRESS=peer1.org1.example.com:7051 - CORE_PEER_LOCALMSPID=Org1MSP - CORE_PEER_TLS_ENABLED=true - CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/server.crt - CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/server.key - CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/ca.crt - CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer volumes: - /var/run/:/host/var/run/ - ../chaincode/go/:/opt/gopath/src/github.com/hyperledger/fabric/examples/chaincode/go - ./crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ - ./scripts:/opt/gopath/src/github.com/hyperledger/fabric/peer/scripts/ - ./channel-artifacts:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts depends_on: - peer1.org1.example.com extra_hosts: - "orderer.example.com:10.174.13.185" - "peer0.org1.example.com:10.51.120.220" - "peer1.org1.example.com:10.51.126.19" - "peer0.org2.example.com:10.51.116.133" - "peer1.org2.example.com:10.51.126.5"
接下來繼續使用scp命令將orderer上的文件夾傳送給peer0.org2.example.com和peer1.org2.example.com,然后也是修改一下docker-compose-peer.yaml文件,使得其啟動對應的peer節點。
3.啟動Fabric
現在所有文件都已經准備完畢,我們可以啟動我們的Fabric網絡了。
3.1啟動orderer
讓我們首先來啟動orderer節點,在orderer服務器上運行:
docker-compose -f docker-compose-orderer.yaml up –d
運行完畢后我們可以使用docker ps看到運行了一個名字為orderer.example.com的節點。
3.2啟動peer
然后我們切換到peer0.org1.example.com服務器,啟動本服務器的peer節點和cli,命令為:
docker-compose -f docker-compose-peer.yaml up –d
運行完畢后我們使用docker ps應該可以看到2個正在運行的容器。
接下來依次在另外3台服務器運行啟動peer節點容器的命令:
docker-compose -f docker-compose-peer.yaml up –d
現在我們整個Fabric4+1服務器網絡已經成型,接下來是創建channel和運行ChainCode。
3.3創建Channel測試ChainCode
我們切換到peer0.org1.example.com服務器上,使用該服務器上的cli來運行創建Channel和運行ChainCode的操作。首先進入cli容器:
docker exec -it cli bash
進入容器后我們可以看到命令提示變為:
root@b41e67d40583:/opt/gopath/src/github.com/hyperledger/fabric/peer#
說明我們已經以root的身份進入到cli容器內部。官方已經提供了完整的創建Channel和測試ChainCode的腳本,並且已經映射到cli容器內部,所以我們只需要在cli內運行如下命令:
./scripts/script.sh mychannel
那么該腳本就可以一步一步的完成創建通道,將其他節點加入通道,更新錨節點,創建ChainCode,初始化賬戶,查詢,轉賬,再次查詢等鏈上代碼的各個操作都可以自動化實現。直到最后,系統提示:
===================== All GOOD, End-2-End execution completed =====================
說明我們的4+1的Fabric多級部署成功了。我們現在是在peer0.org1.example.com的cli容器內,我們也可以切換到peer0.org2.example.com服務器,運行docker ps命令,可以看到本來是2個容器的,現在已經變成了3個容器,因為ChainCode會創建一個容器:
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
add457f79d57 dev-peer0.org2.example.com-mycc-1.0 "chaincode -peer.a..." 11 minutes ago Up 11 minutes dev-peer0.org2.example.com-mycc-1.0
0c06fb8e8f20 hyperledger/fabric-tools "/bin/bash" 13 minutes ago Up 13 minutes cli
632c3e5d3a5e hyperledger/fabric-peer "peer node start" 13 minutes ago Up 13 minutes 0.0.0.0:7051-7053->7051-7053/tcp peer0.org2.example.com
4.總結
我在Fabric多機部署的過程中還是遇到了不少坑,前前后后花了2天的時間才趟坑完畢,實現了最終的4+1多機部署。其中與單機部署最大的不同的地方就是在單機部署的時候,我們是在同一個docker網絡中,所以相互之間通過主機名通訊很容易,而在多機環境中,就需要額外設置DNS或者就是通過extra_hosts參數,設置容器中的hosts文件。而且不能一股腦的就跟cli一樣把5台機器的域名IP配置到peer中,那樣會報錯的,所以只需要設置需要的即可。
官方給的腳本已經替我們做了很多工作,同時也隱藏了很多細節,所以我們並沒有真正了解其內部的實現過程,我以后會再寫一篇博客詳細介紹Fabric多機部署的詳細過程。為了方便,我把設計到的幾個docker-compose文件打包了一份放出來,如果大家想進行同樣的部署,只需要修改一下IP即可復用。
最后,大家如果想進一步探討Fabric或者使用中遇到什么問題可以加入QQ群【494085548】大家一起討論。