天天看點

超級賬本Fabric 1.0 多節點叢集的部署(3)——具體配置

上兩期文章闡述了超級賬本Fabric 1.0多節點部署概述以及多節點叢集部署的準備工作,得到廣大讀者的關注,今天釋出連載之三,介紹搭建 Fabric 1.0 叢集的具體配置和chaincode管理的步驟。因為是手動部署,是以步驟比較多。

多節點 Fabric 的配置

以下各VM的工作目錄為:

$GOPATH/src/github.com/hyperledger/fabric/examples/e2e_cli

可在任意VM上運作以下指令,生成建構 Fabric 網絡所需的成員證書等必要材料:

bash generateArtifacts.sh

該指令隻需在某個VM上運作一次,其他VM上就不需要運作。

在運作該指令的VM中會生成 channel-artifacts 和 crypto-config 目錄,需要把它們拷貝到其他VM的 e2e_cli 目錄下,如果在VM中已經存在該目錄,則先把目錄删除。當每個VM中都有統一的 channel-artifacts 和 crypto-config 目錄後接下來就開始配置 compose 檔案。

I. VM1的配置:

1.修改 /etc/hosts 的映射關系

因為容器内部通過域名的方式通路 orderer , 是以需要通過修改 /etc/hosts 把orderer 的域名和 ip 位址對應起來,在檔案中添加:

10.112.122.69 orderer.example.com

2.修改docker-compose-cli.yaml

在預設的情況下,docker-compose-cli.yaml會啟動6個service(容器),它們分别為 peer0.org1.example.com、 peer1.org1.example.com、 peer0.org2.example.com、 peer1.org2.example.com、 orderer.example.com 和 cli,因為每台機器隻運作與之對應的一個節點,是以需要注釋掉無需啟動的 service。

(1) 除 peer0.org1.example.com 和 cli service 外,其他 service 全部注釋。

(2) 在 cli 的 volumes 中加入映射關系:

-./peer/:/opt/gopath/src/github.com/hyperledger/fabric/peer/

-/etc/hosts:/etc/hosts

(3) 注釋 cli 中的 depends_on 和 command :

depends_on:

#- orderer.example.com

- peer0.org1.example.com

#- peer1.org1.example.com

#- peer0.org2.example.com

#- peer1.org2.example.com

#command: /bin/bash -c ‘./scripts/script.sh CHANNELNAME;sleepTIMEOUT’

之前我們把容器中的工作目錄挂載到主控端的 e2e_cli/peer 目錄下, 是因為在執行 create channel 的過程中,orderer 會傳回一個 mychannel.block 作為 peer 加入 channel 的依據,其他的 peer 要加入到相同的 channel 中必須先擷取該 mychannel.block 檔案。是以,通過挂載目錄從主控端就能友善獲得 mychannel.block ,并且把它傳輸到其他的 VM 上。

挂載 /etc/hosts 的目的是把主機中 orderer.exmaple.com 與 IP 位址10.112.122.69 的映射關系帶入容器中,目的是讓 cli 能通過域名通路 orderer 。在實際環境中,建議通過配置 DNS 而不是修改 /etc/hosts 檔案(下同)。

3.修改 base/peer-base.yaml,添加 volumes:

volumes:

-/etc/hosts:/etc/hosts

這樣 peer 容器能通過域名通路orderer了。

II. VM2配置:

1.修改 /etc/hosts 的映射關系

peer1.org1.example.com 使用了 peer0.org1.example.com 作為它的初始化節點,是以需要在主機中還需要加入 VM1 的 ip 位址。

10.112.122.69 orderer.example.com

10.112.122.144 peer0.org1.example.com

2.修改docker-compose-cli.yaml

(1) 類似VM1,除 peer1.org1.example.com 和 cli service 外,其他 service 全部注釋。

(2) 在 cli 的 volumes 中加入映射關系:

-./peer/:/opt/gopath/src/github.com/hyperledger/fabric/peer/

-/etc/hosts:/etc/hosts

(3) 注釋cli中的 depends_on 和 command:

depends_on:

#- orderer.example.com

#- peer0.org1.example.com

- peer1.org1.example.com

#- peer0.org2.example.com

#- peer1.org2.example.com

#command:/bin/bash -c ‘./scripts/script.sh CHANNELNAME;sleepTIMEOUT’

(4) 修改cli中的環境變量

CORE_PEER_ADDRESS=peer1.org1.example.com:7051

3.修改base/peer-base.yaml,同VM1的修改。

III. VM3配置:

1.修改 /etc/hosts 的映射關系

10.112.122.69 orderer.example.com

2.修改docker-compose-cli.yaml

(1) VM3 上運作 peer2 節點,是以除 peer0.org2.example.com 和 cli service 外,其他 service 全部注釋。

(2) 在cli的 volumes 中加入映射關系:

- ./peer/:/opt/gopath/src/github.com/hyperledger/fabric/peer/

-/etc/hosts:/etc/hosts

(3) 注釋cli中的 depends_on 和 command :

depends_on:

#- orderer.example.com

#- peer0.org1.example.com

#- peer1.org1.example.com

- peer0.org2.example.com

#- peer1.org2.example.com

#command:/bin/bash -c ‘./scripts/script.sh CHANNELNAME;sleepTIMEOUT’

(4) 修改cli中的環境變量

CORE_PEER_LOCALMSPID=”Org2MSP”

CORE_PEER_ADDRESS=peer0.org2.example.com:7051

CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt

CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp

3.修改base/peer-base.yaml,同VM1。

IV. VM4配置:

1.修改/etc/hosts的映射關系

peer1.org2.example.com 使用了 peer0.org2.example.com 作為它的初始化節點,是以需要在映射關系中加入 VM3 的 ip 位址

10.112.122.69 orderer.example.com

10.112.122.12 peer0.org2.example.com

2.修改docker-compose-cli.yaml

(1) VM4運作peer3,是以除peer1.org2.example.com和cliservice 外,其他service全部注釋

(2) 在cli的volumes中加入映射關系:

-./peer/:/opt/gopath/src/github.com/hyperledger/fabric/peer/

-/etc/hosts:/etc/hosts

(3) 修改cli中的 depends_on 和 command:

depends_on:

- peer1.org2.example.com

command:/bin/bash -c ‘./scripts/script.sh CHANNELNAME;sleepTIMEOUT’

(4) 修改cli中的環境變量

CORE_PEER_LOCALMSPID=”Org2MSP”

CORE_PEER_ADDRESS=peer1.org2.example.com:7051

CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt

CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp

3.修改base/peer-base.yaml,同VM1。

V. VM5配置如下:

1.修改docker-compose-cli.yaml

除orderer外的其他 service 全部注釋,即隻啟動 orderer 。

啟動多節點Fabric叢集

1.啟動orderer

進入到 VM5 的 fabric/examples/e2e_cli 目錄下,運作

docker-compose -f docker-compose-cli.yaml up -d

此時終端會出現大量記錄,當出現Beginning to service requests時,orderer啟動完成。有了 orderer 之後,就可以通過它來管理 channel 。

2.啟動 org1的第一個節點 peer0 ,即 peer0.org1.example.com

進入到 VM1 的 fabric/examples/e2e_cli 目錄下,運作

docker-compose -f docker-compose-cli.yaml up -d

此時通過docker ps -a 指令可以看到成功啟動了peer0.org1.example.com 和 cli 兩個容器。

接下來實作建立channel 、加入channel和安裝chanicode。首先進入到cli容器内:

docker exec -it cli bash

cli 與 orderer 之間的通訊使用 tls 加密,設定環境變量 ORDERER_CA 以作建立握手的憑證:

$ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/cacerts/ca.example.com-cert.pem

注:以下所有涉及到 ORDERER_CA 環境變量的指令都需預先給該變量指派。

進入到 cli 容器後會自動跳轉到 /opt/gopath/src/github.com/hyperledger/fabric/peer 目錄,即工作目錄,通過compose檔案的配置,該目錄映射為主控端的 /e2e_cli/peer 。

在工作目錄下輸入以下指令,建立名為 mychannel 的 channel :

peer channel create -o orderer.example.com:7050 -c mychannel -f ./channel-artifacts/channel.tx –tls –cafile $ORDERER_CA

channel 建立成功後,會在目前目錄下生成mychannel.block檔案。每個peer 在向 orderer 發送 join channel 交易的時候,需要提供這個檔案才能加入到 mychannel 中,是以運作在其他 VM 上的 peer 需要得到 mychannel.block 檔案來加入到 mychannel 中。由于之前的檔案映射關系, mychannel.block 檔案可在主控端的 e2e_cli/peer 目錄下擷取,這時可以通過主控端把 mychannel.block 拷貝到 VM2, VM3, VM4的 e2e_cli/peer 目錄下。

把 peer0.org1.example.com 加入到 mychannel 中:

peer channel join -b mychannel.block

更新 mychannel 中 org1 的 anchor peer 的資訊:

peer channel update -o orderer.example.com:7050 -c mychannel -f ./channel-artifacts/Org1MSPanchors.tx –tls –cafile $ORDERER_CA

安裝 chaincode 示例 chaincode_example02 到 peer0.org1.example.com 中:

peer chaincode install -nmycc -v 1.0 -p \

github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02

這時候 chaincode 代碼已經安裝到了 peer0 節點上,但并未執行個體化運作。接下來先配置好其他節點。

3.啟動 org1 的第二個節點 peer1,即 peer1.org1.example.com

進入到VM2的 fabric/examples/e2e_cli 目錄下,運作

docker-compose -f docker-compose-cli.yaml up -d

進入到 cli 容器内部:

docker exec -it cli bash

由于前面已經把 mychannel.block 拷貝到了 VM2 的 e2e_cli/peer 目錄下,是以 mychannel.block 可通過容器内的 /opt/gopath/src/github.com/hyperledger/fabric/peer 目錄通路。

把 peer1.org1.example.com 加入到 mychannel 中:

peer channel join -b mychannel.block

安裝 chaincode_example02 到 peer1.org1.example.com 中:

peer chaincode install -nmycc -v 1.0 –p \

github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02

4.啟動 org2 的第一個節點 peer2,即 peer0.org2.example.com

進入到 VM3 的 fabric/examples/e2e_cli 目錄下,運作

docker-compose-f docker-compose-cli.yaml up -d

進入到cli容器内部:

docker exec -it cli bash

把peer0.org2.example.com加入到mychannel中:

peer channel join -b mychannel.block

更新 mychannel 中 org2 的 anchor peer 的資訊:

peer channel update -oorderer.example.com:7050 -c mychannel -f ./channel-artifacts/Org2MSPanchors.tx –tls –cafile $ORDERER_CA

安裝 chaincode_example02 到 peer0.org2.example.com 中:

peer chaincode install -nmycc -v 1.0 -p \

github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02

5.啟動org2的第二個節點 peer3 ,即啟動 peer1.org2.example.com

進入到 VM4 的 fabric/examples/e2e_cli 目錄下,運作

docker-compose-f docker-compose-cli.yaml up -d

首先進入到cli容器内部:

docker exec -it cli bash

把 peer1.org2.example.com 加入到 mychannel 中:

peer channel join -b mychannel.block

安裝 chaincode_example02 到 peer1.org2.example.com 中:

peer chaincode install -nmycc -v 1.0 -p \

github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02

運作chaincode

通過前面的步驟,整個 多節點Fabric 網絡已經運作起來了,每個peer都加入到了辨別為 mychannel 的 channel 中,并且都安裝了一個簡單的 chaincode (該 chaincode 在安裝時被辨別為 mycc ) 。下面步驟運作和維護 chaincode。

1.執行個體化chaincode

chaincode 的執行個體化可在任意 peer 上進行,并且 chaincode 隻能被執行個體化一次,下面以在 peer0.org2.example.com 上執行個體化 chaincode 為例。

首先登入VM3并進入到cli容器内部運作:

peer chaincode instantiate -o orderer.example.com:7050 –tls –cafile $ORDERER_CA -C mychannel-nmycc -v 1.0 -c ‘{“Args”:[“init”,”a”,”100”,”b”,”200”]}’ -P “OR (‘Org1MSP.member’,’Org2MSP.member’)”

這時候會建構一個新的容器來運作chaincode,通過docker ps -a 指令可以看到新容器:

dev-peer0.org2.example.com-mycc-1.0

上述執行個體化中,我們對兩個變量‘a’和‘b’分别賦予初值100和200,通過 channel 它們的值被同步到了其他peer的賬本上,即使其他peer還沒有建構運作 chaincode 的容器。

2.執行 chaincode 的 query 交易

由于 chaincode 已經被 peer0.org2.example.com 執行個體化了,是以其他 peer 不需要再次執行個體化它了,但是 chaincode 的狀态(world state)卻是已經記錄在各個peer的賬本上的。

接下來我們在peer0.org1.example.com上檢視chaincode的狀态,登入到VM1上并進入cli容器内部執行:

peer chaincode query -C mychannel -nmycc -c ‘{“Args”:[“query”,”a”]}’

上面的指令檢視 mycc 中變量 a 的值,由于在 peer 跟 chaincode 發生互動之前還不存在運作 chaincode 的容器,是以第一次互動的時候需要先建構運作 chaincode 的容器,等待一段時間後傳回結果:100 。

此時通過 docker ps -a 指令能看到新容器:

dev-peer0.org1.example.com-mycc-1.0

該值與執行個體化時的指派一緻,說明 peer0.org1 和 peer0.org2 兩個 peer 可以互相通信。

3.執行chaincode的invoke交易

接下來,我們執行一個 invoke 交易,使得變量 a 向變量 b 轉帳 20,得到最終值為[“a”:”80”,”b”:”220”]。

登入到VM2并進入到cli容器中中通過以下指令查詢mycc的狀态:

peer chaincode query -C mychannel -n mycc -c ‘{“Args”:[“query”,”a”]}’

稍作等待後傳回結果為100,下面執行 invoke 交易,改變 a 的值為 80 :

peer chaincode invoke -oorderer.example.com:7050 –tls –cafile $ORDERER_CA -C mychannel -n mycc -c ‘{“Args”:[“invoke”,”a”,”b”,”20”]}’

4.再次執行 chaincode 的 query 交易

在peer1.org1.example.com 上重複以上檢視 chaincode 的步驟,得到傳回結果為 80 ,說明測試通過,至此,Fabric網絡建構完畢,各個部件工作正常。

更新chaincode

通過 channel upgrade 指令可以使得 chaincode 更新到最新的版本,而低版本 chaincode 将不能再使用。

登入到VM1的 cli 容器中再次安裝 chaincode_example02 ,但賦予它更高的版本号 2.0:

peer chaincode install -n mycc -v 2.0 -p \

github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02

在 VM1 的 cli 容器更新 chaincode ,添加兩個變量 ‘c’和‘d’:

peer chaincode upgrade -o orderer.example.com:7050 –tls –cafile $ORDERER_CA -n mycc -v 2.0 -c ‘{“Args”:[“init”,”c”, “10”,”d”,”20”]}’

等待一段時間後,可以通過docker ps -a 來檢視新容器建構的容器,該容器的名稱為:

dev-peer0.org1.example.com-mycc-2.0

通過以下指令查詢c的變量:

peer chaincode -n mycc -C mychannel -v 2.0 -c ‘{“Args”:[“query”,”c”]}’

傳回結果為10

再次查詢a的變量:

peer chaincode -n mycc -C mychannel -v 2.0 -c’{“Args”:[“query”,”a”]}’

傳回結果為80,說明更新 chaincode 成功。

這時候對賬本的修改會通過 orderer 同步到其他 peer 上,但是在其他 peer 上将無法檢視或更改 chaincode 的狀态,因為它們還在使用舊版的 chaincode ,是以其他 pee r要想正常通路還需再次安裝 chaincode ,并且設定相同的版本号 ( chaincode 代碼沒發生改變,隻是安裝時版本号更新為 2.0 ),指令如下:

peerchaincode install -n mycc -v 2.0 –p \

github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02

結束語

本連載介紹了如何建構多節點Fabric叢集的基本方法。為說明原理,安裝配置過程是全手動的,是以比較繁瑣。今後我們将介紹如何使用容器平台K8S等部署Fabric,敬請關注。

文章來自于微信公衆号“亨利筆記”,已獲得作者轉載授權。

作者簡介

張海甯(Henry Zhang),現任VMware中國研發中心雲原生應用首席架構師, Harbor企業級容器Registry開源項目負責人,Cloud Foundry中國社群最早的技術布道師之一,《區塊鍊技術指南》作者之一。目前着重關注區塊鍊、容器和雲計算等領域的研究和開發工作。

陳家豪,廣州大學密碼學研究所學生,現為VMware公司區塊鍊項目實習生,熟悉超級賬本、以太坊和比特币等區塊鍊項目等開發工作。

更多區塊鍊投稿請發送郵箱:[email protected]

繼續閱讀