티스토리 뷰

하이퍼레저 패브릭 2.2 버전으로 멀티 호스트 (2 Host) 구축을 실습해봤습니다.

 

환경 :

Ubuntu 20.04 VM - Host1, Host2

docker 20.10.13

go 1.17.8

Hyperledger Fabric v2.2

 

과정은 다음과 같습니다.

1. Host1 : 컨테이너 구성위한 yaml 작성 

2. Host1 : 호스트가 공통으로 가져야 하는 genesis block, transaction file 등 생성

3. Host2 : Host1에서 생성한 공통 파일 가져오기 (github에 올려서 clone 받음)

4. docker swarm으로 Host1, Host2의 컨테이너 연결

5. Host1 : 채널 생성

6. Host1 : 모든 피어 노드 채널 가입 (애플리케이션인 cli를 Host1만 가지도록 설계하여 cli 애플리케이션 컨테이너로 트랜잭션 컨트롤)

7. 체인코드 배포

 

각 호스트 구성은 다음과 같습니다.

Host1 : orderer, orderer1, peer0.org1, peer1.org1, cli

Host2 : orderer2, peer0.org2, peer1.org2

 

네트워크 구성은 다음과 같습니다.

network : testnet
domain : example.com
port : orderer : 7050, orderer1 : 8050 orderer2 : 9050, peer0.Org1 : 7051, peer1.Org1 : 8051, peer0.Org2 : 9051, peer1.Org2 : 10051
channel : channel1

 

인증서는 cryptogen으로 생성하였는데 이 때 생성하는 모든 노드의 인증서의 개인키와 같이 생성되기 때문에 Host2에 복사할 때는 개인키는 복사 안 하도록 하였습니다.

 

Ordering은 기본으로 제공하는 Raft 오더링을 사용하였고, 체인코드는 fabric-samples/asset-transfer-basic을 사용하였습니다.

각 Org의 앵커피어는 peer0 입니다.

fabric-samples 아래에 해당 디렉토리를 만들었고 fabric-samples/bin, fabric-samples/chaincode가 필요합니다. 

 

코드 : https://github.com/hobin-jang/2host-test

 

참고 :

 

과정은 다음과 같습니다.

 

1. Host1 : 컨테이너 구성위한 yaml 작성 (위 참고 블로그의 yaml을 수정하였습니다.)

 

- configtx.yaml

 

- crypto-config.yaml

- base/docker-compose-base.yaml

- base/peer-base.yaml

 

2. Host1 : 호스트가 공통으로 가져야 하는 genesis block, transaction file 등 생성

 

bin 파일 경로 설정, FABRIC_CFG_PATH 설정 (configtx.yaml 경로)

export PATH=${PWD}/../bin:$PATH
export FABRIC_CFG_PATH=${PWD}

인증서 발급

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

genesis block 생성

../bin/configtxgen -profile SampleMultiNodeEtcdRaft -channelID system-channel -outputBlock ./channel-artifacts/genesis.block

 

트랜잭션 파일 생성

../bin/configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel1.tx -channelID channel1

 

앵커피어 트랜잭션 파일 생성 (Org1)

../bin/configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID channel1 -asOrg Org1MSP

 

앵커피어 트랜잭션 파일 생성 (Org2)

../bin/configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org2MSPanchors.tx -channelID channel1 -asOrg Org2MSP

 

genesis block 생성 시 오더링 채널 이름과 애플리케이션 채널 이름을 다르게 설정해주어야 합니다... 그렇지 않으면 멀티호스트 구성 시 같은 채널로 인식해서 채널 생성 시 Host2에 필요한 노드를 요구하는 에러가 뜹니다....

 

3. Host2 : Host1에서 생성한 공통 파일 가져오기 (github에 올려서 clone 받음)

아무 방법으로나 해당 파일을 받으면 됩니다. 저는 깃헙에 올려서 clone 받았습니다. cryptogen으로 생성 시 모든 노드의 개인키와 인증서가 같이 발급되어 개인키는 gitignore로 안 올라가도록 처리했습니다.

4. docker swarm으로 Host1, Host2의 컨테이너 연결

Host1을 swarm의 manager로 설정하고 Host2를 worker로 설정했습니다.

 

Host1 : 

docker swarm init --advertise-addr <Host1 ip>
docker swarm join-token manager

Host2 :

docker swarm join --token <token>

Host1 :

docker network create --attachable --driver overlay testnet

각 Host에서 컨테이너 올리기

 

5. Host1 : 채널 생성

docker exec cli peer channel create -o orderer.example.com:7050 -c channel1 -f ./channel-artifacts/channel1.tx --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

 

6. Host1 : 모든 피어 노드 채널 가입 (애플리케이션인 cli를 Host1만 가지도록 설계하여 cli 애플리케이션 컨테이너로 트랜잭션 컨트롤)

 

채널 가입 (peer0.org1.example.com)

cli 컨테이너 기본 환경 변수가 peer0.org1과 동일하기 때문에 다른 환경 변수 설정 없이 가입 진행

docker exec cli peer channel join -b channel1.block

채널 가입 (peer1.org1.example.com)

docker exec -e CORE_PEER_ADDRESS=peer1.org1.example.com:8051 -e CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/ca.crt cli peer channel join -b channel1.block

 

채널 가입 (peer0.org2.example.com)

docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 -e CORE_PEER_LOCALMSPID="Org2MSP" -e 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 cli peer channel join -b channel1.block

 

채널 가입 (peer1.org2.example.com)

docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp -e CORE_PEER_ADDRESS=peer1.org2.example.com:10051 -e CORE_PEER_LOCALMSPID="Org2MSP" -e CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/tls/ca.crt cli peer channel join -b channel1.block

앵커피어 지정 (cli 기본 환경변수가 peer0.org1 에 맞춰짐)

docker exec cli peer channel update -o orderer.example.com:7050 -c channel1 -f ./channel-artifacts/Org1MSPanchors.tx --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

앵커피어 지정 (peer0.org2 가 org2의 앵커피어)

docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 -e CORE_PEER_LOCALMSPID="Org2MSP" -e 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 cli peer channel update -o orderer.example.com:7050 -c channel1 -f ./channel-artifacts/Org2MSPanchors.tx --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

연결 확인 (Host1, Host2)

Host2에서는 아무것도 안 했지만 swarm으로 연결되어 있기 때문에 채널 정보를 잘 불러옵니다.

 

7. 체인코드 배포

fabric-samples/asset-transfer-basic/chaincode-go 를 이용해 체인코드를 배포합니다. (현재 디렉토리 : fabric-samples/2host-test) 그리고 chaincode 디렉토리로 옮겨줍니다.

cd ../asset-transfer-basic/chaincode-go
GO111MODULE=on go mod vendor
mv chaincode-go asset-transfer-basic-go
mv asset-transfer-basic-go ./../chaincode/

 

 Host1 : 체인코드 패키지 만들기

docker exec cli peer lifecycle chaincode package basic.tar.gz --path /opt/gopath/src/github.com/chaincode/asset-transfer-basic-go --label basic_1.0

체인코드 각 peer에 설치

peer0.org1 : 

docker exec cli peer lifecycle chaincode install basic.tar.gz

peer1.org1 : 

CORE_PEER_ADDRESS=peer1.org1.example.com:8051 -e CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/ca.crt cli peer lifecycle chaincode install basic.tar.gz

peer0.org2 :

docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 -e CORE_PEER_LOCALMSPID="Org2MSP" -e 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 cli peer lifecycle chaincode install basic.tar.gz

peer1.org2 :

docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp -e CORE_PEER_ADDRESS=peer1.org2.example.com:10051 -e CORE_PEER_LOCALMSPID="Org2MSP" -e CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/tls/ca.crt cli peer lifecycle chaincode install basic.tar.gz

각 호스트에 체인코드 이미지가 올라갔습니다.

아직 승인 안 받아서 아무것도 안 나옵니다.

체인코드 아이디 확인

docker exec cli peer lifecycle chaincode queryinstalled

Org별로 체인코드 승인 받기

org1 :

docker exec cli peer lifecycle chaincode approveformyorg --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 --channelID channel1 --name basic --version 1 --sequence 1 --waitForEvent --package-id basic_1.0:4f242eb6ce2de3f425a471fd6278cce6da267793fb427b845902bd17f082aaac

org2 :

docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 -e CORE_PEER_LOCALMSPID="Org2MSP" -e 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 cli peer lifecycle chaincode approveformyorg --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 --channelID channel1 --name basic --version 1 --sequence 1 --waitForEvent --package-id basic_1.0:4f242eb6ce2de3f425a471fd6278cce6da267793fb427b845902bd17f082aaac

 

승인 결과 확인

docker exec cli peer lifecycle chaincode checkcommitreadiness --channelID channel1 --name basic --version 1 --sequence 1

 

체인코드 커밋 (peer0를 앵커 피어로 설정했으므로 peer0로 체인코드 커밋을 합니다.)

docker exec cli peer lifecycle chaincode commit -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 --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt --channelID channel1 --name basic --version 1 --sequence 1

 

체인코드 시작 (2Host가 제대로 됨을 확인하기 위해 orderer2를 통해 오더링 시킵니다.) (invoke로 트랜잭션 날림)

docker exec cli peer chaincode invoke -o orderer2.example.com:9050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer2.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C channel1 -n basic --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"Args":["initLedger"]}'

 

체인코드 확인 (peer0.org2를 이용해 확인) (체인에 쿼리 날리기)

docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 -e CORE_PEER_LOCALMSPID="Org2MSP" -e 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 cli peer chaincode query -n basic -C channel1 -c '{"Args":["GetAllAssets"]}'

 

블록 결과 확인

docker exec cli peer channel getinfo -c channel1

 

처음에 오더링 서비스랑 애플리케이션 서비스 채널 이름을 동일하게 설정해놨어서 해결한다고 하루를 날렸었습니다.... (에러가 이거 때문인지 몰랐었다....)

그리고 애플리케이션 역할인 cli가 Host1에만 올라가도록 yaml을 만들었지만 제대로 된 설계 시 cli와 sdk를 연결해 웹 서비스로 체인 네트워크에 접속하거나 모든 호스트에서 애플리케이션을 이용하도록 설계해야겠습니다.

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
TAG
more
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
글 보관함