原文来自这里。
如果想了解最新版Fabric的特殊事项,详见Upgrading to the latest release of Fabric。
本章只介绍更新Fabric组件的操作。关于如何通过编辑通道来改变你通道的capability版本,详见Updating a 通道 capability。
注意:在Hyperledger Fabric中使用术语升级时,指的是升级组件的版本(例如,将可执行文件升级到最新版)。使用更新时,指的是配置的更新,例如更新通道的配置或部署脚本。在Fabric中,如果没有数据迁移的话,我们不会使用术语迁移。
总览
整体来看,在可执行程序层面升级你的节点,分两步:
- 备份账本和MSPs
- 更新所有的可执行程序到最新版
如果你拥有排序节点和peers,最好的做法是先升级排序节点。peer节点版本滞后或暂时无法处理某些交易,之后它总是可以赶上的。但如果相当数量的排序节点宕机,那Fabric网络将无法提供服务。
本文所有的操作都是通过Docker CLI命令执行。如果你使用其它的部署方法(Rancher,Kubernetes,OpenShift,等等),请查阅它的文档了解其CLI如何使用。
对于本机部署的,你还需要更新节点的YAML配置文件,例如orderer.yaml
。
备份orderer.yaml
或core.yaml
(peer节点),然后使用最新发布版中的orderer.yaml
或core.yaml
来替换它们。之后将备份的orderer.yaml
或core.yaml
文件中修改的地方更新到新的文件中。可以使用diff
来协助。注意,更新YAML文件时,推荐使用最新发布的来替换原有的,这样可以减少很多错误。
本文是假设你是使用Docker来部署Fabric网络的,YAML文件都已经内嵌到docker镜像中,配置文件中的默认值可以通过环境变量覆盖。
环境变量配置
在部署peer或order节点时,你需要设置大量跟配置相关的环境变量。最好的做法是将这些环境记录在与要部署相关节点相关的文件中,并保存到本地。这样,在更新节点时可以保证你使用的是更节点创建是一样的环境变量。
下面是peer相关的一系列环境变量(这些环境变量是本地部署使用的)可以放在文件中,你可能并不需要用到下面所有的环境变量:
CORE_PEER_TLS_ENABLED=true
CORE_PEER_GOSSIP_USELEADERELECTION=true
CORE_PEER_GOSSIP_ORGLEADER=false
CORE_PEER_PROFILE_ENABLED=true
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
CORE_PEER_ID=peer0.org1.example.com
CORE_PEER_ADDRESS=peer0.org1.example.com:7051
CORE_PEER_LISTENADDRESS=0.0.0.0:7051
CORE_PEER_CHAINCODEADDRESS=peer0.org1.example.com:7052
CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052
CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org1.example.com:7051
CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.example.com:7051
CORE_PEER_LOCALMSPID=Org1MSP
下面是orderer相关的一系列环境变量(这些环境变量是本地部署使用的)可以放在文件中,你可能并不需要用到下面所有的环境变量:
ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
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_TLS_ENABLED=true
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]
ORDERER_GENERAL_CLUSTER_CLIENTCERTIFICATE=/var/hyperledger/orderer/tls/server.crt
ORDERER_GENERAL_CLUSTER_CLIENTPRIVATEKEY=/var/hyperledger/orderer/tls/server.key
ORDERER_GENERAL_CLUSTER_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt]
你需要为每个你想升级的节点设置环境变量。
账本备份与还原
虽然我们将在本教程中演示备份账本数据的过程,但并不严格要求备份peer或排序节点(提供排序服务的一组排序节点之一)的账本数据。因为即使是最坏的情况下(例如硬盘故障),peer节点也能在没有账本的情况下启动。之后你再将peer节点重新加入到期望的通道中,peer节点会自动为每个通道创建账本,并周期性的从排序符合或其它peer节点中接受区块数据。在处理区块的过程中,peer节点会构建它自己的状态数据库。
但是,备份账本数据可以直接还原peer节点,不需要考虑从创世块构建数据和重新处理所有交易所花费的时间和计算成本,这一通过通常会花费数小时(取决于账本的大小)。此外,账本数据的备份还可能有助于新增peer节点,它可以从现有的peer节点获取账本数据来启动自己。
本文假定账本数据存放的文件路径并没有改变,还放在默认的路径:/var/hyperledger/production/
(peer节点)或/var/hyperledger/production/orderer
(排序节点)。如果你的路径改变了,那么在执行下面的命令时就需要输入你存放账本数据的路径。
需要注意的是账本和chaincodes数据都保存在该路径下。最好的做法是将两者都进行备份,这样做的话会忽略/var/hyperledger/production/ledgersData
下的stateLeveldb
、historyLeveldb
和chains/index
目录。尽管这样可以减少备份所需的存储空间,但peer从备份的数据中恢复时可能会花费更多的时间,因为这些账本会在peer启动时重新构建。
如果使用CouchDB作为状态数据库,那么默认路径下是没有stateLeveldb
的,因为状态数据库的数据会存如CouchDB中。同样的,如果peer启动时找不到CouchDB数据库或块高较小(基于早先的CouchDB备份),状态数据库会自动地重构数据直至当前块高。所以,如果你分别备份peer的账本数据和CouchDB数据,那么你需要确保CouchDB备份总早于peer的备份。
升级排序节点
排序节点应该以滚动的方式进行升级(在一次升级过程中)。总体来讲,排序节点的更新步骤如下:
- 关闭排序节点。
- 备份排序节点的账本和MSP。
- 移除排序节点容器。
- 使用相应的镜像启动新的排序节点。
在排序服务的所有节点上重复执行上面的过程,直至整个排序服务都完成升级。
设置环境变量
在更新排序节点前导入以下环境变量:
- ORDERER_CONTAINER:排序节点的容器名称。注意,每个节点更新时你都样设置一遍。
- LEDGERS_BACKUP:存放备份数据的路径。就如下面的示例中,每个节点都有它自己的子目录来存放它的账本。目录如果不存在的话,你需要手动创建。
- IMAGE_TAG:你期望升级到的Fabric版本,例如v2.0。
注意,镜像标签是必须设置,这样才能确保你使用正确的镜像来启动节点。设置标签的过程取决你的部署方式。
升级容器
开始更新之前,我们需要先下线排序节点:
docker stop $ORDERER_CONTAINER
服务下线后,你就可以备份账本和MSP:
docker cp $ORDERER_CONTAINER:/var/hyperledger/production/orderer/ ./$LEDGERS_BACKUP/$ORDERER_CONTAINER
然后删除排序服务容器(因为我们需要新容器与现有的容器同名):
docker rm -f $ORDERER_CONTAINER
最后,启用新的排序节点容器:
docker run -d -v /opt/backup/$ORDERER_CONTAINER/:/var/hyperledger/production/orderer/
-v /opt/msp/:/etc/hyperledger/fabric/msp/
--env-file ./env<name of node>.list
--name $ORDERER_CONTAINER
hyperledger/fabric-orderer:$IMAGE_TAG orderer
当所有的排序节点都完成升级,你就可以开始升级peer节点。
升级peer节点
与排序节点升级一样,peer节点也应该以滚动的方式进行升级(在一次升级过程中)。正如排序节点升级时提到的,排序节点的升级和peer节点的升级是可以并行的,但在本教程中我们是串行执行这两个过程。总体来看,peer节点的升级需要以下几步:
- 下线peer节点。
- 备份peer账本和MSP。
- 移除chaincode容器和镜像。
- 移除peer容器。
- 使用相应的镜像启动新的peer容器。
设置环境变量
在更新peer节点前导入以下环境变量:
- PEER_CONTAINER:peer节点的容器名称。注意,每个节点更新时你都样设置一遍。
- LEDGERS_BACKUP:存放备份数据的路径。就如下面的示例中,每个节点都有它自己的子目录来存放它的账本。目录如果不存在的话,你需要手动创建。
- IMAGE_TAG:你期望升级到的Fabric版本,例如v2.0。
注意,镜像标签是必须设置,这样才能确保你使用正确的镜像来启动节点。设置标签的过程取决你的部署方式。
在所有peer节点上重复执行上面的过程,以便完成所有peer节点的升级。
升级容器
首先,使用下面的命令来下线peer节点:
docker stop $PEER_CONTAINER
然后备份peer账本和MSP:
docker cp $PEER_CONTAINER:/var/hyperledger/production ./$LEDGERS_BACKUP/$PEER_CONTAINER
在完成peer节点下线和账本备份后,移除peerchaincode容器和镜像:
CC_CONTAINERS=$(docker ps | grep dev-$PEER_CONTAINER | awk '{print $1}')
if [ -n "$CC_CONTAINERS" ] ; then docker rm -f $CC_CONTAINERS ; fi
CC_IMAGES=$(docker images | grep dev-$PEER | awk '{print $1}')
if [ -n "$CC_IMAGES" ] ; then docker rmi -f $CC_IMAGES ; fi
然后删除peer容器(因为我们需要新容器与现有的容器同名):
docker rm -f $PEER_CONTAINER
最后,启动新的peer容器:
docker run -d -v /opt/backup/$PEER_CONTAINER/:/var/hyperledger/production/
-v /opt/msp/:/etc/hyperledger/fabric/msp/
--env-file ./env<name of node>.list
--name $PEER_CONTAINER
hyperledger/fabric-peer:$IMAGE_TAG peer node start
chaincode容器并不需要手动启动。在收到chaincode请求时(invoke或query),peer首先会检查chaincode是否在运行。如果是,直接使用;如果没有的话,peer节点会启动chaincode(必要时会重建chaincode镜像)。
验证peer升级完成
确认peer是否完成升级最好的方法是一次chaincode调用请求。注意,查询操作只能确定账本所在的单个peer节点成功升级。如果你想确认多个peer节点是否升级完成,同时更新chaincode也是升级操作的一部分的话,那你应该等到符合背书策略、且来自足够多组织的peer节点完成升级之后在进行验证。
在你计划验证之前,你需要升级来自足够多的组织的peer节点,以满足你的背书策略。但只有将更新chaincode作为升级peer操作的一部分时,才需要这样做。如果你的升级操作中不包括更新chaincode,那验证peer升级是否完成的操作可能会得到运行不同Fabric版本的peer节点的背书。
升级CA
要了解如何升级你的Fabric CA服务,详见CA documentation。
升级 Node.js SDK
升级Node.js SDK前需要先升级Fabric和Fabric CA。Fabric和Fabric CA兼容旧版的SDK。在旧版的Fabric和Fabric CA上使用较新的SDK,通常会提示旧版的Fabric和Fabric CA部分功能不可用,且兼容性并未经过测试。
在你应用程序的根目录下执行下面的命令可以升级所有的Node.js
客户端:
npm install fabric-client@latest
npm install fabric-ca-client@latest
上面的命令安装最新版的Fabric和Fabric CA客户端,并将版本信息写入package.json
中。
升级CouchDB
如果使用CouchDB作为状态数据库,那么在你升级peer节点也要同步升级CouchDB。
升级CouchDB:
- 下线CouchDB。
- 备份CouchDB数据目录。
- 安装最新版的CouchDB或更新部署脚本启用新的Docker镜像。
- 重启CouchDB。
升级Node chaincode
要升级到新版的Node chaincode shim包,开发人员需要:
- 更新chaincode
package.json
中的fabric-shim
至新版。 - 重新打包新的chaincode包,并在通道的所有背书节点上进行安装。
- 升级新到新的chaincode,详见Peer chaincode commands。
升级Go chaincode
关于升级Go chaincode到v2.0版,详见Chaincode shim changes。
有大量的第三方工具来帮你管理你的chaincode shim包。选择你熟悉的方式来管理你的chaincode shim包,并重新打包你的chaincode。
如果你更新了chaincode shim包,那你必须在所有已安装改chaincode的peer节点上重新安装它。安装时使用相同的名称,不同的版本号。之后你还要在部署了该chaincode的所有通道上执行chaincode升级操作来升级chaincode。
声明:本作品采用署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)进行许可,使用时请注明出处。
Author: MonsterMeng92