Hyperledger Fabric 2.0 官方文档中文版 第9章 升级到最新版本


总目录

第1章 引言
第2章 Hyperledger Fabric v2.0的新增功能
第3章 关键概念
第4章 入门
第5章 开发应用程序
第6章 教程(上)
第6章 教程(下)
第7章 部署生产网络
第8章 操作指南
第9章 升级到最新版本


9.升级到最新版本

如果您熟悉Hyperledger Fabric的早期版本,您会意识到将节点和通道升级到Fabric的最新版本在较高层次上是一个四步过程。

  1. 备份账本和MSP。
  2. 以滚动方式将排序节点二进制文件升级到最新的Fabric版本。
  3. 以滚动方式将普通节点二进制文件升级到最新的Fabric版本。
  4. 将排序节点系统通道和任何应用程序通道更新到最新的功能级别(如果可用)。请注意,有些版本在所有组中都有功能,而其他版本可能几乎没有新功能,甚至根本没有。

有关功能的更多信息,请查看通道功能。

要了解这些升级过程是如何完成的,请参考以下教程:

  1. 升级组件。在更新任何功能之前,应将组件升级到最新版本。
  2. 更新通道的功能级别。更新所有节点的版本后完成。
  3. 启用新的链码生命周期。有必要添加特定于组织的背书策略,使之成为Fabric v2.0的新链码生命周期的核心。

由于节点升级和增加通道的能力级别现在被认为是一个标准的Fabric过程,我们将不展示升级到最新版本的具体命令。类似地,fabric-samplesrepo中没有将示例网络从以前的版本升级到这个版本的脚本,就像以前的版本一样。

注意:作为网络常规升级的一部分,最好将SDK升级到最新版本。虽然SDK将始终与Fabric和更低版本的同等版本兼容,但可能需要升级到最新的SDK以利用最新的Fabric功能。有关如何升级的信息,请参阅您正在使用的Fabric SDK的文档。

使用v2.0的注意事项

链码生命周期

在v2.0中首次出现的新的链码生命周期允许多个组织在链码可以用于通道之前就如何操作达成一致。有关新的链码生命周期的更多信息,请参阅Fabric链码生命周期概念主题。

最佳做法是在启用新链码生命周期的通道应用程序功能之前升级通道上的所有节点(通道功能不是严格要求的,但此时进行更新是有意义的)。请注意,任何不在v2.0上的普通节点都将在启用这两种功能后崩溃,而任何不在v2.0版本下的排序节点都将在启用通道功能后崩溃。这种崩溃行为是故意的,因为普通节点或排序节点无法安全地参与通道,如果它不支持所需的功能。

在通道上的应用程序功能更新到V2_0后,必须使用V2.0生命周期过程在通道上打包、安装、批准和提交新的链码。因此,在更新功能之前,一定要为新的生命周期做好准备。

新生命周期默认使用通道配置中配置的背书策略(例如,大多数组织)。因此,在通道上启用功能时,应将此背书策略添加到通道配置中。

有关如何通过为每个组织添加背书策略来编辑相关通道配置以启用新生命周期的信息,请查看启用新链码生命周期

链码shim更改(仅限Go链码)

建议的方法是在升级节点和通道之前,在v1.4 Go链代码中提供shim。如果执行此操作,则不需要对链码进行任何其他更改。

如果您的v1.4链码中没有提供垫片,那么旧的v1.4链码镜像在升级后技术上仍然可以工作,但您处于危险状态。如果链码镜像由于任何原因从您的环境中被删除,v2.0节点上的下一个调用将尝试重新生成链码镜像,您将得到一个错误消息,即找不到填充程序。

此时,您有两个选项:

  1. 如果整个通道都准备好升级链码,则可以在所有节点和通道上升级链码(根据启用的应用程序功能级别,使用旧的或新的生命周期)。此时的最佳实践是使用模块提供新的Go链码填充程序。
  2. 如果整个通道尚未准备好升级链码,则可以使用节点环境变量来指定用于重建链码镜像的v1.4链码环境ccenv。这个v1.4ccenv应该仍然可以与v2.0节点一起工作。

链码记录器(仅限Go链码)

已删除对用户链码通过NewLogger()使用链码填充程序的记录器的支持。使用shim的NewLogger()的链码现在必须转换为自己的首选日志记录机制。

有关详细信息,请查看日志记录控件

节点数据库升级

作为升级到v2.0的一部分,必须使用v2.0数据格式重建所有节点的数据库(不仅包括状态数据库,还包括历史数据库和其他节点的内部数据库)。要触发重建,必须在节点启动之前删除数据库。

有关如何升级节点的信息,请参阅有关升级组件的文档。在升级节点的过程中,需要传递peer node upgrade-dbs命令来删除节点的数据库。

按照命令升级节点,直到看到docker run命令启动新的节点容器(您可以跳过设置IMAGE_TAG的步骤,因为upgrade dbs命令仅用于Fabric的v2.0版本,但您需要设置PEER_CONTAINERLEDGERS_BACKUP环境变量)。不要使用docker run命令来启动节点,而是运行以下命令:

docker run --rm -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:2.0 peer node upgrade-dbs

这将删除节点的数据库。然后发出以下命令以使用2.0标记启动节点:

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:2.0 peer node start

因为重建数据库可能是一个漫长的过程(几个小时,取决于数据库的大小),所以监视节点日志以检查重建的状态。每隔1000个块,您将看到一条类似[lockbasedtxmgr] CommitLostBlock -> INFO 041 Recommitting block [1000] to state database的消息,指示正在进行重建。

如果在升级过程中没有删除数据库,节点启动将返回一条错误消息,指出其数据库是旧格式的,必须使用上面的peer node upgrade-dbs命令将其删除。然后需要重新启动节点。

能力

正如2.0发行版所预期的那样,2.0版有一整套新功能。

  • 应用程序V2_0:启用新的链代码生命周期,如Fabric链码生命周期概念主题中所述。
  • 通道v2_0:此功能没有更改,但用于与应用程序和排序节点功能级别保持一致。
  • 排序节点 V2_0:控制UseChannelCreationPolicyAsAdmins,更改验证通道创建交易的方式。当与configtxgen的-baseProfile选项结合使用时,以前从排序程序系统通道继承的值现在可以被覆盖。

与功能级别的任何更新一样,请确保在更新应用程序通道功能之前升级节点二进制文件,并确保在更新排序程序通道功能之前升级排序程序二进制文件。

有关如何设置新功能的信息,请查看更新通道的功能级别

按组织定义排序节点端点(推荐)

从版本v1.4.2开始,建议在系统通道和组织级别的所有应用程序通道中定义排序节点端点,方法是在组织的通道配置中添加新的OrdererEndpoints,替换通道配置的全局OrdererAddresses部分。如果至少有一个组织在组织级别定义了排序服务端点,那么在连接到排序节点时,所有排序节点和普通节点都将忽略通道级端点。

当对多个组织提供的排序节点使用服务发现时,需要利用组织级的排序节点端点。这允许客户端提供正确的组织TLS证书。

如果你的通道配置还不包括每个组织的OrdererEndpoints,则需要执行通道配置更新以将其添加到配置中。首先,创建一个包含新配置节的JSON文件。

在本例中,我们将为一个名为OrdererOrg的组织创建一个节。请注意,如果您有多个排序服务组织,则必须更新它们以包括端点。让我们调用JSON文件orglevelEndpoints.json

{
    
    
  "OrdererOrgEndpoint": {
    
    
      "Endpoints": {
    
    
          "mod_policy": "Admins",
          "value": {
    
    
              "addresses": [
                 "127.0.0.1:30000"
              ]
          }
      }
   }
}

然后,导出以下环境变量:

  • CH_NAME:正在更新的通道的名称。请注意,所有系统通道和应用程序通道都应包含用于排序节点的组织端点。
  • CORE_PEER_LOCALMSPID:提出通道更新的组织的MSP ID。这将是排序组织之一的MSP。
  • CORE_PEER_MSPCONFIGPATH:表示组织的MSP的绝对路径。
  • TLS_ROOT_CA:建议系统通道更新的组织的根CA证书的绝对路径。
  • ORDERER_CONTAINER:排序节点容器的名称。当确定排序服务的目标时,您可以针对排序服务中的任何特定节点。你的请求将自动转发给领导。
  • ORGNAME:当前正在更新的组织的名称。例如,OrdererOrg

设置好环境变量后,导航到步骤1:拉取并转换配置

获得modified_config.json后,使用以下命令添加生命周期组织策略(如orglevelEndpoints.json中所列):

jq -s ".[0] * {\"channel_group\":{\"groups\":{\"Orderer\": {\"groups\": {\"$ORGNAME\": {\"values\": .[1].${ORGNAME}Endpoint}}}}}}" config.json ./orglevelEndpoints.json > modified_config.json

然后,按照步骤3:重新编码并提交配置

如果每个排序服务组织都执行自己的通道编辑,则他们可以编辑配置而无需进一步签名(默认情况下,编辑组织内参数所需的唯一签名是该组织的管理员)。如果其他组织提出更新,则正在编辑的组织将需要签署通道更新请求。


升级组件

受众:网络管理员、节点管理员

有关Fabric最新版本的特殊注意事项的信息,请查看Fabric最新版本的升级

本主题仅介绍升级组件的过程。有关如何编辑通道以更改通道的功能级别的信息,请参阅更新通道功能

注意:当我们在Hyperledger Fabric中使用术语“升级”时,我们指的是更改组件的版本(例如,从一个二进制版本转换到下一个版本)。另一方面,术语“更新”不是指版本,而是指配置更改,例如更新通道配置或部署脚本。从技术上讲,在Fabric中没有数据迁移,所以我们在这里不会使用术语“migration”或“migrate”。


概述

在较高的级别上,升级节点的二进制级别需要两个步骤:

  1. 备份账本和MSP。
  2. 将二进制文件升级到最新版本。

如果您同时拥有排序节点和普通节点,则最好先升级排序节点。如果节点落后或暂时无法处理某些交易,它总是可以赶上。相比之下,如果足够多的有序节点停止工作,网络就可以有效地停止工作。

本主题假定这些步骤将使用Docker CLI命令执行。如果您使用不同的部署方法(Rancher、Kubernetes、OpenShift等),请参考他们的文档,了解如何使用CLI。

对于本机部署,请注意,您还需要使用发布构件中的配置文件更新节点的YAML配置文件(例如,orderer.yaml文件)。

为此,备份orderer.yamlcore.yaml文件(对于节点),并将其替换为发布工件中的orderer.yamlcore.yaml文件。然后将任何修改过的变量从备份的orderer.yamlcore.yaml移植到新的变量。使用diff之类的实用程序可能会有所帮助。注意,从版本更新YAML文件而不是更新旧YAML文件是更新节点YAML文件的推荐方法,因为这样可以减少出错的可能性。

本教程假设一个Docker部署,其中YAML文件将被烘焙到镜像中,环境变量将用于覆盖配置文件中的默认值。

二进制文件的环境变量

部署普通节点或排序节点时,必须设置与其配置相关的许多环境变量。最佳实践是为这些环境变量创建一个文件,为其指定与所部署节点相关的名称,并将其保存在本地文件系统的某个位置。这样,您就可以确保在升级普通节点或排序节点时使用的变量与创建节点时设置的变量相同。

下面是一些节点环境变量的列表(带有示例值-从地址中可以看到,这些环境变量用于本地部署的网络),可以在文件中列出这些变量。请注意,您可能需要也可能不需要设置所有这些环境变量:

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_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]

但是,如果选择设置环境变量,请注意,必须为要升级的每个节点设置这些变量。

账本备份和恢复

虽然我们将在本教程中演示备份账本数据的过程,但并不严格要求备份普通节点或排序节点的账本数据(假设该节点是排序服务中较大节点组的一部分)。这是因为,即使在普通节点发生灾难性故障(如磁盘故障)的最坏情况下,也可以完全不使用账本来启动普通节点。然后,您可以让普通节点重新加入所需的通道,因此,普通节点将自动为每个通道创建一个账本,并将通过常规块传输机制从排序服务或通道中的其他节点接收数据块。当节点进程阻塞时,它还将建立其状态数据库。

但是,备份账本数据可以恢复普通节点,而无需从创世区块引导和重新处理所有交易相关的时间和计算成本,这一过程可能需要数小时(取决于账本的大小)。此外,账本数据备份可能有助于加快添加新的节点,这可以通过从一个节点备份账本数据并用备份的账本数据启动新节点来实现。

本教程假定账本数据的文件路径没有从默认值/var/hyperledger/production/(对于普通节点)或/var/hyperledger/production/orderer(对于排序节点)没有更改。如果节点的此位置已更改,请在下面的命令中输入账本上数据的路径。

请注意,此文件位置将同时存在账本和链码的数据。虽然最好同时备份这两个文件夹,但是可以跳过位于/var/hyperledger/production/ledgersDatastateLeveldbhistoryLeveldbchains/index文件夹。虽然跳过这些文件夹会减少备份所需的存储空间,但从备份数据中进行节点恢复可能需要更长的时间,因为这些账本工件将在节点启动时重新构建。

如果使用CouchDB作为状态数据库,则不会有stateLeveldb目录,因为状态数据库数据将存储在CouchDB中。但类似地,如果peer启动后发现CouchDB数据库丢失或处于较低的块高度(基于使用较旧的CouchDB备份),状态数据库将自动重新构建以赶上当前块高度。因此,如果分别备份节点账本数据和CouchDB数据,请确保CouchDB备份始终比节点备份旧。

升级排序节点

排序节点容器应以滚动方式升级(一次一个)。在较高级别上,排序节点升级过程如下所示:

  1. 停止排序节点。
  2. 备份排序节点的账本和MSP。
  3. 移除排序节点容器。
  4. 使用相关的镜像标记启动新的排序节点容器。

对排序服务中的每个节点重复此过程,直到整个排序服务已升级。


设置命令环境变量

在尝试升级排序节点之前,请先导出以下环境变量。

  • ORDERER_CONTAINER:排序节点容器的名称。请注意,在升级每个节点时,需要为每个节点导出此变量。
  • LEDGERS_BACKUP:本地文件系统中要存储正在备份的账本的位置。正如您将在下面看到的,正在备份的每个节点都有自己的子文件夹,其中包含其账本。您需要创建此文件夹。
  • IMAGE_TAG:要升级到的Fabric版本。例如,2.0。

请注意,您必须设置一个image标记,以确保您正在启动的节点使用正确的镜像。用于设置标记的过程将取决于您的部署方法。

升级容器

让我们通过关闭排序程序开始升级过程:

docker stop $ORDERER_CONTAINER

排序程序关闭后,您需要备份其账本和MSP

docker cp $ORDERER_CONTAINER:/var/hyperledger/production/orderer/ ./$LEDGERS_BACKUP/$ORDERER_CONTAINER

然后删除ordering node容器本身(因为我们将为新容器指定与旧容器相同的名称):

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

一旦所有的排序节点都启动了,您就可以继续升级您的普通节点。

升级普通节点

普通节点应该像排序节点一样,以滚动方式升级(一次一个)。正如在ordering node upgrade中提到的,ordering node和Peer可以并行升级,但为了本教程的目的,我们将这些过程分离出来。我们将执行以下步骤:

  1. 停止普通节点。
  2. 备份普通节点的账本和MSP。
  3. 删除链码容器和镜像。
  4. 移除节点容器。
  5. 使用相关的镜像标记启动一个新的节点容器。

设置命令环境变量

在尝试升级节点之前,请先导出以下环境变量。

  • PEER_CONTAINER:节点容器的名称。请注意,您需要为每个节点设置此变量。
  • LEDGERS_BACKUP:本地文件系统中要存储正在备份的账本的位置。正如您将在下面看到的,正在备份的每个节点都有自己的子文件夹,其中包含其账本。您需要创建此文件夹。
  • IMAGE_TAG:要升级到的Fabric版本。例如,2.0
    请注意,您必须设置一个image标记,以确保正在启动的节点使用的是正确的镜像。用于设置标记的过程将取决于您的部署方法。

对每个节点重复此过程,直到每个节点都已升级。

升级容器

让我们用下面的命令关闭第一个普通节点

docker stop $PEER_CONTAINER

然后我们可以备份普通节点的账本和MSP

docker cp $PEER_CONTAINER:/var/hyperledger/production ./$LEDGERS_BACKUP/$PEER_CONTAINER

停止普通节点并备份账本后,删除节点链码容器

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

然后删除节点容器本身(因为我们将为新容器指定与旧容器相同的名称):

docker rm -f $PEER_CONTAINER

然后,您可以通过发出以下命令来启动新的节点容器:

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

不需要重新启动链码容器。当节点收到对链码的请求时(调用或查询),它首先检查是否有该链码的副本正在运行。如果是这样,它就用它。否则,在本例中,节点启动链码(如果需要,重新构建镜像)。

验证节点升级完成

最好的做法是确保使用链码调用正确完成升级。请注意,应该可以通过查询节点上托管的一个账本来验证单个节点是否已成功更新。如果要验证是否已升级多个节点,并且正在升级过程中更新链码,则应等到来自足够多的组织的节点已升级以满足背书策略。

在尝试此操作之前,您可能需要从足够多的组织升级节点,以满足您的背书策略。但是,只有在升级过程中更新链码时,这才是必需的。如果不在升级过程中更新链码,则有可能从运行于不同Fabric版本的节点获得背书。

升级你的CAs

要了解如何升级Fabric CA服务器,请单击CA文档

升级Node-SDK-clients

在升级节点SDK客户端之前升级Fabric和Fabric CA。Fabric和Fabric CA测试了与旧SDK客户端的向后兼容性。虽然较新的SDK客户机通常使用较旧的Fabric和Fabric CA版本,但它们可能会暴露在旧的Fabric和Fabric CA发行版中尚不可用的功能,并且没有进行完全兼容性测试。
通过在应用程序的根目录中执行以下命令,使用NPM升级任何Node.js客户端:

npm install fabric-client@latest

npm install fabric-ca-client@latest

这些命令安装结构客户端和结构CA客户端的新版本,并将新版本写入package.json

升级CouchDB

如果您使用CouchDB作为状态数据库,那么应该在升级节点的同时升级节点的CouchDB。

要升级CouchDB:

  1. 停止CouchDB。
  2. 备份CouchDB数据目录。
  3. 安装最新的CouchDB二进制文件或更新部署脚本以使用新的Docker镜像。
  4. 重新启动CouchDB。

升级节点链码填充程序

要迁移到新版本的节点链码填充程序,开发人员需要:

  1. 将其链码package.jsonfabric-shim的级别从旧级别更改为新级别。
  2. 重新打包这个新的链码包,并将其安装到通道中所有背书的节点上。
  3. 执行此新链码的升级。要了解如何执行此操作,请查看节点链码命令

使用vendored shim升级链码

有关升级特定于v2.0版本的Go链码填充程序的信息,请查看链码填充程序更改

存在许多第三方工具,允许您提供链码填充程序。如果您使用了这些工具之一,请使用相同的工具更新您的供应商链码填充程序并重新打包链码。

如果您的链码供应商提供了填充程序,则在更新了填充程序版本之后,必须将其安装到已经具有链码的所有节点。使用相同的名称安装,但要使用更新的版本。然后,您应该在部署了此链码的每个通道上执行链码升级,以移动到新版本。

更新通道的功能级别

受众:网络管理员、节点管理员

如果您不熟悉功能,请在继续之前检查功能,特别注意属于通道的节点和排序节点必须在启用功能之前升级

有关Fabric最新版本中任何新功能级别的信息,请查看升级组件

注意:当我们在Hyperledger Fabric中使用术语“升级”时,我们指的是更改组件的版本(例如,从一个二进制版本转换到下一个版本)。另一方面,术语“更新”不是指版本,而是指配置更改,例如更新通道配置或部署脚本。从技术上讲,在Fabric中没有数据迁移,所以我们在这里不会使用术语“migration”或“migrate”。

必备组件和注意事项

如果您还没有这样做,请确保您拥有您的计算机上的所有依赖项,如必备组件中所述。这将确保您拥有进行通道配置更新所需的工具的最新版本。

尽管Fabric二进制文件可以而且应该以滚动方式升级,但是在启用功能之前完成二进制文件的升级是很重要的。任何未升级到至少相关功能级别的二进制文件都将崩溃,表明配置错误,否则可能导致账本分叉。

一旦启用了某个功能,它将成为该通道永久记录的一部分。这意味着,即使禁用了该功能,旧的二进制文件也将无法参与通道,因为它们无法处理超出启用该功能的块的进程,从而到达禁用该功能的块。因此,一旦启用了某个功能,则不建议也不支持禁用该功能。

因此,将启用通道功能视为不可回头的一点。请在测试环境中试用新功能,并在继续将其投入生产之前充满信心。

概述

在本教程中,我们将展示在排序系统通道和任何应用程序通道的配置的所有部分中更新功能的过程。

您是否需要为所有通道更新配置的每个部分取决于最新版本的内容以及您自己的用例。有关详细信息,请查看升级到最新版本的Fabric。请注意,在使用最新版本中的功能之前,可能需要更新到最新的功能级别,并且始终保持最新的二进制版本和功能级别被认为是最佳做法。

因为更新通道的功能级别涉及到配置更新交易处理过程,所以我们将依赖于更新通道配置主题来执行许多命令。

与任何通道配置更新一样,更新功能在较高级别上是一个三步过程(对于每个通道):

  1. 获取最新的通道配置
  2. 创建修改的通道配置
  3. 创建配置更新交易

我们将按照以下顺序启用这些功能:

  1. 排序系统通道
  • 排序节点组
  • 通道组
  1. 应用通道
  • 排序节点组
  • 通道组
  • 应用程序组

虽然可以同时编辑通道配置的多个部分,但在本教程中,我们将展示如何以增量方式完成此过程。换句话说,我们不会将对排序节点组和系统通道的通道组的更改绑定到一个配置更改中。这是因为并不是每个版本都同时具有新的排序节点组功能和通道组功能。

注意,在生产网络中,一个用户不可能或不希望单方面地更新所有这些通道(和部分配置)。例如,排序节点系统通道由排序节点组织管理员专门管理(尽管可以添加普通节点组织作为排序服务组织)。类似地,更新通道配置的排序节点通道组需要排序服务组织和普通节点组织的签名。分布式系统需要协作管理。

创建功能配置文件

注意,本教程假定一个名为capabilities.json的文件已创建,并包含要对配置的各个部分进行的功能更新。它还使用jq对修改后的配置文件应用编辑。

请注意,您没有义务创建capabilities.json或者使用像jq这样的工具。修改后的配置也可以手动编辑(在拉取、转换和确定范围之后)。请查看此示例通道配置以供参考。

然而,这里描述的过程(使用JSON文件和jq这样的工具)确实具有可编写脚本的优点,因此适合于向大量通道提案配置更新。这就是为什么它是推荐的更新通道的方法。

在本例中capabilities.json文件如下所示(注意:如果在升级到Fabric的最新版本时更新通道,则需要将功能设置为与该版本相应的级别):

{
    
    
     "channel": {
    
    
         "mod_policy": "Admins",
             "value": {
    
    
                 "capabilities": {
    
    
                     "V2_0": {
    
    }
                 }
             },
         "version": "0"
     },
     "orderer": {
    
    
         "mod_policy": "Admins",
             "value": {
    
    
                 "capabilities": {
    
    
                     "V2_0": {
    
    }
                 }
             },
         "version": "0"
     },
     "application": {
    
    
         "mod_policy": "Admins",
             "value": {
    
    
                 "capabilities": {
    
    
                     "V2_0": {
    
    }
                 }
             },
         "version": "0"
     }
   }

请注意,默认情况下,节点组织不是排序节点系统通道的管理员,因此无法向其提出配置更新。排序节点组织管理员必须创建这样一个文件(没有应用程序组功能,这在系统通道中不存在)来建议更新系统通道配置。请注意,由于默认情况下,应用程序通道复制系统通道配置,除非创建指定功能级别的不同通道配置文件,否则应用程序通道的通道排序节点组功能将与网络系统通道中的功能相同。

排序节点系统通道能力

由于默认情况下,应用程序通道复制排序节点系统通道的配置,因此在任何应用程序通道之前更新系统通道的功能被认为是最佳做法。这反映了将排序节点更新到普通节点之前的最新版本的过程,如升级组件中所述。

请注意,排序节点系统通道由排序服务组织管理。默认情况下,这将是单个组织(在排序服务中创建初始节点的组织),但可以在此处添加更多组织(例如,如果多个组织向排序服务提供了节点)。

在更新排序程序通道功能之前,请确保排序服务中的所有排序节点都已升级到所需的二进制级别。如果排序节点不在所需级别,它将无法处理具有该功能的配置块,并将崩溃。类似地,请注意,如果在这个排序服务上创建了一个新通道,那么将加入该通道的所有普通节点必须至少达到与该通道和应用程序功能相对应的节点级别,否则它们在尝试处理配置块时也会崩溃。有关更多信息,请查看功能

设置环境变量

您需要导出以下变量:

  • CH_NAME:正在更新的通道的名称。
  • CORE_PEER_LOCALMSPID:提出通道更新的组织的MSP ID。这将是排序组织之一的MSP。
  • TLS_ROOT_CA:排序节点的TLS证书的绝对路径。
  • CORE_PEER_MSPCONFIGPATH:表示组织的MSP的绝对路径。
  • ORDERER_CONTAINER:排序节点容器的名称。当确定排序服务的目标时,您可以针对排序服务中的任何特定节点。你的请求将自动转发给领导。

Orderer

有关如何拉取、转换和限定通道配置范围的命令,请导航到步骤1:拉动并转换配置。有了modified_config.json之后,使用以下命令将功能添加到config的Orderer组(如capabilities.json中所列):

jq -s '.[0] * {"channel_group":{"groups":{"Orderer": {"values": {"Capabilities": .[1].orderer}}}}}' config.json ./capabilities.json > modified_config.json

然后,按照步骤3:重新编码并提交配置

请注意,因为您正在更新系统通道,所以系统通道的mod_policy只需要排序服务组织管理员的签名。

Channel

再次,导航到步骤1:拉取并转换配置。有了modified_config.json之后,使用以下命令将功能添加到config的Channel组(如capabilities.json中所列):

jq -s '.[0] * {"channel_group":{"values": {"Capabilities": .[1].channel}}}' config.json ./capabilities.json > modified_config.json

然后,按照步骤3:重新编码并提交配置

请注意,因为您正在更新系统通道,所以系统通道的mod_policy只需要排序服务组织管理员的签名。在应用程序通道中,正如您将看到的,您通常需要同时满足应用程序组(由普通节点组织的MSPs组成)和排序节点组(由排序服务组织组成)的多数``管理员策略,假设您没有更改默认值。

在现有通道上启用功能

现在我们已经更新了orderer系统通道上的功能,我们需要更新您想要更新的任何现有应用程序通道的配置。

正如您将看到的,应用程序通道的配置与系统通道的配置非常相似。这使我们可以重用capabilities.json和更新系统通道时使用的相同命令(使用不同的环境变量,我们将在下面讨论)。

**在更新功能之前,请确保排序服务中的所有排序节点和通道上的普通节点都已升级到所需的二进制级别。如果普通节点或排序节点不在所需级别,它将无法处理具有该功能的配置块,并将崩溃。**有关更多信息,请查看功能

设置环境变量

您需要导出以下变量:

  • CH_NAME:正在更新的应用程序通道的名称。您必须为您更新的每个通道重置此变量。
  • CORE_PEER_LOCALMSPID:提出通道更新的组织的MSP ID。这将是你的节点组织的MSP。
  • TLS_ROOT_CA:节点组织TLS证书的绝对路径。
  • CORE_PEER_MSPCONFIGPATH:表示组织的MSP的绝对路径。
  • ORDERER_CONTAINER:排序节点容器的名称。当确定排序服务的目标时,您可以针对排序服务中的任何特定节点。你的请求将自动转发给领导。

Orderer

有关如何拉取、转换和限定通道配置范围的命令,请导航到步骤1:拉动并转换配置。有了modified_config.json之后,使用以下命令将功能添加到config的Orderer组(如capabilities.json中所列):

jq -s '.[0] * {"channel_group":{"groups":{"Orderer": {"values": {"Capabilities": .[1].orderer}}}}}' config.json ./capabilities.json > modified_config.json

然后,按照步骤3:重新编码并提交配置

注意,此功能的mod_policy默认为排序节点组的大多数管理员(换句话说,排序服务的大多数管理员)。节点组织可以提出对此功能进行更新,但在这种情况下,它们的签名将不满足相关策略。

Channel

再次,导航到步骤1:拉取并转换配置。有了modified_config.json之后,使用以下命令将功能添加到config的Channel组(如capabilities.json中所列):

jq -s '.[0] * {"channel_group":{"values": {"Capabilities": .[1].channel}}}' config.json ./capabilities.json > modified_config.json

然后,按照步骤3:重新编码并提交配置

请注意,此功能的mod_policy默认为需要来自应用程序组和排序节点组中大多数``管理员的签名。换句话说,大多数节点组织管理员和排序服务组织管理员都必须签署此请求。

Application

再次,导航到步骤1:拉取并转换配置。有了modified_config.json之后,使用以下命令将功能添加到config的Application组(如capabilities.json中所列):

jq -s '.[0] * {"channel_group":{"groups":{"Application": {"values": {"Capabilities": .[1].application}}}}}' config.json ./capabilities.json > modified_config.json

然后,按照步骤3:重新编码并提交配置

请注意,此功能的mod_policy默认为需要来自应用程序组中大多数``管理员的签名。换言之,大多数同行组织都需要批准。排序服务管理员对此功能没有发言权。

**因此,请小心不要将此功能更改为不存在的级别。**因为排序节点既不了解也不验证应用程序功能,所以它们将批准任何级别的配置,并将新的配置块发送给普通节点,以提交给它们的账本。但是,普通节点将无法处理该功能并将崩溃。即使有可能将更正的配置更改驱动到有效的功能级别,以前具有错误功能的配置块仍将存在于账本上,并导致普通节点在尝试处理时崩溃。

这就是为什么像capabilities.json这样的文件是有用的。它可以防止一个简单的用户错误(例如,当用户打算将应用程序功能设置为V20时,将其设置为V2_0),这可能会导致通道不可用和不可恢复。

启用功能后验证交易

最佳实践是确保在所有通道上使用链码调用成功地启用了功能。如果任何不了解新功能的节点没有升级到足够的二进制级别,它们将崩溃。在他们成功升级之前,你必须重新启动他们的二进制文件。

启用新的链码生命周期

从v1.4.x升级到v2.0的用户必须编辑他们的通道配置以启用新的生命周期功能。此过程涉及相关用户必须执行的一系列通道配置更新

请注意,应用程序 通道和应用程序功能必须更新到V2_0,新的链码生命周期才能正常工作。了解更多信息,请查看升级到2.0的注意事项。

从较高的层次来看,更新通道配置是一个三步过程(对于每个通道):

  • 获取最新的通道配置
  • 创建修改的通道配置
  • 创建配置更新交易

我们将利用一个名为enable_lifecycle.json的文件执行这些通道配置更新,该文件包含我们将在通道配置中进行的所有更新。请注意,在生产设置中,可能有多个用户发出这些通道更新请求。但是,为了简单起见,我们将所有更新显示为它们在单个文件中的显示方式。

创建enable_lifecycle.json

注意,除了使用enable_lifecycle.json之外,本教程还使用jq将编辑应用于修改后的配置文件。修改后的配置也可以手动编辑(在拉取、转换和确定范围之后)。请查看此示例通道配置以供参考。

但是,这里描述的过程(使用JSON文件和jq这样的工具)确实具有可编写脚本的优点,使其适合于向大量通道建议配置更新,并且是推荐的通道配置编辑过程。

请注意,enable_lifecycle.json使用示例值,例如org1PoliciesOrg1ExampleCom,它们将特定于您的部署):

{
    
    
  "org1Policies": {
    
    
      "Endorsement": {
    
    
           "mod_policy": "Admins",
           "policy": {
    
    
               "type": 1,
               "value": {
    
    
               "identities": [
                  {
    
    
                     "principal": {
    
    
                         "msp_identifier": "Org1ExampleCom",
                         "role": "PEER"
                     },
                     "principal_classification": "ROLE"
                  }
                ],
                "rule": {
    
    
                  "n_out_of": {
    
    
                       "n": 1,
                       "rules": [
                        {
    
    
                            "signed_by": 0
                        }
                       ]
                   }
                },
                "version": 0
              }
           },
           "version": "0"
      }
   },
  "org2Policies": {
    
    
      "Endorsement": {
    
    
           "mod_policy": "Admins",
           "policy": {
    
    
               "type": 1,
               "value": {
    
    
               "identities": [
                  {
    
    
                     "principal": {
    
    
                         "msp_identifier": "Org2ExampleCom",
                         "role": "PEER"
                     },
                     "principal_classification": "ROLE"
                  }
                ],
                "rule": {
    
    
                  "n_out_of": {
    
    
                       "n": 1,
                       "rules": [
                        {
    
    
                            "signed_by": 0
                        }
                       ]
                   }
                },
                "version": 0
              }
           },
           "version": "0"
      }
   },
   "appPolicies": {
    
    
        "Endorsement": {
    
    
            "mod_policy": "Admins",
            "policy": {
    
    
                "type": 3,
                "value": {
    
    
                    "rule": "MAJORITY",
                    "sub_policy": "Endorsement"
                }
            },
            "version": "0"
        },
        "LifecycleEndorsement": {
    
    
            "mod_policy": "Admins",
            "policy": {
    
    
                "type": 3,
                "value": {
    
    
                    "rule": "MAJORITY",
                    "sub_policy": "Endorsement"
                }
            },
            "version": "0"
        }
   },
   "acls": {
    
    
        "_lifecycle/CheckCommitReadiness": {
    
    
            "policy_ref": "/Channel/Application/Writers"
        },
        "_lifecycle/CommitChaincodeDefinition": {
    
    
            "policy_ref": "/Channel/Application/Writers"
        },
        "_lifecycle/QueryChaincodeDefinition": {
    
    
            "policy_ref": "/Channel/Application/Readers"
        },
        "_lifecycle/QueryChaincodeDefinitions": {
    
    
            "policy_ref": "/Channel/Application/Readers"
        }
   }
}

注意:这些新策略的“角色”字段应为“普通节点”,如果为组织启用了NodeOUs,则应为'MEMBER'

编辑通道配置

系统通道更新

由于对系统通道的配置更改以启用新的生命周期,仅涉及通道配置中普通节点组织的配置内部的参数,因此正在编辑的每个节点组织都必须签署相关的通道配置更新。

但是,默认情况下,系统通道只能由系统通道管理员(通常是排序服务组织的管理员,而不是普通节点组织的管理员)编辑,这意味着联盟中普通节点组织的配置更新必须由系统通道管理员提出,并发送到相关普通节点组织进行签名。

您需要导出以下变量:

  • CH_NAME:正在更新的系统通道的名称。
  • CORE_PEER_LOCALMSPID:建议通道更新的组织的MSP ID。这将是其中一个排序服务组织的MSP。
  • CORE_PEER_MSPCONFIGPATH:代表组织的MSP的绝对路径。
  • TLS_ROOT_CA:提出系统通道更新的组织的根CA证书的绝对路径。
  • ORDERER_CONTAINER:排序节点容器的名称。当确定排序服务的目标时,您可以针对排序服务中的任何特定节点。你的请求将自动转发给领导。
  • ORGNAME:当前正在更新的组织的名称。
  • CONSORTIUM_NAME:更新的联盟名称。

设置好环境变量后,导航到步骤1:拉取并转换配置

获得modified_config.json后,使用以下命令添加生命周期组织策略(如enable_lifecycle.json中所列):

jq -s ".[0] * {\"channel_group\":{\"groups\":{\"Consortiums\":{\"groups\": {\"$CONSORTIUM_NAME\": {\"groups\": {\"$ORGNAME\": {\"policies\": .[1].${ORGNAME}Policies}}}}}}}}" config.json ./enable_lifecycle.json > modified_config.json

然后,按照步骤3:重新编码并提交配置

如上所述,这些更改必须由系统通道管理员提出,并发送到相关节点组织进行签名。

应用程序通道更新

编辑普通节点组织

我们需要对所有应用程序通道上的所有组织执行类似的编辑。

注意,与系统通道不同,节点组织能够向应用程序通道发出配置更新请求。如果要对自己的组织进行配置更改,则无需其他组织的签名即可进行这些更改。但是,如果您试图对其他组织进行更改,则该组织必须批准该更改。
您需要导出以下变量:

  • CH_NAME:正在更新的系统通道的名称。
  • ORGNAME:当前正在更新的组织的名称。
  • TLS_ROOT_CA:排序节点的TLS证书的绝对路径。
  • CORE_PEER_MSPCONFIGPATH:代表组织的MSP的绝对路径。
  • CORE_PEER_LOCALMSPID:建议通道更新的组织的MSP ID。这将是一个节点组织的MSP。
  • ORDERER_CONTAINER:排序节点容器的名称。当确定排序服务的目标时,您可以针对排序服务中的任何特定节点。你的请求将自动转发给领导。

设置好环境变量后,导航到步骤1:拉取并转换配置

获得modified_config.json后,使用以下命令添加生命周期组织策略(如enable_lifecycle.json中所列):

jq -s ".[0] * {\"channel_group\":{\"groups\":{\"Application\": {\"groups\": {\"$ORGNAME\": {\"policies\": .[1].${ORGNAME}Policies}}}}}}" config.json ./enable_lifecycle.json > modified_config.json

然后,按照步骤3:重新编码并提交配置

编辑应用程序通道

在所有应用程序通道都已更新为包含V2_0功能后,必须向每个通道添加新链码生命周期的背书策略。

您可以设置与更新节点组织时设置的相同的环境。请注意,在本例中,您不会在配置中更新组织的配置,因此不会使用ORGNAME变量。

设置好环境变量后,导航到步骤1:拉取并转换配置

获得modified_config.json后,使用以下命令添加通道背书策略(如enable_lifecycle.json中所列):

jq -s '.[0] * {"channel_group":{"groups":{"Application": {"policies": .[1].appPolicies}}}}' config.json ./enable_lifecycle.json > modified_config.json

然后,按照步骤3:重新编码并提交配置

要批准此通道更新,必须满足修改配置的Channel/Application部分的策略。默认情况下,这是通道上的大多数节点组织。

编辑通道ACL(可选)

enable_lifecycle.json中的以下访问控制列表(ACL)是新生命周期的默认值,不过您可以根据您的用例选择更改它们。

"acls": {
    
    
 "_lifecycle/CheckCommitReadiness": {
    
    
   "policy_ref": "/Channel/Application/Writers"
 },
 "_lifecycle/CommitChaincodeDefinition": {
    
    
   "policy_ref": "/Channel/Application/Writers"
 },
 "_lifecycle/QueryChaincodeDefinition": {
    
    
   "policy_ref": "/Channel/Application/Readers"
 },
 "_lifecycle/QueryChaincodeDefinitions": {
    
    
   "policy_ref": "/Channel/Application/Readers"

您可以保留以前编辑应用程序通道时相同的环境。

设置好环境变量后,导航到步骤1:拉取并转换配置

有了modified_config.json之后,使用以下命令添加ACLs(如enable_lifecycle.json中所列):

jq -s '.[0] * {"channel_group":{"groups":{"Application": {"values": {"ACLs": {"value": {"acls": .[1].acls}}}}}}}' config.json ./enable_lifecycle.json > modified_config.json

然后,按照步骤3:重新编码并提交配置

要批准此通道更新,必须满足修改配置的Channel/Application部分的策略。默认情况下,这是通道上的大多数节点组织。

core.yaml中启用新生命周期

如果按照推荐的流程使用diff等工具将打包的新版本core.yaml与旧版本的二进制文件进行比较,则不需要将白名单_lifecycle:enable,因为新的core.yaml已将其添加到chaincode/system下。

但是,如果要直接更新旧节点YAML文件,则必须将_lifecycle:enable添加到系统链码白名单中。

有关升级节点的详细信息,请查看升级组件

参考自官方文档
如有侵权,请联系作者删除,谢谢!
If there is infringement, please contact the author to delete, thank you!

猜你喜欢

转载自blog.csdn.net/bean_business/article/details/108689783