Hyperledger Fabric v1.1 在线更新配置的步骤

1. 概览

由于Hyperledger Fabric目前没有提供动态更新配置的API,只能通过peer命令来发送protobuf数据,所以配置更新非常的繁琐。
本例以向Orderer Group添加Capabilities Requirements和给Channel增加Organization为例,详细记录Fabric v1.1下更新配置的步骤。

2. 条件

2.1. 初始配置

本文的样例初始配置来自Fabric v1.0,包含1个Orderer服务节点和2个Organization.

configtx.yaml配置文件Orderer部分内容如下
Profiles:
    TwoOrgsOrdererGenesis:
        Orderer:
            <<: *OrdererDefaults
            Organizations:
                - *OrdererOrg
        Consortiums:
            SampleConsortium:
                Organizations:
                    - *Org1
                    - *Org2
    TwoOrgsChannel:
        Consortium: SampleConsortium
        Application:
            <<: *ApplicationDefaults
            Organizations:
                - *Org1
                - *Org2

2.2. Fabric环境:

    # docker ps
    IMAGE                                        NAMES
    hyperledger/fabric-tools:x86_64-1.1.0        cli
    hyperledger/fabric-peer:x86_64-1.1.0         peer0.org1.example.com
    hyperledger/fabric-peer:x86_64-1.1.0         peer1.org2.example.com
    hyperledger/fabric-peer:x86_64-1.1.0         peer0.org2.example.com
    hyperledger/fabric-peer:x86_64-1.1.0         peer1.org1.example.com
    hyperledger/fabric-ca:x86_64-1.1.0           ca_peerOrg2
    hyperledger/fabric-ca:x86_64-1.1.0           ca_peerOrg1
    hyperledger/fabric-orderer:x86_64-1.1.0      orderer.example.com

2.3. Tools:

    # Fabric的peer,用来拉取和推送配置
    $ peer --version
    peer:
         Version: 1.1.0
         Go version: go1.9.2
         OS/Arch: linux/amd64
         Experimental features: false
         Chaincode:
          Base Image Version: 0.4.6
          Base Docker Namespace: hyperledger
          Base Docker Label: org.hyperledger.fabric
          Docker Namespace: hyperledge

    # Fabric的configtxlator, 用于在protobuf和json间做转换,以及计算配置的差异
    $ configtxlator --help
    usage: configtxlator [<flags>] <command> [<args> ...]
    
    Utility for generating Hyperledger Fabric channel configurations
    
    Flags:
      --help  Show context-sensitive help (also try --help-long and --help-man).
    
    Commands:
      help [<command>...]
        Show help.
    
      start [<flags>]
        Start the configtxlator REST server
    
      proto_encode --type=TYPE [<flags>]
        Converts a JSON document to protobuf.
    
      proto_decode --type=TYPE [<flags>]
        Converts a proto message to JSON.
    
      compute_update --channel_id=CHANNEL_ID [<flags>]
        Takes two marshaled common.Config messages and computes the config update which transitions between the two.
    
      version
        Show version information
    

    $ configtxlator version
    configtxlator:
         Version: 1.1.1-snapshot-c257bb3
         Go version: go1.10.1
         OS/Arch: linux/amd64
         
    #jq, 用于读写json文件.
    $ apt install jq
    


3. 更新Capabilities Requirements的步骤

3.1. 启动configtxlator.

configtxlator v1.0.x版本只能运行成server, v1.1.x可作为命令行工具单独使用,也可运行成server来提供服务
本例中运行为server, 工具默认会监听本地7059端口,也可指定端口

$ configtxlator start
2018-05-03 09:28:18.090 CST [configtxlator] startServer -> INFO 001 Serving HTTP requests on 0.0.0.0:7059

3.2. 设置Fabric CLI运行环境变量

$ env |grep CORE 
CORE_PEER_LOCALMSPID=OrdererMSP
CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
CORE_PEER_TLS_ENABLED=true
CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/crypto/users/Admin@example.com/msp
CORE_PEER_ID=cli
CORE_PEER_ADDRESS=peer0.org1.example.com:7051
ORDERER_CA=/etc/hyperledger/crypto/orderer/tls/ca.crt
CH_NAME=mychannel

其中CORE_PEER_LOCALMSPID 和 CORE_PEER_MSPCONFIGPATH要注意一定要使用Orderer的Admin,否则只能拉取配置,不能推送回去。

3.3 使用Fabric CLI拉取配置

$ peer channel fetch config config_block.pb -o orderer.example.com:7050 -c $CH_NAME  --tls --cafile $ORDERER_CA

命令运行成功会把被encode的配置写入config_block.pb文件

3.4 把配置转成可读的json格式

$ curl -s -X POST --data-binary @config_block.pb http://localhost:7059/protolator/decode/common.Block" | jq . >  config_block.json

这里根据消息类型的不同,调用的URL也会有不同,本例中用到的是common.Block
其他的类型我以后会深入研究一下。

3.5 从json中取出配置部分

$ jq .data.data[0].payload.data.config config_block.json > config.json

3.6 把要更新的内容加入当前的配置json

这里是和更新配置相关度最高的一步,其他步骤基本都是标准的流程.

$ jq -s '.[0] * {"channel_group":{"groups":{"Orderer": {"values": {"Capabilities": .[1]}}}}}' config.json capability.json >  updated_config.json

这一步在channel_group.groups.Orderer.values中加入Capabilities这个key,value是capability.json中的内容:

{
    "mod_policy": "Admins",
    "value": {
      "capabilities": {
        "V1_1": {}
      }
    },
    "version": "0"
}

3.7 把原始的配置的json数据转换成pb

$ curl -s -X POST --data-binary @config.json http://localhost:7059/protolator/encode/common.Config >  config.pb

3.8 把更新后配置的json数据转换成pb

$ curl -s -X POST --data-binary @updated_config.json http://localhost:7059/protolator/encode/common.Config >  updated_config.pb

3.9 获取更新后的配置和原始配置的相比需要update的部分

$ curl -s -X POST -F channel="${CH_NAME}" -F "original=@config.pb" -F "updated=@updated_config.pb" http://localhost:7059/configtxlator/compute/update-from-configs > config_update.pb

3.10 把update转换成可读的json

$ curl -s -X POST --data-binary @config_update.pb http://localhost:7059/protolator/decode/common.ConfigUpdate" | jq . >  config_update.json

其中可以找到我们需要update的部分:

$ grep -A6 Capabilities config_update.json
      "Capabilities": {
        "mod_policy": "Admins",
        "value": {
          "capabilities": {
            "V1_1": {}
          }
        },

3.11 把update打包成Fabric CLI协议的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

3.12 把json编码成pb格式

$ curl -s -X POST --data-binary @config_update_in_envelope.json http://localhost:7059/protolator/encode/common.Envelope >  config_update_in_envelope.pb

3.13 把最终的update提交到channel

$ peer channel update -f 'config_update_in_envelope.pb' -o orderer.example.com:7050 -c $CH_NAME --tls --cafile  $ORDERER_CA
2018-05-03 03:01:56.403 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2018-05-03 03:01:56.488 UTC [channelCmd] update -> INFO 002 Successfully submitted channel update
2018-05-03 03:01:56.488 UTC [main] main -> INFO 003 Exiting....

我最初没有使用Admin MSP,遇到了如下错误:

2018-05-02 15:04:24.739 UTC [channelCmd] InitCmdFactory -> INFO 002 Endorser and orderer connections initialized
Error: got unexpected status: BAD_REQUEST -- error authorizing update: error validating DeltaSet: policy for [Group]  /Channel/Orderer not satisfied: Failed to reach implicit threshold of 1 sub-policies, required 1 remaining

3.14. 验证

使用3.3和3.4中的方法拉取并解析配置,发现配置文件中已经有了Capabilities的内容

$ peer channel fetch config config_block.pb -o orderer.example.com:7050 -c $CH_NAME  --tls --cafile $ORDERER_CA
$ curl -s -X POST --data-binary @config_block.pb http://localhost:7059/protolator/decode/common.Block" | jq . >  config_block.json
$ grep Capabilities -A6 config_block.json
                  "Capabilities": {
                    "mod_policy": "Admins",
                    "value": {
                      "capabilities": {
                        "V1_1": {}
                      }
                    },
                    

整个过程用到的文件如下:

0.config_block.pb
1.config_block.json
2.config.json
3.updated_config.json
4.config.pb
5.updated_config.pb
6.config_update.pb
7.config_update.json
8.config_update_in_envelope.json
9.config_update_in_envelope.pb
capabilities.json

4. 给Channel添加Organization的步骤

更新Channel level的配置和更新Orderer类似,这节主要写的是和第3节差异的地方

4.1 更新Organization需要update哪些数据?

看看创世块, 使用configtxlator工具,把创世块解码成json,我们会发现
Organization的crypto信息也被写在了配置中,那么手动构造这些json就太复杂了.
clipboard.png

4.2 生成新的Org配置

这里有2种方法
1:

在原有的cryptogen.yaml和configtx.yaml里添加Org3相关部分,使用cryptogen和configtxgen重新生成crypto和genesis block到独立的目录.
然后把新的crypto目录中org3的目录拷贝到原有的crypto目录下对应的路径.
再把原有的genesis block和新的genesis block使用configtxlator工具解码,使用diff工具比较解码后的json文件. 得出需要update的部分

2:

新建org3-crypto.yaml和configtx.yaml文件,其中只描述Org3相关内容,然后运行cryptogen和configtxgen.
把新的crypto目录中org3的目录拷贝到原有的crypto目录下对应的路径.

cryptogen.yaml配置样例:

PeerOrgs:
  - Name: Org3
    Domain: org3.example.com
    EnableNodeOUs: true
    Template:
      Count: 2
    Users:
      Count: 1

cryptogen命令:

cryptogen generate --config=./org3-crypto.yaml


      

configtx.yaml配置样例:

Organizations:
    - &Org3
        Name: Org3MSP
        ID: Org3MSP
        MSPDir: crypto-config/peerOrganizations/org3.example.com/msp
        AnchorPeers:
            - Host: peer0.org3.example.com
              Port: 7051

configtxgen命令:

$ configtxgen -printOrg Org3MSP > patch.json  

这个patch.json就是要update给Channel的内容了.
我选择了方法2

4.3 更新步骤

步骤与3.3 - 3.13类似
与3.6不同之处:

jq -s '.[0] * {"channel_group":{"groups":{"Consortiums": {"groups": {"SampleConsortium": {"groups": {"Org3MSP": .[1]}}}}}}}' config.json patch.json >  updated_config.json

与3.13不同之处:

由于这里更新的是Channel的Org配置,Channel的修改策略默认是超过半数通过.
假设此Channel中已经有2个Org,则需2个Org签名来通过block上链

Organization CLI:

首先切换当前CLI环境到Org1 Admin
    $ env |grep CORE
    CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/crypto/peers/tls/ca.crt
    CORE_PEER_LOCALMSPID=Org1MSP
    CORE_PEER_TLS_ENABLED=true
    CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/crypto/users/Admin@org1.example.com/msp
    CORE_PEER_ID=cli.org1
    CORE_LOGGING_LEVEL=DEBUG
    CORE_PEER_ADDRESS=peer0.org1.example.com:7051
Org1签名:
    $ peer channel signconfigtx config_update_in_envelope.pb
Org1签名后pb文件追加了部分内容,把pb文件放在Org2 CLI可以访问的路径,切换CLI环境到Org2 Admin:
    $ env |grep CORE
    CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/crypto/peers/tls/ca.crt
    CORE_PEER_LOCALMSPID=Org2MSP
    CORE_PEER_TLS_ENABLED=true
    CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/crypto/users/Admin@org2.example.com/msp
    CORE_PEER_ID=cli.org2
    CORE_LOGGING_LEVEL=DEBUG
    CORE_PEER_ADDRESS=peer0.org2.example.com:7051
Org2提交update到Channel,会自动附上Org2的签名:
    $ peer channel update -f 'config_update_in_envelope.pb' -o orderer.example.com:7050 -c $CH_NAME --tls --cafile  $ORDERER_CA
    2018-05-04 05:35:00.422 UTC [channelCmd] update -> INFO 010 Successfully submitted channel update
    2018-05-04 05:35:00.423 UTC [main] main -> INFO 011 Exiting.....

完成,验证方法与3节一致.
至此,可以启动Org3的peer节点并让Org3加入Channel了.

5. 参考

http://hyperledger-fabric.rea...
http://hyperledger-fabric.rea...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值