8. 数据产品登记与认证安装部署
8.1. 概述
数据要素流通平台基于k3s环境部署,提供了一键部署脚本和yaml文件,用户可以根据自己的需求,选择部署对应的服务, 可根据实际情况调整适配yaml文件。
8.2. 环境依赖
8.2.1. 硬件要求
| 配置 | 最低配置 | 推荐配置 | 
|---|---|---|
| CPU | 1.5GHz | 2.4GHz | 
| 内存 | 16GB | 64GB | 
| 核心 | 8核 | 16核 | 
| 带宽 | 20Mb | 40Mb | 
8.2.2. 软件依赖
| 名称 | 版本 | 描述 | 是否必须 | 
|---|---|---|---|
| docker | 24+ | 运行核心组件及服务 | 是 | 
| docker-compose | v2.24.6+ | 本地部署长安链服务 | 否 | 
| k3s | v1.28.2+ | 与 Kubernetes 集群进行交互和管理,管理核心组件及服务 | 是 | 
| helm | v3.14.0+ | 管理 Kubernetes 应用部署的包,管理服务任务 | 是 | 
8.3. 基础环境安装
8.3.1. 安装docker
参考官网:https://docs.docker.com/engine/install/
安装完成后,执行以下命令进行验证:
➜  ~ docker version
Client:
 Version:           24.0.6-rd
 API version:       1.43
 Go version:        go1.20.7
 Git commit:        da4c87c
 Built:             Wed Sep  6 16:39:20 2023
 OS/Arch:           darwin/amd64
 Context:           desktop-linux
Server: Docker Desktop 4.27.1 (136059)
 Engine:
  Version:          25.0.2
  API version:      1.44 (minimum version 1.24)
  Go version:       go1.21.6
  Git commit:       fce6e0c
  Built:            Thu Feb  1 00:23:17 2024
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.6.28
  GitCommit:        ae07eda36dd25f8a1b98dfbf587313b99c0190bb
 runc:
  Version:          1.1.12
  GitCommit:        v1.1.12-0-g51d5e94
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0
8.3.2. k3s集群部署
注:安装K3S前需要先完成Docker安装
8.3.2.1. 使用脚本安装
下面以 Linux为例进行安装,
使用K3S安装脚本进行安装,具体步骤如下:
#1. 下载K3S安装脚本和依赖包
➜  ~  wget  -c "https://get.k3s.io" -O install.sh
➜  ~  wget  -c "https://github.com/k3s-io/k3s/releases/download/v1.28.2%2Bk3s1/k3s"
➜  ~  wget  -c "https://github.com/k3s-io/k3s/releases/download/v1.28.2%2Bk3s1/k3s-airgap-images-amd64.tar.gz"
➜  ~  wget  -c "https://github.com/k3s-io/k3s/releases/download/v1.28.2%2Bk3s1/k3s-images.txt"
➜  ~  wget  -c "https://github.com/k3s-io/k3s/releases/download/v1.28.2%2Bk3s1/sha256sum-amd64.txt"
# 2. 设置K3S配置文件
➜  ~ mkdir -p /etc/rancher/k3s/
➜  ~ tee /etc/rancher/k3s/config.yaml <<-'EOF'
docker: true
tls-san: k3s.domain.com
service-node-port-range: 30000-40000
kubelet-arg: system-reserved=cpu=500m,memory=512Mi,ephemeral-storage=1024Mi,pid=100
kubelet-arg: kube-reserved=cpu=500m,memory=512Mi,ephemeral-storage=1024Mi,pid=100
kubelet-arg: eviction-hard=memory.available<1024Mi,nodefs.available<10%,imagefs.available<10%
kubelet-arg: eviction-minimum-reclaim=memory.available=500Mi,nodefs.available=500Mi,imagefs.available=500Mi
EOF
# 3. 导入K3S镜像,并执行安装脚本
➜  ~ docker load -i k3s-airgap-images-amd64.tar.gz
➜  ~ cp -f k3s /usr/local/bin/
➜  ~ chmod 700 /usr/local/bin/k3s
➜  ~ chmod 700 install.sh
➜  ~ INSTALL_K3S_SKIP_DOWNLOAD=true  ./install.sh
安装完成后,执行以下命令进行验证:
➜  ~ k3s -v
k3s version v1.21.4+k3s- ()
go version go1.16.6
➜  ~ kubectl get ns
NAME              STATUS   AGE
default           Active   420d
kube-system       Active   420d
kube-public       Active   420d
8.3.2.2. 使用Rancher-Desktop安装
除命令行安装k3s外,还可使用Rancher Desktop工具进行可视化安装。
Rancher Desktop官网为:https://rancherdesktop.io/
安装步骤:https://docs.rancherdesktop.io/getting-started/installation/#linux
8.3.3. helm安装
Helm是Kubernetes的包管理工具,可以方便的在Kubernetes集群中部署应用。
Helm安装官网:https://helm.sh/docs/intro/install/
安装Rancher后,默认会安装helm,如果未安装可以通过脚本单独安装,步骤如下:
➜  ~ curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
➜  ~ chmod 700 get_helm.sh
➜  ~ ./get_helm.sh
安装完成后,使用以下命令进行验证:
➜  ~ helm version
version.BuildInfo{Version:"v3.13.1", GitCommit:"3547a4b5bf5edb5478ce352e18858d8a552a4110", GitTreeState:"clean", GoVersion:"go1.20.8"}
8.4. 数据要素流通平台部署
8.4.1. 获取部署脚本
# 1. 获取数据要素流通平台部署脚本
➜  ~ git clone https://git.chainweaver.org.cn/chainweaver/ida/ida-deployment.git
# 2. 切换到v2.1.0 tag
➜  ~ git checkout v2.1.0
8.4.2. 部署长安链和智能合约
8.4.2.1. 部署长安链
数据要素流通平台依赖长安链(需要启用docker go VM),需要先部署长安链。如果已经部署长安链,可以跳过该步骤。
- 长安链提供了多种部署方式, 可以参考官方部署文档,如: 通过Docker部署链 
8.4.2.2. 安装智能合约
数据要素流通平台智能合约包括数据产品登记合约:
- 数据产品登记合约: - ida合约
智能合约的部署方式与链的管理方式有关,一般有两种方式:
- 通过管控台管理的链:合约可以通过管控台直接部署或升级 
- 无管控台管理的链:合约需要通过命令行部署或升级 
注:多个参与方分别部署数据要素流通平台时,一条链上合约也仅需部署一次,无需每个参与方分别部署。
下面以命令行部署为例:
对应脚本中的节点,证书,私钥等信息需要用户根据实际情况自行调整。
# 使用ida-deployment进行合约部署
# 1. 进入合约部署目录
➜ cd ida-deployment/contract
# 2. 查看合约压缩包和部署脚本
➜ tree -L 2
.
├── contracts # mira和ida合约文件
│   ├── contract_ida.7z
├── crypto-config # 长安链用户证书,需要根据实际情况进行替换(下面为cert模式链的证书列表)
│   ├── wx-org1.chainmaker.org
│   ├── wx-org2.chainmaker.org
│   ├── wx-org3.chainmaker.org
│   └── wx-org4.chainmaker.org
├── deploy.sh # 部署合约脚本
├── scripts # 部署合约脚本、配置文件(支持cert模式和pk模式)
│   ├── cmc
│   ├── create_contract.sh
│   ├── create_contract_pk.sh
│   ├── sdk_config.yml
│   ├── sdk_config_pk.yml
│   ├── upgrade_contract.sh
│   └── upgrade_contract_pk.sh
└── upgrade.sh # 升级合约脚本
# 3. 执行脚本部署智能合约
# 支持cert模式和pk模式, 以cert模式为例
➜ ./deploy.sh cert
# 如果是升级合约,执行upgrade.sh脚本。
# 支持cert模式和pk模式, 同时支持升级ida合约
# 以升级ida合约为例:
# ida:v2.1.0表示ida合约升级到v2.1.0版本
➜ ./upgrade.sh cert ida:v2.1.0
8.4.3. 部署公共服务和ida组件
ida-deployment提供了公共服务和ida组件的部署脚本,用户可以根据实际情况进行部署,默认使用版本为v2.1.0
8.4.3.1. 初始化环境
- 切换到helm目录 
cd ida-deployment/helm
- 创建namespace, “public”和”ida” 服务 
kubectl create ns public
kubectl create ns ida
- 创建数据放置的文件夹,这里示例中,数据放置在数据放置服务器上的(这里是k8s-node1节点):: /mnt/data,需要提前创建 
- 文件夹要在服务部署的k8s/k3s的节点机器上创建 
public目录
mkdir -p /mnt/data/public/mysql # mysql 数据存储路径, 如果采用kingbase数据库,这里mysql修改为kingbase,其中的"public"为上一步创建的namespace
mkdir -p /mnt/data/public/redis # redis 数据存储路径, 其中的"public"为上一步创建的namespace
mkdir -p /mnt/data/public/kingbase # kingbase 数据存储路径, 其中的"public"为上一步创建的namespace
mkdir -p /mnt/data/public/key/logs # key 日志存储路径, 其中的"public"为上一步创建的namespace
mkdir -p /mnt/data/public/chain/logs # chain 日志存储路径, 其中的"public"为上一步创建的namespace
ida目录
mkdir -p /mnt/data/ida/certification/logs # certification 日志存储路径, 其中的"ida"为上一步创建的namespace
mkdir -p /mnt/data/ida/registration/logs # registration 日志存储路径, 其中的"ida"为上一步创建的namespace
mkdir -p /mnt/data/ida/gateway/logs # gateway 日志存储路径, 其中的"ida"为上一步创建的namespace
mkdir -p /mnt/data/ida/circulation/logs # circulation 日志存储路径, 其中的"ida"为上一步创建的namespace
8.4.3.2. 启动服务
- 启动public 服务, 自定义的配置如mysql password等可在public/values.yaml中修改 
- 节点名称查询,其中NAME列是节点名称 
$ kubectl get node -o wide
NAME         STATUS   ROLES           AGE    VERSION   INTERNAL-IP     EXTERNAL-IP   OS-IMAGE                KERNEL-VERSION                 CONTAINER-RUNTIME
k8s-master   Ready    control-plane   246d   v1.28.2   192.168.1.181   <none>        CentOS Linux 7 (Core)   3.10.0-1160.119.1.el7.x86_64   containerd://1.6.33
k8s-node1    Ready    <none>          222d   v1.26.9   192.168.1.182   <none>        CentOS Linux 7 (Core)   3.10.0-1160.105.1.el7.x86_64   containerd://1.6.27
命令解析
helm install public ./public helm安装public服务,并且配置目录在./public
--namespace public 设置namespace
--set 'global.nodeAffinity.values[0]=k8s-node1' 设置配置文件中的节点名称
--set global.dataPath=/mnt/data 设置配置文件中的数据目录
--set global.mgr.database=mysql 指定数据库类型,目前支持mysql和kingbase,默认是mysql,如果需要使用kingbase则需要指定
--set global.mgr.database_conf=mysql 指定数据库配置类型,目前支持mysql和kingbase,默认是mysql,如果需要使用kingbase则需要指定
命令执行
helm install public ./public --namespace public --set 'global.nodeAffinity.values[0]=k8s-node1' --set global.dataPath=/mnt/data
- 启动ida 服务, 自定义的配置如mysql password等可在public/values.yaml中修改 
命令解析
helm install ida ./ida  --namespace ida helm安装ida服务,并且配置目录在./ida
  --set global.publicNameSpace=public  指定public的namespace,这里前面的示例为 public
  --set 'global.nodeAffinity.values[0]=k8s-node1'  指定数据希望放置的K8S节点名称,这里示例为 k8s-node1
  --set global.dataPath=/mnt/data  指定数据存储路径,这里示例为 /mnt/data
  --set global.circulation.nodePort=31090  指定 circulation 服务的nodePort,这里示例为 31090
  --set global.mgr.database=mysql 指定数据库类型,目前支持mysql和kingbase,默认是mysql,如果需要使用kingbase则需要指定
  --set global.mgr.database_conf=mysql 指定数据库配置类型,目前支持mysql和kingbase,默认是mysql,如果需要使用kingbase则需要指定
命令执行
helm install ida ./ida  --namespace ida --set global.publicNameSpace=public --set 'global.nodeAffinity.values[0]=k8s-node1' --set global.dataPath=/mnt/data --set global.circulation.nodePort=31090
8.4.3.3. 查看服务状态
kubectl get pods -n public
kubectl get pods -n ida
- 本地生成yaml文件,方便调试 
# 生成public yaml文件
helm template public ./public --namespace public --set 'global.nodeAffinity.values[0]=k8s-node1' --set global.dataPath=/mnt/data > ../output_public.yaml
# 生成ida yaml文件
helm template ida ./ida --namespace ida  \
  --set global.publicNameSpace=public \
  --set 'global.nodeAffinity.values[0]=k8s-node1' \
  --set global.dataPath=/mnt/data \
  --set global.circulation.nodePort=31090 > ../output_ida.yaml
8.4.3.4. 卸载服务
# 卸载 public
helm uninstall public --namespace public
# 卸载 ida
helm uninstall ida --namespace ida
# 删除namespace
kubectl delete ns public
kubectl delete ns ida
# 删除数据
rm -rf /mnt/data/public
rm -rf /mnt/data/ida
8.4.3.5. 服务验证
安装完成后,执行以下命令进行验证:
# 查看public命名空间下的pod,如果以下服务正常运行,说明公共服务组件部署成功
➜  ~ kubectl get pod -n public
NAME                                       READY   STATUS    RESTARTS   AGE
mysql-8c648b66b-4clz5                      1/1     Running   0          3m18s
redis-797cf49c8c-wkgvw                     1/1     Running   0          3m18s
key-ff87f646f-288qc                        1/1     Running   0          3m18s
chain-f5f7f896c-2b2nl                      1/1     Running   0          3m18s
# 查看ida命名空间下的pod,如果以下服务正常运行,说明ida组件部署成功
➜  ~ kubectl get pod -n ida
NAME                             READY   STATUS    RESTARTS   AGE
circulation-6c6cffffcc-nvkdl     1/1     Running   0          3m19s
gateway-6bd8cf8c9b-7gwsb         1/1     Running   0          3m19s
certification-64d8885b57-8c9qj   1/1     Running   0          3m19s
registration-6db56bccc5-bxrp7    1/1     Running   0          3m19s
8.5. 服务列表
必选组件安装成功后,集群中会部署以下服务或组件:
| 服务/组件名称 | 说明 | 命名空间 | 部署类型 | Docker镜像名称 | K8S Service名称 | dataPath / logPath | 
|---|---|---|---|---|---|---|
| mysql | 公共服务-存储 | public | Deployment | mysql | mysql | /mnt/data/public/mysql (mysql存储目录) | 
| redis | 公共服务-缓存 | public | Deployment | redis | redis | /mnt/data/public/redis (redis存储目录) | 
| key | 公共服务-链密钥管理 | public | Deployment | public-key | key | /mnt/data/public/key/logs | 
| chain | 公共服务-链服务 | public | Deployment | public-chain | chain | /mnt/data/public/chain/logs | 
| certification | IDA-数据产品认证服务 | ida | Deployment | ida-certification | certification | /mnt/data/ida/certification/logs | 
| registration | IDA-数据产品登记服务 | ida | Deployment | ida-registration | registration | /mnt/data/ida/registration/logs | 
| gateway | IDA-网关 | ida | Deployment | ida-gateway | gateway | /mnt/data/ida/gateway/logs | 
| circulation | IDA-数据要素流通平台前端 | ida | Deployment | ida-circulation | circulation | /mnt/data/ida/circulation/logs | 
8.6. 部署验证
部署完成后,可以通过前端页面登录模块-用户列表-区块链配置-合约配置-链账户配置-平台配置全流程进行验证。
详细步骤请参考,文档中3.4. 产品使用说明-公共模块: 用户使用手册链接
8.7. 部署升级
8.7.1. 升级流程
- 服务升级至v2.1.0版本 
- 合约升级至v2.1.0版本 
- 服务配置处理(顺序不能错误) - 系统配置中选择链账户,并进行平台英文名,企业身份和企业角色配置;(配置信息中体现出来平台12的区分) 
- 在链账户绑定页面,点击关联平台; 
 
8.7.2. 通过拉取新版本代码升级(推荐)
原分支:v2.0.0 更新后的分支:v2.1.0
8.7.2.1. 升级helm
更新完镜像/配置等信息后,需要对helm部署的服务进行升级,执行下面的命令
# 进入到helm目录下
cd helm
# 升级public的服务
helm upgrade public ./public -n public 
# 升级ida的服务
helm upgrade ida ./ida -n ida 
8.7.3. 通过手动更新配置升级
- 建议通过拉取新版本的方式进行升级,手动更新等于手动更新代码变更,复杂且容易出错误; 
- 如果手动部署出现问题,请严格对比git仓库代码 
- 下面列出的是从 v2.0.0 => v2.1.0 版本的升级调整 
8.7.3.1. 更新镜像
如果只是服务进行了升级,且没有配置的更新时,可以只在helm的values.yaml文件中更新对应的镜像,然后进行helm升级即可
下面以更新前端服务为例
文件路径: helm/ida/values.yaml
circulation:
  cnf:
    listen:
      host: 0.0.0.0
    grpcConf:
      caCertFile: ""
      serverCertFile: ""
      serverKeyFile: ""
    keyServiceConf:
      caCertFile: ""
      serverCertFile: ""
      serverKeyFile: ""
  pv:
    capacity:
      storage: 200Mi
    accessModes: ReadWriteOnce
    persistentVolumeReclaimPolicy: Retain
    local:
      path: /circulation/logs
  containers:
    replicas: 1
    image: docker.oa.com:5000/ida/asset-circulation:v2.0.4
    pullPolicy: IfNotPresent
  service:
    type: NodePort
找到circulation.containers.image,把对应镜像名称更新为新镜像即可,比如
docker.oa.com:5000/ida/asset-circulation:v2.0.4 => docker.oa.com:5000/ida/asset-circulation:v2.0.5
下表是具体需要更新的镜像:
| 服务/组件名称 | 是否需要更新 | 说明 | 命名空间 | 新镜像名称 | 文件路径 | 
|---|---|---|---|---|---|
| mysql | 否 | 公共服务-存储 | public | - | - | 
| redis | 否 | 公共服务-缓存 | public | - | - | 
| key | 是 | 公共服务-链密钥管理 | public | docker.oa.com:5000/chainweaver/public-key:v2.1.0 | helm/public/values.yaml | 
| chain | 是 | 公共服务-链服务 | public | docker.oa.com:5000/chainweaver/public-chain:v2.1.0 | helm/public/values.yaml | 
| certification | 是 | IDA-数据产品认证服务 | ida | docker.oa.com:5000/chainweaver/ida-certification:v2.1.0 | helm/ida/values.yaml | 
| registration | 是 | IDA-数据产品登记服务 | ida | docker.oa.com:5000/chainweaver/ida-registration:v2.1.0 | helm/ida/values.yaml | 
| gateway | 是 | IDA-网关 | ida | docker.oa.com:5000/chainweaver/ida-gateway:v2.1.0 | helm/ida/values.yaml | 
| circulation | 是 | IDA-数据要素流通平台前端 | ida | docker.oa.com:5000/ida/asset-circulation:v2.2.0 | helm/ida/values.yaml | 
8.7.3.2. 更新配置
8.7.3.2.1. 更新public服务配置
文件路径:helm/public/values.yaml
# global.mgr下新增
    # 使用哪种数据库:mysql,kingbase
    database: mysql
    
# global下新增
  kingbase:
    name: kingbase
    port: 54321
    user: kingbase
    password: 123456
    
# global.redis下新增
    # redis 部署类型,单节点:node,集群:cluster,哨兵:sentinel
    ConfType: "node"
# 文件下根节点新增
kingbase:
  enabled: true
  env:
    dbMode: oracle
  pv:
    capacity:
      storage: 200Mi
    accessModes: ReadWriteOnce
    persistentVolumeReclaimPolicy: Retain
    local:
      path: /kingbase
  containers:
    replicas: 1
    image: docker.oa.com:5000/kingbase_v008r006c008b0014_single_x86:v1
    pullPolicy: IfNotPresent
  service:
    type: ClusterIP
# redis下新增
  enabled: true
  
# 文件下根节点新增
redis-cluster:
  enabled: false
# chain.cnf下新增
    # chain sdk proxy 地址,如果不走代理,配置空即可
    sdkProxyUrl: ""
    adapterConf:
      # 是否启动适配器
      enable: false
      type: "ftp"
      config_file_path: "./etc/ftp_config.yml"
      #type: "kafka"
      #config_file_path: "./etc/kafka_config.yml"
    kafkaConf:
      brokers:
        - 192.168.2.35:9092
        - 192.168.2.35:9093
        - 192.168.2.35:9094
      security:
        enabled: true
        sasl:
          enabled: true
          # PLAIN / SCRAM-SHA-256 (目前不支持 SCRAM-SHA-512 )
          mechanism: "SCRAM-SHA-256"
          user: "kafkauser"
          password: "password"
        ssl:
          enabled: true
          # true 为允许自签名证书
          insecure: true
          ca_cert: "./testdata/kafka-ssl/ca.crt"
          client_cert: "./testdata/kafka-ssl/broker1.crt"
          client_key: "./testdata/kafka-ssl/broker1.key"
      topic_manager_config:
        # 对于用程序创建的topic,需要等待对端consumer准备完成后,再向新topic发送消息,便于对端能及时消费到交易(建议 >= 10s,否则可能导致第一笔交易丢失)
        # 根据环境配置(有sasl+ssl认证的环境下,这个过程会较长,可适当调整)(可能需要30s或者更长)
        # 对于已经预创建的topic,可以配置为0,或者不配置
        # (second)
        wait_new_topic_ready_interval: 45
        # 刷新consumer的topic,用于监听是否有新topic的加入
        refresh_topic:
          enable: true
          # 刷新间隔( second )
          interval: 3
        # single 单主题(所有链的所有交易放在同一主题)
        # multi_by_chain 多主题(按链区分,每条链一个主题)
        # multi_by_chain_and_contract 多主题(按 链id+合约名 区分主题,每条链的每个合约作为一个主题,方便做合约内交易有序)
        # 其中主题名需以特定前缀开头,便于consumer消费者获取到所有与该业务相关的topic
        # 如果需要保证合约内交易有序,需要配置为 multi_by_chain_and_contract
        tx_msg_topic_mod: multi_by_chain_and_contract
        # 启动时校验sarama client是否有创建topic权限,如果没有权限则创建kafkaClient时返回失败
        # 如果只能手动创建topic,这里配置为false
        # 如果为false,则不会主动创建审计topic,需要预先手动创建审计topic (见audit_subscribe配置)
        check_topic_permission: true
      # GetChainMakerServerVersion 接口超时时间(second)
      # (default) 30s
      get_request_timeout: 120
8.7.3.2.2. 更新ida服务配置
文件路径:helm/ida/values.yaml
# global.mgr下新增
    # 使用哪种数据库:mysql,kingbase
    database: mysql
# global下新增
  kingbase:
    name: kingbase
    port: 54321
    user: kingbase
    password: 123456
    
# global.redis下新增
    # redis 部署类型,单节点:node,集群:cluster,哨兵:sentinel
    ConfType: "node"
8.7.3.2.3. 链服务需要更新/新增的配置如下
文件路径:helm/public/charts/chain/templates/configmap.yaml
文件中chain-service.yaml: |-行下面既是配置文件;
apiVersion: v1
data:
  chain-service: |-
...
    # SubscribeConf字段,替换为下面的内容
    SubscribeConf:
      # redis 部署类型,单节点:node,集群:cluster,哨兵:sentinel
      ConfType: {{.Values.global.redis.ConfType}}
      # 集群方式下,多个 redis 地址用逗号分隔
      RedisAddr: {{.Values.global.redis.name}}.{{ .Release.Namespace }}.svc.cluster.local:{{ .Values.global.redis.port }}
      RedisUserName:
      RedisPassword: {{ .Values.global.secret.redis.password | b64dec | quote  }}
    
    # 新增AdapterConfig配置
    # 适配器配置,目前支持 ftp、kafka
    AdapterConfig:
      # 是否启动适配器
      Enable: {{ .Values.cnf.adapterConf.enable }}
      Type: {{ .Values.cnf.adapterConf.type }}
      ConfFilePath: {{ .Values.cnf.adapterConf.config_file_path }}
    # 新增SdkProxyUrl配置
    # chain sdk proxy 地址,如果不走代理,配置空即可
    SdkProxyUrl: {{ .Values.cnf.sdkProxyUrl }}
    # 删除FtpConfig的配置
    FtpConfig:
      # 是否启动 ftp 传输 tx
      Enable: false
      ConfFilePath: ./etc/ftp_config.yml    
...
新增kafka配置文件:
  kafka_config.yml: |-
    #kafka集群配置 / 单点
    kafka_config:
      brokers: {{ .Values.cnf.kafkaConf.brokers }}
      security:
        enabled: {{ .Values.cnf.kafkaConf.security.enabled }}
        sasl:
          enabled: {{ .Values.cnf.kafkaConf.security.sasl.enabled }}
          # PLAIN / SCRAM-SHA-256 (目前不支持 SCRAM-SHA-512 )
          mechanism: {{ .Values.cnf.kafkaConf.security.sasl.mechanism }}
          user: {{ .Values.cnf.kafkaConf.security.sasl.user }}
          password: {{ .Values.cnf.kafkaConf.security.sasl.password }}
        ssl:
          enabled: {{ .Values.cnf.kafkaConf.security.ssl.enabled }}
          # true 为允许自签名证书
          insecure: {{ .Values.cnf.kafkaConf.security.ssl.insecure }}
          ca_cert: {{ .Values.cnf.kafkaConf.security.ssl.ca_cert }}
          client_cert: {{ .Values.cnf.kafkaConf.security.ssl.client_cert }}
          client_key: {{ .Values.cnf.kafkaConf.security.ssl.client_key }}
      # chain / client (default: client)
      # 配置为chain表示为链端服务
      side: client
      topic_manager_config:
        # 对于用程序创建的topic,需要等待对端consumer准备完成后,再向新topic发送消息,便于对端能及时消费到交易(建议 >= 10s,否则可能导致第一笔交易丢失)
        # 根据环境配置(有sasl+ssl认证的环境下,这个过程会较长,可适当调整)(可能需要30s或者更长)
        # 对于已经预创建的topic,可以配置为0,或者不配置
        # (second)
        wait_new_topic_ready_interval: {{ .Values.cnf.kafkaConf.topic_manager_config.wait_new_topic_ready_interval }}
        # 刷新consumer的topic,用于监听是否有新topic的加入
        refresh_topic:
          enable: {{ .Values.cnf.kafkaConf.topic_manager_config.refresh_topic.enable }}
          # 刷新间隔( second )
          interval: {{ .Values.cnf.kafkaConf.topic_manager_config.refresh_topic.interval }}
        # single 单主题(所有链的所有交易放在同一主题)
        # multi_by_chain 多主题(按链区分,每条链一个主题)
        # multi_by_chain_and_contract 多主题(按 链id+合约名 区分主题,每条链的每个合约作为一个主题,方便做合约内交易有序)
        # 其中主题名需以特定前缀开头,便于consumer消费者获取到所有与该业务相关的topic
        # 如果需要保证合约内交易有序,需要配置为 multi_by_chain_and_contract
        tx_msg_topic_mod: {{ .Values.cnf.kafkaConf.topic_manager_config.tx_msg_topic_mod }}
        # 启动时校验sarama client是否有创建topic权限,如果没有权限则创建kafkaClient时返回失败
        # 如果只能手动创建topic,这里配置为false
        # 如果为false,则不会主动创建审计topic,需要预先手动创建审计topic (见audit_subscribe配置)
        check_topic_permission: {{ .Values.cnf.kafkaConf.topic_manager_config.check_topic_permission }}
      # 交易信息编码方式: json(default,目前只支持json) | pb
      tx_msg_encode: json
      # 交易容量(default 50)
      tx_buffer_size: 50
      # 合约事件容量
      event_buffer_size: 50
      # GetChainMakerServerVersion 接口超时时间(second)
      # (default) 30s
      get_request_timeout: {{ .Values.cnf.kafkaConf.get_request_timeout }}
      # 订阅审计,用于链端服务重启后恢复交易
      audit_subscribe:
        enable: true
        # kafka / file (目前只支持kafka,以kafka topic形式记录订阅进度)
        mod: kafka
        topic_name: ida-audit-subscribe
      producer:
        #     client端配置
        topic_prefix: ida-request
        # 链端配置
        #    topic_prefix: ida-response
        #  0: 生产者不等待任何确认,延迟低,但可能导致消息丢失
        #  1: (default)生产者等待leader副本的确认后返回。如果leader崩溃,消息可能会丢失
        #  all: 生产者等待所有同步副本的确认,提供最高的可靠性
        acks: "all"
        #  生产者在发送失败时的重试次数
        #  (default) 最大整数,无限重试
        retries: 3
        #  请求的超时时间,如果在此时间内未收到响应,生产者将认为请求失败
        # (default)30000 毫秒(30秒)
        request_timeout_ms: 30000
      consumer:
        # client端配置
        topic_prefix: ida-response
        #    # 链端配置
        #    topic_prefix: ida-request
        group:
          # single 所有主题用同一个consumer(生产者单topic,消费者消费交易具有顺序性;多topic,不保证全局顺序性)
          # by_topic 每个topic一个consumer(同上,多topic时不保证全局顺序性; topic内是否有序,依tx_msg_key_enable配置确定,为true则topic内有序)
          topic_consumer:
            mod: by_topic
        #  自动提交可能会在消费者故障时丢失已接收但未完成处理的偏移量。手动提交可以确保消息处理的原子性
        #  (default)true
        enable_auto_commit: false
8.7.3.2.4. 认证服务需要更新/新增的配置如下
文件路径:helm/ida/charts/certification/templates/configmap.yaml
文件中certification.yaml: |-行下面既是配置文件;
apiVersion: v1
data:
  certification.yaml: |-
...
    # EventConf字段,替换为下面的内容
    EventConf:
      # redis 部署类型,单节点:node,集群:cluster,哨兵:sentinel
      ConfType: {{.Values.global.redis.ConfType}}
      Host: {{.Values.global.redis.name}}.{{ .Values.global.publicNameSpace }}.svc.cluster.local:{{ .Values.global.redis.port }}
      Password: {{ .Values.global.secret.redis.password | b64dec | quote  }}
      Consumer: {{ .Values.global.certification.name }}_consumer
      GroupName: {{ .Values.global.certification.name }}
      ChainConfigInterval: {{ .Values.global.certification.ChainConfigInterval }}
    # 新增CornCertificationExpiration字段 
    # 定时任务,认证过期配置
    CornCertificationExpiration:
      # 每天3点执行
      Spec: "0 3 * * *"
...
8.7.3.2.5. 网关服务需要修改的配置如下
文件路径:helm/ida/charts/gateway/templates/configmap.yaml
文件中gateway.yaml: |-行下面既是配置文件;
apiVersion: v1
data:
  gateway.yaml: |-
...
    # MaxBytes字段,设置为0
    # 请求体最大允许字节数 50MB,根据实际情况设置,0为不设置限制
    MaxBytes: 0
    
    # Cache字段,替换为下面的内容
    # redis 缓存配置
    Cache:
      # redis 部署类型,单节点:node,集群:cluster,哨兵:sentinel
      ConfType: {{.Values.global.redis.ConfType}}
      Host: {{.Values.global.redis.name}}.{{ .Values.global.publicNameSpace }}.svc.cluster.local:{{ .Values.global.redis.port }}
      Pass: {{ .Values.global.secret.redis.password | b64dec | quote }}
      
    # 新增JWTConfig字段 
    JWTConfig:
      # 生成jwt的密钥
      JWTSecret: xxx
      # 过期时间秒
      JWTExpired: 7200
...
8.7.3.2.6. 登记服务需要更新/新增的配置如下
文件路径:helm/ida/charts/registration/templates/configmap.yaml
文件中registration-service.yaml: |-行下面既是配置文件;
apiVersion: v1
data:
  registration-service.yaml: |-
...
    # EventConf字段,替换为下面的内容
    EventConf:
      Host: {{.Values.global.redis.name}}.{{ .Values.global.publicNameSpace }}.svc.cluster.local:{{ .Values.global.redis.port }}
      Password: {{ .Values.global.secret.redis.password | b64dec | quote  }}
      # redis 部署类型,单节点:node,集群:cluster,哨兵:sentinel
      ConfType: {{.Values.global.redis.ConfType}}
      GroupName: {{ .Values.global.registration.name }}
      ChainConfigInterval: {{ .Values.global.registration.ChainConfigInterval }}
...
8.7.3.3. 升级helm
更新完镜像/配置等信息后,需要对helm部署的服务进行升级,执行下面的命令
# 进入到helm目录下
cd helm
# 升级public的服务
helm upgrade public ./public -n  public 
# 升级ida的服务
helm upgrade ida ./ida -n ida 
命令解析:
- ida: 指的是部署的helm的名称 
- ./ida: helm部署文件的路径,路径下需要有value.yaml文件 
- -n ida: 是指定命名空间 
8.7.3.4. 重启服务(可选)
使用helm升级过后,容器pod并不一定会重启;比如如果只更新了configmap,那么升级过后服务不会重启,这时就需要手动进行重启
- 重启方式:deployment滚动重启(推荐) 
先查询deployment的名称,然后进行重启服务;这种方式是滚动更新,不会中断服务
# 查询deployment名称
$ kubectl get deployment -n ida
NAME            READY   UP-TO-DATE   AVAILABLE   AGE
certification   1/1     1            1           18d
circulation     1/1     1            1           18d
gateway         1/1     1            1           18d
registration    1/1     1            1           18d
# 重启多个服务,输入deployment的名称,certification circulation gateway registration
$ kubectl rollout restart deployment certification circulation gateway registration  -n ida
8.8. 高可用部署
- 是否要进行高可用部署? - 在需要保证服务持续可用的场景中,可以考虑进行高可用部署。高可用性可以确保系统在面对硬件故障、软件问题或其他意外情况下仍然能够正常运行,从而减少停机时间和业务损失。 
- 上文的常规部署方式,helm+k8s,已经能做到应用意外退出后自动重启,高可用可以进一步减少不可用时间。 
 
- 高可用有什么优势? - 减少停机时间:高可用架构通过冗余和故障转移机制,能够在某个组件发生故障时迅速切换到备用系统,从而保持服务的持续可用性。 
- 提升用户体验:用户可以在任何时候访问服务,而不会受到系统故障的影响,这对于提供在线服务的企业尤为重要。 
- 增强系统可靠性:高可用性可以提高系统的整体可靠性,确保关键业务应用始终在线,满足业务连续性的要求。 
 
- 高可用有什么劣势? - 成本增加:实现高可用性通常需要额外的硬件、软件和网络资源,这会增加总体运营成本。例如,冗余服务器、负载均衡器和备份方案都需要额外投入。 
- 复杂性提高:高可用架构通常比单一系统更复杂,需要更多的配置、监控和维护工作。这可能导致运维团队面临更大的管理压力。 
- 故障转移延迟:在某些情况下,故障转移可能会导致短暂的服务中断,尽管这种时间通常很短,但仍然可能影响用户体验。 
- 性能开销:为了实现高可用性,可能需要牺牲一些性能,例如在某些情况下进行数据复制或同步,这可能会影响系统的响应速度。 
 
8.8.1. 高可用redis部署
- 其他步骤同上文 - 单个系统部署,helm部署命令有所不同
8.8.1.1. 创建namespace
kubectl create ns public
kubectl create ns ida
8.8.1.2. 创建文件夹
- 创建数据放置的文件夹,这里示例中,数据放置在数据放置服务器上的(这里是k8s-node1节点):: /mnt/data,需要提前创建 
mkdir -p /mnt/data/public/mysql 
mkdir -p /mnt/data/public/redis 
mkdir -p /mnt/data/public/key/logs 
mkdir -p /mnt/data/public/chain/logs 
mkdir -p /mnt/data/ida/certification/logs 
mkdir -p /mnt/data/ida/registration/logs 
mkdir -p /mnt/data/ida/gateway/logs 
mkdir -p /mnt/data/ida/circulation/logs 
8.8.1.3. 启动服务
- 设置redis的部署名称:这里要改为namespace,–set global.redis.name={namespace}-redis-cluster 
- 指定部署文件:-f public/redis-sentinel-values.yaml 
# 部署public的命令 
helm install public ./public --namespace public  --set 'global.nodeAffinity.values[0]=k8s-node1' --set global.dataPath=/mnt/data  --set global.redis.name=public-redis-cluster -f public/redis-sentinel-values.yaml
# 部署ida的命令 
helm install ida ./ida  --namespace ida --set global.publicNameSpace=public --set 'global.nodeAffinity.values[0]=k8s-node1' --set global.dataPath=/mnt/data --set global.redis.name=public-redis-cluster --set global.circulation.nodePort=31090 -f ida/values.yaml -f ida/ha-values.yaml
8.8.1.4. 状态查询
# 查询public的运行状态,其中默认的是2个副本
$ kubectl get pod -npublic
NAME                           READY   STATUS    RESTARTS   AGE
chain-f77cd87-87pjh            1/1     Running   0          45m
key-75f8db6d79-2r9k8           1/1     Running   0          45m
mysql-586c49df5d-glkm6         1/1     Running   0          45m
public-redis-cluster-node-0    2/2     Running   0          45m
public-redis-cluster-node-1    2/2     Running   0          45m
# 查询ida的运行状态
kubectl get pod -nida
NAME                             READY   STATUS    RESTARTS   AGE
certification-575979565d-7xw8x   1/1     Running   0          73m
circulation-99fd9ffc8-jc4lc      1/1     Running   0          73m
gateway-67ff487cbc-dkhxn         1/1     Running   0          73m
registration-7894cf744d-m77p7    1/1     Running   0          73m
8.8.2. 高可用mysql部署
- 其他步骤同上文 - 单个系统部署,helm部署命令有所不同
- 一个k8s集群中只能部署一套高可用mysql 
- 部署的节点数至少为4个 
8.8.2.1. 创建namespace
同上
8.8.2.2. 创建文件夹
同上
8.8.2.3. 启动服务
- 指定部署文件:-f public/ha-values.yaml 
# 部署public的命令 
helm install public ./public --namespace public --set 'global.nodeAffinity.values[0]=host127' --set global.dataPath=/mnt/data -f public/values.yaml -f public/ha-values.yaml
# 部署ida的命令 
helm install ida ./ida  --namespace ida --set global.publicNameSpace=public  --set 'global.nodeAffinity.values[0]=host127' --set global.dataPath=/mnt/data --set global.circulation.nodePort=31090
8.8.2.4. 状态查询
# 查询public的运行状态
$ kubectl get  pod -npublic
NAME                              READY   STATUS    RESTARTS   AGE
chain-759c9c79c8-k7p6q            1/1     Running   0          2m42s
key-67b768b858-7k7vc              1/1     Running   0          26m
mysql-0                           2/2     Running   0          4h33m
mysql-1                           2/2     Running   0          4h33m
mysql-2                           2/2     Running   0          4h33m
mysql-operator-847f8d455b-tkp2m   1/1     Running   0          4h33m
mysql-router-85bdd8c985-cpcpj     1/1     Running   1          4h32m
redis-589576bbb5-sqxxn            1/1     Running   1          4h33m
# 查询ida的运行状态
$ kubectl get pod -nida
NAME                             READY   STATUS    RESTARTS   AGE
certification-7455ffd796-mbmqt   1/1     Running   0          40s
circulation-7468bf985f-tfvm7     1/1     Running   0          40s
gateway-7c5767945f-7j4hs         1/1     Running   0          40s
registration-6bb95c695b-bvkkb    1/1     Running   0          40s
8.8.2.5. 卸载服务
- 高可用public组件删除步骤,要按照顺序进行操作 
# 1. 手动删除mysql InnodbCluster 组件, namespace 自行替换
kubectl patch innodbcluster mysql -p '{"metadata":{"finalizers":[]}}' --type=merge -n public
kubectl delete innodbcluster mysql -n public
# 1.1 查询是否已经被卸载
kubectl get pod -n public
# mysql-0/1/2/router 四个pod卸载完毕
# 上一步卸载成功,再执行helm卸载
# 2. helm 卸载public
helm uninstall public -n public
# 3. 清除数据pvc,重新部署时需要删除(根据是否保留mysql数据选执行)
kubectl delete pvc -n public datadir-mysql-0 datadir-mysql-1 datadir-mysql-2