天天看點

Fabric向現有組織中添加新節點

  • 1. 生成新節點證書
  • 2. 添加新節點配置資訊并啟動
  • 3. 新節點加入通道
  • 4. 安裝鍊碼
  • 5. 參考資料

向 fabric 網絡中添加新節點是常見的業務需求,基本上需要以下幾個步驟:

  1. 生成新節點證書
  2. 添加新節點配置資訊并啟動
  3. 新節點加入通道
  4. 安裝鍊碼

以 fabric-sample 庫中 v1.3 版本的 byfn.sh 建立的簡單測試網為例進行操作。這個測試網絡中包含兩個組織,每個組織都有兩個節點:

  • org1:
    • peer0.org1.example.com
    • peer1.org1.example.com
  • org2:
    • peer0.org2.example.com
    • peer1.org2.example.com

我們需要在 org2 中添加一個 peer2.org2.example.com 節點。

1. 生成新節點證書

每個節點都有相應的證書才能連接配接網絡,需要使用 cryptogen 工具生成新節點的證書。因為是新節點加入現有網絡組織,是以,需要使用

cryptogen extend

指令首先對現有網絡的證書檔案進行擴充。在執行該指令之前需要首先修改 crypto-config.yaml 配置檔案,将 org2 組織的節點數增加 1,其它的配置資訊不要修改。

點選檢視修改後的 crypto-config.yaml 配置檔案

# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#

# ---------------------------------------------------------------------------
# "OrdererOrgs" - Definition of organizations managing orderer nodes
# ---------------------------------------------------------------------------
OrdererOrgs:
  # ---------------------------------------------------------------------------
  # Orderer
  # ---------------------------------------------------------------------------
  - Name: Orderer
    Domain: example.com
    # ---------------------------------------------------------------------------
    # "Specs" - See PeerOrgs below for complete description
    # ---------------------------------------------------------------------------
    Specs:
      - Hostname: orderer
# ---------------------------------------------------------------------------
# "PeerOrgs" - Definition of organizations managing peer nodes
# ---------------------------------------------------------------------------
PeerOrgs:
  # ---------------------------------------------------------------------------
  # Org1
  # ---------------------------------------------------------------------------
  - Name: Org1
    Domain: org1.example.com
    EnableNodeOUs: true
    # ---------------------------------------------------------------------------
    # "Specs"
    # ---------------------------------------------------------------------------
    # Uncomment this section to enable the explicit definition of hosts in your
    # configuration.  Most users will want to use Template, below
    #
    # Specs is an array of Spec entries.  Each Spec entry consists of two fields:
    #   - Hostname:   (Required) The desired hostname, sans the domain.
    #   - CommonName: (Optional) Specifies the template or explicit override for
    #                 the CN.  By default, this is the template:
    #
    #                              "{{.Hostname}}.{{.Domain}}"
    #
    #                 which obtains its values from the Spec.Hostname and
    #                 Org.Domain, respectively.
    # ---------------------------------------------------------------------------
    # Specs:
    #   - Hostname: foo # implicitly "foo.org1.example.com"
    #     CommonName: foo27.org5.example.com # overrides Hostname-based FQDN set above
    #   - Hostname: bar
    #   - Hostname: baz
    # ---------------------------------------------------------------------------
    # "Template"
    # ---------------------------------------------------------------------------
    # Allows for the definition of 1 or more hosts that are created sequentially
    # from a template. By default, this looks like "peer%d" from 0 to Count-1.
    # You may override the number of nodes (Count), the starting index (Start)
    # or the template used to construct the name (Hostname).
    #
    # Note: Template and Specs are not mutually exclusive.  You may define both
    # sections and the aggregate nodes will be created for you.  Take care with
    # name collisions
    # ---------------------------------------------------------------------------
    Template:
      Count: 2
      # Start: 5
      # Hostname: {{.Prefix}}{{.Index}} # default
    # ---------------------------------------------------------------------------
    # "Users"
    # ---------------------------------------------------------------------------
    # Count: The number of user accounts _in addition_ to Admin
    # ---------------------------------------------------------------------------
    Users:
      Count: 1
  # ---------------------------------------------------------------------------
  # Org2: See "Org1" for full specification
  # ---------------------------------------------------------------------------
  - Name: Org2
    Domain: org2.example.com
    EnableNodeOUs: true
    Template:
      Count: 3 # count 表示組織下的peer數量,這裡需要把 2 改為 3
    Users:
      Count: 1
           

修改完成後即可使用

cryptogen extend

指令生成新節點證書,注意,這裡需要使用

--config

選項指定剛才修改的配置檔案:

$ cryptogen extend --config=crypto-config.yaml
           

生成之後,可以發現 org2 組織下增加了一個 peer2.org2.example.com peer:

$ tree crypto-config/peerOrganizations/org2.example.com/ -L 2
crypto-config/peerOrganizations/org2.example.com/
├── ca
│   ├── 7083e512097fba904427ffabefeae7b6cceb76563f40cee9f3e287d0ede0d38c_sk
│   └── ca.org2.example.com-cert.pem
├── msp
│   ├── admincerts
│   ├── cacerts
│   ├── config.yaml
│   └── tlscacerts
├── peers
│   ├── peer0.org2.example.com
│   ├── peer1.org2.example.com
│   └── peer2.org2.example.com     # 新增 peer
├── tlsca
│   ├── e0be59442c004221c94a48d68fb3d72f822d0bc88c31258ced26018c7d4d4de5_sk
│   └── tlsca.org2.example.com-cert.pem
└── users
    ├── [email protected]
    └── [email protected]

13 directories, 5 files
           

2. 添加新節點配置資訊并啟動

證書檔案生成之後,需要在 base/docker-compose-base.yaml 中添加新節點 peer2.org2.example.com 的配置資訊,包括環境變量、映射的端口号、證書檔案目錄等資訊。

點選檢視修改後的 base/docker-compose-base.yaml 配置檔案

# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#

version: '2'

services:

  orderer.example.com:
    container_name: orderer.example.com
    image: hyperledger/fabric-orderer:$IMAGE_TAG
    environment:
      - ORDERER_GENERAL_LOGLEVEL=INFO
      - 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
      # enabled TLS
      - 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]
    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
    - orderer.example.com:/var/hyperledger/production/orderer
    ports:
      - 7050:7050

  peer0.org1.example.com:
    container_name: peer0.org1.example.com
    extends:
      file: peer-base.yaml
      service: peer-base
    environment:
      - CORE_PEER_ID=peer0.org1.example.com
      - CORE_PEER_ADDRESS=peer0.org1.example.com:7051
      - CORE_PEER_GOSSIP_BOOTSTRAP=peer1.org1.example.com:7051
      - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.example.com:7051
      - CORE_PEER_LOCALMSPID=Org1MSP
    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
        - peer0.org1.example.com:/var/hyperledger/production
    ports:
      - 7051:7051
      - 7053:7053

  peer1.org1.example.com:
    container_name: peer1.org1.example.com
    extends:
      file: peer-base.yaml
      service: peer-base
    environment:
      - CORE_PEER_ID=peer1.org1.example.com
      - CORE_PEER_ADDRESS=peer1.org1.example.com:7051
      - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.org1.example.com:7051
      - CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org1.example.com:7051
      - CORE_PEER_LOCALMSPID=Org1MSP
    volumes:
        - /var/run/:/host/var/run/
        - ../crypto-config/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/msp:/etc/hyperledger/fabric/msp
        - ../crypto-config/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls:/etc/hyperledger/fabric/tls
        - peer1.org1.example.com:/var/hyperledger/production

    ports:
      - 8051:7051
      - 8053:7053

  peer0.org2.example.com:
    container_name: peer0.org2.example.com
    extends:
      file: peer-base.yaml
      service: peer-base
    environment:
      - CORE_PEER_ID=peer0.org2.example.com
      - CORE_PEER_ADDRESS=peer0.org2.example.com:7051
      - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org2.example.com:7051
      - CORE_PEER_GOSSIP_BOOTSTRAP=peer1.org2.example.com:7051
      - CORE_PEER_LOCALMSPID=Org2MSP
    volumes:
        - /var/run/:/host/var/run/
        - ../crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/msp:/etc/hyperledger/fabric/msp
        - ../crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls:/etc/hyperledger/fabric/tls
        - peer0.org2.example.com:/var/hyperledger/production
    ports:
      - 9051:7051
      - 9053:7053

  peer1.org2.example.com:
    container_name: peer1.org2.example.com
    extends:
      file: peer-base.yaml
      service: peer-base
    environment:
      - CORE_PEER_ID=peer1.org2.example.com
      - CORE_PEER_ADDRESS=peer1.org2.example.com:7051
      - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.org2.example.com:7051
      - CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org2.example.com:7051
      - CORE_PEER_LOCALMSPID=Org2MSP
    volumes:
        - /var/run/:/host/var/run/
        - ../crypto-config/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/msp:/etc/hyperledger/fabric/msp
        - ../crypto-config/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/tls:/etc/hyperledger/fabric/tls
        - peer1.org2.example.com:/var/hyperledger/production
    ports:
      - 10051:7051
      - 10053:7053

  # 新增加的節點配置資訊
  peer2.org2.example.com:
    container_name: peer2.org2.example.com
    extends:
      file: peer-base.yaml
      service: peer-base
    environment:
      - CORE_PEER_ID=peer2.org2.example.com
      - CORE_PEER_ADDRESS=peer2.org2.example.com:7051
      - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer2.org2.example.com:7051
      - CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org2.example.com:7051
      - CORE_PEER_LOCALMSPID=Org2MSP
    volumes:
        - /var/run/:/host/var/run/
        - ../crypto-config/peerOrganizations/org2.example.com/peers/peer2.org2.example.com/msp:/etc/hyperledger/fabric/msp
        - ../crypto-config/peerOrganizations/org2.example.com/peers/peer2.org2.example.com/tls:/etc/hyperledger/fabric/tls
        - peer2.org2.example.com:/var/hyperledger/production
    ports:
      - 11051:7051
      - 11053:7053
           

為了友善對各個節點的控制,還會啟動一個名為 cli 的容器,使用者可以進入該容器通過修改相關環境變量以不同的節點身份運作 peer 等指令。因為新增一個新節點,是以需要對現有的 docker-compose-cli.yaml 配置檔案進行 3 處修改,主要新增 peer2.org2.example.com 節點相關資訊。

點選檢視修改後的 docker-compose-cli.yaml 配置檔案

# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#

version: '2'

volumes:
  orderer.example.com:
  peer0.org1.example.com:
  peer1.org1.example.com:
  peer0.org2.example.com:
  peer1.org2.example.com:
  peer2.org2.example.com: # 新增節點卷

networks:
  byfn:

services:

  orderer.example.com:
    extends:
      file:   base/docker-compose-base.yaml
      service: orderer.example.com
    container_name: orderer.example.com
    networks:
      - byfn

  peer0.org1.example.com:
    container_name: peer0.org1.example.com
    extends:
      file:  base/docker-compose-base.yaml
      service: peer0.org1.example.com
    networks:
      - byfn

  peer1.org1.example.com:
    container_name: peer1.org1.example.com
    extends:
      file:  base/docker-compose-base.yaml
      service: peer1.org1.example.com
    networks:
      - byfn

  peer0.org2.example.com:
    container_name: peer0.org2.example.com
    extends:
      file:  base/docker-compose-base.yaml
      service: peer0.org2.example.com
    networks:
      - byfn

  peer1.org2.example.com:
    container_name: peer1.org2.example.com
    extends:
      file:  base/docker-compose-base.yaml
      service: peer1.org2.example.com
    networks:
      - byfn

  # 新增的節點服務
  peer2.org2.example.com:
    container_name: peer2.org2.example.com
    extends:
      file:  base/docker-compose-base.yaml
      service: peer2.org2.example.com
    networks:
      - byfn

  cli:
    container_name: cli
    image: hyperledger/fabric-tools:$IMAGE_TAG
    tty: true
    stdin_open: true
    environment:
      - GOPATH=/opt/gopath
      - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
      #- CORE_LOGGING_LEVEL=DEBUG
      - CORE_LOGGING_LEVEL=INFO
      - CORE_PEER_ID=cli
      - CORE_PEER_ADDRESS=peer0.org1.example.com:7051
      - CORE_PEER_LOCALMSPID=Org1MSP
      - CORE_PEER_TLS_ENABLED=true
      - 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/[email protected]/msp
    working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
    command: /bin/bash
    volumes:
        - /var/run/:/host/var/run/
        - ./../chaincode/:/opt/gopath/src/github.com/chaincode
        - ./crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/
        - ./scripts:/opt/gopath/src/github.com/hyperledger/fabric/peer/scripts/
        - ./channel-artifacts:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts
    depends_on:
      - orderer.example.com
      - peer0.org1.example.com
      - peer1.org1.example.com
      - peer0.org2.example.com
      - peer1.org2.example.com
      - peer2.org2.example.com # 新增 cli 對 peer2.org2.example.com 服務的依賴
    networks:
      - byfn
           

之後使用 docker-compose 啟動新節點容器并重新建立 cli 容器:

$ docker-compose -f docker-compose-cli.yaml up -d
Creating peer2.org2.example.com ... done
peer0.org1.example.com is up-to-date
peer1.org1.example.com is up-to-date
orderer.example.com is up-to-date
peer0.org2.example.com is up-to-date
Creating peer2.org2.example.com ...
peer1.org2.example.com is up-to-date
Recreating cli ... done
           

至此,新節點 peer2.org2.example.com 已經啟動。

3. 新節點加入通道

此時該節點并沒有加入到任何一個通道中,需要進入 cli 容器執行添加操作。

進入 cli 指令行,之後的所有操作均在容器内部進行:

設定環境變量,使 cli 切換到 peer2.org2.example.com 下:

$ export CHANNEL_NAME=mychannel
$ CORE_PEER_LOCALMSPID="Org2MSP"
$ CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer2.org2.example.com/tls/ca.crt
$ CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp
$ CORE_PEER_ADDRESS=peer2.org2.example.com:7051
           

從 orderer 上拉取通道的創世區塊:

$ peer channel fetch oldest mychannel.block -c mychannel -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
2020-12-09 07:17:52.078 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2020-12-09 07:17:52.079 UTC [cli/common] readBlock -> INFO 002 Received block: 0
           

加入通道:

$ peer channel join -b mychannel.block -o orderer.example.com:7050
2020-12-09 07:18:01.562 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2020-12-09 07:18:01.598 UTC [channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel
           

4. 安裝鍊碼

安裝鍊碼:

$ peer chaincode install -n mycc -v 1.0 -p github.com/chaincode/chaincode_example02/go
2020-12-09 09:02:29.834 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 001 Using default escc
2020-12-09 09:02:29.834 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 002 Using default vscc
2020-12-09 09:02:30.034 UTC [chaincodeCmd] install -> INFO 003 Installed remotely response:<status:200 payload:"OK" >
           

同一個通道内所有節點隻需要對同樣的鍊碼執行個體化一次即可,該鍊碼已經在之前的舊有節點初始化一次,是以新節點安裝完鍊碼後并不需要再次執行個體化,直接可以對鍊碼進行調用。

檢驗鍊碼是否安裝成功就需要簡單查詢鍊碼内容:

$ peer chaincode query -C mychannel -n mycc -c '{"Args":["query","a"]}'
82
           

5. 參考資料

  • Fabric1.1 新增組織内節點

繼續閱讀