doc: add zh version for Fabric Full Stack Development Workshop Cloud Native Fabric part (#901)

Signed-off-by: Sam Yuan <yy19902439@126.com>
This commit is contained in:
Sam Yuan 2023-01-18 22:13:54 +08:00 committed by GitHub
parent e7d3b41287
commit 5095954756
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 635 additions and 6 deletions

View file

@ -96,11 +96,11 @@ We'll create a digital representation of these cards on the blockchain ledger. T
## Cloud Native Fabric
- [Cloud Ready!](docs/CloudReady/00-setup.md)
- **Exercise:** [Deploy a Kubernetes Cluster](docs/CloudReady/10-kube.md)
- **Exercise:** [Deploy a Fabric Network](docs/CloudReady/20-fabric.md)
- **Exercise:** [Deploy a Smart Contract](docs/CloudReady/30-chaincode.md)
- **Exercise:** [Deploy a Client Application](docs/CloudReady/40-bananas.md)
- [Cloud Ready!](docs/CloudReady/00-setup.md) [中文](docs/CloudReady/00-setup-zh.md)
- **Exercise:** [Deploy a Kubernetes Cluster](docs/CloudReady/10-kube.md) [中文](docs/CloudReady/10-kube-zh.md)
- **Exercise:** [Deploy a Fabric Network](docs/CloudReady/20-fabric.md) [中文](docs/CloudReady/20-fabric-zh.md)
- **Exercise:** [Deploy a Smart Contract](docs/CloudReady/30-chaincode.md)[中文](docs/CloudReady/30-chaincode-zh.md)
- **Exercise:** [Deploy a Client Application](docs/CloudReady/40-bananas.md)[中文](docs/CloudReady/40-bananas-zh.md)
## Epilogue

View file

@ -0,0 +1,92 @@
# 云原生
==> [下一步: 部署一个kube集群](./10-kube-zh.md)
---
Hyperledger Fabric的云原生支持一个Hyperledger Fabric中立的分层透视图,其中集成了容器服务和API。在这个workshop的这部分例子中您将会完整的运行应用并且可以尝试从本地开发环境部署到公有云环境中。
![Cloud Ready](../images/CloudReady/00-cloud-ready-2.png)
云原生结构堆栈中的每个应用程序层通常都是模块化的只需对在不同环境之间切换。在每个应用程序层客户端库和连接URL用于确保跨运行时堆栈的可移植性和独立性。
例如:
- Hyperledger Fabric peerorderer和CA节点之间的交互都通过编译后的可执行文件交互通过TCP和GRPCs的方式。一旦Hyperledger Fabric网络被建立所有的管理员和账本访问将通过服务的方式进行。因此对外Hyperledger Fabric网络仅仅暴露服务地址和x509证书。
- 所有和容器的交互都通过k8s API完成在后续的练习中您将会使用`kubectl`命令从宿主机(本机)访问并连接容器。请注意,这种方式并不局限在本地,您也可以通过合适的配置来访问您的远程集群。
- 一些必要的虚拟化技术对本实验有所帮助。您可能需要通过multipass/vagrant或远程虚拟机来执行这个实验。详细信息请参考原文
In some cases a virtualization layer is necessary to emulate the cloud-native practices. For instance, a VM running
locally with multipass/vagrant (or a remote instance at EC2) can be used to supplement a local development workflow.
This can be extremely useful as a means to build platform-neutral runtimes, supporting a variety of chipsets and
development environments (WSL2, Mac M1, z/OS, amd64, etc.)
在使用一个 _Cloud Native Fabric_ 堆栈时,您会感到非常困惑。当你是感觉迷失了,专注于上面的分层堆栈,帮助重新定位自己,找到指南针方位,然后继续前进。
通常,每个应用程序层都被设计为仅与堆栈中其下的直接层一起工作。
在本次的云部署之旅中,您也许需要牢记一些知识点(下列知识点涉及部分专有词汇,为防止误解,不做翻译):
1. Services are backed by URLs. (It does not matter _where_ the endpoints are running, only how you _locate_ them.)
2. Services run in [OCI Containers](https://github.com/opencontainers/image-spec) and are orchestrated by Kubernetes.
3. All client programs run on your machine, connecting to service endpoints "running somewhere" on a hybrid cloud.
4. At some point in this course, you may encounter a chaincode contract running in a Java Virtual Machine, running in a
docker container, executing as a service running on Kubernetes, which is running in a Docker container, which
is running on a virtual machine, which is running on an x86 emulation layer, which is running on hyperkit, which is
running on Mac M1 silicon on your laptop. At many times, you will forget _where_ your code is running, and question
if it is in fact running at all. Do not be alarmed: this is a natural reaction to container based application
workflows. (See points 1, 2, and 3 above.)
## 让我们开始吧
运行一下程序来检查我们需要的工具是否安装完毕
```shell
# If the check passes, proceed to "Deploy a Kube":
./check.sh
```
## 需要安装工具:
我们需要一些客户端程序来完成这个实验。
您可以使用`./check.sh`来进行检查和查看,或者通过网页的方式:
- [fabric-samples](https://github.com/hyperledger/fabric-samples) (This GitHub project):
```shell
git clone https://github.com/hyperledger/fabric-samples.git fabric-samples
cd fabric-samples/full-stack-asset-transfer-guide
```
- [docker](https://www.docker.com/get-started/)
- [kubectl](https://kubernetes.io/docs/tasks/tools/)
- [jq](https://stedolan.github.io/jq/download/)
- [k9s](https://k9scli.io/topics/install/) (recommended)
- Hyperledger Fabric [客户端](https://hyperledger-fabric.readthedocs.io/en/latest/install.html#download-fabric-samples-docker-images-and-binaries):
```shell
curl -sSL https://raw.githubusercontent.com/hyperledger/fabric/main/scripts/install-fabric.sh | bash -s -- binary
```
- 本实验需要的环境变量:
```shell
export WORKSHOP_PATH=$(pwd)
export FABRIC_CFG_PATH=${WORKSHOP_PATH}/config
export PATH=${WORKSHOP_PATH}/bin:$PATH
```
## 如果还有问题,请参考下列原文
For the duration of the workshop, a number of temporary, short-run virtual machines will be available on the web for
your usage. The systems have been provisioned with a [#cloud-config](../../infrastructure/ec2-cloud-config.yaml) and
include all dependencies necessary to run the cloud-native workshop. Check your "Conga Card" for the instance IP and
ssh connection details.
---
==> [下一步: 部署一个kube集群](./10-kube.md)

View file

@ -4,7 +4,7 @@
---
Cloud Native Fabric provides a neutral, tiered perspective of a Hyperledger Fabric Network as an integration of
Cloud Native Hyperledger Fabric provides a neutral, tiered perspective of a Hyperledger Fabric Network as an integration of
containers, service endpoints, and API abstractions. In this module of the workshop, you will assemble a complete
application, building up from a local development running in isolation to a complete blockchain application running
natively on a public cloud.

View file

@ -0,0 +1,67 @@
# 部署一个k8s集群
[上一步: 设置](00-setup-zh.md) <==> [下一步: 部署一个fabric网络](20-fabric-zh.md)
---
Fabric云原生部署所有的组件直接在工作站上运行在这个步骤中您将会配置
- 一个本地[kind](https://kind.sigs.k8s.io) 集群来运行k8s.
- 一个本地[Ingress controller](https://github.com/kubernetes/ingress-nginx), 将k8s集群的路由设置到 `*.localho.st` 这个虚拟域名上.
- 一个本地[Container Registry](https://docs.docker.com/registry/insecure/), 允许您上传智能合约的docker镜像。
![Local KIND](../images/CloudReady/10-kube.png)
## 执行:
```shell
just check-setup
```
## Kubernetes IN Docker (KIND)
- 配置 `localho.st` DNS路由
mapping `*.localho.st` to 127.0.0.1.
```shell
export WORKSHOP_INGRESS_DOMAIN=localho.st
export WORKSHOP_NAMESPACE=test-network
```
- 创建[kind](https://kind.sigs.k8s.io) 集群, Nginx ingress, 和本地 container registry:
```shell
just kind
```
- 在新的terminal中执行如下命令来确认:
```shell
# KIND will set the current kubectl context in ~/.kube/config
kubectl cluster-info
k9s -n test-network
```
## 调试
- Run KIND on a [multipass VM](11-kube-multipass.md) on your local system
- Run KIND on an [EC2 instance](12-kube-ec2-vm.md) at AWS
## 进一步拓展:
- Run the workshop on an [IKS or EKS or DOKS Cloud Kubernetes cluster](13-kube-public-cloud.md).
- Run the workshop on an AWS VM, using your AWS account and an EC2 [#cloud-config](../../infrastructure/ec2-cloud-config.yaml).
---
[上一步: 设置](00-setup-zh.md) <==> [下一步: 部署一个fabric网络](20-fabric-zh.md)

View file

@ -0,0 +1,107 @@
# 部署一个fabric网络
[前一步: 部署一个k8s集群](10-kube-zh.md) <==> [下一步:安装智能合约](30-chaincode-zh.md)
---
[Fabric-operator](https://github.com/hyperledger-labs/fabric-operator)是通过Operator技术使用
[custom resources](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/)来部署Hyperledger Fabric网络中[CA](../../infrastructure/sample-network/config/cas)[peer](../../infrastructure/sample-network/config/peers)[orderer](../../infrastructure/sample-network/config/orderers)节点的一种工具和方式。最终它会将CAPeerOrderer转化为对应的k8s资源如`Pod`,`Deployment`, `Service`, 和 `Ingress`
一旦Fabric网络启动完成可以使用`peer`和命令行工具通过Ingress来访问fabric网络。创建通道合约和应用部署。
![Fabric Operator](../images/CloudReady/20-fabric.png)
## 执行:
```shell
just check-kube
```
## 示例网络
- 安装 fabric-operator [Kubernetes Custom Resources](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/)
```shell
kubectl apply -k https://github.com/hyperledger-labs/fabric-operator.git/config/crd
```
- 部署 [CA](../../infrastructure/sample-network/config/cas), [peer](../../infrastructure/sample-network/config/peers),
和 [orderer](../../infrastructure/sample-network/config/orderers) 资源。并等待operator完成k8s上的资源创建 `Pods`, `Deployments`, `Services`, 和 `Ingress`
```shell
just cloud-network
```
- 建立通道:
```shell
just cloud-channel
```
- 建立TLS证书channel msp用户证书创建:
```shell
export WORKSHOP_CRYPTO=$WORKSHOP_PATH/infrastructure/sample-network/temp
```
## 检查
```shell
curl \
-s \
--cacert $WORKSHOP_CRYPTO/cas/org1-ca/tls-cert.pem \
https://$WORKSHOP_NAMESPACE-org1-ca-ca.$WORKSHOP_INGRESS_DOMAIN/cainfo \
| jq
```
## 云原生和peer节点日志
我们可以通过如下方式获取peer节点信息比如peer节点的日志。
```shell
kubectl config set-context --current --namespace=test-network
kubectl get pods
```
假设org1 peer1 pod名称为`org1-peer1-79df64f8d8-7m9mt`, 我们可以通过如下命令来获取日志从而观察peer节点上的通道合约和落块情况。
```shell
kubectl logs -f org1-peer1-79df64f8d8-7m9mt peer
```
您也可以使用其他工具如[k9s utility](https://k9scli.io/topics/install/).比如:
```shell
k9s -n test-network
```
You'll see the fabric-operator, peer, orderer, and CA pods. Navigate around by hitting `ENTER` on one of the pods, `ENTER` again on one of the containers, and then hit `0` to tail the container's log. Go back up by hitting `ESCAPE`. More tips are available at the top of the k9s user interface.
## 调试
```shell
# While running "just cloud-network and/or just cloud-channel":
tail -f infrastructure/sample-network/network-debug.log
```
# 进一步拓展:
- Deploy the [Fabric Operations Console](21-fabric-operations-console.md)
- Build a network with the [Ansible Blockchain Collection](22-fabric-ansible-collection.md)
---
[前一步: 部署一个k8s集群](10-kube-zh.md) <==> [下一步:安装智能合约](30-chaincode-zh.md)

View file

@ -0,0 +1,213 @@
# Chaincode
[前一步: 部署一个fabric网络](20-fabric-zh.md) <==> [下一步: 部署应用](40-bananas-zh.md)
---
根据Fabric传统的智能合约生命周期及管理智能合约的部署需要通过Fabric administrator来准备和安装定义好的智能合约通常包括智能合约源码metadata和运行时runtime
当合约提交到通道时peers节点将会相应编译过程并将源码作为子进程启动。
这种工作方式可能会引发一些容器运行时的问题。比如在创建智能合约docker镜像的过程中的权限管理问题以及运行阶段的合约容器适配问题。
在容器和云原生环境上如k8s这中经典的智能合约部署过程需要自定义容器服务启动器的支持。
通过Fabric 2.4.1以上提供的[智能合约即服务](https://hyperledger-fabric.readthedocs.io/en/latest/cc_service.html)功能Fabric管理员可以采用另外一种方式来部署智能合约服务。通过自定义智能合约容器将智能合约镜像上传至容器registry并作为k8s服务来启动。通过`peer`命令行执行相关命令来完成这一过程从而完成合约证明周期管理。
通过CCaaS / _no-op_ builder 我们可以减少传统合约生命周期中的相关权限管理问题,并提供了完整的智能合约生命周期管理能力。它将两项新主要责任交给了网络管理员:
- `build` : 管理员需要构建容器镜像并上传。
- `run` : 管理员需要准备`Service`, `Deployment`, 被配置TLS服务端口。
_"But - I just want to write some chaincode!"_
在这个练习中,我们将使用新的[Kubernetes Chaincode Builder](https://github.com/hyperledger-labs/fabric-builder-k8s)来开启外部合约构建通道和从而消除与CCaaS相关的管理负担。
通过使用fabric-k8s-builder, 我们将部署一个通过一下方式定义的智能合约:
1. Preparing a chaincode container image and uploading to a distribution registry.
2. Preparing a `type=k8s` chaincode package specifying the unique and immutable [container image digest](https://github.com/opencontainers/image-spec/blob/main/descriptor.md#digests).
3. Using the `peer` CLI binaries to install and commit the smart contract to a channel.
![Fabric k8s Builder](../images/CloudReady/30-chaincode.png)
## 执行
```shell
just check-network
```
## 设置peer命令行配置
```shell
export ORG1_PEER1_ADDRESS=${WORKSHOP_NAMESPACE}-org1-peer1-peer.${WORKSHOP_INGRESS_DOMAIN}:443
export ORG1_PEER2_ADDRESS=${WORKSHOP_NAMESPACE}-org1-peer2-peer.${WORKSHOP_INGRESS_DOMAIN}:443
# org1-peer1:
export CORE_PEER_LOCALMSPID=Org1MSP
export CORE_PEER_ADDRESS=${ORG1_PEER1_ADDRESS}
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_MSPCONFIGPATH=${WORKSHOP_CRYPTO}/enrollments/org1/users/org1admin/msp
export CORE_PEER_TLS_ROOTCERT_FILE=${WORKSHOP_CRYPTO}/channel-msp/peerOrganizations/org1/msp/tlscacerts/tlsca-signcert.pem
export CORE_PEER_CLIENT_CONNTIMEOUT=15s
export CORE_PEER_DELIVERYCLIENT_CONNTIMEOUT=15s
export ORDERER_ENDPOINT=${WORKSHOP_NAMESPACE}-org0-orderersnode1-orderer.${WORKSHOP_INGRESS_DOMAIN}:443
export ORDERER_TLS_CERT=${WORKSHOP_CRYPTO}/channel-msp/ordererOrganizations/org0/orderers/org0-orderersnode1/tls/signcerts/tls-cert.pem
```
## Docker Engine 配置
**NOTE: SKIP THIS STEP IF USING `localho.st` AS THE INGRESS DOMAIN**
Configure the docker engine with the insecure container registry `${WORKSHOP_INGRESS_DOMAIN}:5000`
For example: (Docker -> Preferences -> Docker Engine)
```json
{
"insecure-registries": [
"192-168-205-6.nip.io:5000"
]
}
```
- apply and restart
## 合约版本
```shell
CHANNEL_NAME=mychannel
VERSION=v0.0.1
SEQUENCE=1
```
## 构建Chaincode Docker Image
```shell
CHAINCODE_NAME=asset-transfer
CHAINCODE_PACKAGE=${CHAINCODE_NAME}.tgz
CONTAINER_REGISTRY=$WORKSHOP_INGRESS_DOMAIN:5000
CHAINCODE_IMAGE=$CONTAINER_REGISTRY/$CHAINCODE_NAME
# Build the chaincode image
docker build -t $CHAINCODE_IMAGE contracts/$CHAINCODE_NAME-typescript
# Push the image to the insecure container registry
docker push $CHAINCODE_IMAGE
```
## 准备 a k8s Chaincode Package
```shell
IMAGE_DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' $CHAINCODE_IMAGE | cut -d'@' -f2)
infrastructure/pkgcc.sh -l $CHAINCODE_NAME -n localhost:5000/$CHAINCODE_NAME -d $IMAGE_DIGEST
```
## 安装智能合约
```shell
# Install the chaincode package on both peers in the org
CORE_PEER_ADDRESS=${ORG1_PEER1_ADDRESS} peer lifecycle chaincode install $CHAINCODE_PACKAGE
CORE_PEER_ADDRESS=${ORG1_PEER2_ADDRESS} peer lifecycle chaincode install $CHAINCODE_PACKAGE
export PACKAGE_ID=$(peer lifecycle chaincode calculatepackageid $CHAINCODE_PACKAGE) && echo $PACKAGE_ID
# Approve the contract for org1
peer lifecycle \
chaincode approveformyorg \
--channelID ${CHANNEL_NAME} \
--name ${CHAINCODE_NAME} \
--version ${VERSION} \
--package-id ${PACKAGE_ID} \
--sequence ${SEQUENCE} \
--orderer ${ORDERER_ENDPOINT} \
--tls --cafile ${ORDERER_TLS_CERT} \
--connTimeout 15s
# Commit the contract on the channel
peer lifecycle \
chaincode commit \
--channelID ${CHANNEL_NAME} \
--name ${CHAINCODE_NAME} \
--version ${VERSION} \
--sequence ${SEQUENCE} \
--orderer ${ORDERER_ENDPOINT} \
--tls --cafile ${ORDERER_TLS_CERT} \
--connTimeout 15s
```
```shell
peer chaincode query -n $CHAINCODE_NAME -C mychannel -c '{"Args":["org.hyperledger.fabric:GetMetadata"]}' | jq
```
# 进一步探索
## 编辑,编译,上传,重新安装合约:
```shell
SEQUENCE=$((SEQUENCE + 1))
VERSION=v0.0.$SEQUENCE
```
- Make a change to the contracts/asset-transfer-typescript source code
- build a new chaincode docker image and publish to the local container registry
- prepare a new chaincode package as above.
- install, approve, and commit as above.
## 基于CI pipeline的结果安装智能合约
```shell
SEQUENCE=$((SEQUENCE + 1))
VERSION=v0.1.3
CHAINCODE_PACKAGE=asset-transfer-typescript-${VERSION}.tgz
```
- Download a chaincode release artifact from GitHub:
```shell
curl -LO https://github.com/hyperledgendary/full-stack-asset-transfer-guide/releases/download/${VERSION}/${CHAINCODE_PACKAGE}
```
- install, approve, and commit as above.
## 通过智能合约即服务进行调试
- prepare a chaincode package with connection.json -> HOST IP:9999 (todo: link to dig out)
- compute CHAINCODE_ID=shasum CC package.tgz
- docker run -e CHAINCODE_ID -e CHAINCODE_SERVER_ADDRESS ... $CHAINCODE_IMAGE in a different shell
- install, approve, commit as above.
## 通过Ansible进行合约部署
- cp tgz from github releases -> _cfg/
- edit _cfg/cc yaml with package name
- `just ... chaincode`
---
[前一步: 部署一个fabric网络](20-fabric-zh.md) <==> [下一步: 部署应用](40-bananas-zh.md)

View file

@ -0,0 +1,150 @@
# Gateway Client Application
[前一步: 安装智能合约](30-chaincode-zh.md) <==> [下一步: 关闭环境](90-teardown.md)
---
这是本次workshop的最后一个练习我们将会使用Gateway Client来将我们开发的应用[应用](../ApplicationDev)部署在云原生的Fabric网络上。
为了查询账本和提交交易到`asset-transfer`智能合约客户端应用必须通过制定CA签发的数字身份来启动。一旦用户身份被注册我们将会用身份来创建交易虚拟“token”资产。
![Gateway Client Application](../../docs/images/CloudReady/40-gateway-client-app.png)
## 执行
```shell
just check-chaincode
```
## 注册新用户
```shell
# User organization MSP ID
export MSP_ID=Org1MSP
export ORG=org1
export USERNAME=org1user
export PASSWORD=org1userpw
```
```shell
ADMIN_MSP_DIR=$WORKSHOP_CRYPTO/enrollments/${ORG}/users/rcaadmin/msp
USER_MSP_DIR=$WORKSHOP_CRYPTO/enrollments/${ORG}/users/${USERNAME}/msp
PEER_MSP_DIR=$WORKSHOP_CRYPTO/channel-msp/peerOrganizations/${ORG}/msp
fabric-ca-client register \
--id.name $USERNAME \
--id.secret $PASSWORD \
--id.type client \
--url https://$WORKSHOP_NAMESPACE-$ORG-ca-ca.$WORKSHOP_INGRESS_DOMAIN \
--tls.certfiles $WORKSHOP_CRYPTO/cas/$ORG-ca/tls-cert.pem \
--mspdir $WORKSHOP_CRYPTO/enrollments/$ORG/users/rcaadmin/msp
fabric-ca-client enroll \
--url https://$USERNAME:$PASSWORD@$WORKSHOP_NAMESPACE-$ORG-ca-ca.$WORKSHOP_INGRESS_DOMAIN \
--tls.certfiles $WORKSHOP_CRYPTO/cas/$ORG-ca/tls-cert.pem \
--mspdir $WORKSHOP_CRYPTO/enrollments/$ORG/users/$USERNAME/msp
mv $USER_MSP_DIR/keystore/*_sk $USER_MSP_DIR/keystore/key.pem
```
## 启动应用
- Set the gateway client to connect to the org1-peer1 as the newly enrolled `${USERNAME}`:
```shell
# Path to private key file
export PRIVATE_KEY=${USER_MSP_DIR}/keystore/key.pem
# Path to user certificate file
export CERTIFICATE=${USER_MSP_DIR}/signcerts/cert.pem
# Path to CA certificate
export TLS_CERT=${PEER_MSP_DIR}/tlscacerts/tlsca-signcert.pem
# Gateway peer SSL host name override
export HOST_ALIAS=${WORKSHOP_NAMESPACE}-${ORG}-peer1-peer.${WORKSHOP_INGRESS_DOMAIN}
# Gateway endpoint
export ENDPOINT=$HOST_ALIAS:443
```
```shell
pushd applications/trader-typescript
npm install
```
```shell
# Create a yellow banana token owned by appleman@org1
npm start create banana bananaman yellow
npm start getAllAssets
# Transfer the banana among users / orgs
npm start transfer banana appleman Org1MSP
npm start getAllAssets
# Transfer the banana among users / orgs
npm start transfer banana bananaman Org2MSP
# Error! Which org owns the banana?
npm start transfer banana bananaman Org1MSP
popd
```
# 进一步探索
## Gateway 负载均衡
在之前的例子中我们的Gateway客户端时通过直接连接的方式连接到peer节点上。我们可以进一步通过负载均衡的方式来进行拓展通过将Gateway连接到虚拟机的Ingress和k8s Service上。当以这种方式连接时网关客户端连接通过网关在网络中的组织对等端之间进行负载平衡对等方进一步向对等方发送交易请求同时保持平衡的账本高度。
![Fabric Gateway deployment](../images/ApplicationDev/fabric-gateway-deployment.png)
相关设置 [Service and Ingress](../../infrastructure/sample-network/config/gateway/org1-peer-gateway.yaml):
- Create a virtual host name / Ingress endpoint for the org peers:
```shell
pushd applications/trader-typescript
kubectl kustomize \
../../infrastructure/sample-network/config/gateway \
| envsubst \
| kubectl -n ${WORKSHOP_NAMESPACE} apply -f -
```
- Run the gateway client application, using the load-balanced Gateway service. When the gateway client
connects to the network, the gRPCs connections will be distributed across peers in the org:
```shell
unset HOST_ALIAS
export ENDPOINT=${WORKSHOP_NAMESPACE}-org1-peer-gateway.${WORKSHOP_INGRESS_DOMAIN}:443
npm start getAllAssets
popd
```
Note that in order to support ingress and host access with the new virtual domain, the peer
CRDs have been instructed to [designate an additional SAN alias](../../infrastructure/sample-network/config/peers/org1-peer1.yaml#L69)
/ host name when provisioning the node TLS certificate with the CA.
---
[前一步: 安装智能合约](30-chaincode-zh.md) <==> [下一步: 关闭环境](90-teardown.md)