Hyperledger1.4 Fabric to kubernetes

Hyperledger Fabric

环境说明

系统说明

IP Hostname 标识
192.168.0.247 kubernetes-1 K8S-Master and Kubectl-Cli
192.168.0.248 kubernetes-2 K8S-Master and Node
192.168.0.249 kubernetes-3 K8S-Node and NFS Server

服务说明

名称 版本
CentOS 7 x64
Hyperledger Fabric 1.4
kubernetes 1.13.2
docker 18.06.1-ce

Fabric 环境配置

docker 配置

由于 实例化 chaincode 需要由 docker 创建容器

而 这个容器需要跟 k8s 里的 peer svc 通信, 所以需要额外配置

 

# 配置 docker 配置

修改 docker 选项 DOCKER_OPTS 

在 DOCKER_OPTS 中 增加 --dns 添加 k8s 中 dns 的 ip


[root@kubernetes-1 /opt/jicki/k8s-yaml]# kubectl get svc -n kube-system    

NAME                   TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)                  AGE
coredns                ClusterIP   10.233.0.3     <none>        53/UDP,53/TCP,9153/TCP   4d23h


# 我这个环境中 coredns IP 为 10.233.0.3

# 所以 添加

--dns 10.233.0.3

 

cryptogen 下载

cryptogen 用于简化生成 fabric 所需要的所有证书

 

# 官方离线下载地址为 
https://nexus.hyperledger.org/content/repositories/releases/org/hyperledger/fabric/hyperledger-fabric/

# 选择相应版本 CentOS 选择 linux-amd64-1.4.0
# Mac 选择 darwin-amd64-1.4.0

# 创建工作目录 ( 后续所有文件都存于此目录中 )

mkdir -p /opt/jicki

cd /opt/jicki

wget https://nexus.hyperledger.org/content/repositories/releases/org/hyperledger/fabric/hyperledger-fabric/linux-amd64-1.4.0/hyperledger-fabric-linux-amd64-1.4.0.tar.gz



# 解压文件
[root@kubernetes-1 /opt/jicki]# tar zxvf hyperledger-fabric-linux-amd64-1.4.0.tar.gz


# 删除 config 这个文件夹,  这里用不到

[root@kubernetes-1 /opt/jicki]# rm -rf config


# 查看文件
[root@kubernetes-1 /opt/jicki]# tree
.
└── bin
    ├── configtxgen
    ├── configtxlator
    ├── cryptogen
    ├── discover
    ├── get-docker-images.sh
    ├── idemixgen
    ├── orderer
    └── peer

1 directory, 8 files


# 为方便使用 我们配置一个 环境变量

vi /etc/profile

# fabric env
export PATH=$PATH:/opt/jicki/bin

# 使文件生效
source /etc/profile

 

Fabric 源码下载

[root@kubernetes-1 /opt/jicki]# git clone https://github.com/hyperledger/fabric

 

生成 证书

# 创建 cryptogen.yaml 文件, 1.4版本 crypto-config.yaml 文件更改为 cryptogen.yaml

vi cryptogen.yaml

OrdererOrgs:
  - Name: Orderer
    Domain: orgorderer1
    CA:
        Country: CN
        Province: GuangDong
        Locality: ShenZhen
    Specs:
      - Hostname: orderer0
      
PeerOrgs:
  - Name: Org1
    Domain: org1
    EnableNodeOUs: true
    CA:
        Country: CN
        Province: GuangDong
        Locality: ShenZhen
    Template:
      Count: 2
    Users:
      Count: 1
  - Name: Org2
    Domain: org2
    EnableNodeOUs: true
    CA:
        Country: CN
        Province: GuangDong
        Locality: ShenZhen
    Template:
      Count: 2
    Users:
      Count: 1

 

# 生成证书

[root@kubernetes-1 /opt/jicki]# cryptogen generate --config=./cryptogen.yaml
org1
org2



# 查看生成目录结构

[root@kubernetes-1 /opt/jicki]# tree -d crypto-config/      
crypto-config/
├── ordererOrganizations
│   └── orgorderer1
│       ├── ca
│       ├── msp
│       │   ├── admincerts
│       │   ├── cacerts
│       │   └── tlscacerts
│       ├── orderers
│       │   └── orderer0.orgorderer1
│       │       ├── msp
│       │       │   ├── admincerts
│       │       │   ├── cacerts
│       │       │   ├── keystore
│       │       │   ├── signcerts
│       │       │   └── tlscacerts
│       │       └── tls
│       ├── tlsca
│       └── users
│           └── Admin@orgorderer1
│               ├── msp
│               │   ├── admincerts
│               │   ├── cacerts
│               │   ├── keystore
│               │   ├── signcerts
│               │   └── tlscacerts
│               └── tls
└── peerOrganizations
    ├── org1
    │   ├── ca
    │   ├── msp
    │   │   ├── admincerts
    │   │   ├── cacerts
    │   │   └── tlscacerts
    │   ├── peers
    │   │   ├── peer0.org1
    │   │   │   ├── msp
    │   │   │   │   ├── admincerts
    │   │   │   │   ├── cacerts
    │   │   │   │   ├── keystore
    │   │   │   │   ├── signcerts
    │   │   │   │   └── tlscacerts
    │   │   │   └── tls
    │   │   └── peer1.org1
    │   │       ├── msp
    │   │       │   ├── admincerts
    │   │       │   ├── cacerts
    │   │       │   ├── keystore
    │   │       │   ├── signcerts
    │   │       │   └── tlscacerts
    │   │       └── tls
    │   ├── tlsca
    │   └── users
    │       ├── Admin@org1
    │       │   ├── msp
    │       │   │   ├── admincerts
    │       │   │   ├── cacerts
    │       │   │   ├── keystore
    │       │   │   ├── signcerts
    │       │   │   └── tlscacerts
    │       │   └── tls
    │       └── User1@org1
    │           ├── msp
    │           │   ├── admincerts
    │           │   ├── cacerts
    │           │   ├── keystore
    │           │   ├── signcerts
    │           │   └── tlscacerts
    │           └── tls
    └── org2
        ├── ca
        ├── msp
        │   ├── admincerts
        │   ├── cacerts
        │   └── tlscacerts
        ├── peers
        │   ├── peer0.org2
        │   │   ├── msp
        │   │   │   ├── admincerts
        │   │   │   ├── cacerts
        │   │   │   ├── keystore
        │   │   │   ├── signcerts
        │   │   │   └── tlscacerts
        │   │   └── tls
        │   └── peer1.org2
        │       ├── msp
        │       │   ├── admincerts
        │       │   ├── cacerts
        │       │   ├── keystore
        │       │   ├── signcerts
        │       │   └── tlscacerts
        │       └── tls
        ├── tlsca
        └── users
            ├── Admin@org2
            │   ├── msp
            │   │   ├── admincerts
            │   │   ├── cacerts
            │   │   ├── keystore
            │   │   ├── signcerts
            │   │   └── tlscacerts
            │   └── tls
            └── User1@org2
                ├── msp
                │   ├── admincerts
                │   ├── cacerts
                │   ├── keystore
                │   ├── signcerts
                │   └── tlscacerts
                └── tls

 

生成初始化Fabric文件

# 创建 configtx.yaml 文件

vi configtx.yaml


Organizations:

    - &OrdererOrg
        Name: Orgorderer1MSP
        ID: Orgorderer1MSP
        MSPDir: crypto-config/ordererOrganizations/orgorderer1/msp
        Policies:
            Readers:
                Type: Signature
                Rule: "OR('Orgorderer1MSP.member')"
            Writers:
                Type: Signature
                Rule: "OR('Orgorderer1MSP.member')"
            Admins:
                Type: Signature
                Rule: "OR('Orgorderer1MSP.admin')"

    - &Org1
        Name: Org1MSP
        ID: Org1MSP
        MSPDir: crypto-config/peerOrganizations/org1/msp
        Policies:
            Readers:
                Type: Signature
                Rule: "OR('Org1MSP.admin', 'Org1MSP.peer', 'Org1MSP.client')"
            Writers:
                Type: Signature
                Rule: "OR('Org1MSP.admin', 'Org1MSP.client')"
            Admins:
                Type: Signature
                Rule: "OR('Org1MSP.admin')"

        AnchorPeers:
            - Host: peer0.org1
              Port: 7051

    - &Org2
        Name: Org2MSP
        ID: Org2MSP
        MSPDir: crypto-config/peerOrganizations/org2/msp
        Policies:
            Readers:
                Type: Signature
                Rule: "OR('Org2MSP.admin', 'Org2MSP.peer', 'Org2MSP.client')"
            Writers:
                Type: Signature
                Rule: "OR('Org2MSP.admin', 'Org2MSP.client')"
            Admins:
                Type: Signature
                Rule: "OR('Org2MSP.admin')"

        AnchorPeers:
            - Host: peer0.org2
              Port: 7051

Capabilities:
    Channel: &ChannelCapabilities
        V1_3: true

    Orderer: &OrdererCapabilities
        V1_1: true

    Application: &ApplicationCapabilities
        V1_3: true
        V1_2: false
        V1_1: false

Application: &ApplicationDefaults

    Organizations:

    Policies:
        Readers:
            Type: ImplicitMeta
            Rule: "ANY Readers"
        Writers:
            Type: ImplicitMeta
            Rule: "ANY Writers"
        Admins:
            Type: ImplicitMeta
            Rule: "MAJORITY Admins"

    Capabilities:
        <<: *ApplicationCapabilities

Orderer: &OrdererDefaults

    OrdererType: kafka

    Addresses:
        - orderer0.orgorderer1:7050

    BatchTimeout: 2s

    BatchSize:
        MaxMessageCount: 10
        AbsoluteMaxBytes: 99 MB
        PreferredMaxBytes: 512 KB

    Kafka:
        Brokers:
            - kafka-0.broker.kafka:9092
            - kafka-1.broker.kafka:9092
            - kafka-2.broker.kafka:9092
            - kafka-3.broker.kafka:9092

    Organizations:

    Policies:
        Readers:
            Type: ImplicitMeta
            Rule: "ANY Readers"
        Writers:
            Type: ImplicitMeta
            Rule: "ANY Writers"
        Admins:
            Type: ImplicitMeta
            Rule: "MAJORITY Admins"
        BlockValidation:
            Type: ImplicitMeta
            Rule: "ANY Writers"

Channel: &ChannelDefaults
    Policies:
        Readers:
            Type: ImplicitMeta
            Rule: "ANY Readers"
        Writers:
            Type: ImplicitMeta
            Rule: "ANY Writers"
        Admins:
            Type: ImplicitMeta
            Rule: "MAJORITY Admins"

    Capabilities:
        <<: *ChannelCapabilities

Profiles:
    TwoOrgsOrdererGenesis:
        <<: *ChannelDefaults
        Orderer:
            <<: *OrdererDefaults
            Organizations:
                - *OrdererOrg
            Capabilities:
                <<: *OrdererCapabilities
        Consortiums:
            SampleConsortium:
                Organizations:
                    - *Org1
                    - *Org2
    TwoOrgsChannel:
        Consortium: SampleConsortium
        Application:
            <<: *ApplicationDefaults
            Organizations:
                - *Org1
                - *Org2
            Capabilities:
                <<: *ApplicationCapabilities

    SampleDevModeKafka:
        <<: *ChannelDefaults
        Capabilities:
            <<: *ChannelCapabilities
        Orderer:
            <<: *OrdererDefaults
            OrdererType: kafka
            Kafka:
                Brokers:
                - kafka-0.broker.kafka:9092
                - kafka-1.broker.kafka:9092
                - kafka-2.broker.kafka:9092
                - kafka-3.broker.kafka:9092

            Organizations:
            - *OrdererOrg
            Capabilities:
                <<: *OrdererCapabilities
        Application:
            <<: *ApplicationDefaults
            Organizations:
            - <<: *OrdererOrg
        Consortiums:
            SampleConsortium:
                Organizations:
                - *Org1
                - *Org2

 

# 首先需要创建一个文件夹

mkdir -p /opt/jicki/channel-artifacts


# 创建 创世区块  TwoOrgsOrdererGenesis 是 
# configtx.yaml 中 Profiles 字段下的名称

[root@kubernetes-1 /opt/jicki]# configtxgen -profile TwoOrgsOrdererGenesis \
 -outputBlock ./channel-artifacts/genesis.block

 

# 下面来生成一个 peer 服务 中使用的 tx 文件 TwoOrgsChannel 名称为 configtx.yaml 中 Profiles 字段下的,这里必须指定上面的 channelID

[root@kubernetes-1 /opt/jicki]# configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID mychannel

 

# 定义组织 生成锚节点更新文件

# Org1MSP

[root@kubernetes-1 /opt/jicki]# configtxgen -profile TwoOrgsChannel \
-outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID mychannel -asOrg Org1MSP



# Org2MSP

[root@kubernetes-1 /opt/jicki]# configtxgen -profile TwoOrgsChannel \
-outputAnchorPeersUpdate ./channel-artifacts/Org2MSPanchors.tx -channelID mychannel -asOrg Org2MSP

 

# 查看生成文件

[root@kubernetes-1 /opt/jicki]# tree channel-artifacts/
channel-artifacts/
├── channel.tx
├── genesis.block
├── Org1MSPanchors.tx
└── Org2MSPanchors.tx

0 directories, 4 files

 

 

配置 NFS StorageClass

NFS 用于 k8s 中 文件挂载,共享

安装NFS

# 服务端 安装 NFS 软件

[root@kubernetes-3 ~]# yum -y install nfs-utils rpcbind


# k8s 所有节点 安装 NFS 客户端

[root@kubernetes-1 ~]# yum -y install nfs-utils
[root@kubernetes-2 ~]# yum -y install nfs-utils

 

配置 NFS

这里需要创建几个目录 /opt/nfs/data, /opt/nfs/fabric/

/opt/nfs/data 用于存放 zk, kafka 数据

/opt/nfs/fabric 用于存放 fabric 所有的文件

 

# 创建目录

[root@kubernetes-3 ~]# mkdir -p /opt/nfs/{data,fabric}


# 修改配置文件

[root@kubernetes-3 ~]# vi /etc/exports

增加

/opt/nfs/data       192.168.0.0/24(rw,sync,no_root_squash)
/opt/nfs/fabric     192.168.0.0/24(rw,sync,no_root_squash)

 

# 启动 NFS 服务

[root@kubernetes-3 ~]# systemctl enable rpcbind.service    
[root@kubernetes-3 ~]# systemctl enable nfs-server.service

[root@kubernetes-3 ~]# systemctl start rpcbind.service    
[root@kubernetes-3 ~]# systemctl start nfs-server.service

[root@kubernetes-3 ~]# systemctl status rpcbind.service    
[root@kubernetes-3 ~]# systemctl status nfs-server.service



# 查看服务
[root@kubernetes-3 ~]# showmount -e 192.168.0.249
Export list for 192.168.0.249:
/opt/nfs/fabric 192.168.0.0/24
/opt/nfs/data   192.168.0.0/24

 

配置 NFS Client Provisioner

官方 说明 https://github.com/kubernetes-incubator/external-storage/tree/master/nfs-client

# 下载官方 yaml 文件 
wget https://raw.githubusercontent.com/kubernetes-incubator/external-storage/master/nfs-client/deploy/rbac.yaml 
wget https://raw.githubusercontent.com/kubernetes-incubator/external-storage/master/nfs-client/deploy/deployment.yaml 
wget https://raw.githubusercontent.com/kubernetes-incubator/external-storage/master/nfs-client/deploy/class.yaml

 

# 修改 deployment.yaml 文件

vi deployment.yaml


apiVersion: v1
kind: ServiceAccount
metadata:
  name: nfs-client-provisioner
---
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: nfs-client-provisioner
spec:
  replicas: 1
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
      serviceAccountName: nfs-client-provisioner
      containers:
        - name: nfs-client-provisioner
          image: quay.io/external_storage/nfs-client-provisioner:latest
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              value: fuseim.pri/ifs
            - name: NFS_SERVER
              value: 192.168.0.249
            - name: NFS_PATH
              value: /opt/nfs/data
      volumes:
        - name: nfs-client-root
          nfs:
            server: 192.168.0.249
            path: /opt/nfs/data

 

# 修改 class.yaml , 这里修改 name 名称

vi class.yaml

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: zk-kafka-nfs-storage
provisioner: fuseim.pri/ifs 
parameters:
  archiveOnDelete: "false"

 

# 导入 yaml 文件

[root@kubernetes-1 /opt/yaml/nfs-client]# kubectl apply -f .
storageclass.storage.k8s.io/fabric-nfs-storage created
serviceaccount/nfs-client-provisioner created
clusterrole.rbac.authorization.k8s.io/nfs-client-provisioner-runner created
deployment.extensions/nfs-client-provisioner created
clusterrolebinding.rbac.authorization.k8s.io/run-nfs-client-provisioner created
role.rbac.authorization.k8s.io/leader-locking-nfs-client-provisioner created
rolebinding.rbac.authorization.k8s.io/leader-locking-nfs-client-provisioner created

 

# 查看服务

[root@kubernetes-1 /opt/yaml/nfs-client]# kubectl get storageclass
NAME                   PROVISIONER      AGE
zk-kafka-nfs-storage   fuseim.pri/ifs   27s


[root@kubernetes-1 /opt/yaml/nfs-client]# kubectl get pods
NAME                                      READY   STATUS    RESTARTS   AGE
nfs-client-provisioner-578785c589-qlgnx   1/1     Running   0          2m24s

 

部署 fabric

创建 zookeeper

[root@kubernetes-1 /opt/jicki/k8s-yaml]# vi kafka-namespace.yaml

apiVersion: v1
kind: Namespace
metadata:
  name: kafka

 

# 创建 zk

[root@kubernetes-1 /opt/jicki/k8s-yaml]# vi zookeeper.yaml


apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: zoo
  namespace: kafka
spec:
  serviceName: "zoo"
  replicas: 4
  template:
    metadata:
      labels:
        app: zookeeper
    spec:
      terminationGracePeriodSeconds: 10
      containers:
        - name: zookeeper
          image: hyperledger/fabric-zookeeper:0.4.14
          ports:
            - containerPort: 2181
              name: client
            - containerPort: 2888
              name: peer
            - containerPort: 3888
              name: leader-election
          volumeMounts:
            - name: zkdata
              mountPath: /var/lib/zookeeper
  volumeClaimTemplates:
  - metadata:
      name: zkdata 
      annotations:
        volume.beta.kubernetes.io/storage-class: "zk-kafka-nfs-storage"
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 10Gi

---
apiVersion: v1
kind: Service
metadata:
  name: zoo
  namespace: kafka
spec:
  ports:
  - port: 2888
    name: peer
  - port: 3888
    name: leader-election
  clusterIP: None
  selector:
    app: zookeeper

---
apiVersion: v1
kind: Service
metadata:
  name: zookeeper
  namespace: kafka
spec:
  ports:
  - port: 2181
    name: client
  selector:
    app: zookeeper

 

# 导入 yaml 文件

[root@kubernetes-1 /opt/jicki/k8s-yaml]# kubectl apply -f namespace.yaml
[root@kubernetes-1 /opt/jicki/k8s-yaml]# kubectl apply -f zookeeper.yaml

 

# 查看服务

[root@kubernetes-1 /opt/jicki/k8s-yaml]# kubectl get all -n kafka
NAME        READY   STATUS    RESTARTS   AGE
pod/zoo-0   1/1     Running   0          20m
pod/zoo-1   1/1     Running   0          9m11s
pod/zoo-2   1/1     Running   0          111s
pod/zoo-3   1/1     Running   0          108s

NAME                TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)             AGE
service/zoo         ClusterIP   None           <none>        2888/TCP,3888/TCP   21m
service/zookeeper   ClusterIP   10.233.22.96   <none>        2181/TCP            21m

NAME                   READY   AGE
statefulset.apps/zoo   4/4     20m

 

创建 kafka

vi kafka.yaml



apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
  name: kafka
  namespace: kafka
spec:
  serviceName: "broker"
  replicas: 4
  template:
    metadata:
      labels:
        app: kafka
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: broker
        image: hyperledger/fabric-kafka:0.4.14
        ports:
          - containerPort: 9092
        env:
          - name: KAFKA_MESSAGE_MAX_BYTES
            value: "102760448"
          - name: KAFKA_REPLICA_FETCH_MAX_BYTES
            value: "102760448"
          - name: KAFKA_UNCLEAN_LEADER_ELECTION_ENABLE
            value: "false"
          - name: KAFKA_ZOOKEEPER_CONNECT
            value: zoo-0.zoo:2181,zoo-1.zoo:2181,zoo-2.zoo:2181,zoo-3.zoo:2181
          - name: KAFKA_PORT
            value: "9092"
          - name: GODEBUG
            value: netdns=go
          - name: KAFKA_ZOOKEEPER_CONNECTION_TIMEOUT_MS
            value: "30000"
          - name: KAFKA_LOG_DIRS
            value: /opt/kafka/data
          - name: KAFKA_LOG_RETENTION_MS
            value: "-1"
        volumeMounts:
        - name: kafkadata
          mountPath: /opt/kafka/data
  volumeClaimTemplates:
  - metadata:
      name: kafkadata 
      annotations:
        volume.beta.kubernetes.io/storage-class: "zk-kafka-nfs-storage"
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 20Gi


---
apiVersion: v1
kind: Service
metadata:
  name: kafka
  namespace: kafka
spec:
  ports:
  - port: 9092
  selector:
    app: kafka
    
---
apiVersion: v1
kind: Service
metadata:
  name: broker
  namespace: kafka
spec:
  ports:
  - port: 9092
  clusterIP: None
  selector:
    app: kafka

 

# 导入 yaml 文件

[root@kubernetes-1 /opt/jicki/k8s-yaml]# kubectl apply -f kafka.yaml 
statefulset.apps/kafka created
service/kafka created
service/broker created

 

# 查看服务

[root@kubernetes-1 /opt/jicki/k8s-yaml]# kubectl get pods -n kafka
NAME      READY   STATUS    RESTARTS   AGE
kafka-0   1/1     Running   0          2m26s
kafka-1   1/1     Running   0          100s
kafka-2   1/1     Running   0          53s
kafka-3   1/1     Running   0          43s



[root@kubernetes-1 /opt/jicki/k8s-yaml]# kubectl get svc -n kafka
NAME        TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)             AGE
broker      ClusterIP   None            <none>        9092/TCP            2m45s
kafka       ClusterIP   10.233.48.233   <none>        9092/TCP            2m45s



[root@kubernetes-1 /opt/jicki/k8s-yaml]# kubectl get statefulset -n kafka
NAME    READY   AGE
kafka   4/4     3m13s

 

创建 fabric 服务

初始化

# 在 操作的机器上 挂载 nfs 目录 /opt/nfs/fabric
# 为了预先拷贝一些证书进去

mkdir -p /opt/nfs/fabric

mount -t nfs 192.168.0.249:/opt/nfs/fabric /opt/nfs/fabric

 

# 拷贝文件到挂载目录

# 创建两个目录 data 数据目录, 以及 证书,创世区块 等文件目录

mkdir -p /opt/nfs/fabric/{data,fabric}

 

# 拷贝 证书文件 创世区块 文件

mkdir ./channel-artifacts/chaincode

cp -r ./fabric/examples/chaincode/go/example* channel-artifacts/chaincode/

cp ./channel-artifacts/genesis.block ./crypto-config/ordererOrganizations/*

cp -r ./crypto-config /opt/nfs/fabric/fabric/

cp -r ./channel-artifacts /opt/nfs/fabric/fabric/

 

# 创建 fabric 运行时生成的共享数据文件夹

mkdir -p /opt/nfs/fabric/data/{orderer,peer}
mkdir -p /opt/nfs/fabric/data/orderer/orgorderer1/orderer0
mkdir -p /opt/nfs/fabric/data/peer/org{1,2}/ca
mkdir -p /opt/nfs/fabric/data/peer/org{1,2}/peer{0,1}/{couchdb,peerdata}

 

配置 orderer

# 创建 orderer1 的 namespaces 

vi orgorderer1-namespace.yaml


apiVersion: v1
kind: Namespace
metadata:
    name: orgorderer1

 

# 创建 orderer1 的 pv 与 pvc


vi orgorderer1-pv-pvc.yaml


apiVersion: v1
kind: PersistentVolume
metadata:
  name: orgorderer1-pv
  labels:
    app: orgorderer1-pv
spec:
  capacity:
    storage: 500Mi
  accessModes:
    - ReadWriteMany
  nfs:
    path: /opt/nfs/fabric/fabric/crypto-config/ordererOrganizations/orgorderer1
    server: 192.168.0.249

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
 namespace: orgorderer1
 name: orgorderer1-pv
spec:
 accessModes:
   - ReadWriteMany
 resources:
   requests:
     storage: 10Mi
 selector:
   matchLabels:
     app: orgorderer1-pv

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: orgorderer1-pvdata
  labels:
    app: orgorderer1-pvdata
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteMany
  nfs:
    path: /opt/nfs/fabric/data/orderer/orgorderer1
    server: 192.168.0.249

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
 namespace: orgorderer1
 name: orgorderer1-pvdata
spec:
 accessModes:
   - ReadWriteMany
 resources:
   requests:
     storage: 10Gi
 selector:
   matchLabels:
     app: orgorderer1-pvdata

 

# 创建 orderer1 Deployment 服务


vi orderer0.orgorderer1.yaml


apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  namespace: orgorderer1
  name: orderer0-orgorderer1
spec:
  replicas: 1
  strategy: {}
  template:
    metadata:
      labels:
        app: hyperledger
        role: orderer
        org: orgorderer1
        orderer-id: orderer0
    spec:
      containers:
      - name: orderer0-orgorderer1
        image: hyperledger/fabric-orderer:1.4.0
        env:
        - name: ORDERER_GENERAL_LOGLEVEL
          value: debug
        - name: ORDERER_GENERAL_LISTENADDRESS
          value: 0.0.0.0
        - name: ORDERER_GENERAL_GENESISMETHOD
          value: file
        - name: ORDERER_GENERAL_GENESISFILE
          value: /var/hyperledger/orderer/orderer.genesis.block
        - name: ORDERER_GENERAL_LOCALMSPID
          value: Orgorderer1MSP
        - name: ORDERER_GENERAL_LOCALMSPDIR
          value: /var/hyperledger/orderer/msp
        - name: ORDERER_GENERAL_TLS_ENABLED
          value: "false"
        - name: ORDERER_GENERAL_TLS_PRIVATEKEY
          value: /var/hyperledger/orderer/tls/server.key
        - name: ORDERER_GENERAL_TLS_CERTIFICATE
          value: /var/hyperledger/orderer/tls/server.crt
        - name: ORDERER_GENERAL_TLS_ROOTCAS
          value: '[/var/hyperledger/orderer/tls/ca.crt]'
        - name: ORDERER_KAFKA_VERSION
          value: 0.10.0.1
        - name: ORDERER_KAFKA_VERBOSE
          value: "true"
        - name: ORDERER_KAFKA_BROKERS
          value: "kafka-0.broker.kafka:9092,kafka-1.broker.kafka:9092,kafka-2.broker.kafka:9092,kafka-3.broker.kafka:9092"
        - name: GODEBUG
          value: netdns=go
        workingDir: /opt/gopath/src/github.com/hyperledger/fabric
        ports:
         - containerPort: 7050
        command: ["orderer"]
        volumeMounts:
         - mountPath: /var/hyperledger/orderer/msp
           name: certificate
           subPath: orderers/orderer0.orgorderer1/msp
         - mountPath: /var/hyperledger/orderer/tls
           name: certificate
           subPath: orderers/orderer0.orgorderer1/tls
         - mountPath: /var/hyperledger/orderer/orderer.genesis.block
           name: certificate
           subPath: genesis.block
         - mountPath: /var/hyperledger/production
           name: ordererdata
           subPath: orderer0
      volumes:
       - name: certificate
         persistentVolumeClaim:
             claimName: orgorderer1-pv
       - name: ordererdata
         persistentVolumeClaim:
             claimName: orgorderer1-pvdata

---
apiVersion: v1
kind: Service
metadata:
  name: orderer0
  namespace: orgorderer1
spec:
 selector:
   app: hyperledger
   role: orderer
   orderer-id: orderer0
   org: orgorderer1
 type: NodePort
 ports:
   - name: listen-endpoint
     protocol: TCP
     port: 7050
     targetPort: 7050
     nodePort: 32000

 

# 导入 yaml 文件 创建服务


# 创建 namespaces

[root@kubernetes-1 /opt/jicki/k8s-yaml]# kubectl apply -f orgorderer1-namespace.yaml 
namespace/orgorderer1 created


# 创建 pv pvc

[root@kubernetes-1 /opt/jicki/k8s-yaml]# kubectl apply -f orgorderer1-pv-pvc.yaml 
persistentvolume/orgorderer1-pv created
persistentvolumeclaim/orgorderer1-pv created
persistentvolume/orgorderer1-pvdata created
persistentvolumeclaim/orgorderer1-pvdata created



# 创建 deployment

[root@kubernetes-1 /opt/jicki/k8s-yaml]# kubectl apply -f orderer0.orgorderer1.yaml 
deployment.extensions/orderer0-orgorderer1 created
service/orderer0 created

 

 

# 查看创建的服务

[root@kubernetes-1 /opt/jicki/k8s-yaml]# kubectl get pods -n orgorderer1
NAME                                    READY   STATUS    RESTARTS   AGE
orderer0-orgorderer1-6b896b94c4-5gs2c   1/1     Running   0          36s



[root@kubernetes-1 /opt/jicki/k8s-yaml]# kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                            STORAGECLASS           REASON   AGE
orgorderer1-pv                             500Mi      RWX            Retain           Bound    orgorderer1/orgorderer1-pv                                       115s
orgorderer1-pvdata                         10Gi       RWX            Retain           Bound    orgorderer1/orgorderer1-pvdata                                   115s



[root@kubernetes-1 /opt/jicki/k8s-yaml]# kubectl get pvc -n orgorderer1
NAME                 STATUS   VOLUME               CAPACITY   ACCESS MODES   STORAGECLASS   AGE
orgorderer1-pv       Bound    orgorderer1-pv       500Mi      RWX                           2m9s
orgorderer1-pvdata   Bound    orgorderer1-pvdata   10Gi       RWX                           2m9s

 

配置 org1 服务

每个 org 包含 ca cli peer 三个服务

 

# 配置 org1 namespaces

vi org1-namespace.yaml


apiVersion: v1
kind: Namespace
metadata:
    name: org1

 

# 配置 org1  pv 与 pvc


vi org1-pv-pvc.yaml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: org1-pv
  labels:
    app: org1-pv
spec:
  capacity:
    storage: 500Mi
  accessModes:
    - ReadWriteMany
  nfs:
    path: /opt/nfs/fabric/fabric/crypto-config/peerOrganizations/org1
    server: 192.168.0.249

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
 namespace: org1
 name: org1-pv
spec:
 accessModes:
   - ReadWriteMany
 resources:
   requests:
     storage: 10Mi
 selector:
   matchLabels:
     app: org1-pv

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: org1-pvdata
  labels:
    app: org1-pvdata
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteMany
  nfs:
    path: /opt/nfs/fabric/data/peer/org1
    server: 192.168.0.249

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
 namespace: org1
 name: org1-pvdata
spec:
 accessModes:
   - ReadWriteMany
 resources:
   requests:
     storage: 10Gi
 selector:
   matchLabels:
     app: org1-pvdata

 

# 配置 org1  ca
# FABRIC_CA_SERVER_TLS_KEYFILE 配置为自己生成的 sk
# sk 存在目录 crypto-config/peerOrganizations/org1/ca/



vi org1-ca.yaml


apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  namespace: org1
  name: ca
spec:
  replicas: 1
  strategy: {}
  template:
    metadata:
      labels:
       app: hyperledger
       role: ca
       org: org1
       name: ca
    spec:
     containers:
       - name: ca
         image: hyperledger/fabric-ca:1.4.0
         env:
         - name: FABRIC_CA_HOME
           value: /etc/hyperledger/fabric-ca-server
         - name: FABRIC_CA_SERVER_CA_NAME
           value: ca
         - name: FABRIC_CA_SERVER_TLS_ENABLED
           value: "false"
         - name: FABRIC_CA_SERVER_TLS_CERTFILE
           value: /etc/hyperledger/fabric-ca-server-config/ca.org1-cert.pem
         - name: FABRIC_CA_SERVER_TLS_KEYFILE
           value: /etc/hyperledger/fabric-ca-server-config/904aa978bf690c8198526a6410045cc308468ca7171d02af70ffc7d969eb4c7e_sk
         - name: GODEBUG
           value: netdns=go
         ports:
          - containerPort: 7054
         command: ["sh"]
         args: ["-c", " fabric-ca-server start --ca.certfile /etc/hyperledger/fabric-ca-server-config/ca.org1-cert.pem --ca.keyfile /etc/hyperledger/fabric-ca-server-config/904aa978bf690c8198526a6410045cc308468ca7171d02af70ffc7d969eb4c7e_sk -b admin:adminpw -d "]
         volumeMounts:
          - mountPath: /etc/hyperledger/fabric-ca-server-config
            name: certificate
            subPath: ca/
          - mountPath: /etc/hyperledger/fabric-ca-server
            name: cadata
            subPath: ca/
     volumes:
       - name: certificate
         persistentVolumeClaim:
            claimName: org1-pv
       - name: cadata
         persistentVolumeClaim:
            claimName: org1-pvdata

---
apiVersion: v1
kind: Service
metadata:
   namespace: org1
   name: ca
spec:
 selector:
   app: hyperledger
   role: ca
   org: org1
   name: ca
 type: NodePort
 ports:
   - name: endpoint
     protocol: TCP
     port: 7054
     targetPort: 7054
     nodePort: 30000

 

# 配置 org1  peer 服务 
# 这里有两个 peer 分别为 peer0, peer1


vi peer0.org1.yaml



apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  namespace: org1
  name: peer0-org1
spec:
  replicas: 1
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
       app: hyperledger
       role: peer
       peer-id: peer0
       org: org1
    spec:
      containers:
      - name: couchdb
        image: hyperledger/fabric-couchdb:0.4.10
        env:
         - name: COUCHDB_USER
           value: ""
         - name: COUCHDB_PASSWORD
           value: ""
        ports:
          - containerPort: 5984
        volumeMounts:
          - mountPath: /opt/couchdb/data
            name: peerdata
            subPath: peer0/couchdb
      - name: peer0-org1
        image: hyperledger/fabric-peer:1.4.0
        env:
        - name: CORE_LEDGER_STATE_STATEDATABASE
          value: "CouchDB"
        - name: CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS
          value: "localhost:5984"
        - name: CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME
          value: ""
        - name: CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD
          value: ""
        - name: CORE_VM_ENDPOINT
          value: "unix:///host/var/run/docker.sock"
        - name: CORE_LOGGING_LEVEL
          value: "DEBUG"
        - name: CORE_PEER_TLS_ENABLED
          value: "false"
        - name: CORE_PEER_GOSSIP_USELEADERELECTION
          value: "true"
        - name: CORE_PEER_GOSSIP_ORGLEADER
          value: "false"
        - name: CORE_PEER_PROFILE_ENABLED
          value: "true"
        - name: CORE_PEER_TLS_CERT_FILE
          value: "/etc/hyperledger/fabric/tls/server.crt"
        - name: CORE_PEER_TLS_KEY_FILE
          value: "/etc/hyperledger/fabric/tls/server.key"
        - name: CORE_PEER_TLS_ROOTCERT_FILE
          value: "/etc/hyperledger/fabric/tls/ca.crt"
        - name: CORE_PEER_ADDRESSAUTODETECT
          value: "true"
        - name: CORE_PEER_CHAINCODELISTENADDRESS
          value: "0.0.0.0:7052"
        - name: CORE_PEER_ID
          value: peer0.org1
        - name: CORE_PEER_ADDRESS
          value: peer0.org1:7051
        - name: CORE_PEER_GOSSIP_BOOTSTRAP
          value: peer0.org1:7051
        - name: CORE_PEER_GOSSIP_EXTERNALENDPOINT
          value: peer0.org1:7051
        - name: CORE_PEER_LOCALMSPID
          value: Org1MSP
        workingDir: /opt/gopath/src/github.com/hyperledger/fabric/peer
        ports:
         - containerPort: 7051
         - containerPort: 7052
         - containerPort: 7053
        command: ["peer"]
        args: ["node","start"]
        volumeMounts:
         - mountPath: /etc/hyperledger/fabric/msp
           name: certificate
           subPath: peers/peer0.org1/msp
         - mountPath: /etc/hyperledger/fabric/tls
           name: certificate
           subPath: peers/peer0.org1/tls
         - mountPath: /var/hyperledger/production
           name: peerdata
           subPath: peer0/peerdata
         - mountPath: /host/var/run/
           name: run
      volumes:
       - name: certificate
         persistentVolumeClaim:
             claimName: org1-pv
       - name: peerdata
         persistentVolumeClaim:
             claimName: org1-pvdata
       - name: run
         hostPath:
           path: /var/run

---
apiVersion: v1
kind: Service
metadata:
   namespace: org1
   name: peer0
spec:
 selector:
   app: hyperledger
   role: peer
   peer-id: peer0
   org: org1
 type: NodePort
 ports:
   - name: externale-listen-endpoint
     protocol: TCP
     port: 7051
     targetPort: 7051
     nodePort: 30001

   - name: chaincode-listen
     protocol: TCP
     port: 7052
     targetPort: 7052
     nodePort: 30002

   - name: event-listen
     protocol: TCP
     port: 7053
     targetPort: 7053
     nodePort: 30003

 

vi peer1.org1.yaml


apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  namespace: org1
  name: peer1-org1
spec:
  replicas: 1
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
       app: hyperledger
       role: peer
       peer-id: peer1
       org: org1
    spec:
      containers:
      - name: couchdb
        image: hyperledger/fabric-couchdb:0.4.10
        env:
         - name: COUCHDB_USER
           value: ""
         - name: COUCHDB_PASSWORD
           value: ""
        ports:
          - containerPort: 5984
        volumeMounts:
          - mountPath: /opt/couchdb/data
            name: peerdata
            subPath: peer1/couchdb
      - name: peer1-org1
        image: hyperledger/fabric-peer:1.4.0
        env:
        - name: CORE_LEDGER_STATE_STATEDATABASE
          value: "CouchDB"
        - name: CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS
          value: "localhost:5984"
        - name: CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME
          value: ""
        - name: CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD
          value: ""
        - name: CORE_VM_ENDPOINT
          value: "unix:///host/var/run/docker.sock"
        - name: CORE_LOGGING_LEVEL
          value: "DEBUG"
        - name: CORE_PEER_TLS_ENABLED
          value: "false"
        - name: CORE_PEER_GOSSIP_USELEADERELECTION
          value: "true"
        - name: CORE_PEER_GOSSIP_ORGLEADER
          value: "false"
        - name: CORE_PEER_PROFILE_ENABLED
          value: "true"
        - name: CORE_PEER_TLS_CERT_FILE
          value: "/etc/hyperledger/fabric/tls/server.crt"
        - name: CORE_PEER_TLS_KEY_FILE
          value: "/etc/hyperledger/fabric/tls/server.key"
        - name: CORE_PEER_TLS_ROOTCERT_FILE
          value: "/etc/hyperledger/fabric/tls/ca.crt"
        - name: CORE_PEER_ADDRESSAUTODETECT
          value: "true"
        - name: CORE_PEER_CHAINCODELISTENADDRESS
          value: "0.0.0.0:7052"
        - name: CORE_PEER_ID
          value: peer1.org1
        - name: CORE_PEER_ADDRESS
          value: peer1.org1:7051
        - name: CORE_PEER_GOSSIP_BOOTSTRAP
          value: peer1.org1:7051
        - name: CORE_PEER_GOSSIP_EXTERNALENDPOINT
          value: peer1.org1:7051
        - name: CORE_PEER_LOCALMSPID
          value: Org1MSP
        workingDir: /opt/gopath/src/github.com/hyperledger/fabric/peer
        ports:
         - containerPort: 7051
         - containerPort: 7052
         - containerPort: 7053
        command: ["peer"]
        args: ["node","start"]
        volumeMounts:
         - mountPath: /etc/hyperledger/fabric/msp
           name: certificate
           subPath: peers/peer1.org1/msp
         - mountPath: /etc/hyperledger/fabric/tls
           name: certificate
           subPath: peers/peer1.org1/tls
         - mountPath: /var/hyperledger/production
           name: peerdata
           subPath: peer1/peerdata
         - mountPath: /host/var/run/
           name: run
      volumes:
       - name: certificate
         persistentVolumeClaim:
             claimName: org1-pv
       - name: peerdata
         persistentVolumeClaim:
             claimName: org1-pvdata
       - name: run
         hostPath:
           path: /var/run

---
apiVersion: v1
kind: Service
metadata:
   namespace: org1
   name: peer1
spec:
 selector:
   app: hyperledger
   role: peer
   peer-id: peer1
   org: org1
 type: NodePort
 ports:
   - name: externale-listen-endpoint
     protocol: TCP
     port: 7051
     targetPort: 7051
     nodePort: 30004

   - name: chaincode-listen
     protocol: TCP
     port: 7052
     targetPort: 7052
     nodePort: 30005

   - name: event-listen
     protocol: TCP
     port: 7053
     targetPort: 7053
     nodePort: 30006

 

 

# 导入 yaml 文件 创建服务

[root@kubernetes-1 /opt/jicki/k8s-yaml]# kubectl apply -f org1-namespace.yaml 
namespace/org1 created


[root@kubernetes-1 /opt/jicki/k8s-yaml]# kubectl apply -f org1-pv-pvc.yaml 
persistentvolume/org1-pv created
persistentvolumeclaim/org1-pv created
persistentvolume/org1-pvdata created
persistentvolumeclaim/org1-pvdata created


[root@kubernetes-1 /opt/jicki/k8s-yaml]# kubectl apply -f org1-ca.yaml 
deployment.extensions/ca created
service/ca created

[root@kubernetes-1 /opt/jicki/k8s-yaml]# kubectl apply -f peer0.org1.yaml 
deployment.extensions/peer0-org1 created
service/peer0 created


[root@kubernetes-1 /opt/jicki/k8s-yaml]# kubectl apply -f peer1.org1.yaml 
deployment.extensions/peer1-org1 created
service/peer1 created

 

# 查看 创建的服务


[root@kubernetes-1 /opt/jicki/k8s-yaml]# kubectl get all -n org1
NAME                              READY   STATUS    RESTARTS   AGE
pod/ca-75b9859c54-d5x9b           1/1     Running   0          120m
pod/peer0-org1-5767789cd7-7g2z7   2/2     Running   0          22m
pod/peer1-org1-866b6bcd45-c5mbp   2/2     Running   0          22m

NAME            TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)                                        AGE
service/ca      NodePort   10.233.5.5      <none>        7054:30000/TCP                                 120m
service/peer0   NodePort   10.233.57.55    <none>        7051:30001/TCP,7052:30002/TCP,7053:30003/TCP   36m
service/peer1   NodePort   10.233.31.189   <none>        7051:30004/TCP,7052:30005/TCP,7053:30006/TCP   34m

NAME                         READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/ca           1/1     1            1           120m
deployment.apps/peer0-org1   1/1     1            1           36m
deployment.apps/peer1-org1   1/1     1            1           34m

NAME                                    DESIRED   CURRENT   READY   AGE
replicaset.apps/ca-75b9859c54           1         1         1       120m
replicaset.apps/peer0-org1-5767789cd7   1         1         1       22m
replicaset.apps/peer0-org1-8c98c4c9     0         0         0       36m
replicaset.apps/peer1-org1-768c8d8f69   0         0         0       34m
replicaset.apps/peer1-org1-866b6bcd45   1         1         1       22m

配置 org2 服务

# 配置 org2 namespaces

vi org2-namespace.yaml


apiVersion: v1
kind: Namespace
metadata:
    name: org2

 

# 配置 org2 pv pvc

vi org2-pv-pvc.yaml


apiVersion: v1
kind: PersistentVolume
metadata:
  name: org2-pv
  labels:
    app: org2-pv
spec:
  capacity:
    storage: 500Mi
  accessModes:
    - ReadWriteMany
  nfs:
    path: /opt/nfs/fabric/fabric/crypto-config/peerOrganizations/org2
    server: 192.168.0.249

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
 namespace: org2
 name: org2-pv
spec:
 accessModes:
   - ReadWriteMany
 resources:
   requests:
     storage: 10Mi
 selector:
   matchLabels:
     app: org2-pv

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: org2-pvdata
  labels:
    app: org2-pvdata
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteMany
  nfs:
    path: /opt/nfs/fabric/data/peer/org2
    server: 192.168.0.249

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
 namespace: org2
 name: org2-pvdata
spec:
 accessModes:
   - ReadWriteMany
 resources:
   requests:
     storage: 10Gi
 selector:
   matchLabels:
     app: org2-pvdata

 

# 配置 org2  ca
# FABRIC_CA_SERVER_TLS_KEYFILE 配置为自己生成的 sk
# sk 存在目录 crypto-config/peerOrganizations/org2/ca/

vi org2-ca.yaml


apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  namespace: org2
  name: ca
spec:
  replicas: 1
  strategy: {}
  template:
    metadata:
      labels:
       app: hyperledger
       role: ca
       org: org2
       name: ca
    spec:
     containers:
       - name: ca
         image: hyperledger/fabric-ca:1.4.0
         env:
         - name: FABRIC_CA_HOME
           value: /etc/hyperledger/fabric-ca-server
         - name: FABRIC_CA_SERVER_CA_NAME
           value: ca
         - name: FABRIC_CA_SERVER_TLS_ENABLED
           value: "false"
         - name: FABRIC_CA_SERVER_TLS_CERTFILE
           value: /etc/hyperledger/fabric-ca-server-config/ca.org2-cert.pem
         - name: FABRIC_CA_SERVER_TLS_KEYFILE
           value: /etc/hyperledger/fabric-ca-server-config/44299d5dfb204e07b5274a7048269171876157d1efdab11a5ac631bd78d2fe0d_sk
         - name: GODEBUG
           value: netdns=go
         ports:
          - containerPort: 7054
         command: ["sh"]
         args: ["-c", " fabric-ca-server start --ca.certfile /etc/hyperledger/fabric-ca-server-config/ca.org2-cert.pem --ca.keyfile /etc/hyperledger/fabric-ca-server-config/44299d5dfb204e07b5274a7048269171876157d1efdab11a5ac631bd78d2fe0d_sk -b admin:adminpw -d "]
         volumeMounts:
          - mountPath: /etc/hyperledger/fabric-ca-server-config
            name: certificate
            subPath: ca/
          - mountPath: /etc/hyperledger/fabric-ca-server
            name: cadata
            subPath: ca/
     volumes:
       - name: certificate
         persistentVolumeClaim:
            claimName: org2-pv
       - name: cadata
         persistentVolumeClaim:
            claimName: org2-pvdata

---
apiVersion: v1
kind: Service
metadata:
   namespace: org2
   name: ca
spec:
 selector:
   app: hyperledger
   role: ca
   org: org2
   name: ca
 type: NodePort
 ports:
   - name: endpoint
     protocol: TCP
     port: 7054
     targetPort: 7054
     nodePort: 30100

 

# 配置 org2  peer 服务 
# 这里有两个 peer 分别为 peer0, peer1


vi peer0.org2.yaml


apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  namespace: org2
  name: peer0-org2
spec:
  replicas: 1
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
       app: hyperledger
       role: peer
       peer-id: peer0
       org: org2
    spec:
      containers:
      - name: couchdb
        image: hyperledger/fabric-couchdb:0.4.10
        env:
        - name: COUCHDB_USER
          value: ""
        - name: COUCHDB_PASSWORD
          value: ""
        ports:
         - containerPort: 5984
        volumeMounts:
         - mountPath: /opt/couchdb/data
           name: peerdata
           subPath: peer0/couchdb
      - name: peer0-org2
        image: hyperledger/fabric-peer:1.4.0
        env:
        - name: CORE_LEDGER_STATE_STATEDATABASE
          value: "CouchDB"
        - name: CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS
          value: "localhost:5984"
        - name: CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME
          value: ""
        - name: CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD
          value: ""
        - name: CORE_VM_ENDPOINT
          value: "unix:///host/var/run/docker.sock"
        - name: CORE_LOGGING_LEVEL
          value: "DEBUG"
        - name: CORE_PEER_TLS_ENABLED
          value: "false"
        - name: CORE_PEER_GOSSIP_USELEADERELECTION
          value: "true"
        - name: CORE_PEER_GOSSIP_ORGLEADER
          value: "false"
        - name: CORE_PEER_PROFILE_ENABLED
          value: "true"
        - name: CORE_PEER_TLS_CERT_FILE
          value: "/etc/hyperledger/fabric/tls/server.crt"
        - name: CORE_PEER_TLS_KEY_FILE
          value: "/etc/hyperledger/fabric/tls/server.key"
        - name: CORE_PEER_TLS_ROOTCERT_FILE
          value: "/etc/hyperledger/fabric/tls/ca.crt"
        - name: CORE_PEER_ADDRESSAUTODETECT
          value: "true"
        - name: CORE_PEER_CHAINCODELISTENADDRESS
          value: "0.0.0.0:7052"
        - name: CORE_PEER_ID
          value: peer0.org2
        - name: CORE_PEER_ADDRESS
          value: peer0.org2:7051
        - name: CORE_PEER_GOSSIP_BOOTSTRAP
          value: peer0.org2:7051
        - name: CORE_PEER_GOSSIP_EXTERNALENDPOINT
          value: peer0.org2:7051
        - name: CORE_PEER_LOCALMSPID
          value: Org2MSP
        workingDir: /opt/gopath/src/github.com/hyperledger/fabric/peer
        ports:
         - containerPort: 7051
         - containerPort: 7052
         - containerPort: 7053
        command: ["peer"]
        args: ["node","start"]
        volumeMounts:
         - mountPath: /etc/hyperledger/fabric/msp
           name: certificate
           subPath: peers/peer0.org2/msp
         - mountPath: /etc/hyperledger/fabric/tls
           name: certificate
           subPath: peers/peer0.org2/tls
         - mountPath: /var/hyperledger/production
           name: peerdata
           subPath: peer0/peerdata
         - mountPath: /host/var/run/
           name: run
      volumes:
       - name: certificate
         persistentVolumeClaim:
             claimName: org2-pv
       - name: peerdata
         persistentVolumeClaim:
             claimName: org2-pvdata
       - name: run
         hostPath:
           path: /var/run

---
apiVersion: v1
kind: Service
metadata:
   namespace: org2
   name: peer0
spec:
 selector:
   app: hyperledger
   role: peer
   peer-id: peer0
   org: org2
 type: NodePort
 ports:
   - name: externale-listen-endpoint
     protocol: TCP
     port: 7051
     targetPort: 7051
     nodePort: 30101

   - name: chaincode-listen
     protocol: TCP
     port: 7052
     targetPort: 7052
     nodePort: 30102

   - name: event-listen
     protocol: TCP
     port: 7053
     targetPort: 7053
     nodePort: 30103

 

 

# 配置 org2 的 peer1


vi peer1.org2.yaml


apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  namespace: org2
  name: peer1-org2
spec:
  replicas: 1
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
       app: hyperledger
       role: peer
       peer-id: peer1
       org: org2
    spec:
      containers:
      - name: couchdb
        image: hyperledger/fabric-couchdb:0.4.10
        env:
        - name: COUCHDB_USER
          value: ""
        - name: COUCHDB_PASSWORD
          value: ""
        ports:
         - containerPort: 5984
        volumeMounts:
         - mountPath: /opt/couchdb/data
           name: peerdata
           subPath: peer1/couchdb
      - name: peer1-org2
        image: hyperledger/fabric-peer:1.4.0
        env:
        - name: CORE_LEDGER_STATE_STATEDATABASE
          value: "CouchDB"
        - name: CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS
          value: "localhost:5984"
        - name: CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME
          value: ""
        - name: CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD
          value: ""
        - name: CORE_VM_ENDPOINT
          value: "unix:///host/var/run/docker.sock"
        - name: CORE_LOGGING_LEVEL
          value: "DEBUG"
        - name: CORE_PEER_TLS_ENABLED
          value: "false"
        - name: CORE_PEER_GOSSIP_USELEADERELECTION
          value: "true"
        - name: CORE_PEER_GOSSIP_ORGLEADER
          value: "false"
        - name: CORE_PEER_PROFILE_ENABLED
          value: "true"
        - name: CORE_PEER_TLS_CERT_FILE
          value: "/etc/hyperledger/fabric/tls/server.crt"
        - name: CORE_PEER_TLS_KEY_FILE
          value: "/etc/hyperledger/fabric/tls/server.key"
        - name: CORE_PEER_TLS_ROOTCERT_FILE
          value: "/etc/hyperledger/fabric/tls/ca.crt"
        - name: CORE_PEER_ADDRESSAUTODETECT
          value: "true"
        - name: CORE_PEER_CHAINCODELISTENADDRESS
          value: "0.0.0.0:7052"
        - name: CORE_PEER_ID
          value: peer1.org2
        - name: CORE_PEER_ADDRESS
          value: peer1.org2:7051
        - name: CORE_PEER_GOSSIP_BOOTSTRAP
          value: peer1.org2:7051
        - name: CORE_PEER_GOSSIP_EXTERNALENDPOINT
          value: peer1.org2:7051
        - name: CORE_PEER_LOCALMSPID
          value: Org2MSP
        workingDir: /opt/gopath/src/github.com/hyperledger/fabric/peer
        ports:
         - containerPort: 7051
         - containerPort: 7052
         - containerPort: 7053
        command: ["peer"]
        args: ["node","start"]
        volumeMounts:
         - mountPath: /etc/hyperledger/fabric/msp
           name: certificate
           subPath: peers/peer1.org2/msp
         - mountPath: /etc/hyperledger/fabric/tls
           name: certificate
           subPath: peers/peer1.org2/tls
         - mountPath: /var/hyperledger/production
           name: peerdata
           subPath: peer1/peerdata
         - mountPath: /host/var/run/
           name: run
      volumes:
       - name: certificate
         persistentVolumeClaim:
             claimName: org2-pv
       - name: peerdata
         persistentVolumeClaim:
             claimName: org2-pvdata
       - name: run
         hostPath:
           path: /var/run

---
apiVersion: v1
kind: Service
metadata:
   namespace: org2
   name: peer1
spec:
 selector:
   app: hyperledger
   role: peer
   peer-id: peer1
   org: org2
 type: NodePort
 ports:
   - name: externale-listen-endpoint
     protocol: TCP
     port: 7051
     targetPort: 7051
     nodePort: 30104

   - name: chaincode-listen
     protocol: TCP
     port: 7052
     targetPort: 7052
     nodePort: 30105

   - name: event-listen
     protocol: TCP
     port: 7053
     targetPort: 7053
     nodePort: 30106

 

# 导入 yaml 文件 创建服务

[root@kubernetes-1 /opt/jicki/k8s-yaml]# kubectl apply -f org2-namespace.yaml 
namespace/org2 created


[root@kubernetes-1 /opt/jicki/k8s-yaml]# kubectl apply -f org2-pv-pvc.yaml 
persistentvolume/org2-pv created
persistentvolumeclaim/org2-pv created
persistentvolume/org2-pvdata created
persistentvolumeclaim/org2-pvdata created


[root@kubernetes-1 /opt/jicki/k8s-yaml]# kubectl apply -f org2-ca.yaml 
deployment.extensions/ca created
service/ca created

[root@kubernetes-1 /opt/jicki/k8s-yaml]# kubectl apply -f peer0.org2.yaml 
deployment.extensions/peer0-org2 created
service/peer0 created


[root@kubernetes-1 /opt/jicki/k8s-yaml]# kubectl apply -f peer1.org2.yaml 
deployment.extensions/peer1-org2 created
service/peer1 created

 

# 查看 org2 的服务


[root@kubernetes-1 /opt/jicki/k8s-yaml]# kubectl get all -n org2
NAME                              READY   STATUS    RESTARTS   AGE
pod/ca-594d86d8fc-fwg7r           1/1     Running   0          55s
pod/peer0-org2-68579cc9fd-gjmdw   2/2     Running   0          40s
pod/peer1-org2-7645b97c44-5f64k   2/2     Running   0          30s

NAME            TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)                                        AGE
service/ca      NodePort   10.233.4.94     <none>        7054:30100/TCP                                 55s
service/peer0   NodePort   10.233.49.35    <none>        7051:30101/TCP,7052:30102/TCP,7053:30103/TCP   40s
service/peer1   NodePort   10.233.56.135   <none>        7051:30104/TCP,7052:30105/TCP,7053:30106/TCP   30s

NAME                         READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/ca           1/1     1            1           55s
deployment.apps/peer0-org2   1/1     1            1           40s
deployment.apps/peer1-org2   1/1     1            1           30s

NAME                                    DESIRED   CURRENT   READY   AGE
replicaset.apps/ca-594d86d8fc           1         1         1       55s
replicaset.apps/peer0-org2-68579cc9fd   1         1         1       40s
replicaset.apps/peer1-org2-7645b97c44   1         1         1       30s

 

配置 cli 服务

cli 服务,用于 命令行操作组织节点的环境。

这里每一个 org 配置一个 cli 服务,方便操作不同的 org 节点

 

# 创建 org1  cli 的 pv pvc 


vi org1-cli-pv-pvc.yaml


apiVersion: v1
kind: PersistentVolume
metadata:
    name: org1-cli-pv
    labels:
      app: org1-cli-pv
spec:
    capacity:
       storage: 500Mi
    accessModes:
       - ReadWriteMany
    nfs:
      path: /opt/nfs/fabric/fabric/channel-artifacts
      server: 192.168.0.249

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
    namespace: org1
    name: org1-cli-pv
spec:
   accessModes:
     - ReadWriteMany
   resources:
      requests:
        storage: 10Mi
   selector:
     matchLabels:
       app: org1-cli-pv

 

# 创建 org1  cli  服务

vi org1-cli.yaml


apiVersion: extensions/v1beta1
kind: Deployment
metadata:
   namespace: org1
   name: cli
spec:
  replicas: 1
  strategy: {}
  template:
    metadata:
      labels:
       app: cli
    spec:
      containers:
        - name: cli
          image: hyperledger/fabric-tools:1.4.0
          env:
          - name: CORE_PEER_TLS_ENABLED
            value: "false"
          - name: CORE_VM_ENDPOINT
            value: unix:///host/var/run/docker.sock
          - name: GOPATH
            value: /opt/gopath
          - name: CORE_LOGGING_LEVEL
            value: DEBUG
          - name: CORE_PEER_ID
            value: cli
          - name: CORE_PEER_ADDRESS
            value: peer0.org1:7051
          - name: CORE_PEER_LOCALMSPID
            value: Org1MSP
          - name: CORE_PEER_MSPCONFIGPATH
            value: /etc/hyperledger/fabric/msp
          - name: GODEBUG
            value: netdns=go
          workingDir: /opt/gopath/src/github.com/hyperledger/fabric/peer
          command: ["/bin/bash", "-c", "--"]
          args: ["while true; do sleep 30; done;"]
          volumeMounts:
           - mountPath: /host/var/run/
             name: run
           - mountPath: /etc/hyperledger/fabric/msp
             name: certificate
             subPath: users/Admin@org1/msp
           - mountPath: /opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts
             name: artifacts
      volumes:
        - name: certificate
          persistentVolumeClaim:
              claimName: org1-pv
        - name: artifacts
          persistentVolumeClaim:
              claimName: org1-cli-pv
        - name: run
          hostPath:
            path: /var/run

 

# 导入 yaml 文件

[root@kubernetes-1 /opt/jicki/k8s-yaml]# kubectl apply -f org1-cli-pv-pvc.yaml 
persistentvolume/org1-cli-pv created
persistentvolumeclaim/org1-cli-pv created


[root@kubernetes-1 /opt/jicki/k8s-yaml]# kubectl apply -f org1-cli.yaml 
deployment.extensions/cli created

 

# 创建 org2  cli 的 pv pvc 


vi org2-cli-pv-pvc.yaml


apiVersion: v1
kind: PersistentVolume
metadata:
    name: org2-cli-pv
    labels:
      app: org2-cli-pv
spec:
    capacity:
       storage: 500Mi
    accessModes:
       - ReadWriteMany
    nfs:
      path: /opt/nfs/fabric/fabric/channel-artifacts
      server: 192.168.0.249

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
    namespace: org2
    name: org2-cli-pv
spec:
   accessModes:
     - ReadWriteMany
   resources:
      requests:
        storage: 10Mi
   selector:
     matchLabels:
       app: org2-cli-pv

 

# 创建 org2  cli  服务

vi org2-cli.yaml



apiVersion: extensions/v1beta1
kind: Deployment
metadata:
   namespace: org2
   name: cli
spec:
  replicas: 1
  strategy: {}
  template:
    metadata:
      labels:
       app: cli
    spec:
      containers:
        - name: cli
          image: hyperledger/fabric-tools:1.4.0
          env:
          - name: CORE_PEER_TLS_ENABLED
            value: "false"
          - name: CORE_VM_ENDPOINT
            value: unix:///host/var/run/docker.sock
          - name: GOPATH
            value: /opt/gopath
          - name: CORE_LOGGING_LEVEL
            value: DEBUG
          - name: CORE_PEER_ID
            value: cli
          - name: CORE_PEER_ADDRESS
            value: peer0.org2:7051
          - name: CORE_PEER_LOCALMSPID
            value: Org2MSP
          - name: CORE_PEER_MSPCONFIGPATH
            value: /etc/hyperledger/fabric/msp
          - name: GODEBUG
            value: netdns=go
          workingDir: /opt/gopath/src/github.com/hyperledger/fabric/peer
          command: ["/bin/bash", "-c", "--"]
          args: ["while true; do sleep 30; done;"]
          volumeMounts:
           - mountPath: /host/var/run/
             name: run
           - mountPath: /etc/hyperledger/fabric/msp
             name: certificate
             subPath: users/Admin@org2/msp
           - mountPath: /opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts
             name: artifacts
      volumes:
        - name: certificate
          persistentVolumeClaim:
              claimName: org2-pv
        - name: artifacts
          persistentVolumeClaim:
              claimName: org2-cli-pv
        - name: run
          hostPath:
            path: /var/run

 

# 导入 yaml 文件

[root@kubernetes-1 /opt/jicki/k8s-yaml]# kubectl apply -f org2-cli-pv-pvc.yaml 
persistentvolume/org2-cli-pv created
persistentvolumeclaim/org2-cli-pv created



[root@kubernetes-1 /opt/jicki/k8s-yaml]# kubectl apply -f org2-cli.yaml 
deployment.extensions/cli created

 

# 查看服务

[root@kubernetes-1 /opt/jicki/k8s-yaml]# kubectl get pods --all-namespaces

NAMESPACE     NAME                                       READY   STATUS    RESTARTS   AGE
org1          cli-68647b4c-6db4f                         1/1     Running   0          5m12s
org2          cli-5bd96dc66d-bhm65                       1/1     Running   0          18s

 

 

测试 集群

测试集群

  1. 初始化 channel 2. 加入 channel 3. 更新为 锚节点 4. 安装 chaincode 5. 实例化 chaincode 6. 操作 chaincode

org1 节点

# 登录  org1 cli

[root@kubernetes-1 /opt/jicki/k8s-yaml]# kubectl exec -it cli-68647b4c-6db4f -n org1 bash



1. 初始化 创建channel

peer channel create -o orderer0.orgorderer1:7050 -c mychannel -f ./channel-artifacts/channel.tx

 

 

拷贝 mychannel.block 文件到 channel-artifacts 共享目录

# 拷贝

cp mychannel.block channel-artifacts



# 加入 channel


peer channel join -b channel-artifacts/mychannel.block


2019-01-21 02:40:58.478 UTC [main] InitCmd -> WARN 001 CORE_LOGGING_LEVEL is no longer supported, please use the FABRIC_LOGGING_SPEC environment variable
2019-01-21 02:40:58.497 UTC [main] SetOrdererEnv -> WARN 002 CORE_LOGGING_LEVEL is no longer supported, please use the FABRIC_LOGGING_SPEC environment variable
2019-01-21 02:40:58.500 UTC [channelCmd] InitCmdFactory -> INFO 003 Endorser and orderer connections initialized
2019-01-21 02:40:58.589 UTC [channelCmd] executeJoin -> INFO 004 Successfully submitted proposal to join channel

 

# 更新 锚节点 peer,每个 org 只需执行一次

# 更新对应的 org1 的

peer channel update -o orderer0.orgorderer1:7050 -c mychannel -f ./channel-artifacts/Org1MSPanchors.tx

 

org2 节点

# 登录 org2 节点 cli

[root@kubernetes-1 /opt/jicki/k8s-yaml]# kubectl exec -it cli-5bd96dc66d-j2m6d -n org2 bash

 

# 加入 mychannel 

peer channel join -b channel-artifacts/mychannel.block


2019-01-21 02:47:14.529 UTC [main] InitCmd -> WARN 001 CORE_LOGGING_LEVEL is no longer supported, please use the FABRIC_LOGGING_SPEC environment variable
2019-01-21 02:47:14.549 UTC [main] SetOrdererEnv -> WARN 002 CORE_LOGGING_LEVEL is no longer supported, please use the FABRIC_LOGGING_SPEC environment variable
2019-01-21 02:47:14.551 UTC [channelCmd] InitCmdFactory -> INFO 003 Endorser and orderer connections initialized
2019-01-21 02:47:14.629 UTC [channelCmd] executeJoin -> INFO 004 Successfully submitted proposal to join channel

 

# 更新 锚节点 peer,每个 org 只需执行一次

# 更新对应的 org2 的

peer channel update -o orderer0.orgorderer1:7050 -c mychannel -f ./channel-artifacts/Org2MSPanchors.tx 

 

安装 chaincode

安装 chaincode 需要在 org1 org2 的 cli 分别安装

 

#  org1

kubectl exec -it cli-68647b4c-lhdhf -n org1 bash


# org2

kubectl exec -it cli-5bd96dc66d-j2m6d -n org2 bash

 

# 分别执行安装

peer chaincode install -n example2 -v 1.0 -p github.com/hyperledger/fabric/peer/channel-artifacts/chaincode/example02

 

实例化 chaincode

实例化 chaincode 只需要在 其中一个 org 执行就可以

 

peer chaincode instantiate -o orderer0.orgorderer1:7050 \
                             -C mychannel -n example2 -v 1.0 \
                             -c '{"Args":["init","A", "100", "B","200"]}' \
                             -P "OR ('Org1MSP.peer','Org2MSP.peer')"

 

# 实例化以后~会在 docker 中生成 一个容器, 脱离于k8s 是由 docker 生成

[root@kubernetes-3 ~]# docker ps -a

CONTAINER ID        IMAGE                                                                                          COMMAND                  CREATED             STATUS                        PORTS               NAMES
26666283f935        dev-peer0.org1-example2-1.0-e8792315af3bc6f98b5be21c4c98ece1ab5c65537e361691af638304c0670cd5   "chaincode -peer.add…"   6 minutes ago       Up 6 minutes                                      dev-peer0.org1-example2-1.0

 

操作 chaincode

执行 转账,查询 操作

# 查询 A, B 账户的值


peer chaincode query -C mychannel -n example2 -c '{"Args":["query","A"]}'


# 输出如下:
2019-01-21 03:45:18.469 UTC [main] InitCmd -> WARN 001 CORE_LOGGING_LEVEL is no longer supported, please use the FABRIC_LOGGING_SPEC environment variable
2019-01-21 03:45:18.485 UTC [main] SetOrdererEnv -> WARN 002 CORE_LOGGING_LEVEL is no longer supported, please use the FABRIC_LOGGING_SPEC environment variable
100



peer chaincode query -C mychannel -n example2 -c '{"Args":["query","B"]}'


# 输出如下:
2019-01-21 03:47:21.683 UTC [main] InitCmd -> WARN 001 CORE_LOGGING_LEVEL is no longer supported, please use the FABRIC_LOGGING_SPEC environment variable
2019-01-21 03:47:21.701 UTC [main] SetOrdererEnv -> WARN 002 CORE_LOGGING_LEVEL is no longer supported, please use the FABRIC_LOGGING_SPEC environment variable
200

 

# invoke 转账

# 从A账户 转账 50 个币 到 B 账户

peer chaincode invoke -C mychannel -n example2 -c '{"Args":["invoke", "A", "B", "50"]}'

# 输出如下:
2019-01-21 03:48:43.787 UTC [main] InitCmd -> WARN 001 CORE_LOGGING_LEVEL is no longer supported, please use the FABRIC_LOGGING_SPEC environment variable
2019-01-21 03:48:43.806 UTC [main] SetOrdererEnv -> WARN 002 CORE_LOGGING_LEVEL is no longer supported, please use the FABRIC_LOGGING_SPEC environment variable
2019-01-21 03:48:43.816 UTC [chaincodeCmd] InitCmdFactory -> INFO 003 Retrieved channel (mychannel) orderer endpoint: orderer0.orgorderer1:7050
2019-01-21 03:48:43.830 UTC [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 004 Chaincode invoke successful. result: status:200 



# 转账后在查询 A, B 的值

peer chaincode query -C mychannel -n example2 -c '{"Args":["query","A"]}'

# 输出:
2019-01-21 03:49:10.686 UTC [main] InitCmd -> WARN 001 CORE_LOGGING_LEVEL is no longer supported, please use the FABRIC_LOGGING_SPEC environment variable
2019-01-21 03:49:10.702 UTC [main] SetOrdererEnv -> WARN 002 CORE_LOGGING_LEVEL is no longer supported, please use the FABRIC_LOGGING_SPEC environment variable
50



peer chaincode query -C mychannel -n example2 -c '{"Args":["query","B"]}'

# 输出:
2019-01-21 03:49:41.883 UTC [main] InitCmd -> WARN 001 CORE_LOGGING_LEVEL is no longer supported, please use the FABRIC_LOGGING_SPEC environment variable
2019-01-21 03:49:41.898 UTC [main] SetOrdererEnv -> WARN 002 CORE_LOGGING_LEVEL is no longer supported, please use the FABRIC_LOGGING_SPEC environment variable
250

 

 

blockchain-explorer 部署

blockchain-explorer 是 fabric 的区块浏览器

配置 postgres

# 创建 数据目录 , 创建于 nfs 中

mkdir -p /opt/nfs/fabric/data/postgres

 

# 创建 namesapce

vi explorer-namespace.yaml


apiVersion: v1
kind: Namespace
metadata:
    name: explorer

 

 

# 创建 pv  pvc

vi explorer-pv-pvc.yaml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: postgres-pv
  labels:
    app: postgres-pv
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteMany
  nfs:
    path: /opt/nfs/fabric/data/postgres
    server: 192.168.0.249

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
 namespace: explorer
 name: postgres-pv
spec:
 accessModes:
   - ReadWriteMany
 resources:
   requests:
     storage: 10Gi
 selector:
   matchLabels:
     app: postgres-pv


---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: explorer-pv
  labels:
    app: explorer-pv
spec:
  capacity:
    storage: 500Mi
  accessModes:
    - ReadWriteMany
  nfs:
    path: /opt/nfs/fabric/fabric/crypto-config
    server: 192.168.0.249

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
 namespace: explorer
 name: explorer-pv
spec:
 accessModes:
   - ReadWriteMany
 resources:
   requests:
     storage: 100Mi
 selector:
   matchLabels:
     app: explorer-pv

 

# 创建 postgres deployment


vi postgres-deployment.yaml


apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  namespace: explorer
  name: postgres-db
spec:
  replicas: 1
  template:
    metadata:
      labels:
        name: explorer-db
    spec:
      containers:
      - name: postgres
        image: postgres:10-alpine
        env:
        - name: TZ
          value: "Asia/Shanghai"
        - name: DATABASE_DATABASE
          value: "fabricexplorer"
        - name: DATABASE_USERNAME
          value: "jicki"
        - name: DATABASE_PASSWORD
          value: "password"
        volumeMounts:
        - mountPath: /var/lib/postgresql/data
          name: postgresdata
      volumes:
       - name: postgresdata
         persistentVolumeClaim:
           claimName: postgres-pv
---
apiVersion: v1
kind: Service
metadata:
  name: postgres-db
  namespace: explorer
  labels:
    run: explorer-db
spec:
 selector:
   name: explorer-db
 ports:
  - protocol: TCP
    port: 5432

 

 

# 查看 服务

[root@kubernetes-1 /opt/jicki/k8s-yaml/explorer]# kubectl get pods -n explorer
NAME                           READY   STATUS    RESTARTS   AGE
postgres-db-7884d8c859-s8hqq   1/1     Running   0          32s

 

# 初始化数据库 
# 初始化数据库这边只能手动登录 pods 里操作一下, 导入表结构以及初始化数据。


kubectl get pods -n explorer
NAME                           READY   STATUS    RESTARTS   AGE
postgres-db-7884d8c859-s8hqq   1/1     Running   0          2m33s



kubectl exec -it postgres-db-7884d8c859-s8hqq -n explorer bash



cd /tmp/

wget https://raw.githubusercontent.com/hyperledger/blockchain-explorer/master/app/persistence/fabric/postgreSQL/db/createdb.sh
wget https://raw.githubusercontent.com/hyperledger/blockchain-explorer/master/app/persistence/fabric/postgreSQL/db/explorerpg.sql
wget https://raw.githubusercontent.com/hyperledger/blockchain-explorer/master/app/persistence/fabric/postgreSQL/db/processenv.js
wget https://raw.githubusercontent.com/hyperledger/blockchain-explorer/master/app/persistence/fabric/postgreSQL/db/updatepg.sql


# 安装依赖软件

apk update
apk add jq
apk add nodejs
apk add sudo
rm -rf /var/cache/apk/*

# 执行创建脚本

chmod +x ./createdb.sh
./createdb.sh

# 看出输出 表示完成
You are now connected to database "fabricexplorer" as user "postgres".

退出pods

 

# 创建 explorer 配置文件 config.json


vi config.json

{
  "network-configs": {
    "network-1": {
      "version": "1.0",
      "clients": {
        "client-1": {
          "tlsEnable": false,
          "organization": "Org1MSP",
          "channel": "mychannel",
          "credentialStore": {
            "path": "./tmp/credentialStore_Org1/credential",
            "cryptoStore": {
              "path": "./tmp/credentialStore_Org1/crypto"
            }
          }
        }
      },
      "channels": {
        "mychannel": {
          "peers": {
            "peer0.org1": {},
            "peer1.org1": {},
            "peer0.org2": {},
            "peer1.org2": {}
          },
          "connection": {
            "timeout": {
              "peer": {
                "endorser": "6000",
                "eventHub": "6000",
                "eventReg": "6000"
              }
            }
          }
        }
      },
      "organizations": {
        "Org1MSP": {
          "mspid": "Org1MSP",
          "fullpath": false,
          "adminPrivateKey": {
            "path":
              "/fabric/peerOrganizations/org1/users/Admin@org1/msp/keystore"
          },
          "signedCert": {
            "path":
              "/fabric/peerOrganizations/org1/users/Admin@org1/msp/signcerts"
          }
        },
        "Org2MSP": {
          "mspid": "Org2MSP",
          "fullpath": false,
          "adminPrivateKey": {
            "path":
              "/fabric/peerOrganizations/org2/users/Admin@org2/msp/keystore"
          },
          "signedCert": {
            "path":
              "/fabric/peerOrganizations/org2/users/Admin@org2/msp/signcerts"
          }
        },
        "Orgorderer1MSP": {
          "mspid": "Orgorderer1MSP",
          "adminPrivateKey": {
            "path":
              "/fabric/ordererOrganizations/orgorderer1/users/Admin@orgorderer1/msp/keystore"
          }
        }
      },
      "peers": {
        "peer0.org1": {
          "tlsCACerts": {
            "path":
              "/fabric/peerOrganizations/org1/peers/peer0.org1/tls/ca.crt"
          },
          "url": "grpc://peer0.org1:7051",
          "eventUrl": "grpc://peer0.org1:7053",
          "grpcOptions": {
            "ssl-target-name-override": "peer0.org1"
          }
        },
        "peer1.org1": {
          "tlsCACerts": {
            "path":
              "/fabric/peerOrganizations/org1/peers/peer1.org1/tls/ca.crt"
          },
          "url": "grpc://peer1.org1:7051",
          "eventUrl": "grpc://peer1.org1:7053",
          "grpcOptions": {
            "ssl-target-name-override": "peer1.org1"
          }
        },
        "peer0.org2": {
          "tlsCACerts": {
            "path":
              "/fabric/peerOrganizations/org2/peers/peer0.org2/tls/ca.crt"
          },
          "url": "grpc://peer0.org2:7051",
          "eventUrl": "grpc://peer0.org2:7053",
          "grpcOptions": {
            "ssl-target-name-override": "peer0.org2"
          }
        },
        "peer1.org2": {
          "tlsCACerts": {
            "path":
              "/fabric/peerOrganizations/org2/peers/peer1.org2/tls/ca.crt"
          },
          "url": "grpc://peer1.org2:7051",
          "eventUrl": "grpc://peer1.org2:7053",
          "grpcOptions": {
            "ssl-target-name-override": "peer1.org2"
          }
        }
      },
      "orderers": {
        "orderer0.orgorderer1": {
          "url": "grpc://orderer0.orgorderer1:7050"
        }
      }
    },
    "network-2": {}
  },
  "configtxgenToolPath": "/fabric-path/workspace/fabric-samples/bin",
  "license": "Apache-2.0"
}

 

 

# 创建运行脚本 run.sh


vi run.sh


#!/bin/sh
mkdir -p /opt/explorer/app/platform/fabric/

mv /opt/explorer/app/platform/fabric/config.json /opt/explorer/app/platform/fabric/config.json.vanilla
cp /fabric/config.json /opt/explorer/app/platform/fabric/config.json

cd /opt/explorer
node $EXPLORER_APP_PATH/main.js && tail -f /dev/null

 

# 拷贝文件到 NFS 目录中 并 授权

cp config.json run.sh /opt/nfs/fabric/fabric/crypto-config/

chmod +x /opt/nfs/fabric/fabric/crypto-config/run.sh

 

# 创建 deployment 服务

vi explorer-deployment.yaml


apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  namespace: explorer
  name: explorer
spec:
  replicas: 1
  template:
    metadata:
      labels:
        name: explorer
    spec:
      containers:
      - name: explorer
        image: hyperledger/explorer:latest
        command: ["sh" , "-c" , "/fabric/run.sh"]
        env:
        - name: TZ
          value: "Asia/Shanghai"
        - name: DATABASE_HOST
          value: "postgres-db"
        - name: DATABASE_USERNAME
          value: "jicki"
        - name: DATABASE_PASSWORD
          value: "password"
        volumeMounts:
        - mountPath: /fabric
          name: certfile
      volumes:
       - name: certfile
         persistentVolumeClaim:
             claimName: explorer-pv

---
apiVersion: v1
kind: Service
metadata:
  name: explorer
  namespace: explorer
spec:
 selector:
   name: explorer
 ports:
   - name: webui
     protocol: TCP
     port: 8080


---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: explorer-ingress
  namespace: explorer
spec:
  rules:
  - host: explorer.jicki.me
    http:
      paths:
      - backend:
          serviceName: explorer
          servicePort: 8080

 

 

 

发表评论