Fabric 1.0环境

1.环境准备
我们要部署的是1Peer+1Orderer的架构,需要准备2台机器,可以开2台虚拟机,也可以购买2台云服务器。不管怎么样,我们需要这2台机器网络能够互通,而且安装相同的系统,我用的是CentOS7.1 (docker要求内核在3.10以上,6.5内核是2.6需要升级,查看升级教程)、内核3.10.0-693.el7.x86_64。为了方便,我先启用1台虚拟机把环境搭建好,然后再复制出1台。这里是我Server主机名(角色)和IP:

orderer.example.com 192.168.1.9
peer0.org1.example.com 192.168.1.10

接下来我们软件环境,包括Go、Docker、Docker-Compose:

1.1 Go的安装

具体涉及到的命令包括:

1
2
yum install epel -y#安装 EPEL 源
yum install go -y#yum 安装 Golang

接下来编辑当前用户的环境变量:

1
vi /etc/profile

添加以下内容:

1
2
3
export GOROOT=/usr/local/go
export GOPATH=/usr/local/gopath
export PATH=$PATH:$GOPATH:$GOROOT/bin

编辑保存并退出vi后,把这些环境载入:

1
source /etc/profile

查看go版本信息

1
2
3
go version

go version go1.9 linux/amd64

1.2 Docker安装

详情看CentOS docker yum 源配置方法

1
2
3
4
5
6
7
yum list docker-engine.x86_64 --showduplicates |sort -r#获取可以安装的docker版本
yum -y install docker-engine-1.9.1
service docker restart

docker --version

Docker version 18.02.0-ce, build fc4de44

1.3 Docker-Compose的安装

Docker-compose是支持通过模板脚本批量创建Docker容器的一个组件。在安装Docker-Compose之前,需要安装Python-pip,运行脚本:

1
2
yum install python-pip#安装pip
pip install --upgrade pip#安装好的pip进行升级

安装完成后,接下来安装Docker-compose:

pip install docker-compose>=1.8.0#推荐为 1.8.0以上版本,防止和docker不匹配

1.4 Fabric源码下载

我们可以使用Git命令下载源码:

1
2
3
4
mkdir -p /usr/local/gopath/src/github.com/hyperledger/
cd /usr/local/gopath/src/github.com/hyperledger/

git clone https://github.com/hyperledger/fabric.git

由于Fabric一直在更新,需要切换到v1.0.0版本的源码即可:

1
2
3
cd /usr/local/gopath/src/github.com/hyperledger/fabric
git branch -a
git checkout v1.0.0

1.5 Fabric Docker镜像的下载

设置了Docker Hub镜像地址,可以下载很快。官方文件提供了批量下载的脚本,直接运行:

1
2
cd /usr/local/gopath/src/github.com/hyperledger//fabric/examples/e2e_cli/
source download-dockerimages.sh -c x86_64-1.0.0 -f x86_64-1.0.0

或者手动下载,下载完成修改所有的镜像tag为latest

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
docker pull hyperledger/fabric-orderer:x86_64-1.0.0
&&docker pull hyperledger/fabric-peer:x86_64-1.0.0
&&docker pull hyperledger/fabric-zookeeper:x86_64-1.0.0
&&docker pull hyperledger/fabric-couchdb:x86_64-1.0.0
&&docker pull hyperledger/fabric-kafka:x86_64-1.0.0
&&docker pull hyperledger/fabric-ca:x86_64-1.0.0
&&docker pull hyperledger/fabric-ccenv:x86_64-1.0.0
&&docker pull hyperledger/fabric-javaenv:x86_64-1.0.0

&&docker tag hyperledger/fabric-peer:x86_64-1.0.0 hyperledger/fabric-peer:latest
&&docker tag hyperledger/fabric-zookeeper:x86_64-1.0.0 hyperledger/fabric-zookeeper:latest
&&docker tag hyperledger/fabric-couchdb:x86_64-1.0.0 hyperledger/fabric-couchdb:latest
&&docker tag hyperledger/fabric-kafka:x86_64-1.0.0 hyperledger/fabric-kafka:latest
&&docker tag hyperledger/fabric-ca:x86_64-1.0.0 hyperledger/fabric-ca:latest
&&docker tag hyperledger/fabric-ccenv:x86_64-1.0.0 hyperledger/fabric-ccenv:latest
&&docker tag hyperledger/fabric-javaenv:x86_64-1.0.0 hyperledger/fabric-javaenv:latest

2.docker-compose 配置文件准备
在Fabric的源码中,提供了单机部署4Peer+1Orderer的示例,在Example/e2e_cli文件夹中。我们可以在其中一台机器上运行单机的Fabric实例,确认无误后,在该机器上,生成公私钥,修改该机器中的Docker-compose配置文件,然后把这些文件分发给另外1台机器。我们就以orderer.example.com这台机器为例

2.1单机运行4+1 Fabric实例,确保脚本和镜像正常

我们先进入这个文件夹,然后直接运行

1
2
cd /usr/local/gopath/src/github.com/hyperledger//fabric/examples/e2e_cli/
./network_setup.sh up

这个命令可以在本机启动4+1的Fabric网络并且进行测试,跑Example02这个ChainCode。我们可以看到每一步的操作,最后确认单机没有问题。确认我们的镜像和脚本都是正常的,我们就可以关闭Fabric网络,继续我们的多机Fabric网络设置工作。:

1
2
3
4
5
6
7
8
9
10

...
Exiting.....
===================== Query on chaincode on PEER0 on channel 'mychannel' is successful
=====================
===================== All GOOD, End-2-End execution completed
=====================

#执行完成后,关闭Fabric命令
./network_setup.sh down

2.2生成公私钥、证书、创世区块等

公私钥和证书是用于Server和Server之间的安全通信,另外要创建Channel并让其他节点加入Channel就需要创世区块,这些必备文件都可以一个命令生成,官方已经给出了脚本:

1
./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配置如下:

1
2
3
4
5
6
7
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:192.168.1.9"

同样,cli也需要能够和各个节点通讯,所以cli下面也需要添加extra_hosts设置,去掉无效的依赖,并且去掉command这一行,因为我们是每个peer都会有个对应的客户端,也就是cli,所以我只需要去手动执行一次命令,而不是自动运行。修改后的cli配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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
#command: /bin/bash -c './scripts/script.sh ${CHANNEL_NAME}; sleep $TIMEOUT'
depends_on:
- peer0.org1.example.com
extra_hosts:
- "orderer.example.com:192.168.1.9"
- "peer0.org1.example.com:192.168.1.10"
#- "peer1.org1.example.com:192.168.1.10"
#- "peer0.org2.example.com:192.168.1.10"
#- "peer1.org2.example.com:192.168.1.10"

2.4设置orderer节点的docker-compose文件

1
cp docker-compose-cli.yaml docker-compose-orderer.yaml

orderer服务器上我们只需要保留order设置,其他peer和cli设置都可以删除。orderer可以不设置extra_hosts。

2.5分发配置文件

前面4步的操作,我们都是在orderer.example.com上完成的,接下来我们需要将这些文件分发到另外1台服务器上。Linux之间的文件传输,我们可以使用scp命令。

我先登录peer0.org1.example.com,将本地的e2e_cli文件夹删除:

rm e2e_cli –R
然后再登录到orderer服务器上,退回到examples文件夹,因为这样可以方便的把其下的e2e_cli文件夹整个传到peer0服务器上。

scp -r e2e_cli root@192.168.1.10:/home/fabric/go/src/github.com/hyperledger/fabric/examples/
我们在前面配置的就是peer0.org1.example.com上的节点,所以复制过来后不需要做任何修改。

3.启动Fabric

3.1启动orderer

让我们首先来启动orderer节点,在orderer服务器上运行:

1
2
3
4
5
6
docker-compose -f docker-compose-orderer.yaml up –d#运行完毕后我们可以使用docker ps看到运行了一个名字为orderer.example.com的节点。

[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
959c37406935 hyperledger/fabric-tools "/bin/bash" 26 hours ago Up 26 hours cli
c6a168eeee78 hyperledger/fabric-orderer "orderer" 26 hours ago Up 26 hours 0.0.0.0:7050->7050/tcp orderer.example.com

3.2启动peer

然后我们切换到peer0.org1.example.com服务器,启动本服务器的peer节点和cli,命令为:

1
2
3
4
5
6
docker-compose -f docker-compose-peer.yaml up –d#运行完毕后我们使用docker ps应该可以看到2个正在运行的容器。

[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8042dfd42881 hyperledger/fabric-tools "/bin/bash" 27 hours ago Up 27 hours cli
b143a5deabb4 hyperledger/fabric-peer "peer node start" 27 hours ago Up 27 hours 0.0.0.0:7051-7053->7051-7053/tcp peer0.org1.example.com

现在我们整个Fabric1+1服务器网络已经成型,接下来是创建channel和运行ChainCode。

====================================================================================

这个时候建议系统快照,后面环境出问题重新恢复到这个地方,方便再次使用单步执行启动fabric网络

====================================================================================

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内运行如下命令:

#需要注释掉里面关于别的三个peer的操作,script.sh脚本里面createChannel,joinChannel,updateAnchorPeers,installChaincode只能执行一次
./scripts/script.sh mychannel

那么该脚本就可以一步一步的完成创建通道,将其他节点加入通道,更新锚节点,创建ChainCode,初始化账户,查询,转账,再次查询等链上代码的各个操作都可以自动化实现。直到最后,系统提示:

===================== All GOOD, End-2-End execution completed =====================

说明我们的1+1的Fabric多级部署成功了。我们现在是在peer0.org1.example.com的cli容器内,我们也可以切换到peer0.org2.example.com服务器,运行docker ps命令,可以看到本来是2个容器的,现在已经变成了3个容器,因为ChainCode会创建一个容器:

1
2
3
4
5
[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
25286d800de8 dev-peer0.org1.example.com-mycc-1.1 "chaincode -peer.add…" 25 hours ago Up 25 hours dev-peer0.org1.example.com-mycc-1.1
8042dfd42881 hyperledger/fabric-tools "/bin/bash" 27 hours ago Up 27 hours cli
b143a5deabb4 hyperledger/fabric-peer "peer node start" 27 hours ago Up 27 hours 0.0.0.0:7051-7053->7051-7053/tcp peer0.org1.example.com

=====================然而可能并不好使!!!自动脚本还是会出问题的,下面看手动脚本=====================
1.
出问题后首先要关闭清空Fabric,重新执行一般不行就只能删除容器重新下载

#关闭peer的fabric网络
docker-compose -f docker-compose-peer.yaml down

#清空编译文件,会删除部分容器
make clean

#删除所有容器
docker rm -f $(docker ps -aq)

运行完成后不要忘记清空ledger文件夹/var/hyperledger/:
rm -rf /var/hyperledger/*

2.
查看证书文件夹不在重新执行,保证peer和orderer一套文件

1
2
./generateCfgTrx.sh mychannel
source download-dockerimages.sh -c x86_64-1.0.0 -f x86_64-1.0.0

3.
初始化完环境后,重新启动

4.
开始单步执行createChannel,joinChannel,updateAnchorPeers,installChaincode只能执行一次,出现错误提示重复的步骤,可以跳过继续下一步

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

#进入cli
docker exec -it cli bash

#创建channel
peer channel create -o orderer.example.com:7050 -c mychannel -f ./channel-artifacts/channel.tx --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

#完成后会在/opt/gopath/src/github.com/hyperledger/fabric/peer生成mychannel.block
#peer加入channel
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代码安装到每一个peer,提示已存在可以修改 -v后面的版本号
peer chaincode install -n mycc -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02

#peer上实例化chaincode,只需要在一个peer实例化,别的peer在需要时会同步
peer chaincode instantiate -o orderer.example.com:7050 -C mychannel -n mycc -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 -c '{"Args":["init","a", "100", "b","200"]}' -P "OR ('Org0MSP.member','Org1MSP.member')" --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

==========================================

#docker ps -a查看运行中的容器,如果chaincode启动成功,则显示

1
2
3
4
5
6
7
8
9
10
11
12
13
docker ps 

[root@localhost e2e_cli]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
25286d800de8 dev-peer0.org1.example.com-mycc-1.1 "chaincode -peer.add…" 26 hours ago Up 26 hours dev-peer0.org1.example.com-mycc-1.1
8042dfd42881 hyperledger/fabric-tools "/bin/bash" 28 hours ago Up 28 hours cli
b143a5deabb4 hyperledger/fabric-peer "peer node start" 28 hours ago Up 28 hours 0.0.0.0:7051-7053->7051-7053/tcp peer0.org1.example.com

#调用chaincode从“a”转移“10”给“b“
peer chaincode invoke -o orderer.example.com:7050 -C mychannel -n mycc -c '{"Args":["invoke","a","b","10"]}'

#返回值应是 90
peer chaincode query -o orderer.example.com:7050 -C mychannel -n mycc -c '{"Args":["query","a"]}'

4.总结
我在Fabric多机部署的过程中还是遇到了不少坑,查看了好多文档最终才实现了1+1多机部署。其中与单机部署最大的不同的地方就是在单机部署的时候,我们是在同一个docker网络中,所以相互之间通过主机名通讯很容易,而在多机环境中,就需要额外设置DNS或者就是通过extra_hosts参数,设置容器中的hosts文件。而且不能一股脑的就跟cli一样把5台机器的域名IP配置到peer中,那样会报错的,所以只需要设置需要的即可。

修改hosts方法

1
2
3
4
5
6
7
8
9
#在hosts添加域名映射

vi /etc/hosts
192.168.1.9 orderer.example.com

#修改docker-compose-cli.yaml

volumes:
-/etc/hosts:/etc/hosts

官方文档链接,可以对比下执行命令,不同的源码部分命令可能不一样

热评文章