基于Kubernetes集群构建并部署Hyperledger Fabric网络

共4.6k字 阅读时长约24分 访问量

操作前必读

👀 本文为个人在使用Kubernetes搭建Hyperledger Facric 2.X网络的个人笔记,原视频教程在这里,有需要可以移步观看。需要注意的是该视频实操过程中链码部分的内容已经不适用于最新的hlf-operator版本。

📚 这篇文档的内容参考了视频内容,视频作者GitHub笔记bevel-operator-fabric官方文档,留于此用于日后学习。

🎈 操作前请先完成环境配置与相关依赖安装。或者参考我的另一篇文章

准备

  1. 按照官方教程准备好依赖
  2. 配置版本号,避免出现不兼容现象
1
2
3
4
5
6
7
8
export PEER_IMAGE=hyperledger/fabric-peer
export PEER_VERSION=2.4.6

export ORDERER_IMAGE=hyperledger/fabric-orderer
export ORDERER_VERSION=2.4.6

export CA_IMAGE=hyperledger/fabric-ca
export CA_VERSION=1.5.6-beta2

创建Hyperledger Fabric网络

我们将创建一个两组织(Org1、Org2),每个组织包括两个Peer节点(Peer1、Peer2)和一个Orderer(包含一个排序节点ord-node1)的Hyperledger Fabric网络。

创建命名空间

1
kubectl create ns fabric

管理CA

  1. 创建CA
1
2
3
4
# 有几个CA就创建几个,例如:org1-ca/org2-ca/ord-ca
kubectl hlf ca create --image=$CA_IMAGE --version=$CA_VERSION --storage-class=standard --capacity=1Gi --name=org1-ca --enroll-id=enroll --enroll-pw=enrollpw --namespace=fabric
kubectl hlf ca create --image=$CA_IMAGE --version=$CA_VERSION --storage-class=standard --capacity=1Gi --name=org2-ca --enroll-id=enroll --enroll-pw=enrollpw --namespace=fabric
kubectl hlf ca create --image=$CA_IMAGE --version=$CA_VERSION --storage-class=standard --capacity=1Gi --name=ord-ca --enroll-id=enroll --enroll-pw=enrollpw --namespace=fabric

参数解释

参数 解释
1 –storage-class 存储类
2 –capacity 存储容量
3 –name 名称
4 –enroll-id
5 –enroll-pw
6 –namespace 命名空间
  1. 验证CA

可以使用source <(kubectl completion bash)填充kubectl命令补全到bash。

1
kubectl get fabriccas.hlf.kungfusoftware.es -A -n fabric

管理Peer

  1. 注册Peer身份
1
2
3
4
5
# 有几个CA就注册几个,例如:org1-ca/org2-ca
kubectl hlf ca register --name=org1-ca --user=org1-peer1 --secret=peerpw --type=peer --enroll-id=enroll --enroll-secret=enrollpw --mspid=Org1MSP --namespace=fabric
kubectl hlf ca register --name=org1-ca --user=org1-peer2 --secret=peerpw --type=peer --enroll-id=enroll --enroll-secret=enrollpw --mspid=Org1MSP --namespace=fabric
kubectl hlf ca register --name=org2-ca --user=org2-peer1 --secret=peerpw --type=peer --enroll-id=enroll --enroll-secret=enrollpw --mspid=Org2MSP --namespace=fabric
kubectl hlf ca register --name=org2-ca --user=org2-peer2 --secret=peerpw --type=peer --enroll-id=enroll --enroll-secret=enrollpw --mspid=Org2MSP --namespace=fabric

参数解释

参数 解释
1 –name 使用的CA
2 –user Peer用户
3 –secret Peer密码
4 –type 类型
5 –enroll-id CA的ID
6 –enroll-secret 对应CA的密码
7 –mspid MSP的ID
8 –namespace 命名空间
  1. 创建Peer节点
1
2
3
4
5
6
# 有几个Peer节点就创建几个,例如:org1-peer1/org2-peer2
kubectl hlf peer create --image=$PEER_IMAGE --version=$PEER_VERSION --storage-class=standard --capacity=1Gi --enroll-id=org1-peer1 --mspid=Org1MSP --enroll-pw=peerpw --name=org1-peer1 --ca-name=org1-ca.fabric --namespace=fabric --statedb=couchdb
kubectl hlf peer create --image=$PEER_IMAGE --version=$PEER_VERSION --storage-class=standard --capacity=1Gi --enroll-id=org1-peer2 --mspid=Org1MSP --enroll-pw=peerpw --name=org1-peer2 --ca-name=org1-ca.fabric --namespace=fabric --statedb=couchdb

kubectl hlf peer create --image=$PEER_IMAGE --version=$PEER_VERSION --storage-class=standard --capacity=1Gi --enroll-id=org2-peer1 --mspid=Org2MSP --enroll-pw=peerpw --name=org2-peer1 --ca-name=org2-ca.fabric --namespace=fabric --statedb=couchdb
kubectl hlf peer create --image=$PEER_IMAGE --version=$PEER_VERSION --storage-class=standard --capacity=1Gi --enroll-id=org2-peer2 --mspid=Org2MSP --enroll-pw=peerpw --name=org2-peer2 --ca-name=org2-ca.fabric --namespace=fabric --statedb=couchdb

参数解释

参数 解释
1 –storage-class 存储类
2 –capacity Peer用户
3 –enroll-id 注册Peer的ID
4 –mspid MSP的ID
5 –enroll-pw Peer密码
6 –name Peer的名称
7 –ca-name 使用的CA名称
8 –namespace 命名空间
9 –statedb 状态数据库
10 –output 输出至文件(可选)
  1. 验证Peer创建情况
1
kubectl get fabricpeers.hlf.kungfusoftware.es -A -n fabric

注册并写入Admin证书

  1. 创建文件夹
1
2
mkdir klf-k8s-demo
cd hlf-k8s-demo
  1. 注册组织Admin
1
2
3
# 有几个CA就注册几个,例如:org1-ca/org2-ca
kubectl hlf ca register --name=org1-ca --user=admin --secret=adminpw --type=admin --enroll-id=enroll --enroll-secret=enrollpw --mspid=Org1MSP --namespace=fabric
kubectl hlf ca register --name=org2-ca --user=admin --secret=adminpw --type=admin --enroll-id=enroll --enroll-secret=enrollpw --mspid=Org2MSP --namespace=fabric

参数解释

参数 解释
1 –name CA名称
2 –user Admin用户名
3 –secret Admin密码
4 –type 注册类型
5 –enroll-id 注册Admin的ID
6 –mspid MSP的ID
7 –enroll-secret 注册密码
8 –namespace 命名空间
  1. 获取Admin证书
1
2
3
# 有几个CA就写入几个,例如:org1-peer/org2-peer
kubectl hlf ca enroll --name=org1-ca --user=admin --secret=adminpw --ca-name=ca --mspid=Org1MSP --namespace=fabric --output=org1-peer.yaml
kubectl hlf ca enroll --name=org2-ca --user=admin --secret=adminpw --ca-name=ca --mspid=Org2MSP --namespace=fabric --output=org2-peer.yaml

参数解释

参数 解释
1 –name CA名称
2 –user Admin用户名
3 –secret Admin密码
4 –ca-name CA名称
5 –mspid MSP的ID
6 –namespace 命名空间
7 –output 输出至文件(需要保存文件)
  1. 创建连接文件
1
kubectl hlf inspect -o Org1MSP -o Org2MSP -o OrdererMSP --output=networkConfig.yaml

参数解释

参数 解释
1 -o 需要连接的MSP
2 –output 输出至文件(需要保存文件)
  1. 添加用户至网络
1
2
3
# 有几个添加几个,例如:org1-peer/org2-peer
kubectl hlf utils adduser --userPath=org1-peer.yaml --config=networkConfig.yaml --username=admin --mspid=Org1MSP
kubectl hlf utils adduser --userPath=org2-peer.yaml --config=networkConfig.yaml --username=admin --mspid=Org2MSP

参数解释

参数 解释
1 –userPath 认证文件
2 –config 目标网络配置
3 –username
4 –mspid MSP的ID

可在networkConfig.yaml:Org1/2MSP:users中看到已添加的认证信息。

使用服务名替换网络配置中的IP以在kubernetes cluster中运行(可选)

1
2
# use --internal=true, such as:
kubectl hlf inspect -o Org1MSP -o Org2MSP -o OrdererMSP --internal=true --output=servicename-networkConfig.yaml

添加排序服务至网络

  1. 创建排序服务身份文件

需要先创建排序CA

1
2
# 此处只展示一个排序服务,例如:ord-ca
kubectl hlf ca register --name=ord-ca --user=orderer --secret=ordererpw --type=orderer --enroll-id=enroll --enroll-secret=enrollpw --mspid=OrdererMSP --namespace=fabric

参数解释

参数 解释
1 –name CA名称
2 –user Admin用户名
3 –secret Admin密码
4 –type 注册类型
5 –enroll-id 注册Admin的ID
6 –enroll-secret 注册密码
7 –mspid MSP的ID
8 –namespace 命名空间
  1. 创建排序节点
1
2
# 此处只展示一个排序节点,例如:ord-node1
kubectl hlf ordnode create --image=$ORDERER_IMAGE --version=$ORDERER_VERSION --storage-class=standard --enroll-id=orderer --enroll-pw=ordererpw --mspid=OrdererMSP --capacity=1Gi --name=ord-node1 --ca-name=ord-ca.fabric --namespace=fabric

参数解释

参数 解释
1 –storage-class 存储类
2 –enroll-id 注册ID
3 –enroll-pw 注册密码
4 –mspid MSP的ID
5 –capacity 存储
6 –name 节点名
7 –ca-name CA名称
8 –namespace 命名空间
  1. 准备与排序服务交互的文件
1
2
3
4
5
6
7
8
9
10
# 要准备连接字符串,我们必须:
#
# 获取没有用户的连接字符串
kubectl hlf inspect --output ordservice.yaml -o OrdererMSP
# 在证书颁发机构中注册用户以进行签名
kubectl hlf ca register --name=ord-ca --user=admin --secret=adminpw --type=admin --enroll-id=enroll --enroll-secret=enrollpw --mspid=OrdererMSP --namespace=fabric
# 使用上面创建的用户获取证书
kubectl hlf ca enroll --name=ord-ca --user=admin --secret=adminpw --mspid=OrdererMSP --ca-name=ca --output=admin-ordservice.yaml --namespace=fabric
# 将用户附加到连接字符串
kubectl hlf utils adduser --userPath=admin-ordservice.yaml --config=ordservice.yaml --username=admin --mspid=OrdererMSP

通道操作

  1. 注册和登记Orderer的身份
1
2
3
4
# 注册
kubectl hlf ca register --name=ord-ca --user=admin --secret=adminpw --type=admin --enroll-id=enroll --enroll-secret=enrollpw --mspid=OrdererMSP --namespace=fabric
# 登记
kubectl hlf ca enroll --name=ord-ca --user=admin --secret=adminpw --mspid=OrdererMSP --ca-name=tlsca --namespace=fabric --output=orderermsp.yaml
  1. 注册和登记Org1/Org2的身份
1
2
3
4
5
6
7
8
9
10
11
# Org1
# 注册
kubectl hlf ca register --name=org1-ca --namespace=default --user=admin --secret=adminpw --type=admin --enroll-id=enroll --enroll-secret=enrollpw --mspid=Org1MSP --namespace=fabric
# 登记
kubectl hlf ca enroll --name=org1-ca --user=admin --secret=adminpw --mspid=Org1MSP --ca-name=ca --namespace=fabric --output=org1msp.yaml

# Org2
# 注册
kubectl hlf ca register --name=org2-ca --namespace=default --user=admin --secret=adminpw --type=admin --enroll-id=enroll --enroll-secret=enrollpw --mspid=Org2MSP --namespace=fabric
# 登记
kubectl hlf ca enroll --name=org2-ca --user=admin --secret=adminpw --mspid=Org2MSP --ca-name=ca --namespace=fabric --output=org2msp.yaml
  1. 创建密钥
1
kubectl create secret generic wallet --from-file=org1msp.yaml=$PWD/org1msp.yaml --from-file=orderermsp.yaml=$PWD/orderermsp.yaml --from-file=org2msp.yaml=$PWD/org2msp.yaml --namespace=fabric
  1. 创建连接文件
1
kubectl hlf inspect --output networkConfig.yaml -o Org1MSP -o OrdererMSP -o Org2MSP

参数解释

参数 解释
1 -o 需要连接的MSP
2 –output 网络配置文件
  1. 创建通道

命令1:生成创世块

1
kubectl hlf channel generate --name=mychannel --organizations=Org1MSP --organizations=Org2MSP --ordererOrganizations=OrdererMSP --output=mychannel.block

命令1参数解释

参数 解释
1 –name 通道名称
2 –organizations 加入的组织MSP
3 –ordererOrganizations 加入的排序组织MSP
4 –output 输出块

命令2:加入排序节点

1
2
# 这里要使用--ca-name=tls生成的Orderer证书
kubectl hlf ordnode join --block=mychannel.block --name=ord-node1 --identity=orderermsp.yaml --namespace=fabric
1
2
3
# 输出
INFO[0000] name=ord-node1 namespace=fabric
INFO[0000] Status code=201
  1. Peer加入通道
1
2
3
4
kubectl hlf channel join --name=mychannel --config=networkConfig.yaml --user=admin -p=org1-peer1.fabric
kubectl hlf channel join --name=mychannel --config=networkConfig.yaml --user=admin -p=org1-peer2.fabric
kubectl hlf channel join --name=mychannel --config=networkConfig.yaml --user=admin -p=org2-peer1.fabric
kubectl hlf channel join --name=mychannel --config=networkConfig.yaml --user=admin -p=org2-peer2.fabric
1
2
3
4
5
# 输出
INFO[0000] Channel joined
INFO[0000] Channel joined
INFO[0000] Channel joined
INFO[0000] Channel joined

可能会出现错误Error: failed to create resmgmt client due to context error: user not found,参见问题汇总2.

配置锚节点

1
2
kubectl hlf channel addanchorpeer --channel=mychannel --config=networkConfig.yaml --user=admin --peer=org1-peer1.fabric
kubectl hlf channel addanchorpeer --channel=mychannel --config=networkConfig.yaml --user=admin --peer=org2-peer1.fabric
1
2
3
4
5
# 输出
INFO[0000] Anchor peers []
INFO[0000] anchor anchorPeers added: 84795de5658a970dbebe0ee43c9a33ecb3e9000760371e0e162a6764bae4e6c4
INFO[0000] Anchor peers []
INFO[0000] anchor anchorPeers added: a8159c79cddac86702207054d2f9a57b2cf6900d37df1ce138017090a3938863

安装链码

📍CCAAS参考文档

  1. 为链码准备Docker镜像

从官方示例链码仓库拉去链码源码

1
2
3
4
5
6
7
8
# 以 fabcar 为例
# 从 https://github.com/hyperledger/fabric-samples/tree/main/chaincode/marbles02/go 获取源码
# 可参考:https://developer.aliyun.com/article/749446#slide-4 通过本地拉取链码容器

# 创建marble02链码容器请参考:http://blog.hubwiz.com/2020/03/12/fabric-2-external-chaincode/

mkdir chaincode/marble/go -p
cd chaincode/marble/go

Dockerfile文件修改如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# This image is a microservice in golang for the Degree chaincode
FROM golang:1.13.8-alpine AS build

COPY ./ /go/src/github.com/marbles
WORKDIR /go/src/github.com/marbles

# Build application
RUN go build -o chaincode -v .

# Production ready image
# Pass the binary to the prod image
FROM alpine:3.11 as prod

COPY --from=build /go/src/github.com/marbles/chaincode /app/chaincode

USER 1000

WORKDIR /app
CMD ./chaincode

构建镜像

1
2
3
4
# 构建镜像
docker build -t hyggeno1/marble-go:1.0 .
# 由于k8s不能使用本地镜像,所以需要把构建好的镜像推到公共仓库,没有账号需要先注册
docker push hyggeno1/marble-go:1.0

以下操作默认在hlf-k8s-demo/下进行

  1. 安装链码

创建元文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# https://github.com/adityajoshi12/hlf-operator-meetup
# https://hyperledger-fabric.readthedocs.io/zh_CN/latest/cc_launcher.html

# remove the code.tar.gz chaincode.tgz if they exist
rm code.tar.gz chaincode.tgz
export CHAINCODE_NAME=marble-go
export CHAINCODE_LABEL=marble-go
cat << METADATA-EOF > "metadata.json"
{
"type": "ccaas",
"label": "${CHAINCODE_LABEL}"
}
METADATA-EOF
## chaincode as a service

准备连接文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
cat > "connection.json" <<CONN_EOF
{
"address": "${CHAINCODE_NAME}:7052",
"dial_timeout": "10s",
"tls_required": false
}
CONN_EOF

tar cfz code.tar.gz connection.json
tar cfz chaincode.tgz metadata.json code.tar.gz
export PACKAGE_ID=$(kubectl hlf chaincode calculatepackageid --path=chaincode.tgz --language=node --label=$CHAINCODE_LABEL)
echo "PACKAGE_ID=$PACKAGE_ID"

# 在节点上安装
kubectl hlf chaincode install --path=./chaincode.tgz --config=networkConfig.yaml --language=golang --label=$CHAINCODE_LABEL --user=admin --peer=org1-peer1.fabric
kubectl hlf chaincode install --path=./chaincode.tgz --config=networkConfig.yaml --language=golang --label=$CHAINCODE_LABEL --user=admin --peer=org1-peer2.fabric
kubectl hlf chaincode install --path=./chaincode.tgz --config=networkConfig.yaml --language=golang --label=$CHAINCODE_LABEL --user=admin --peer=org2-peer1.fabric
kubectl hlf chaincode install --path=./chaincode.tgz --config=networkConfig.yaml --language=golang --label=$CHAINCODE_LABEL --user=admin --peer=org2-peer2.fabric
  1. 在集群上部署链码容器
1
kubectl hlf externalchaincode sync --image=hyggeno1/marble-go:1.5 --name=$CHAINCODE_NAME --namespace=fabric --package-id=$PACKAGE_ID --tls-required=false --replicas=1

部署后检查marble-gopodSTATUS是否为ErrImagePull,如果是的话,可能就是使用了本地仓库,请重新把链码推到公有仓库中。解决办法参见问题汇总6。

  1. 安装并部署链码(安装链码为外部服务)

检查安装的链码

1
kubectl hlf chaincode queryinstalled --config=networkConfig.yaml --user=admin --peer=org1-peer1.fabric

批准链码

1
2
3
4
5
export SEQUENCE=1
export VERSION="1.0"
# 需要所有参与组织的同意
kubectl hlf chaincode approveformyorg --config=networkConfig.yaml --user=admin --peer=org1-peer1.fabric --package-id=$PACKAGE_ID --version "$VERSION" --sequence "$SEQUENCE" --name=$CHAINCODE_NAME --policy="OR('Org1MSP.member','Org2MSP.member')" --channel=mychannel
kubectl hlf chaincode approveformyorg --config=networkConfig.yaml --user=admin --peer=org2-peer1.fabric --package-id=$PACKAGE_ID --version "$VERSION" --sequence "$SEQUENCE" --name=$CHAINCODE_NAME --policy="OR('Org1MSP.member','Org2MSP.member')" --channel=mychannel

提交链码

1
kubectl hlf chaincode commit --config=networkConfig.yaml --user=admin --mspid=Org1MSP --version="$VERSION" --sequence="$SEQUENCE" --name=$CHAINCODE_NAME --policy="OR('Org1MSP.member','Org2MSP.member')" --channel=mychannel

调用与查询

1
2
3
4
# 调用
kubectl hlf chaincode invoke --config=networkConfig.yaml --user=admin --peer=org1-peer1.fabric --chaincode=$CHAINCODE_NAME --channel=mychannel --fcn=createCar -a "1000" -a "honda" -a "civic" -a "red" -a "aditya"
# 查询 | 格式化输出
kubectl hlf chaincode query --config=networkConfig.yaml --user=admin --peer=org1-peer1.fabric --chaincode=$CHAINCODE_NAME --channel=mychannel --fcn=queryAllCars -a '' | jq -r '.'

其他命令

1
2
kubectl hlf channel top --channel=mychannel --config=networkConfig.yaml --user=admin -p=org1-peer1.fabric
kubectl hlf channel inspect --channel=mychannel --config=networkConfig.yaml --user=admin -p=org1-peer1.fabric > mychannel.json

清理集群

1
2
3
4
5
6
kubectl delete fabricorderernodes.hlf.kungfusoftware.es --all-namespaces --all
kubectl delete fabricpeers.hlf.kungfusoftware.es --all-namespaces --all
kubectl delete fabriccas.hlf.kungfusoftware.es --all-namespaces --all
kubectl delete fabricchaincode.hlf.kungfusoftware.es --all-namespaces --all
kubectl delete fabricmainchannels --all-namespaces --all
kubectl delete fabricfollowerchannels --all-namespaces --all

部署Operation Console

创建密钥

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
openssl genrsa -out ca.key 2048

openssl req -x509 \
-new -nodes \
-days 365 \
-key ca.key \
-out ca.crt \
-subj "/CN=console"


kubectl create secret tls console-tls-secret \
--cert=ca.crt \
--key=ca.key

# 查看密钥
kubectl get secrets

为TLS生成证书

1
2
3
export CONSOLE_PASSWORD="admin"
export TLS_SECRET_NAME="console-tls-secret"
kubectl hlf console create --name=console --namespace=fabric --version="latest" --image="ghcr.io/hyperledger-labs/fabric-console" --admin-user="admin" --admin-pwd="$CONSOLE_PASSWORD" --tls-secret-name="$TLS_SECRET_NAME"

添加证书颁发机构
将证书颁发机构导出至JSON

1
2
3
export CA_NAME=fabric-ca-name
export CA_NS=fabric
kubectl hlf fop export ca --name="${CA_NAME}" --namespace="${CA_NS}" --out="${CA_NAME}.json"

部署Operator UI

  1. 创建Operator UI
1
2
3
export HOST=operator-ui.fabric.test
export API_URL="http://api-operator.fabric.test/graphql"
kubectl hlf operatorui create --name=operator-ui --namespace=fabric --hosts=$HOST --ingress-class-name=istio --api-url=$API_URL
  1. 创建带有身份验证的Operator UI
1
2
3
4
5
6
7
export HOST=operator-ui.fabric.test
export API_URL="http://api-operator.fabric.test/graphql"
export OIDC_AUTHORITY="<url_authority>" # without the /.well-known/openid-configuration
export OIDC_CLIENT_ID="<client_id>" # OIDC Client ID for the Operator UI
export OIDC_SCOPE="profile email" # OIDC Scope for the Operator UI
kubectl hlf operatorui create --name=operator-ui --namespace=fabric --hosts=$HOST --ingress-class-name=istio --api-url=$API_URL \
--oidc-authority="${OIDC_AUTHORITY}" --oidc-client-id="${OIDC_CLIENT_ID}" --oidc-scope="${OIDC_SCOPE}"

部署Operator API

  1. 创建Operator API
1
2
export API_URL=api-operator.fabric.test
kubectl hlf operatorapi create --name=operator-api --namespace=fabric --hosts=$API_URL --ingress-class-name=istio
  1. 创建带有身份验证的Operator API
1
2
3
4
5
export API_URL=api-operator.<domain>
export OIDC_ISSUER=https://<your_oidc_issuer>
export OIDC_JWKS=https://<oidc_jwks_url>
kubectl hlf operatorapi create --name=operator-api --namespace=default --hosts=$API_HOST --ingress-class-name=istio \
--oidc-issuer="${OIDC_ISSUER}" --oidc-jwks="${OIDC_JWKS}"
  1. 使用浏览器创建Operator API
1
2
3
4
5
6
7
8
export API_URL=api-operator.<domain>
export HLF_SECRET_NAME="k8s-secret"
export HLF_MSPID="<your_mspid>"
export HLF_SECRET_KEY="<network_config_key_secret>" # e.g. networkConfig.yaml
export HLF_USER="<hlf_user>"
kubectl hlf operatorapi create --name=operator-api --namespace=default --hosts=$API_HOST --ingress-class-name=istio \
--hlf-mspid="${HLF_MSPID}" --hlf-secret="${HLF_SECRET_NAME}" --hlf-secret-key="${HLF_SECRET_KEY}" \
--hlf-user="${HLF_USER}"

问题汇总

  1. unknown command "krew" for "kubectl"
1
2
3
4
cat >> ~/.bashrc <<EOF
export PATH="${PATH}:${HOME}/.krew/bin"
EOF
source ~/.bashrc
  1. Error: failed to create resmgmt client due to context error: user not found

因为连接Orderer时重新生成了networkConfig.yaml文件,所以需要重新添加用户。命令如下.

1
2
3
# 添加Org1/Org2
kubectl hlf utils adduser --userPath=org1-peer.yaml --config=networkConfig.yaml --username=admin --mspid=Org1MSP
kubectl hlf utils adduser --userPath=org2-peer.yaml --config=networkConfig.yaml --username=admin --mspid=Org2MSP
  1. docker build is disabled error when installing my chaincode on hyperledger fabric

安装链码为外部服务

以下为过期建议!!!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# https://stackoverflow.com/questions/73100516/docker-build-is-disabled-error-when-installing-my-chaincode-on-hyperledger-fabri/73153204#73153204

# Peer节点版本不相符,除了上述的解决方案,推荐使用官方文档中对版本进行限定,再使用 --image=$CA_IMAGE --version=$CA_VERSION
export PEER_IMAGE=hyperledger/fabric-peer
export PEER_VERSION=2.4.6

export ORDERER_IMAGE=hyperledger/fabric-orderer
export ORDERER_VERSION=2.4.6

export CA_IMAGE=hyperledger/fabric-ca
export CA_VERSION=1.5.6-beta2

# Go配置也可能是出现错误的原因
go env -w GOPROXY=https://goproxy.cn
go env -w GO111MODULE=on
go mod vendor

# 需要使用外部服务部署链码
  1. 不支持minikube
  2. docker build 出现failed to solve: process "/bin/sh -c go install ...

官方链码示例Dockerfile给出的GO_VER=1.13.8版本过低,修改成GO_VER=1.18即可。

  1. pod STATUS ErrImagePull
1
2
3
4
5
6
7
# 首先删除出错的链码容器
# 获取容器ID
kubectl get pods -n fabric
# 删除外部链码
kubectl hlf externalchaincode delete --name=fabcar-go --namespace=fabric
# 上传容器至公共仓库并获取最新版本后重新创建外部链码服务,eg.
kubectl hlf externalchaincode sync --image=hyggeno1/fabcar-go:1.1 --name=$CHAINCODE_NAME --namespace=fabric --package-id=$PACKAGE_ID --tls-required=false --replicas=1

其他脚本

  1. 查询链码是否成功安装

kubectl exec -it org1-peer1-xxxxxx -n fabric -- ls -l var/hyperledger/production/lifecycle/chaincodes

  1. 自动化脚本(创建fabcar)
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#!/bin/bash

# Define the range of values to use for the first -a parameter(索引参数)
START=1001
END=2000

# Define an array of car brands to choose from
CAR_BRANDS=("honda" "toyota" "nissan" "chevrolet" "ford" "bmw")

# Define an associative array of car types keyed by car brand
declare -A CAR_TYPES=(
["honda"]="civic"
["toyota"]="camry"
["nissan"]="altima"
["chevrolet"]="impala"
["ford"]="fusion"
["bmw"]="3 series"
)

# Define an array of colors to choose from
COLORS=("red" "blue" "green" "yellow" "orange" "purple")

# Define an array of peer values to choose from
PEERS=("org1-peer1.fabric" "org1-peer2.fabric" "org2-peer2.fabric" "org2-peer1.fabric")

# Define an array of 100 person names
NAMES=("Adam" "Bob" "Charlie" "David" "Emma" "Frank" "Grace" "Henry" "Isabella" "John"
"Kate" "Liam" "Mary" "Nathan" "Olivia" "Peter" "Quinn" "Rachel" "Samuel" "Thomas"
"Ursula" "Victoria" "William" "Xavier" "Yvonne" "Zachary" "Alice" "Ben" "Cathy" "Dylan"
"Eva" "Fiona" "George" "Hannah" "Isaac" "Jacob" "Karen" "Lena" "Megan" "Natalie"
"Oscar" "Patrick" "Qian" "Rita" "Sarah" "Trevor" "Uma" "Vera" "Wendy" "Xander"
"Yara" "Zoe" "Annie" "Bill" "Caroline" "Daniel" "Ellie" "Freya" "Gavin" "Heidi"
"Irene" "Jenny" "Kyle" "Lila" "Maddie" "Noah" "Owen" "Penny" "Quincy" "Riley"
"Sofia" "Tessa" "Una" "Violet" "Wyatt" "Ximena" "Yan" "Zara" "Amelia" "Bridget"
"Connor" "Daisy" "Ethan" "Finn" "Grace" "Hazel" "Ivy" "Julia" "Kai" "Landon")

# Loop over the range of values and run the kubectl hlf chaincode invoke command with each value
for ((i=START;i<=END;i++)); do
echo "Processing value: $i"
# Choose a random car brand from the array of car brands
RANDOM_CAR_BRAND=${CAR_BRANDS[$RANDOM % ${#CAR_BRANDS[@]}]}
# Choose a random color from the array of colors
RANDOM_COLOR=${COLORS[$RANDOM % ${#COLORS[@]}]}
# Choose a random peer from the array of peers
RANDOM_PEER=${PEERS[$RANDOM % ${#PEERS[@]}]}
# Get the car type that matches the randomly selected car brand
RANDOM_CAR_TYPE=${CAR_TYPES[$RANDOM_CAR_BRAND]}
# Choose a random name from the array of names
RANDOM_NAME=${NAMES[$RANDOM % ${#NAMES[@]}]}

# Call the kubectl hlf chaincode invoke command with the modified parameters
kubectl hlf chaincode invoke --config=networkConfig.yaml \
--user=admin --peer=$RANDOM_PEER --chaincode=$CHAINCODE_NAME \
--channel=mychannel --fcn=createCar \
-a "$i" \
-a "$RANDOM_CAR_BRAND" \
-a "$RANDOM_CAR_TYPE" \
-a "$RANDOM_COLOR" \
-a "$RANDOM_NAME"

echo "Command processed with the following parameters:"
echo " -a $i"
echo " -a $RANDOM_CAR_BRAND"
echo " -a $RANDOM_CAR_TYPE"
echo " -a $RANDOM_COLOR"
echo " -a $RANDOM_NAME"
echo " --peer $RANDOM_PEER"
done