之前写了手动部署Fabric中的first-network网络。但是Fabric网络都是运行在多台机器上的。本文将会详细说明Fabric如何完成solo模式下的多机部署。在看这篇文章之前建议读者自己动手运行过first-network
网络,并且默认读者熟悉Linux基本的命令。然后大致看过整篇文章后,再按照此篇文章搭建。
参考:
系统:ubuntu 18.04、Fabric版本:v1.4.0。
本次Solo模式的搭建共用到了5台虚拟机,都是由最初的一台虚拟机复制来的 。这5台电脑域名和担任的角色如下所示:
域名 | 角色 | ip地址 |
---|---|---|
orderer.example.com | orderer | 10.xx.xx.201 |
peer0.org1.example.com | Org1 | 10.xx.xx.202 |
peer1.org1.example.com | Org1 | 10.xx.xx.203 |
peer0.org2.example.com | Org2 | 10.xx.xx.204 |
peer1.org2.example.com | Org2 | 10.xx.xx.205 |
first-cluster
文件,并生成证书# 当前目录位置为 fabric-samples
# 复制first-network目录,并改名为first-cluster
cp -r first-network first-cluster
# 进入 first-cluster
cd first-cluster
# 删除不必要的文件,最后firstcluster目录中的文件为
├── base
│ ├── docker-compose-base.yaml
│ └── peer-base.yaml
├── channel-artifacts
├── configtx.yaml
├── crypto-config.yaml
├── docker-compose-cli.yaml
├── docker-compose-couch.yaml
生成公私钥和MSP证书
# 当前目录位置为first-cluster
#step1 生成证书文件
../bin/cryptogen generate --config=./crypto-config.yaml
#step2 生成创世区块
../bin/configtxgen -profile TwoOrgsOrdererGenesis -channelID byfn-sys-channel -outputBlock ./channel-artifacts/genesis.block
#step3 生成通道配置文件 其中通道名mychannel可以修改为自己的
../bin/configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID mychannel
#step4 生成锚节点配置文件
#========Org1=============
../bin/configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID mychannel -asOrg Org1MSP
##========Org2=============
../bin/configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org2MSPanchors.tx -channelID mychannel -asOrg Org2MSP
修改base/docker-compose-base.yaml
文件
将所有peer节点的端口映射都改为相同的,之前不同是因为所有的peer节点都在一台电脑运行,而现在分别在多台电脑运行的话,我们就可以改为相同的。
所有peer节点端口映射,如图:
# 当前目录位置为first-cluster
# 复制docker-compose-cli.yaml 并重命名为docker-compose-orderer.yaml
cp docker-compose-cli.yaml docker-compose-orderer.yaml
# 用vim打开docker-compose-orderer.yaml
vim docker-compose-orderer.yaml
将docker-compose-orderer.yaml
文件中与orderer节点无关的内容都删除,最后留下的内容为:
peer0.org1
为例,创建和修改peer节点的配置文件# 当前目录位置为first-cluster
# 复制docker-compose-cli.yaml 并重命名为docker-compose-p0o1.yaml
cp docker-compose-cli.yaml docker-compose-p0o1.yaml
# 用vim打开docker-compose-p0o1.yaml
vim docker-compose-p0o1.yaml
peer节点的修改稍微要麻烦一些,首先将其他节点的配置删除,只留下peer0.org1
和cli
然后在peer0.org1
中添加extra_hosts
, 添加后代码如图:
修改cli
配置
去掉FABRIC_LOGGING_SPEC=DEBUG
这一行的注释
将command: /bin/bash
这一行删掉或注释掉, 这一步我在其他的节点没有做,但是也不影响整个网络的运行。留个坑吧,等我什么时候知道了这一步作用,再回来改。
删除多余的depends_on
,只留下peer0.org1
添加extra_hosts
还有修改cli
环境变量,因cli
环境默认为peer0.org1
,所以除了此节点不用修改之外,其他节点都需要修改默认环境变量,如果读者不会的话,这一步可以不做,下面会有解决办法。
最后peer0.org1
的配置文件如图所示:
peer1.org1
:修改过程基本和peer0.org1
一样,但是因为它不是锚节点,所以要添加上锚节点的信息,才能和其他组织(本文特指Org2)通信。添加的位置是在peer1.org1
的extra_hosts
中加入peer0.org1
节点的信息。如图:
cli
部分,建议将所有的peer0.org1
修改为peer1.org1
,这样进入cli中就会默认为peer1.org1
环境。
peer0.org2
和peer1.org2
的修改步骤和上述peer0.org1,peer1.org1
的一样:删除无关节点、去掉FABRIC_LOGGING_SPEC=DEBUG
、添加command: /bin/bash
注释、添加extra_hosts
,替换cli中的环境变量(这一步如果不会的话可以不做)
最后一共创建了5个配置文件,分别是
配置文件名称 | 所属节点 |
---|---|
docker-compose-orderer.yaml | orderer节点 |
docker-compose-p0o1.yaml | peer0.org1节点 |
ocker-compose-p1o1.yaml | peer1.org1节点 |
ocker-compose-p0o2.yaml | peer0.org2节点 |
ocker-compose-p0o2.yaml | peer1.org2节点 |
然后,将first-cluster
文件,复制到其他虚拟机的fabric-samples
目录下,操作如下
# 当前在first-cluster目录下
# 复制到某个虚拟机
scp -r first/ [peer0.org1节点主机名]@10.xx.xx.201:/home/[用户名]/xx/xx/xx/
如图:
除了第三个红框遮住的是ip地址,其他的都是主机名称。
**注意:**第一次不建议将5个配置文件都写出来,可以先将order节点配置文件创建出来,然后将first-cluster
目录复制到其他peer节点的主机上,复制完成之后在peer节点的主机中再创建peer节点配置文件也可以。
在搭建之前,要检查是否有上次搭建留下来的的docker镜像,或者docker缓存,如果有的话,就删除它们。
# 查看docker镜像
docker ps -a
# 删除之前的所有docker镜像,由于这些主机只用来搭建Fabric,所以下面的命令会将所有的docker镜像删除,请谨慎使用。
dokcer rm $(docker ps -aq)
# 删除之前docker缓存
docker volume prune
若在搭建过程中出现了失败的情况,需要重新搭建的话。每次重新搭建前都运行一下上述的命令,特别是删除docker镜像和docker缓存的命令,不然搭建过程中很可能会报错。
# 当前位置在orderer节点的 first-cluster目录下
docker-compose -f docker-compose-orderer.yaml up -d
# 若要关闭orderer节点, 则命令如下
docker-compose -f docker-compose-orderer.yaml down
启动orderer节点后,输入docker ps
查看正在运行的镜像
如出现上述3个虚框中的内容,代表启动成功。
首先远程控制peer0.org1
主机,然后进入之前传输到peer节点的first-cluster
目录中。
# 启动peer0.org1
docker-compose -f docker-compose-p0o1.yaml up -d
输入 docker ps
查看正在运行的docker容器,如图:
# 进入 cli中
docker exec -it cli bahs
# 创建channel
export ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
peer channel create -o orderer.example.com:7050 -c mychannel -f ./channel-artifacts/channel.tx --tls true --cafile $ORDERER_CA
创建成功如图
然后可以观察到,本目录下出现了mychannel.block
文件,如图
# CLI默认连接的是peer0.org1,那么我们要将这个Peer加入mychannel就很简单,不需要修改环境变量
peer channel join -b mychannel.block
运行成功如图:
因为peer0.org1
是Org1组织的锚节点,所以需要向orderer
节点更新锚节点。
# 更新锚节点
peer channel update -o orderer.example.com:7050 -c mychannel -f ./channel-artifacts/Org1MSPanchors.tx --tls true --cafile $ORDERER_CA
更新成功如图
将其他节点加入网络很简单,只需要在peer0.org1
节点的cli
中修改环境变量,将cli
指向其他节点就行了。
再将其他节点加入网络之前,记得要在其他主机上启动该节点,不然会失败。需要注意的是启动后无法再其他节点的cli
中直接加入网络,因为其他节点cli
中没有mychannel.block
这个文件,所以需要通过再peer0.org1
节点修改环境变量指向其他节点,然后将其他节点加入网络。当然也可以将mychannel.block
文件传输到其他节点,但那样太麻烦了。
将peer1.org1
加入网络
# 修改环境变量为 peer1.org1
CORE_PEER_LOCALMSPID="Org1MSP"
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/[email protected]/msp
CORE_PEER_ADDRESS=peer1.org1.example.com:7051
# 加入通道
peer channel join -b mychannel.block
将peer0.org2
加入网络
# 修改环境变量为 peer0.org2
CORE_PEER_LOCALMSPID="Org2MSP"
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
CORE_PEER_ADDRESS=peer0.org2.example.com:7051
# 因为peer0.org2为锚节点,所以需要更新
peer channel update -o orderer.example.com:7050 -c mychannel -f ./channel-artifacts/Org2MSPanchors.tx --tls true --cafile $ORDERER_CA
# 加入通道
peer channel join -b mychannel.block
将peer1.org2
加入网络
# 修改环境变量为 peer1.org2
CORE_PEER_LOCALMSPID="Org2MSP"
CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer1.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
CORE_PEER_ADDRESS=peer1.org2.example.com:7051
# 加入通道
peer channel join -b mychannel.block
修改peer0.org1
中cli
的环境变量为peer0.org1
CORE_PEER_LOCALMSPID="Org1MSP"
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/[email protected]/msp
CORE_PEER_ADDRESS=peer0.org1.example.com:7051
安装链码
peer chaincode install -n mycc -v 1.0 -p github.com/chaincode/chaincode_example02/go/
安装成功如图
实例化链码
peer chaincode instantiate -o orderer.example.com:7050 --tls true --cafile $ORDERER_CA -C mychannel -n mycc -v 1.0 -c '{"Args":["init","a","100","b","200"]}' -P "OR('Org1MSP.member','Org2MSP.member')"
实例化成功如图
查询账户a的金额,因为实例化链码时我们共初始化了两个账户:a、b,并且设置金额分别是100、200。所以如果查询账户a的金额,应该返回100。
peer chaincode query -C mychannel -n mycc -c '{"Args":["query","a"]}'
返回如图:
如果想在其他节点安装链码可以,可以通过修改peer0.org1
中cli
的环境变量实现,而我之前在启动其他节点时已经将配置文件中的环境变量修改过了,所以我选择直接远程其他节点,然后进入其他节点的cli
安装链码。
如果有读者不会修改配置文件的话,可以1)先远程其他节点;2)进入其他节点的cli
;3)修改环境变量;4)安装链码,或者1)修改peer0.org1
中cli
的环境变量,让其指向其他节点;2)安装链码。
以 peer0.org2
为例
# 远程连接到peer0.org2的主机上
# 进入 cli
docker exec -it cli bash
# 安装链码
peer chaincode install -n mycc -v 1.0 -p github.com/chaincode/chaincode_example02/go/
# 查询a的值
peer chaincode query -C mychannel -n mycc -c '{"Args":["query","a"]}'
**注意:**链码实例化时会生成一个运行链码的容器,链码就这这个容器中运行。链码不管在那个peer中被实例化,都只能被实例化一次,因为此链码已经在peer0.org1
中被实例化过了,所以其他节点安装过链码之后就不用再实例化此链码了。但是在第一次查询的过程中,等待时间可能会有些长,请耐心等待。
另外,如果不知道自己当前cli
是那个peer节点的环境可以输入
echo $CORE_PEER_LOCALMSPID
echo $CORE_PEER_ADDRESS
如果发现有错的话,重新修改一下环境变量就没问题了。
到这一步默认其他节点都已经安装好链码了。
首先切换到peer0.org1
节点的cli
中,然后
# 从a向b转10
peer chaincode invoke -o orderer.example.com:7050 --tls true --cafile $ORDERER_CA -C mychannel -n mycc -c '{"Args":["invoke","a","b","10"]}'
返回 successful:
然后切换到其他节点,查询a的余额
# 此次切换到 peer1.org2的cli中
# 查询a的余额
peer chaincode query -C mychannel -n mycc -c '{"Args":["query","a"]}'
返回 90:
之后远程peer1.org1
# 当前位置为 peer1.org1的cli中
# 从b向a转50
peer chaincode invoke -o orderer.example.com:7050 --tls true --cafile $ORDERER_CA -C mychannel -n mycc -c '{"Args":["invoke","b","a","50"]}'
最后远程peer0.org2
# 当前位置 为peer0.org2的cli
# 查询b的值
peer chaincode query -C mychannel -n mycc -c '{"Args":["query","b"]}'
# 查询a的值
peer chaincode query -C mychannel -n mycc -c '{"Args":["query","a"]}'
b返回160,a返回140
最后如果你觉得我写的还可以的话,请鼓励一下下吧!!!
我的个人博客:http://39.99.158.115:8090/categories/blockchain
支付宝 | 微信 |
---|---|