This directory contains Helm Charts for creating an Hyperledger Fabric network developed in a sandbox.
Obtain a Kubernetes cluster and set KUBECONFIG
to point to it.
export KUBECONFIG=<your kubernetes config file>
-
Download and extract Helm for your platform
-
Follow the instruction on how to set up help for your specific platform
-
Create a namespace where to install the network
kubectl create namespace <namespace>
Note: If using any Kubernetes manager (e.g. Rancher), it is possible this command is enabled only via UI
-
Initialise helm and upgrade the tiller if exists
helm init [--tiller-namespace <namespace>] --upgrade
Complete setup with volumes attached to single components and data persistency
This setup includes:
-
Data persistency for ledger (blockchain and state)
-
Resources such as volumes, secrets and config are attached to single components (and not shared)
-
Private keys, certificates and configuration files stored as secrets
-
Configurations of environment variables stored as
ConfigMap
-
CA equipped with PostgreSQL/MySQL database for storing certificates
-
Registration and enrollment of users is done dynamically
Deploy all the official charts by running the following commands:
./run.sh start -i
# or alternatively
./run.sh start prod
Standard 2-orgs-1-peer not-extandable setup with one unique shared volume; no secrets; no data persistency
Deploy all the local charts by running the following commands:
./run.sh start
Clean up the environment by running the following commands:
./run.sh clean <namespace>
This example is made for the Production
extandable configuration, but can be easily changed to support the Staging
one.
First, set some environment variables:
export namespaece=<k8s namespace where to set up the network>
export channel_name=<channel name id>
export chaincode_name=<chaincode name id>
export peer_address=<full address of the peer including port>
export orderer_address=<full address of the orderer including port>
export chaincode_path=<absolute pathname where your chaincode sits>
export chaincode_name=<partial pathname where your chaincode sits>
export chaincode_version=<initial version of the chaincode to deploy>
# e.g.
export namespaece="blockchain"
export channel_name="mychannel"
export chaincode_name="mychaincode"
export peer_address="org1peer1-hlf-peer:30110"
export orderer_address="orderer-hlf-ord:31010"
export chaincode_path="/home/me/stuff/go/cc"
export chaincode_name="cc"
export chaincode_version="1.0"
Copy the cloud/remote config, add to a file and export it as KUBECONFIG
variable
export KUBECONFIG=<rancher configuration file>
Retrieve the CLI container name
cli_pod=$(kubectl get pods --namespace $namespace -l "app=hlf-tools,release=cli" -o jsonpath="{.items[0].metadata.name}")
Now we are ready to start.
Generate the new channel configuration
./run.sh generate channeltx $channel_name ${PWD}/hlf ${PWD}/hlf/config ${PWD}/hlf/cryptos OneOrgOrdererGenesis OneOrgChannel Org1MSP
Add the channel configurations into a new secret
org_msp=<organisation id of the peer>
# e.g.
org_msp=Org1MSP
kubectl create secret generic --namespace $namespace hlf--${channel_name}-channel --from-file=${PWD}/hlf/channels/$channel_name/${channel_name}_tx.pb --from-file=${PWD}/hlf/channels/$channel_name/${org_msp}_anchors_tx.pb
Upgrade peer container adding the new secret
peer_name=<name assigned to the peer>
# e.g.
peer_name=org1peer1
helm upgrade --namespace $namespace --tiller-namespace $namespace --reuse-values --set secrets.channel=hlf--${channel_name}-channel $peer_name ./hlf/charts/hlf-peer
Retrieve the peer container name
peer_pod=$(kubectl get pods --namespace $namespace -l "app=hlf-peer,release=${peer_name}" -o jsonpath="{.items[0].metadata.name}")
Create the channel through the peer
kubectl exec --namespace $namespace $peer_pod -- bash -c "CORE_PEER_MSPCONFIGPATH=/var/hyperledger/admin_msp peer channel create -o ${orderer_address} -c $channel_name -f /hl_config/channel/${channel_name}_tx.pb"
Fetch the channel block from the orderer
kubectl exec --namespace $namespace $peer_pod -- bash -c "CORE_PEER_MSPCONFIGPATH=/var/hyperledger/admin_msp peer channel fetch config /${channel_name}.block -c $channel_name -o ${orderer_address}"
Join the channel with the peer
kubectl exec --namespace $namespace $peer_pod -- bash -c "CORE_PEER_MSPCONFIGPATH=/var/hyperledger/admin_msp peer channel join -b /${channel_name}.block"
kubectl exec --namespace $namespace $cli_pod -- bash -c "peer channel fetch config ${channel_name}.pb -c $channel_name -o $orderer_address
Copy chaincode codebase into peer container
kubectl cp --namespace $namespace $chaincode_path ${cli_pod}:/opt/gopath/src/chaincode/${chaincode_name}
Install chaincode
kubectl exec --namespace $namespace $cli_pod -- bash -c "CORE_PEER_LOCALMSPID=Org1MSP CORE_PEER_MSPCONFIGPATH=/var/hyperledger/admin_msp CORE_PEER_ADDRESS=${peer_address} peer chaincode install -n $chaincode_name -v $chaincode_version -p chaincode/${chaincode_name}"
# e.g.
Instantiate chaincode
kubectl exec --namespace $namespace $cli_pod -- bash -c "CORE_PEER_LOCALMSPID=Org1MSP CORE_PEER_MSPCONFIGPATH=/var/hyperledger/admin_msp CORE_PEER_ADDRESS=${peer_address} peer chaincode instantiate -o $orderer_address -n $chaincode_name -v $chaincode_version -C $channel_name -l <language of the chaincode> -c <args in json format> -P <endorsment policy>"
# e.g.
kubectl exec --namespace blockchain hlf-cli-pod -- bash -c "CORE_PEER_LOCALMSPID=Org1MSP CORE_PEER_MSPCONFIGPATH=/var/hyperledger/admin_msp CORE_PEER_ADDRESS=peer0:30110 peer chaincode instantiate -o orderer:31010 -n cc -v 1.0 -C mychannel -l golang -c '{\"Args\":[]}' -P \"OR('Org1MSP.member')\""
Install chaincode
chaincode_version=<a not-existing version of chaincode>
kubectl exec --namespace $namespace $cli_pod -- bash -c "CORE_PEER_LOCALMSPID=Org1MSP CORE_PEER_MSPCONFIGPATH=/var/hyperledger/admin_msp CORE_PEER_ADDRESS=${peer_address} peer chaincode install -n $chaincode_name -v $chaincode_version -p chaincode/${chaincode_name}"
# e.g.
kubectl exec --namespace blockchain hlf-cli-pod -- bash -c "CORE_PEER_LOCALMSPID=Org1MSP CORE_PEER_MSPCONFIGPATH=/var/hyperledger/admin_msp CORE_PEER_ADDRESS=peer0:30110 peer chaincode install -n cc -v 1.1 -p chaincode/cc"
Upgrade chaincode to new version
kubectl exec --namespace $namespace $cli_pod -- bash -c "CORE_PEER_LOCALMSPID=Org1MSP CORE_PEER_MSPCONFIGPATH=/var/hyperledger/admin_msp CORE_PEER_ADDRESS=${peer_address} peer chaincode upgrade -o $orderer_address -n $chaincode_name -v $chaincode_version -C $channel_name -l <language of the chaincode> -c <args in json format> -P <endorsment policy>"
# e.g.
kubectl exec --namespace blockchain hlf-cli-pod -- bash -c "CORE_PEER_LOCALMSPID=Org1MSP CORE_PEER_MSPCONFIGPATH=/var/hyperledger/admin_msp CORE_PEER_ADDRESS=peer0:30110 peer chaincode upgrade -o orderer:31010 -n cc -v 1.1 -C mychannel -l golang -c '{\"Args\":[]}' -P \"OR('Org1MSP.member')\""
kubectl exec --namespace $namespace $cli_pod -- bash -c "CORE_PEER_LOCALMSPID=Org1MSP CORE_PEER_MSPCONFIGPATH=/var/hyperledger/admin_msp CORE_PEER_ADDRESS=$peer_address peer chaincode invoke -o $orderer_address -C $channel_name -n $chaincode_name -c '{\"Args\":[\"put\",\"a\",\"10\"]}'"
kubectl exec --namespace blockchain $cli_pod -- bash -c "CORE_PEER_LOCALMSPID=Org1MSP CORE_PEER_MSPCONFIGPATH=/var/hyperledger/admin_msp CORE_PEER_ADDRESS=$peer_address peer chaincode invoke -o $orderer_adddress -C $channel_name -n $chaincode_name -c '{\"Args\":[\"get\",\"a\"]}'"
Note: Chaincode cointainer is hidden, but the log get attached to the peer, so that you can see the output of your commands there.
Copy and export the newer versions in environment variables:
export FABRIC_VERSION="1.4.2"
export THIRDPARTY_VERSION="0.4.15"
Updating the charts without resetting username and password:
Copy and export in environment variables CA_ADMIN
and CA_PASSWORD
and log them to be sure the command did work
export CA_ADMIN=$(kubectl get secret --namespace blockchain ca-hlf-ca--ca -o jsonpath="{.data.CA_ADMIN}" | base64 --decode; echo)
export CA_PASSWORD=$(kubectl get secret --namespace blockchain ca-hlf-ca--ca -o jsonpath="{.data.CA_PASSWORD}" | base64 --decode; echo)
echo $CA_ADMIN $CA_PASSWORD
Upgrade the chart
helm upgrade --namespace $namespace --tiller-namespace $namespace --reuse-values --set image.tag=$FABRIC_VERSION,config.hlfToolsVersion=$FABRIC_VERSION,postgresql.enabled=true,adminUsername=$CA_ADMIN,adminPassword=$CA_PASSWORD ca ./hlf/charts/hlf-ca
Upgrade the chart
helm upgrade --namespace $namespace --tiller-namespace $namespace --reuse-values --set image.tag=$FABRIC_VERSION orderer ./hlf/charts/hlf-ord
Copy and export CouchDB username and password
export COUCHDB_USER=$(kubectl get secret --namespace blockchain cdb-org1peer1-hlf-couchdb -o jsonpath="{.data.COUCHDB_USER}" | base64 --decode; echo)
export COUCHDB_PASSWORD=$(kubectl get secret --namespace blockchain cdb-org1peer1-hlf-couchdb -o jsonpath="{.data.COUCHDB_PASSWORD}" | base64 --decode; echo)
Update the chart without resetting the password (requires running step 2):
helm upgrade --namespace $namespace --tiller-namespace $namespace --reuse-values --set couchdbUsername=$COUCHDB_USER,couchdbPassword=$COUCHDB_PASSWORD cdb-org1peer1 ./hlf/charts/hlf-couchdb
Upgrade the chart
helm upgrade --namespace $namespace --tiller-namespace $namespace --reuse-values --set image.tag=$FABRIC_VERSION org1peer1 ./hlf/charts/hlf-peer
Upgrading the chart
helm upgrade --namespace $namespace --tiller-namespace $namespace --reuse-values --set image.tag=$FABRIC_VERSION cli ./hlf/charts/hlf-tools