版本更新:从1.4.1到1.4.2
因为1.4.2开始fabric官方提供了从kafka迁移到raft功能。考虑到以后可能有这方面的需求,研究一下旧版本更新和依赖1.4.2版本的迁移实现。今天先研究版本更新,大部分内容来着官方文档,有部分在自己跑的时候的修改。
同时适用1.3及以上版本更新至1.4.2
官方文档地址:
<https://hyperledger-fabric.readthedocs.io/en/release-1.4/upgrade_to_newest_version.html>
升级orderer容器
orerer容器应该以顺序的方式升级(一次升级一个)。
orderer的升级过程如下:
1. 停止orderer。
2. 备份orderer的账本数据和MSP。
3. 使用最新镜像重新启动orderer。
4. 验证升级完成。
1.停止orderer
docker stop orderer.example.com
2.备份orderer的账本数据和MSP。
1. mkdir ./ledgers-backup //创建文件夹用来备份账本和MSP
2. docker cp orderer2.baoquan.com:/var/hyperledger/production/orderer/ ./ledgers-backup/orderer2.baoquan.com //备份
3.使用最新镜像重新启动orderer。
1. 修改orderer.yaml文件里拉取得镜像的版本为1.4.2
2. docker-compose -f docker-compose-cli.yaml up -d --no-deps orderer.example.com
//使用指定命令启动orderer
4.验证升级完成。
单机模式
1.重启后执行交易,交易是否可正常进行
生产模式
1.最好的做法是在重启orderer后发出peer channel fetch <blocknumber>,以验证它已经赶上了其他orderer。//TODO
升级peer容器
peer容器同样以顺序的方式升级(一次升级一个)。
peer的升级过程如下:
1. 停止peer。
2. 备份peer的账本数据和MSP。
3. 删除链码容器和镜像。
4. 使用最新镜像重新启动peer。
5. 验证升级完成。
1. 停止peer
docker stop peer0.org1.example.com
2.备份peer的账本数据和MSP
1. mkdir ./ledgers-backup
2. docker cp peer0.org1.example.com:/var/hyperledger/production ./ledgers-backup/peer0.org1.example.com
3.删除链码容器和镜像
在peer停止并备份账本数据的情况下,删除peer链代码容器:
docker rm -f $CC_CONTAINERS
和peer链代码images:
CC_IMAGES=$(docker images | grep dev-$PEER | awk '{print $1}')
if [ -n "$CC_IMAGES" ] ; then docker rmi -f $CC_IMAGES ; fi
4.使用最新镜像重新启动peer
1.修改对应yaml文件的images版本为1.4.2
2.需确认peer的数据仓库持久化。再次启动需依赖
docker-compose -f docker-compose-peer.yaml up -d --no-deps peer0.org1.example.com
ps:如果使用的是couchDB,使用下面的命令
docker-compose -f docker-compose-peer.yaml -f docker-compose-couch.yaml up -d --no-deps peer0.org1.example.com
5.验证升级完成
1.更新cli容器
docker-compose -f docker-compose-cli.yaml stop cli
更改docker-compose-cli.yaml 的镜像版本
docker-compose -f docker-compose-cli.yaml up -d --no-deps cli
2.进入cli容器
docker exec -it cli bash
3.查询-转账-查询
查看结果是否与预估相同
将系统通道功能更新到v1.4.2(可选)
1.设定对应通道信息
CORE_PEER_LOCALMSPID="OrdererMSP"
CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/users/Admin@example.com/msp
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
在orderer容器的账本路径下查看系统通道名称,我们需要将系统通道名称设置为CH_NAME
:
CH_NAME=testchainid
2.Orderer Group 更新
更新通道配置的第一步是获取最新的配置块:
peer channel fetch config config_block.pb -o orderer.example.com:7050 -c $ CH_NAME -tls -cafile $ ORDERER_CA
configtxlator proto_decode -input config_block.pb -type common.Block -output config_block.json
jq .data.data [0] .payload.data.config config_block.json> config.json
接下来,为 orderer group添加功能。以下命令将创建配置文件的副本并更改功能级别:
capabilities.json地址:https://github.com/hyperledger/fabric-samples/blob/release-1.4/first-network/scripts/capabilities.json
jq -s '.[0] * {"channel_group":{"groups":{"Orderer": {"values": {"Capabilities": .[1]}}}}}' config.json ./scripts/capabilities.json > modified_config.json
现在我们可以创建配置更新:
configtxlator proto_encode --input config.json --type common.Config --output config.pb
configtxlator proto_encode --input modified_config.json --type common.Config --output modified_config.pb
configtxlator compute_update --channel_id $CH_NAME --original config.pb --updated modified_config.pb --output config_update.pb
将配置更新打包到事务中:
configtxlator proto_decode --input config_update.pb --type common.ConfigUpdate --output config_update.json
echo '{"payload":{"header":{"channel_header":{"channel_id":"'$CH_NAME'", "type":2}},"data":{"config_update":'$(cat config_update.json)'}}}' | jq . > config_update_in_envelope.json
configtxlator proto_encode --input config_update_in_envelope.json --type common.Envelope --output config_update_in_envelope.pb
提交配置更新事务:
peer channel update -f config_update_in_envelope.pb -c $CH_NAME -o orderer.example.com:7050 --tls true --cafile $ORDERER_CA
我们的配置更新事务表示原始配置和修改配置之间的差异,但订购服务会将其转换为完整通道配置。
3.Channel Group 更新
现在让我们继续更新orderer系统级别的通道组的功能级别。
与以前一样,第一步是获取最新的通道配置。
peer channel fetch config config_block.pb -o orderer.example.com:7050 -c $CH_NAME --tls --cafile $ORDERER_CA
configtxlator proto_decode --input config_block.pb --type common.Block --output config_block.json
jq .data.data[0].payload.data.config config_block.json > config.json
接下来,创建修改后的频道配置:
jq -s '.[0] * {"channel_group":{"values": {"Capabilities": .[1]}}}' config.json ./scripts/capabilities.json > modified_config.json
创建配置更新事务:
configtxlator proto_encode --input config.json --type common.Config --output config.pb
configtxlator proto_encode --input modified_config.json --type common.Config --output modified_config.pb
configtxlator compute_update --channel_id $CH_NAME --original config.pb --updated modified_config.pb --output config_update.pb
将配置更新打包到事务中:
configtxlator proto_decode --input config_update.pb --type common.ConfigUpdate --output config_update.json
echo '{"payload":{"header":{"channel_header":{"channel_id":"'$CH_NAME'", "type":2}},"data":{"config_update":'$(cat config_update.json)'}}}' | jq . > config_update_in_envelope.json
configtxlator proto_encode --input config_update_in_envelope.json --type common.Envelope --output config_update_in_envelope.pb
提交配置更新事务:
peer channel update -f config_update_in_envelope.pb -c $CH_NAME -o orderer.example.com:7050 --tls true --cafile $ORDERER_CA
在现有用户通道上启用功能(可选)
现在我们已经更新了orderer系统channel的功能,我们需要更新任何现有应用程序通道的配置
修改环境变了为mychannel
CH_NAME=mychannel
1.Orderer Group 启用
与orderer系统channel一样,我们的application通道也有一个Orderer Group 。
获取频道配置:
peer channel fetch config config_block.pb -o orderer.example.com:7050 -c $CH_NAME --tls --cafile $ORDERER_CA
configtxlator proto_decode --input config_block.pb --type common.Block --output config_block.json
jq .data.data[0].payload.data.config config_block.json > config.json
更改订货人组的功能级别:
jq -s '.[0] * {"channel_group":{"groups":{"Orderer": {"values": {"Capabilities": .[1]}}}}}' config.json ./scripts/capabilities.json > modified_config.json
创建配置更新:
configtxlator proto_encode --input config.json --type common.Config --output config.pb
configtxlator proto_encode --input modified_config.json --type common.Config --output modified_config.pb
configtxlator compute_update --channel_id $CH_NAME --original config.pb --updated modified_config.pb --output config_update.pb
将配置更新打包到事务中:
configtxlator proto_decode --input config_update.pb --type common.ConfigUpdate --output config_update.json
echo '{"payload":{"header":{"channel_header":{"channel_id":"'$CH_NAME'", "type":2}},"data":{"config_update":'$(cat config_update.json)'}}}' | jq . > config_update_in_envelope.json
configtxlator proto_encode --input config_update_in_envelope.json --type common.Envelope --output config_update_in_envelope.pb
提交配置更新事务:
peer channel update -f config_update_in_envelope.pb -c $CH_NAME -o orderer.example.com:7050 --tls true --cafile $ORDERER_CA
2.Channel Group 启用
现在我们需要更改channel
应用程序通道组的功能。
和以前一样,获取,解码和范围配置:
peer channel fetch config config_block.pb -o orderer.example.com:7050 -c $CH_NAME --tls --cafile $ORDERER_CA
configtxlator proto_decode --input config_block.pb --type common.Block --output config_block.json
jq .data.data[0].payload.data.config config_block.json > config.json
创建修改后的配置:
jq -s '.[0] * {"channel_group":{"values": {"Capabilities": .[1]}}}' config.json ./scripts/capabilities.json > modified_config.json
创建配置更新:
configtxlator proto_encode --input config.json --type common.Config --output config.pb
configtxlator proto_encode --input modified_config.json --type common.Config --output modified_config.pb
configtxlator compute_update --channel_id $CH_NAME --original config.pb --updated modified_config.pb --output config_update.pb
将配置更新打包到事务中:
configtxlator proto_decode --input config_update.pb --type common.ConfigUpdate --output config_update.json
echo '{"payload":{"header":{"channel_header":{"channel_id":"'$CH_NAME'", "type":2}},"data":{"config_update":'$(cat config_update.json)'}}}' | jq . > config_update_in_envelope.json
configtxlator proto_encode --input config_update_in_envelope.json --type common.Envelope --output config_update_in_envelope.pb
因为我们正在更新channel
组的配置,所以相关的orgs - Org1,Org2和OrdererOrg - 需要对其进行签名。这项任务通常由个别组织管理员执行。
首先,切换到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/Admin@org1.example.com/msp
CORE_PEER_ADDRESS=peer0.org1.example.com:7051
peer channel signconfigtx -f config_update_in_envelope.pb
和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/Admin@org2.example.com/msp
CORE_PEER_ADDRESS=peer0.org1.example.com:7051
peer channel signconfigtx -f config_update_in_envelope.pb
而作为OrdererOrg:
CORE_PEER_LOCALMSPID="OrdererMSP"
CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/users/Admin@example.com/msp
peer channel update -f config_update_in_envelope.pb -c $CH_NAME -o orderer.example.com:7050 --tls true --cafile $ORDERER_CA
3.Application Group启用
对于应用程序组,我们需要将环境变量重置为一个组织:
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/Admin@org1.example.com/msp
CORE_PEER_ADDRESS=peer0.org1.example.com:7051
现在,获取最新的通道配置(此过程现在应该非常熟悉):
peer channel fetch config config_block.pb -o orderer.example.com:7050 -c $CH_NAME --tls --cafile $ORDERER_CA
configtxlator proto_decode --input config_block.pb --type common.Block --output config_block.json
jq .data.data[0].payload.data.config config_block.json > config.json
创建修改后的频道配置:
jq -s '.[0] * {"channel_group":{"groups":{"Application": {"values": {"Capabilities": .[1]}}}}}' config.json ./scripts/capabilities.json > modified_config.json
Capabilities
将作为 Application
的 value
添加到channel_group
下(在mychannel
中)。
创建配置更新事务:
configtxlator proto_encode --input config.json --type common.Config --output config.pb
configtxlator proto_encode --input modified_config.json --type common.Config --output modified_config.pb
configtxlator compute_update --channel_id $CH_NAME --original config.pb --updated modified_config.pb --output config_update.pb
将配置更新打包到事务中:
configtxlator proto_decode --input config_update.pb --type common.ConfigUpdate --output config_update.json
echo '{"payload":{"header":{"channel_header":{"channel_id":"'$CH_NAME'", "type":2}},"data":{"config_update":'$(cat config_update.json)'}}}' | jq . > config_update_in_envelope.json
configtxlator proto_encode --input config_update_in_envelope.json --type common.Envelope --output config_update_in_envelope.pb
Org1签署交易:
peer channel signconfigtx -f config_update_in_envelope.pb
将环境变量设置为Org2:
export CORE_PEER_LOCALMSPID="Org2MSP"
export 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
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
export CORE_PEER_ADDRESS=peer0.org2.example.com:7051
Org2使用其签名提交配置更新事务:
peer channel update -f config_update_in_envelope.pb -c $CH_NAME -o orderer.example.com:7050 --tls true --cafile $ORDERER_CA
恭喜!您现在已在所有频道上启用了功能。
启用功能后验证事务
根据自己的链码进行查询-调用-查询。
其他
kafka的更新参考官方文档