手动部署单机单节点
(我的博客即将入驻“云栖社区”,诚邀技术同仁一同入驻。)
之前发布过官方的e2e部署方案,由于环境或是访问权限等各种问题,还是有相当一部分码友无法成功跑起来,故此,本章将来一次纯手动操作的部署。
主要需要的步骤如下:
1:环境整理
2:环境部署
3:源码安装
4:生成证书文件
5:orderer节点处理
6:peer节点处理
7:channel创建加盟
8:chaincode安装部署实例化、测试
本次不再分章,一章写完。
环境整理
这一步并非必须,但鉴于docker容器的实际情况,理论上linux内核需要在3.10及以上。有朋友在3.10上跑通过,具体是什么内核版本没详细去确认,为了顺利起见,请首先升级linux内核到4.x,按照CentOS 7. × 系统及内核升级指南最终通过如下命令来查询版本信息:
uname -a
结果应如下图所示:
除了上述操作外,相关依赖包若无强制性要求,可全部升级到最新版,执行如下命令:
yum upgrade
环境部署
在Hyperledger Fabric 1.0 从零开始(二)——环境构建(公网)和Hyperledger Fabric 1.0 从零开始(三)——环境构建(内网/准离线)两篇文章中,个人感觉已经写的很详尽了,这里就不再赘述,最后给一个我新搭建的环境截图,在写这篇文章的时候,docker和go都有了版本升级,所以我都应用的最新版本,实际版本图如下:
源码安装
截止今日Fabric已经发布了1.1release版,由于时间问题,原本打算整理的版本升级list会延后发布。这里为了顺应需求,也就拿1.1的版本来做部署,具体下载地址hyperledger/fabric v1.1.0。
请自行通过上述地址download最新版本到本地,或按照Hyperledger Fabric 1.0 从零开始(四)——Fabric源码及镜像文件处理中的方案进行安装也一样。
源码下载到本地后,上传至/home或/data或其它数据存储(看着顺眼)的目录中,稍后补图看结果。
这里说明下,fabric的安装目录并非一定要在哪哪哪,但在yaml中的工作路径和映射路径一定不能写错,否则会导致fabric中shim的api各种调用失败(原因如下图),所以还是按照官方的习惯部署会妥当点。
根据上述,我选择/home作为根目录,所以我的fabric会安装在/home/docker/github.com/hyperledger/fabric这个路径下,这个路径中的docker目录可以无视,看上图并记住“github.com/hyperledger/fabric”这个才是关键,对于新手来说不要动了,老鸟随意。
最终我的目录结构图如下:
你们会发现这里多了一个aberic的目录,这是我自己新建的项目目录,有javaweb开发经验的朋友应该能明白如何在tomcat的webapp中部署自己的项目,其实也类似,方便我自己管理和维护。
生成证书文件
这一步之前的文章也发过,Hyperledger Fabric 1.0 从零开始(五)——运行测试e2e,但总还是有码友看的不仔细或把这一整章给略过了,群里不时还会有码友问这些操作。
为了确保完整性,这里就再次重复一遍操作,在上述链接章节中提到了三种获取生成证书文件必备的二进制文件方案,我们使用官网提供的离线下载网址,找到我们本章计划操作的1.1的版本信息,可以得到最终的离线下载文件地址,下载该文件到本地。
根据官网的介绍,解压后会得到一个bin文件夹,将其解压至/home/docker/github.com/hyperledger/fabric/aberic目录下。
接下来,我们继续参考Hyperledger Fabric 1.0 从零开始(八)——Fabric多节点集群生产部署中写到的方案来生成必须的证书文件。
这里说下,在本章操作中使用的configtx.yaml是用的1.0版本的,虽然我们是在1.1的环境中进行部署,相对而言,个人感觉1.1的e2e demo把入门门槛进一步拉高了,导致很多人运行起来很费劲,始终无法跑通。与之配套的crypto-config.yaml也采用1.0版本提供的demo。相关文件自行点入下载或copy。
运行二进制文件需要在命令行中指定路径,故此我的路径安排如下图所示:
接下来我们就可以开始生成所需证书文件了,我们执行相关命令需要指定执行文件的路径,故此,为了方便,直接进入aberic项目目录下进行操作,随后执行如下命令生成我们项目所需文件:
./bin/cryptogen generate --config=./crypto-config.yaml
效果示图如下:
可能各位在执行过程中会报一些没有权限的异常,这些我在Hyperledger Fabric 1.0 从零开始(八)——Fabric多节点集群生产部署已经提到过了,就不赘述了。
上述命令生成的证书文件在/home/docker/github.com/hyperledger/fabric/aberic/crypto-config目录下,也就是说会自动创建一个crypto-config文件夹,示图如下:
接下来,要根据configtx.yaml来生成创世区块,具体命令及综合截图效果如下:
./bin/configtxgen -profile TwoOrgsOrdererGenesis -outputBlock ./channel-artifacts/genesis.block
如上图所示,出现了一个小问题,提示没有该文件或文件夹,channel-artifacts是一个文件夹,故此,我们在/home/docker/github.com/hyperledger/fabric/aberic目录下手动创建一个channel-artifacts文件夹,随后再次运行上述命令,,具体命令及综合截图效果如下:
最终会在/home/docker/github.com/hyperledger/fabric/aberic/channel-artifacts目录下创建出我们指定名称的创世区块,ftp结果视图如下:
创世区块是为了orderer启动时用到的,peer在启动后需要创建的channel配置文件在这里也一并生成,执行具体命令和综合结果示图如下:
./bin/configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/mychannel.tx -channelID mychannel
该命令是生成了一个channelID为mychannel的tx文件(文件名称看各位心情来取),通过该文件,peer可以执行channel的创建工作,后面会提到。
orderer节点处理
单机多节点部署,至少本章采用的共识模式的solo,而非kafka,如果开始考虑kafka做集群的话,相信本章的内容已经不再适合你了,本章偏基础。
首先需要编写一份docker-orderer.yaml文件,源码如下:
version: '2' services: orderer.example.com:
container_name: orderer.example.com
image: hyperledger/fabric-orderer
environment:
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=aberic_default
# - ORDERER_GENERAL_LOGLEVEL=error
- ORDERER_GENERAL_LOGLEVEL=debug
- ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
- ORDERER_GENERAL_LISTENPORT=7050
#- ORDERER_GENERAL_GENESISPROFILE=AntiMothOrdererGenesis
- ORDERER_GENERAL_GENESISMETHOD=file
- ORDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/orderer.genesis.block
- ORDERER_GENERAL_LOCALMSPID=OrdererMSP
- ORDERER_GENERAL_LOCALMSPDIR=/var/hyperledger/orderer/msp
#- ORDERER_GENERAL_LEDGERTYPE=ram
#- ORDERER_GENERAL_LEDGERTYPE=file
# enabled TLS
- ORDERER_GENERAL_TLS_ENABLED=false
- ORDERER_GENERAL_TLS_PRIVATEKEY=/var/hyperledger/orderer/tls/server.key
- ORDERER_GENERAL_TLS_CERTIFICATE=/var/hyperledger/orderer/tls/server.crt
- ORDERER_GENERAL_TLS_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt]
working_dir: /opt/gopath/src/github.com/hyperledger/fabric
command: orderer
volumes:
- ./channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block
- ./crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/msp:/var/hyperledger/orderer/msp
- ./crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/:/var/hyperledger/orderer/tls
networks:
default:
aliases:
- aberic
ports:
- 7050:7050
peer节点处理
有了orderer启动文件,我们还需要docker-peer.yaml启动文件,orderer和peer的启动yaml文件名称随意看心情,源码如下:
version: '2' services: couchdb:
container_name: couchdb
image: hyperledger/fabric-couchdb
# Comment/Uncomment the port mapping if you want to hide/expose the CouchDB service,
# for example map it to utilize Fauxton User Interface in dev environments.
ports:
- "5984:5984" ca:
container_name: ca
image: hyperledger/fabric-ca
environment:
- FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server
- FABRIC_CA_SERVER_CA_NAME=ca
- FABRIC_CA_SERVER_TLS_ENABLED=false
- FABRIC_CA_SERVER_TLS_CERTFILE=/etc/hyperledger/fabric-ca-server-config/ca.org1.example.com-cert.pem
- FABRIC_CA_SERVER_TLS_KEYFILE=/etc/hyperledger/fabric-ca-server-config/95e05e630b6fd2f16b6367823c3a1295cc86e96431dd87b1376bea1d6120eb90_sk
ports:
- "7054:7054"
command: sh -c 'fabric-ca-server start --ca.certfile /etc/hyperledger/fabric-ca-server-config/ca.org1.example.com-cert.pem --ca.keyfile /etc/hyperledger/fabric-ca-server-config/95e05e630b6fd2f16b6367823c3a1295cc86e96431dd87b1376bea1d6120eb90_sk -b admin:adminpw -d'
volumes:
- ./crypto-config/peerOrganizations/org1.example.com/ca/:/etc/hyperledger/fabric-ca-server-config peer0.org1.example.com:
container_name: peer0.org1.example.com
image: hyperledger/fabric-peer
environment:
- CORE_LEDGER_STATE_STATEDATABASE=CouchDB
- CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb:5984 - CORE_PEER_ID=peer0.org1.example.com
- CORE_PEER_NETWORKID=aberic
- CORE_PEER_ADDRESS=peer0.org1.example.com:7051
- CORE_PEER_CHAINCODELISTENADDRESS=peer0.org1.example.com:7052
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.example.com:7051
- CORE_PEER_LOCALMSPID=Org1MSP - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
# the following setting starts chaincode containers on the same
# bridge network as the peers
# https://docs.docker.com/compose/networking/
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=aberic
# - CORE_LOGGING_LEVEL=ERROR
- CORE_LOGGING_LEVEL=DEBUG
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=aberic_default
- CORE_PEER_GOSSIP_SKIPHANDSHAKE=true
- CORE_PEER_GOSSIP_USELEADERELECTION=true
- CORE_PEER_GOSSIP_ORGLEADER=false
- CORE_PEER_PROFILE_ENABLED=false
- CORE_PEER_TLS_ENABLED=false
- CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt
- CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key
- CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt
volumes:
- /var/run/:/host/var/run/
- ./crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp:/etc/hyperledger/fabric/msp
- ./crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls:/etc/hyperledger/fabric/tls
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
command: peer node start
ports:
- 7051:7051
- 7052:7052
- 7053:7053
depends_on:
- couchdb
networks:
default:
aliases:
- aberic 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=ERROR
- CORE_LOGGING_LEVEL=DEBUG
- CORE_PEER_ID=cli
- CORE_PEER_ADDRESS=peer0.org1.example.com:7051
- CORE_PEER_LOCALMSPID=Org1MSP
- CORE_PEER_TLS_ENABLED=false
- 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/aberic/chaincode/go
- ./crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/
- ./channel-artifacts:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts
depends_on:
- peer0.org1.example.com
peer的这份启动文件是目前所写的最全文件,里面有cli客户端、couchdb插件以及ca插件。
有几个地方需要注意修改下,首先是ca部分有两处,一处是FABRIC_CA_SERVER_TLS_KEYFILE,另一处是command中最后一部分,这两处的_sk文件名称需要替换成之前生成的证书文件名称,其实这里的主要目的是加载ca并生成ca用户。
这个peer启动文件启动的是peer0.org1.example.com节点,所以对应的ca证书文件在peer0.org1.example.com下可以找到,具体路径是/home/docker/github.com/hyperledger/fabric/aberic/crypto-config/peerOrganizations/org1.example.com/ca
目标视图如下:
最后将docker-peer.yaml中两处的d8785a9dbc94f677d3e1e6aeb3a6222ee6579fe751204ac1b70094e1d3f0fe06_sk替换成95e05e630b6fd2f16b6367823c3a1295cc86e96431dd87b1376bea1d6120eb90_sk即可。
切记这里的替换是替换各位自己生成的,我在这只是一个demo说明,以免到时无法跑通!!!
在cli客户端配置中我们指定了智能合约的部署路径,故此,我们在aberic目录下创建与之对应的chaincode文件夹,并在该文件夹下创建go文件夹,表示合约目录下以go语言为基础的合约目录。
最终效果截图如下:
如上图,我把官方demo中的chaincode_example02示例也一并上传到go目录下,稍后会以该合约为基础进行测试。
接下来将编写好的docker-orderer.yaml和docker-peer.yaml文件上传至aberic目录下,最终结果示图如下:
运行如下命令启动orderer和peer,按照顺序应该先启动排序服务,命令及综合视图如下:
docker-compose -f docker-orderer.yaml up -d
docker-compose -f docker-peer.yaml up -d
上图有点问题,可能是ssh的问题,导致peer启动的命令被后续命令覆盖。
当然,运行到此步可能有码友提示需要启动镜像,这个我就不赘述了,直接参考Hyperledger Fabric 1.0 从零开始(四)——Fabric源码及镜像文件处理,所需镜像截图如下:
在启动完成后,我们执行如下命令查看容器是否都已启动,具体结果视图如下:
可以看到所有的容器都已经成功启动,接下来就是channel和chaincode的操作了。
channel创建加盟
对peer的操作基本都需要依赖客户端完成,这里我们没有用sdk,但安装了tools镜像,即cli客户端,可以通过如下命令进入客户端进行channel的相关操作:
docker exec -it cli bash
随后执行如下命令创建一个channel:
peer channel create -o orderer.example.com: -c mychannel -t -f ./channel-artifacts/mychannel.tx
请注意,这个channel的创建并非随意,而是之前创建过一个mychannel.tx文件,在创建该文件的时候就已经指定了channelID是mychannel,这里不能随意看心情了。
随后执行ls即可查看已经创建的mychannel.block文件。
最终执行效果视图如下:
创建完channel后,我们需要通过mychannel.block文件来加入该channel,以便后续可以安装实例化并测试智能合约。
具体命令和视图结果如下:
peer channel join -b mychannel.block
至此,我们已经完成了channel的创建并成功加入了该channel。
chaincode安装部署实例化、测试
在之前我们上传了官方的chaincode demo到go目录下,合约目录为/home/docker/github.com/hyperledger/fabric/aberic/chaincode/go/chaincode_example02,这个目录也是我们即将安装的智能合约路径。
首先安装智能合约,具体命令和执行结果如下所示:
peer chaincode install -n mychannel -p github.com/hyperledger/fabric/aberic/chaincode/go/chaincode_example02 -v 1.0
安装完成后需要进行实例化chaincode,执行如下命令并有如下视图:
peer chaincode instantiate -o orderer.example.com: -C mychannel -n mychannel -c '{"Args":["init","A","10","B","10"]}' -P "OR ('Org1MSP.member')" -v 1.0
上图有些问题,但最终执行是成功的。
我们看合约提供的方法中有个query方法,需要传入一个参数,我们执行一次查询看看实例化时候的结果是否传入,如下命令和视图:
peer chaincode query -C mychannel -n mychannel -c '{"Args":["query","A"]}'
我们查到A有10快钱,符合初始化init时候的传参,继续执行如下命令查询B的,视图也如下:
peer chaincode query -C mychannel -n mychannel -c '{"Args":["query","B"]}'
可以看到B也有10快钱。
我们根据合约内容,让A给B转5快钱,执行如下命令并附视图(包括最终再次查询A和B资金的结果):
peer chaincode invoke -C mychannel -n mychannel -c '{"Args":["invoke", "A", "B", "5"]}'
我们可以看到合约已经运行无误,A成功给B转让了5快钱。
至此,先暂时告一段落,多节点部署也是在这个基础上进行的,由于章节太长,下次开接续部分的章节来完善这一块内容,且时间确实比较忙,如果能把这个跑通,后面再部署新节点就肯定能跑通了,最终开一个新节点的视图如下: