본문 바로가기

IT/Block Chain(Hyperledger)

Minikube에 블록체인 네트워크 배포하기

참조문서: https://github.com/IBM/blockchain-network-on-kubernetes/blob/master/README-ko.md

이 패턴을 완료하시면 다음을 배울 수 있습니다:

  • 네트워크 토폴로지에 따른 설정 파일 수정하기
  • Kubernetes 클러스터에 Hyperledger Fabric 네트워크 배포하기

구성 요소

Hyperledger Fabric: Hyperledger Fabric은 고도의 기밀성, 탄력성, 유연성 및 확장성을 제공하는 모듈러 아키텍처 기반의 분산원장 솔루션을 위한 플랫폼입니다.

주요 기술

블록체인: 블록체인은 네트워크의 모든 거래 내역이 분산된 디지털 공개 원장입니다.

minikube: Minikube는 Kubernetes를 로컬에서 쉽게 실행할 수있는 도구입니다. Minikube는 Kubernetes를 시험해 보거나 일상적으로 개발하려는 사용자를 위해 랩톱의 VM 내부에서 단일 노드 Kubernetes 클러스터를 실행합니다.

Kubernetes Cluster: Kubernetes Engine에서 컨테이너 클러스터는 최소 하나의 마스터 클러스터와 노드라고 불리는 여러 작업 시스템으로 구성됩니다. 컨테이너 클러스터는 Kubernetes 엔진의 기반입니다.

Kubernetes의 개념 정의

  • Kubernetes Pods - Pod는 Kubernetes 클러스터에서 배포 가능한 최소 단위를 뜻하며, 단일로 처리해야 하는 여러 컨테이너를 그룹화하는 데 사용됩니다.
  • Kubernetes Jobs - Job은 하나 이상의 Pod를 생성하고 지정된 수의 Pod가 성공적으로 종료하도록 합니다. Pod를 가 성공적으로 완료되면 Job은 이를 기록합니다.
  • Kubernetes Deployment - Deployment는 저장장치, 서비스 및 어노테이션 등 애플리케이션을 실행하기 위해 필요한 기타 리소스와 컨테이너를 지정하는 Kubernetes 리소스입니다.
  • Kubernetes Services - Kubernetes service는 여러 Pod를 그룹화하고 클러스터 내 다른 서비스를 위해 개별 Pod의 IP 주소를 은폐하면서 네트워크 연결을 제공합니다.
  • Kubernetes Persistent Volumes (PV) - Persistent Volume은 사용자가 NFS와 같은 파일 저장소를 요청하는 방법입니다.

순서

다음 순서를 따라 환경을 설정하고 코드를 실행합니다.

  • minikube에 Kubernetes 클러스터 생성
  • Kubernetes 클러스터에 Hyperledger Fabric 네트워크 배포
  • 배포된 네트워크 테스트
  • Kubernetes 대시보드 확인
  •  

1. minikube에 Kubernetes 클러스터 생성

우선, minikube를 설치해야 합니다. 자세한 설치 내용은 Minikube(조태희)를 참조합니다.

설치가 완료되었으면, minikube start를 실행합니다.

$ minikube start

만약 에러가 발생된다면, 이 역시도 위의 링크를 확인하십시오.

2. Kubernetes 클러스터에 Hyperledger Fabric 네트워크 배포

네트워크 토폴로지 이해하기

이 패턴은 각 1개의 피어와 '솔로' 주문 서비스로 구성된, 총 4개의 조직을 포함한 Hyperledger Fabric 네트워크 샘플을 자동으로 준비하는 스크립트를 제공합니다. 스크립트는 또한 channel1이란 이름의 채널을 생성하고 모든 피어를 이 채널로 연결합니다. 그 다음, 체인코드를 모든 피어에게 설치하여 채널에 인스턴스화합니다. 이 패턴은 배포된 체인코드에 대해 트랜잭션 실행이 이루어지도록 도움을 줍니다.

 

Kubernetes 설정 스크립트 복사하기

Kubernetes 설정 스크립트를 사용자의 홈 디렉토리에 복사 또는 다운로드합니다.

$ git clone https://github.com/IBM/blockchain-network-on-kubernetes.git

소스 디렉토리로 이동합니다.

$ cd blockchain-network-on-kubernetes

$ ls

소스 디렉토리 안에,

  • configFiles 디렉토리는 Kubernetes 설정 파일을 포함하고 있습니다.
  • artifacts 디렉토리는 네트워크 설정 파일을 포함하고 있습니다.
  • *.sh 파일은 네트워크를 배포 또는 삭제하는 스크립트입니다.

Kubernetes 설정 스크립트 수정하기

네트워크 토폴로지가 변경되면 구성 파일 (.yaml 파일)을 적절하게 수정해야 합니다. 설정 파일은 artifacts와 configFiles 디렉토리에 있습니다.

예를 들어, 볼륨의 용량을 늘리거나 줄이려면 createVolume.yaml 파일을 수정해야 합니다.

$ eval $(minikube docker-env)

$ docker images

 

스크립트를 실행하여 Hyperledger Fabric 네트워크 배포하기

설정 파일이 완성되면 네트워크를 배포할 준비가 된 것입니다. 스크립트를 실행하여 Hyperledger Fabric 네트워크를 배포하세요.

$ chmod +x setup_blockchainNetwork.sh

$ ./setup_blockchainNetwork.sh

주의: 스크립트를 실행하기 전에 실행환경을 먼저 확인하세요. 3번째 순서에서 설명한 대로 클러스터에서 kubectl 명령을 올바르게 실행할 수 있어야 합니다.

[참고 Kubernetes 전체 개요]

참고 Kubernetes 전체 개요

createVolume.yaml - 영구볼륨 생성

echo "실행중: kubectl create -f ${KUBECONFIG_FOLDER}/createVolume.yaml"
kubectl create -f ${KUBECONFIG_FOLDER}/createVolume.yaml
#잡 컨트롤러는 계속해서 실행되어야하는 성격이 아니라 실행되고나서 종료되어야하는 성격의 작업을 실행시킬때 사용하는 컨트롤러 입니다.
# 잡은 특정 개수 만큼의 Pod가 성공적으로 완료되는걸 보장해 줍니다. 가장 간단한 경우로는 잡이 Pod 하나를 실행하고
# Pod가 정상적으로 종료됐는지 확인하는 것입니다. 실행한 Pod가 실패하거나 하드웨어 장애가 발생하거나 노드가 재부팅 되는등
# 문제가 발생하면 다시 Pod를 실행합니다. 잡 하나가 Pod를 여러개 실행하는 것도 가능합니다.

#kubectl describe job pi로 잡 상태를 확인해 볼수 있습니다. 실행 결과는 로그를 보면 알수 있는데 아래처럼 하면 됩니다. pods에 Pod id를 할당 받아서 kubectl logs명령어로 해당 Pod의 로그를 볼 수 있습니다.
# $ pods=$(kubectl get pods --selector=job-name=copyartifacts --output=jsonpath={.items..metadata.name})
# $ kubectl logs $pods
---
apiVersion: batch/v1
kind: Job
metadata:
  name: copyartifacts
spec:
  backoffLimit: 1   # 작업 실패시 시도 횟수
  template:
    metadata:
      name: copyartifacts
    spec:
      restartPolicy: "Never"
      volumes:
      - name: sharedvolume # createVolume에서 만든 volume입니다.
        persistentVolumeClaim:
          claimName: shared-pvc
      - name: dockersocket # Docker 데몬이 기본적으로 청취하는 유닉스 소켓이며 컨테이너 내에서 데몬과 통신하는 데 사용할 수 있습니다.
        hostPath:
          path: /var/run/docker.sock
      containers:
      - name: copyartifacts
        image: alpine:3.7 # 알파인 리눅스는 가볍고 간단하고 보안성을 목적으로 개발한 리눅스 배포판입니다.
        imagePullPolicy: Always # imagePullPolicy는 Pod를 만들때 마다 매번 컨테이너 이미지를 확인해서 새 이미지를 사용하도록 하는 설정입니다.  컨테이너 이미지는 한번 다운로드가 되면 노드(Node) 에 저장이 되어 있게 되고, 사용이 되지 않는 이미지 중에 오래된 이미지는 Kublet이 가비지 컬렉션 (Garbage collection) 정책에 따라 이미지를 삭제하게 되는데, 문제는 노드에 이미 다운되어 있는 이미지가 있을 경우 컨테이너 생성시 노드에 이미 다운로드 되어 있는 이미지를 사용한다. 컨테이너 리파지토리에 같은 이름으로 이미지를 업데이트 하거나 심지어 그 이미지를 삭제하더라도 노드에 이미지가 이미 다운로드 되어 있으면 다운로드된 이미지를 사용하기 때문에, 업데이트 부분이 반영이 안된다. 이를 방지하기 위해서 imagePullPolicy:Always로 해주면 컨테이너 생성시마다 이미지 리파지토리를 검사해서 새 이미지를 가지고 오기 때문에, 업데이트된 내용을 제대로 반영할 수 있습니다.
        command: ["sh", "-c", "ls -l /shared; rm -rf /shared/*; ls -l /shared; while [ ! -d /shared/artifacts ]; do echo Waiting for artifacts to be copied; sleep 2; done; sleep 10; ls -l /shared/artifacts; "]
        # sh:shell스크립트, -c: 명령 실행 , 내용: shared/artifacts 디렉토리에 configtx.yaml, cruypto-config.yaml, sample chaincode 등을 복사
        volumeMounts: # 볼륨을 사용하기 위해 포드는 포드에 제공 할 볼륨 (.spec.volumes 필드)과 그 볼륨을 컨테이너 (.spec.containers.volumeMounts 필드)에 마운트 할 위치를 지정합니다.
        - mountPath: /shared
          name: sharedvolume
# icp와 ICS에서 작동하도록이 스크립트 수정
kubectl cp ./artifacts $pod:/shared/

generateArtifactsJob.yaml - configtx.yaml와 crypto-config.yaml을 사용하여 네트워크 아티팩트 생성

echo -e "\nGenerating the required artifacts for Blockchain network"
echo "Running: kubectl create -f ${KUBECONFIG_FOLDER}/generateArtifactsJob.yaml"
kubectl create -f ${KUBECONFIG_FOLDER}/generateArtifactsJob.yaml

# crypto-config에서 생성한 인증서 매칭을 안하기 위해 *_sk로 시작하는 인증서를 key.pem을 통일함.

---
apiVersion: batch/v1
kind: Job
metadata:
  name: utils
spec:
  backoffLimit: 1
  template:
    metadata:
      name: utils
    spec:
      restartPolicy: "Never"
      volumes:
      - name: sharedvolume
        persistentVolumeClaim:
          claimName: shared-pvc # createVolume에서 만든 volume입니다.
      - name: dockersocket
        hostPath:
          path: /var/run/docker.sock # Docker 데몬이 기본적으로 청취하는 유닉스 소켓이며 컨테이너 내에서 데몬과 통신하는 데 사용할 수 있습니다.
      containers:
      - name: cryptogen
        image: hyperledger/fabric-tools:x86_64-1.1.0
        imagePullPolicy: Always
        command: ["sh", "-c", "echo 'Cryptogen Starts'; ls -l /shared/artifacts; while [ ! -d /shared/artifacts ]; do echo Waiting for configFiles; sleep 1; done; cryptogen generate --config /shared/artifacts/crypto-config.yaml && cp -r crypto-config /shared/ && for file in $(find /shared/ -iname *_sk); do echo $file; dir=$(dirname $file); echo ${dir}; mv ${dir}/*_sk ${dir}/key.pem; done && find /shared -type d | xargs chmod a+rx && find /shared -type f | xargs chmod a+r && touch /shared/status_cryptogen_complete;"]
        # sh:shell스크립트, -c: 명령 실행 , 내용: cryptogen을 이용해 /shared/artifacts/crypto-config.yaml의 구성파일을 확인하고, Orderer와 Peer 인증서 생성
        volumeMounts: # 볼륨을 사용하기 위해 포드는 포드에 제공 할 볼륨 (.spec.volumes 필드)과 그 볼륨을 컨테이너 (.spec.containers.volumeMounts 필드)에 마운트 할 위치를 지정합니다.
        - mountPath: /shared
          name: sharedvolume
      - name: configtxgen
        image: hyperledger/fabric-tools:x86_64-1.1.0
        imagePullPolicy: Always
        command: ["sh", "-c", "echo 'Configtxgen Starts'; ls -l /shared; sleep 1 && while [ ! -f /shared/status_cryptogen_complete ]; do echo Waiting for cryptogen; sleep 1; done; cp /shared/artifacts/configtx.yaml /shared/; cd /shared/; export FABRIC_CFG_PATH=$PWD; configtxgen -profile SixOrgsOrdererGenesis -outputBlock genesis.block && find /shared -type d | xargs chmod a+rx && find /shared -type f | xargs chmod a+r && touch /shared/status_configtxgen_complete && rm /shared/status_cryptogen_complete;"]
        # sh:shell스크립트, -c: 명령 실행 , 내용: configtxgen을 이용해 configtx.yaml에 정의된 SixOrgsOrdererGenesis를 참고하여 제네시스 블록 생성
        volumeMounts: # 볼륨을 사용하기 위해 포드는 포드에 제공 할 볼륨 (.spec.volumes 필드)과 그 볼륨을 컨테이너 (.spec.containers.volumeMounts 필드)에 마운트 할 위치를 지정합니다.
        - mountPath: /shared
          name: sharedvolume

blockchain-services.yaml - 모든 피어(ca, orderer)에 대한 서비스 작성

echo -e "\nCreating Services for blockchain network"
echo "Running: kubectl create -f ${KUBECONFIG_FOLDER}/blockchain-services.yaml"
kubectl create -f ${KUBECONFIG_FOLDER}/blockchain-services.yaml
---
apiVersion: v1
kind: Service # Kubernetes의 서비스는 Pod와 비슷한 REST 객체입니다. 모든 REST 오브젝트와 마찬가지로, 서비스 정의를 apiserver에 POST하여 새 인스턴스를 작성할 수 있습니다. 예를 들어, 각각 포트 30054을 노출하고 "name = ca"라는 레이블을 가진 Pod 집합이 있다고 가정합니다.
metadata:     # 이 사양은 "name=ca"라는 레이블이 있는 모든 Pod의 TCP 포트 30054를 대상으로하는 "blockchain-ca"라는 새 서비스 개체를 만듭니다. 이 서비스에는 서비스 프록시(아래 참조)가 사용하는 IP 주소("클러스터 IP"라고도 함)가 할당됩니다. 서비스의 selector는 지속적으로 평가되고 결과는 "blockchain-ca"라는 Endpoints 객체에 POST됩니다.
  name: blockchain-ca
  labels:
    run: blockchain-ca
spec:
  type: NodePort
  selector: # 라벨 셀렉터 (label selector)를 이용하여, 관리하고자 하는 Pod들을 정의할 수 있다. 
    name: ca
  ports:
  - protocol: TCP # Kubernetes Services는 프로토콜 용 TCP 및 UDP를 지원합니다. 기본값은 TCP입니다.
    nodePort: 30054 # blockchain-ca 라는 서비스를 NodePort 타입으로 선언을 하고, nodePort를 30054으로 설정하면, 아래 설정에 따라 클러스터 IP의  7054 포트로도 접근이 가능하지만, 모든 노드의 30054 포트로도 서비스를 접근할 수 있다. 
    targetPort: 7054
    port: 30054
    name: grpc
---
apiVersion: v1
kind: Service
metadata:
  name: blockchain-orderer
  labels:
    run: blockchain-orderer
spec:
  type: NodePort
  selector:
    name: orderer
  ports:
  - protocol: TCP
    nodePort: 31010
    targetPort: 31010
    port: 31010
    name: grpc
---
apiVersion: v1
kind: Service
metadata:
  name: blockchain-org1peer1
  labels:
    run: blockchain-org1peer1
spec:
  type: NodePort
  selector:
    name: org1peer1
  ports:
  - protocol: TCP
    nodePort: 30110
    targetPort: 30110
    port: 30110
    name: grpc
  - protocol: TCP
    nodePort: 30111
    targetPort: 30111
    port: 30111
    name: events

---
apiVersion: v1
kind: Service
metadata:
  name: blockchain-org1peer2
  labels:
    run: blockchain-org1peer2
spec:
  type: NodePort
  selector:
    name: org1peer2
  ports:
  - protocol: TCP
    nodePort: 30120
    targetPort: 30120
    port: 30120
    name: grpc
  - protocol: TCP
    nodePort: 30121
    targetPort: 30121
    port: 30121
    name: events

---
apiVersion: v1
kind: Service
metadata:
  name: blockchain-org2peer1
  labels:
    run: blockchain-org2peer1
spec:
  type: NodePort
  selector:
    name: org2peer1
  ports:
  - protocol: TCP
    nodePort: 30210
    targetPort: 30210
    port: 30210
    name: grpc
  - protocol: TCP
    nodePort: 30211
    targetPort: 30211
    port: 30211
    name: events

---
apiVersion: v1
kind: Service
metadata:
  name: blockchain-org2peer2
  labels:
    run: blockchain-org2peer2
spec:
  type: NodePort
  selector:
    name: org2peer2
  ports:
  - protocol: TCP
    nodePort: 30220
    targetPort: 30220
    port: 30220
    name: grpc
  - protocol: TCP
    nodePort: 30221
    targetPort: 30221
    port: 30221
    name: events

---
apiVersion: v1
kind: Service
metadata:
  name: blockchain-org3peer1
  labels:
    run: blockchain-org3peer1
spec:
  type: NodePort
  selector:
    name: org3peer1
  ports:
  - protocol: TCP
    nodePort: 30310
    targetPort: 30310
    port: 30310
    name: grpc
  - protocol: TCP
    nodePort: 30311
    targetPort: 30311
    port: 30311
    name: events

---
apiVersion: v1
kind: Service
metadata:
  name: blockchain-org3peer2
  labels:
    run: blockchain-org3peer2
spec:
  type: NodePort
  selector:
    name: org3peer2
  ports:
  - protocol: TCP
    nodePort: 30320
    targetPort: 30320
    port: 30320
    name: grpc
  - protocol: TCP
    nodePort: 30321
    targetPort: 30321
    port: 30321
    name: events

---
apiVersion: v1
kind: Service
metadata:
  name: blockchain-org4peer1
  labels:
    run: blockchain-org4peer1
spec:
  type: NodePort
  selector:
    name: org4peer1
  ports:
  - protocol: TCP
    nodePort: 30410
    targetPort: 30410
    port: 30410
    name: grpc
  - protocol: TCP
    nodePort: 30411
    targetPort: 30411
    port: 30411
    name: events

---
apiVersion: v1
kind: Service
metadata:
  name: blockchain-org4peer2
  labels:
    run: blockchain-org4peer2
spec:
  type: NodePort
  selector:
    name: org4peer2
  ports:
  - protocol: TCP
    nodePort: 30420
    targetPort: 30420
    port: 30420
    name: grpc
  - protocol: TCP
    nodePort: 30421
    targetPort: 30421
    port: 30421
    name: events

---
apiVersion: v1
kind: Service
metadata:
  name: blockchain-org5peer1
  labels:
    run: blockchain-org5peer1
spec:
  type: NodePort
  selector:
    name: org5peer1
  ports:
  - protocol: TCP
    nodePort: 30510
    targetPort: 30510
    port: 30510
    name: grpc
  - protocol: TCP
    nodePort: 30511
    targetPort: 30511
    port: 30511
    name: events

---
apiVersion: v1
kind: Service
metadata:
  name: blockchain-org5peer2
  labels:
    run: blockchain-org5peer2
spec:
  type: NodePort
  selector:
    name: org5peer2
  ports:
  - protocol: TCP
    nodePort: 30520
    targetPort: 30520
    port: 30520
    name: grpc
  - protocol: TCP
    nodePort: 30521
    targetPort: 30521
    port: 30521
    name: events

---
apiVersion: v1
kind: Service
metadata:
  name: blockchain-org6peer1
  labels:
    run: blockchain-org6peer1
spec:
  type: NodePort
  selector:
    name: org6peer1
  ports:
  - protocol: TCP
    nodePort: 30610
    targetPort: 30610
    port: 30610
    name: grpc
  - protocol: TCP
    nodePort: 30611
    targetPort: 30611
    port: 30611
    name: events

---
apiVersion: v1
kind: Service
metadata:
  name: blockchain-org6peer2
  labels:
    run: blockchain-org6peer2
spec:
  type: NodePort
  selector:
    name: org6peer2
  ports:
  - protocol: TCP
    nodePort: 30620
    targetPort: 30620
    port: 30620
    name: grpc
  - protocol: TCP
    nodePort: 30621
    targetPort: 30621
    port: 30621
    name: events

peerDeployment.yaml - Kubernetes 배포를 사용하여 동료, CA, 주문자 생성

echo -e "\nCreating new Deployment to create six peers in network"
echo "Running: kubectl create -f ${KUBECONFIG_FOLDER}/peersDeployment.yaml"
kubectl create -f ${KUBECONFIG_FOLDER}/peersDeployment.yaml
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata: 
  name: blockchain-orderer # metadata.name에 의해 Deployment name이 선언됩니다.
spec:
  replicas: 1 #1개의 pod만 생성
  template:
    metadata:
      labels: 
        name: orderer # name: orderer로 지칭한 Pod 템플릿을 선택합니다.
    spec:
      volumes: # 볼륨을 불러옵니다.
      - name: sharedvolume
        persistentVolumeClaim:
          claimName: shared-pvc

      containers:
      - name: orderer
        image: hyperledger/fabric-orderer:x86_64-1.1.0
        command: ["sh", "-c", "sleep 5 && while [ ! -f /shared/status_configtxgen_complete ]; do echo Waiting for configtxgen; sleep 1; done; orderer"]

        env:
        - name: ORDERER_CFG_PATH #orderer 경로
          value: /shared/
        - name: ORDERER_GENERAL_LEDGERTYPE # Orderer 원장 타입
          value: file
        - name: ORDERER_FILELEDGER_LOCATION # 파일 원장 위치
          value: /shared/ledger/orderer
        - name: ORDERER_GENERAL_BATCHTIMEOUT # 일괄 처리(batch)를 만들기 전에 기다리는 시간
          value: 1s
        - name: ORDERER_GENERAL_BATCHSIZE_MAXMESSAGECOUNT # 일괄 처리에서 허용 할 최대 메시지 수
          value: "10"
        - name: ORDERER_GENERAL_MAXWINDOWSIZE # ?
          value: "1000"
        - name: ORDERER_GENERAL_ORDERERTYPE # Orderer Type: 시작하려는 orderer 구현
          value: solo
        - name: ORDERER_GENERAL_LISTENADDRESS #어플리케이션 요청에 수신 대기하도록 바인딩할 IP
          value: 0.0.0.0
        - name: ORDERER_GENERAL_LISTENPORT # 어플리케이션 요청에 수신 대기하도록 바인딩할 PORT.
          value: "31010"
        - name: ORDERER_GENERAL_LOGLEVEL # 로그레벨 설정 - error, debug
          value: debug
        - name: ORDERER_GENERAL_LOCALMSPDIR # Orderer 검증에 필요한 Crypto 위치.
          value: /shared/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/msp
        - name: ORDERER_GENERAL_LOCALMSPID # Local MSP 정보를 MSP Manager에 등록. 주의: channel의 msp중 하나와 일치해야함.
          value: OrdererMSP
        - name: ORDERER_GENERAL_GENESISMETHOD # #Provisional(동적인 생성) 과 File(GenesisFile 사용) 옵션이 있음.
          value: file
        - name: ORDERER_GENERAL_GENESISFILE  #(genesis.block 파일 경로).
          value: /shared/genesis.block
        - name: ORDERER_GENERAL_GENESISPROFILE
          value: initial
        # enabledTLS
        - name: ORDERER_GENERAL_TLS_ENABLED
          value: "false"
        # - name: ORDERER_GENERAL_TLS_PRIVATEKEY
        #   value: /var/hyperledger/orderer/tls/server.key #Orderer가 인증에 사용할 PEM으로 인코딩 된 개인키(private key).
        # - name: ORDERER_GENERAL_TLS_CERTIFICATE
        #   value: /var/hyperledger/orderer/tls/server.crt #Orderer가 인증에 사용할 PEM으로 인코딩 된 공개키(public key).
        # - name: ORDERER_GENERAL_TLS_ROOTCAS
        #   value: [/var/hyperledger/orderer/tls/ca.crt] #Kafka 클러스터의 인증서를 확인하는 데 사용되는 PEM으로 인코딩 된 신뢰할 수있는 서명자 인증서.
        # - name: ORDERER_KAFKA_RETRY_SHORTINTERVAL
        #   value: 1s #Kafka Broker가 없는 경우 재접속 연결 시도 주기.
        # - name: ORDERER_KAFKA_RETRY_SHORTTOTAL
        #   value: 30s #Kafka Broker가 없는 경우 총 재접속 연결 시도 시간.
        # - name: ORDERER_KAFKA_VERBOSE
        #   value: true #Kafka 클러스터와 상호 작용하는 데 사용하는 클라이언트 라이브러리 인 sarama에 대한 로깅을 켭니다.
        # - name: ORDERER_KAFKA_BROKERS
        #   value: [kafka1:9092,kafka2:9093,kafka3:9092,kafka4:9093] #Kafka Broker 정보.
        - name: GODEBUG
          value: "netdns=go"
        volumeMounts:
        - mountPath: /shared
          name: sharedvolume

---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: blockchain-ca
spec:
  replicas: 1
  template:
    metadata:
      labels:
        name: ca
    spec:
      volumes:
      - name: sharedvolume
        persistentVolumeClaim:
          claimName: shared-pvc

      containers:
      - name: ca
        image: hyperledger/fabric-ca:x86_64-1.1.0
        command: ["sh", "-c", "sleep 1 && while [ ! -f /shared/status_configtxgen_complete ]; do echo Waiting for configtxgen; sleep 1; done; fabric-ca-server start -b admin:adminpw -d"]
        env:
        - name: FABRIC_CA_SERVER_CA_NAME
          value: "CA1"
        - name: FABRIC_CA_SERVER_CA_CERTFILE # CA_CERTFILE 경로
          value: /shared/crypto-config/peerOrganizations/org1.example.com/ca/ca.org1.example.com-cert.pem
        - name: FABRIC_CA_SERVER_CA_KEYFILE # CA_KEYFILE 경로
          value: /shared/crypto-config/peerOrganizations/org1.example.com/ca/key.pem
        - name: FABRIC_CA_SERVER_DEBUG
          value: "true"
        - name: FABRIC_CA_SERVER_TLS_ENABLED
          value: "false"
        - name: FABRIC_CA_SERVER_TLS_CERTFILE
          value: /certs/ca0a-cert.pem
        - name: FABRIC_CA_SERVER_TLS_KEYFILE
          value: /certs/ca0a-key.pem
        - name: GODEBUG
          value: "netdns=go"
        volumeMounts:
        - mountPath: /shared
          name: sharedvolume

---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: blockchain-org1peer1
spec:
  replicas: 1
  template:
    metadata:
      labels:
        name: org1peer1
    spec:
      volumes:
      - name: sharedvolume
        persistentVolumeClaim:
          claimName: shared-pvc
      - name: dockersocket
        hostPath:
          path: /var/run/docker.sock

      containers:
      - name: org1peer1
        image: hyperledger/fabric-peer:x86_64-1.1.0
        command: ["sh", "-c", "sleep 1 && while [ ! -f /shared/status_configtxgen_complete ]; do echo Waiting for configtxgen; sleep 1; done; peer node start"]
        env:
        - name: CORE_PEER_ADDRESSAUTODETECT
          value: "true"
        - name: CORE_PEER_NETWORKID
          value: nid1
        - name: CORE_PEER_ID # Peer ID는 Peer 인스턴스를 식별하는데 사용됩니다.
          value: org1peer1
        - name: CORE_PEER_ADDRESS # 동일한 ORG내의 다른 peer의 endpoint를 나타내는데 사용됩니다.
          value: blockchain-org1peer1:30110
        - name: CORE_PEER_LISTENADDRESS
          value: 0.0.0.0:30110
        - name: CORE_PEER_EVENTS_ADDRESS
          value: 0.0.0.0:30111
        - name: CORE_PEER_GOSSIP_BOOTSTRAP # 해당 Peer가 도달할 anchor peer의 주소.(동일한 조직!)
          value: blockchain-org1peer1:30110
        #Org 외부의 Peer에게 공개되는 endpoint 설정
        #해당 설정이 없으면 Peer는 다른 Org에 알려지지 않습니다.
        - name: CORE_PEER_GOSSIP_ORGLEADER
          value: "false"
        - name: CORE_PEER_GOSSIP_SKIPHANDSHAKE
          value: "true"
        - name: CORE_PEER_COMMITTER_ENABLED
          value: "true"
        - name: CORE_PEER_PROFILE_ENABLED
          value: "true"
        - name: CORE_VM_ENDPOINT
          value: unix:///host/var/run/docker.sock
        - name: CORE_PEER_LOCALMSPID # 로컬 MSP 설정
          value: Org1MSP
        - name: CORE_PEER_MSPCONFIGPATH
          value: /shared/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp/
        - name: CORE_LOGGING_LEVEL #로깅 레벨
          value: debug
        - name: CORE_LOGGING_PEER
          value: debug
        - name: CORE_LOGGING_CAUTHDSL
          value: debug
        - name: CORE_LOGGING_GOSSIP
          value: debug
        - name: CORE_LOGGING_LEDGER
          value: debug
        - name: CORE_LOGGING_MSP
          value: info
        - name: CORE_LOGGING_POLICIES
          value: debug
        - name: CORE_LOGGING_GRPC
          value: debug
        - name: CORE_PEER_TLS_ENABLED # 보안설정 (TLS) 사용 여부
          value: "false"
        - name: CORE_LEDGER_STATE_STATEDATABASE # StateDB 설정
          value: goleveldb
        - name: FABRIC_CFG_PATH # configtx.yaml 파일의 위치
          value: /etc/hyperledger/fabric/
        - name: ORDERER_URL
          value: blockchain-orderer:31010
        - name: GODEBUG
          value: "netdns=go"
        - name: CORE_VM_DOCKER_ATTACHSTDOUT
          value: "true"
        volumeMounts:
        - mountPath: /shared
          name: sharedvolume
        - mountPath: /host/var/run/docker.sock
          name: dockersocket

---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: blockchain-org1peer2
spec:
  replicas: 1
  template:
    metadata:
      labels:
        name: org1peer2
    spec:
      volumes:
      - name: sharedvolume
        persistentVolumeClaim:
          claimName: shared-pvc
      - name: dockersocket
        hostPath:
          path: /var/run/docker.sock

      containers:
      - name: org1peer2
        image: hyperledger/fabric-peer:x86_64-1.1.0
        command: ["sh", "-c", "sleep 1 && while [ ! -f /shared/status_configtxgen_complete ]; do echo Waiting for configtxgen; sleep 1; done; peer node start"]
        env:
        - name: CORE_PEER_ADDRESSAUTODETECT
          value: "true"
        - name: CORE_PEER_NETWORKID
          value: nid1
        - name: CORE_PEER_ID
          value: org1peer2
        - name: CORE_PEER_ADDRESS
          value: blockchain-org1peer2:30120
        - name: CORE_PEER_LISTENADDRESS
          value: 0.0.0.0:30120
        - name: CORE_PEER_EVENTS_ADDRESS
          value: 0.0.0.0:30121
        - name: CORE_PEER_GOSSIP_BOOTSTRAP
          value: blockchain-org1peer2:30120
        - name: CORE_PEER_GOSSIP_ORGLEADER
          value: "false"
        - name: CORE_PEER_GOSSIP_SKIPHANDSHAKE
          value: "true"
        - name: CORE_PEER_COMMITTER_ENABLED
          value: "true"
        - name: CORE_PEER_PROFILE_ENABLED
          value: "true"
        - name: CORE_VM_ENDPOINT
          value: unix:///host/var/run/docker.sock
        - name: CORE_PEER_LOCALMSPID
          value: Org1MSP
        - name: CORE_PEER_MSPCONFIGPATH
          value: /shared/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp/
        - name: CORE_LOGGING_LEVEL
          value: debug
        - name: CORE_LOGGING_PEER
          value: debug
        - name: CORE_LOGGING_CAUTHDSL
          value: debug
        - name: CORE_LOGGING_GOSSIP
          value: debug
        - name: CORE_LOGGING_LEDGER
          value: debug
        - name: CORE_LOGGING_MSP
          value: info
        - name: CORE_LOGGING_POLICIES
          value: debug
        - name: CORE_LOGGING_GRPC
          value: debug
        - name: CORE_PEER_TLS_ENABLED
          value: "false"
        - name: CORE_LEDGER_STATE_STATEDATABASE
          value: goleveldb
        - name: FABRIC_CFG_PATH
          value: /etc/hyperledger/fabric/
        - name: ORDERER_URL
          value: blockchain-orderer:31010
        - name: GODEBUG
          value: "netdns=go"
        - name: CORE_VM_DOCKER_ATTACHSTDOUT
          value: "true"
        volumeMounts:
        - mountPath: /shared
          name: sharedvolume
        - mountPath: /host/var/run/docker.sock
          name: dockersocket

---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: blockchain-org2peer1
spec:
  replicas: 1
  template:
    metadata:
      labels:
        name: org2peer1
    spec:
      volumes:
      - name: sharedvolume
        persistentVolumeClaim:
          claimName: shared-pvc
      - name: dockersocket
        hostPath:
          path: /var/run/docker.sock

      containers:
      - name: org2peer1
        image: hyperledger/fabric-peer:x86_64-1.1.0
        command: ["sh", "-c", "sleep 1 && while [ ! -f /shared/status_configtxgen_complete ]; do echo Waiting for configtxgen; sleep 1; done;  peer node start"]
        env:
        - name: CORE_PEER_ADDRESSAUTODETECT
          value: "true"
        - name: CORE_PEER_ID
          value: org2peer1
        - name: CORE_PEER_NETWORKID
          value: nid1
        - name: CORE_PEER_ADDRESS
          value: blockchain-org2peer1:30210
        - name: CORE_PEER_LISTENADDRESS
          value: 0.0.0.0:30210
        - name: CORE_PEER_EVENTS_ADDRESS
          value: 0.0.0.0:30211
        - name: CORE_PEER_GOSSIP_BOOTSTRAP
          value: blockchain-org2peer1:30210
        - name: CORE_PEER_GOSSIP_ORGLEADER
          value: "false"
        - name: CORE_PEER_GOSSIP_SKIPHANDSHAKE
          value: "true"
        - name: CORE_PEER_COMMITTER_ENABLED
          value: "true"
        - name: CORE_PEER_PROFILE_ENABLED
          value: "true"
        - name: CORE_VM_ENDPOINT
          value: unix:///host/var/run/docker.sock
        - name: CORE_PEER_LOCALMSPID
          value: Org2MSP
        - name: CORE_PEER_MSPCONFIGPATH
          value: /shared/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/msp/
        - name: CORE_LOGGING_LEVEL
          value: debug
        - name: CORE_LOGGING_PEER
          value: debug
        - name: CORE_LOGGING_CAUTHDSL
          value: debug
        - name: CORE_LOGGING_GOSSIP
          value: debug
        - name: CORE_LOGGING_LEDGER
          value: debug
        - name: CORE_LOGGING_MSP
          value: debug
        - name: CORE_LOGGING_POLICIES
          value: debug
        - name: CORE_LOGGING_GRPC
          value: debug
        - name: CORE_PEER_TLS_ENABLED
          value: "false"
        - name: CORE_LEDGER_STATE_STATEDATABASE
          value: goleveldb
        - name: FABRIC_CFG_PATH
          value: /etc/hyperledger/fabric/
        - name: ORDERER_URL
          value: blockchain-orderer:31010
        - name: GODEBUG
          value: "netdns=go"
        - name: CORE_VM_DOCKER_ATTACHSTDOUT
          value: "true"
        volumeMounts:
        - mountPath: /shared
          name: sharedvolume
        - mountPath: /host/var/run/docker.sock
          name: dockersocket

---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: blockchain-org2peer2
spec:
  replicas: 1
  template:
    metadata:
      labels:
        name: org2peer2
    spec:
      volumes:
      - name: sharedvolume
        persistentVolumeClaim:
          claimName: shared-pvc
      - name: dockersocket
        hostPath:
          path: /var/run/docker.sock

      containers:
      - name: org2peer2
        image: hyperledger/fabric-peer:x86_64-1.1.0
        command: ["sh", "-c", "sleep 1 && while [ ! -f /shared/status_configtxgen_complete ]; do echo Waiting for configtxgen; sleep 1; done;  peer node start"]
        env:
        - name: CORE_PEER_ADDRESSAUTODETECT
          value: "true"
        - name: CORE_PEER_ID
          value: org2peer2
        - name: CORE_PEER_NETWORKID
          value: nid1
        - name: CORE_PEER_ADDRESS
          value: blockchain-org2peer2:30220
        - name: CORE_PEER_LISTENADDRESS
          value: 0.0.0.0:30220
        - name: CORE_PEER_EVENTS_ADDRESS
          value: 0.0.0.0:30221
        - name: CORE_PEER_GOSSIP_BOOTSTRAP
          value: blockchain-org2peer2:30220
        - name: CORE_PEER_GOSSIP_ORGLEADER
          value: "false"
        - name: CORE_PEER_GOSSIP_SKIPHANDSHAKE
          value: "true"
        - name: CORE_PEER_COMMITTER_ENABLED
          value: "true"
        - name: CORE_PEER_PROFILE_ENABLED
          value: "true"
        - name: CORE_VM_ENDPOINT
          value: unix:///host/var/run/docker.sock
        - name: CORE_PEER_LOCALMSPID
          value: Org2MSP
        - name: CORE_PEER_MSPCONFIGPATH
          value: /shared/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/msp/
        - name: CORE_LOGGING_LEVEL
          value: debug
        - name: CORE_LOGGING_PEER
          value: debug
        - name: CORE_LOGGING_CAUTHDSL
          value: debug
        - name: CORE_LOGGING_GOSSIP
          value: debug
        - name: CORE_LOGGING_LEDGER
          value: debug
        - name: CORE_LOGGING_MSP
          value: debug
        - name: CORE_LOGGING_POLICIES
          value: debug
        - name: CORE_LOGGING_GRPC
          value: debug
        - name: CORE_PEER_TLS_ENABLED
          value: "false"
        - name: CORE_LEDGER_STATE_STATEDATABASE
          value: goleveldb
        - name: FABRIC_CFG_PATH
          value: /etc/hyperledger/fabric/
        - name: ORDERER_URL
          value: blockchain-orderer:31010
        - name: GODEBUG
          value: "netdns=go"
        - name: CORE_VM_DOCKER_ATTACHSTDOUT
          value: "true"
        volumeMounts:
        - mountPath: /shared
          name: sharedvolume
        - mountPath: /host/var/run/docker.sock
          name: dockersocket

---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: blockchain-org3peer1
spec:
  replicas: 1
  template:
    metadata:
      labels:
        name: org3peer1
    spec:
      volumes:
      - name: sharedvolume
        persistentVolumeClaim:
          claimName: shared-pvc
      - name: dockersocket
        hostPath:
          path: /var/run/docker.sock

      containers:
      - name: org3peer1
        image: hyperledger/fabric-peer:x86_64-1.1.0
        command: ["sh", "-c", "sleep 1 && while [ ! -f /shared/status_configtxgen_complete ]; do echo Waiting for configtxgen; sleep 1; done;  peer node start"]
        env:
        - name: CORE_PEER_ADDRESSAUTODETECT
          value: "true"
        - name: CORE_PEER_ID
          value: org3peer1
        - name: CORE_PEER_NETWORKID
          value: nid1
        - name: CORE_PEER_ADDRESS
          value: blockchain-org3peer1:30310
        - name: CORE_PEER_LISTENADDRESS
          value: 0.0.0.0:30310
        - name: CORE_PEER_EVENTS_ADDRESS
          value: 0.0.0.0:30311
        - name: CORE_PEER_GOSSIP_BOOTSTRAP
          value: blockchain-org3peer1:30310
        - name: CORE_PEER_GOSSIP_ORGLEADER
          value: "false"
        - name: CORE_PEER_GOSSIP_SKIPHANDSHAKE
          value: "true"
        - name: CORE_PEER_COMMITTER_ENABLED
          value: "true"
        - name: CORE_PEER_PROFILE_ENABLED
          value: "true"
        - name: CORE_VM_ENDPOINT
          value: unix:///host/var/run/docker.sock
        - name: CORE_PEER_LOCALMSPID
          value: Org3MSP
        - name: CORE_PEER_MSPCONFIGPATH
          value: /shared/crypto-config/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/msp/
        - name: CORE_LOGGING_LEVEL
          value: debug
        - name: CORE_LOGGING_PEER
          value: debug
        - name: CORE_LOGGING_CAUTHDSL
          value: debug
        - name: CORE_LOGGING_GOSSIP
          value: debug
        - name: CORE_LOGGING_LEDGER
          value: debug
        - name: CORE_LOGGING_MSP
          value: debug
        - name: CORE_LOGGING_POLICIES
          value: debug
        - name: CORE_LOGGING_GRPC
          value: debug
        - name: CORE_PEER_TLS_ENABLED
          value: "false"
        - name: CORE_LEDGER_STATE_STATEDATABASE
          value: goleveldb
        - name: FABRIC_CFG_PATH
          value: /etc/hyperledger/fabric/
        - name: ORDERER_URL
          value: blockchain-orderer:31010
        - name: GODEBUG
          value: "netdns=go"
        - name: CORE_VM_DOCKER_ATTACHSTDOUT
          value: "true"
        volumeMounts:
        - mountPath: /shared
          name: sharedvolume
        - mountPath: /host/var/run/docker.sock
          name: dockersocket

---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: blockchain-org3peer2
spec:
  replicas: 1
  template:
    metadata:
      labels:
        name: org3peer2
    spec:
      volumes:
      - name: sharedvolume
        persistentVolumeClaim:
          claimName: shared-pvc
      - name: dockersocket
        hostPath:
          path: /var/run/docker.sock

      containers:
      - name: org3peer2
        image: hyperledger/fabric-peer:x86_64-1.1.0
        command: ["sh", "-c", "sleep 1 && while [ ! -f /shared/status_configtxgen_complete ]; do echo Waiting for configtxgen; sleep 1; done;  peer node start"]
        env:
        - name: CORE_PEER_ADDRESSAUTODETECT
          value: "true"
        - name: CORE_PEER_ID
          value: org3peer2
        - name: CORE_PEER_NETWORKID
          value: nid1
        - name: CORE_PEER_ADDRESS
          value: blockchain-org3peer2:30320
        - name: CORE_PEER_LISTENADDRESS
          value: 0.0.0.0:30320
        - name: CORE_PEER_EVENTS_ADDRESS
          value: 0.0.0.0:30321
        - name: CORE_PEER_GOSSIP_BOOTSTRAP
          value: blockchain-org3peer2:30320
        - name: CORE_PEER_GOSSIP_ORGLEADER
          value: "false"
        - name: CORE_PEER_GOSSIP_SKIPHANDSHAKE
          value: "true"
        - name: CORE_PEER_COMMITTER_ENABLED
          value: "true"
        - name: CORE_PEER_PROFILE_ENABLED
          value: "true"
        - name: CORE_VM_ENDPOINT
          value: unix:///host/var/run/docker.sock
        - name: CORE_PEER_LOCALMSPID
          value: Org3MSP
        - name: CORE_PEER_MSPCONFIGPATH
          value: /shared/crypto-config/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/msp/
        - name: CORE_LOGGING_LEVEL
          value: debug
        - name: CORE_LOGGING_PEER
          value: debug
        - name: CORE_LOGGING_CAUTHDSL
          value: debug
        - name: CORE_LOGGING_GOSSIP
          value: debug
        - name: CORE_LOGGING_LEDGER
          value: debug
        - name: CORE_LOGGING_MSP
          value: debug
        - name: CORE_LOGGING_POLICIES
          value: debug
        - name: CORE_LOGGING_GRPC
          value: debug
        - name: CORE_PEER_TLS_ENABLED
          value: "false"
        - name: CORE_LEDGER_STATE_STATEDATABASE
          value: goleveldb
        - name: FABRIC_CFG_PATH
          value: /etc/hyperledger/fabric/
        - name: ORDERER_URL
          value: blockchain-orderer:31010
        - name: GODEBUG
          value: "netdns=go"
        - name: CORE_VM_DOCKER_ATTACHSTDOUT
          value: "true"
        volumeMounts:
        - mountPath: /shared
          name: sharedvolume
        - mountPath: /host/var/run/docker.sock
          name: dockersocket

---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: blockchain-org4peer1
spec:
  replicas: 1
  template:
    metadata:
      labels:
        name: org4peer1
    spec:
      volumes:
      - name: sharedvolume
        persistentVolumeClaim:
          claimName: shared-pvc
      - name: dockersocket
        hostPath:
          path: /var/run/docker.sock

      containers:
      - name: org4peer1
        image: hyperledger/fabric-peer:x86_64-1.1.0
        command: ["sh", "-c", "sleep 1 && while [ ! -f /shared/status_configtxgen_complete ]; do echo Waiting for configtxgen; sleep 1; done;  peer node start"]
        env:
        - name: CORE_PEER_ADDRESSAUTODETECT
          value: "true"
        - name: CORE_PEER_ID
          value: org4peer1
        - name: CORE_PEER_NETWORKID
          value: nid1
        - name: CORE_PEER_ADDRESS
          value: blockchain-org4peer1:30410
        - name: CORE_PEER_LISTENADDRESS
          value: 0.0.0.0:30410
        - name: CORE_PEER_EVENTS_ADDRESS
          value: 0.0.0.0:30411
        - name: CORE_PEER_GOSSIP_BOOTSTRAP
          value: blockchain-org4peer1:30410
        - name: CORE_PEER_GOSSIP_ORGLEADER
          value: "false"
        - name: CORE_PEER_GOSSIP_SKIPHANDSHAKE
          value: "true"
        - name: CORE_PEER_COMMITTER_ENABLED
          value: "true"
        - name: CORE_PEER_PROFILE_ENABLED
          value: "true"
        - name: CORE_VM_ENDPOINT
          value: unix:///host/var/run/docker.sock
        - name: CORE_PEER_LOCALMSPID
          value: Org4MSP
        - name: CORE_PEER_MSPCONFIGPATH
          value: /shared/crypto-config/peerOrganizations/org4.example.com/peers/peer0.org4.example.com/msp/
        - name: CORE_LOGGING_LEVEL
          value: debug
        - name: CORE_LOGGING_PEER
          value: debug
        - name: CORE_LOGGING_CAUTHDSL
          value: debug
        - name: CORE_LOGGING_GOSSIP
          value: debug
        - name: CORE_LOGGING_LEDGER
          value: debug
        - name: CORE_LOGGING_MSP
          value: debug
        - name: CORE_LOGGING_POLICIES
          value: debug
        - name: CORE_LOGGING_GRPC
          value: debug
        - name: CORE_PEER_TLS_ENABLED
          value: "false"
        - name: CORE_LEDGER_STATE_STATEDATABASE
          value: goleveldb
        - name: FABRIC_CFG_PATH
          value: /etc/hyperledger/fabric/
        - name: ORDERER_URL
          value: blockchain-orderer:31010
        - name: GODEBUG
          value: "netdns=go"
        - name: CORE_VM_DOCKER_ATTACHSTDOUT
          value: "true"
        volumeMounts:
        - mountPath: /shared
          name: sharedvolume
        - mountPath: /host/var/run/docker.sock
          name: dockersocket

---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: blockchain-org4peer2
spec:
  replicas: 1
  template:
    metadata:
      labels:
        name: org4peer2
    spec:
      volumes:
      - name: sharedvolume
        persistentVolumeClaim:
          claimName: shared-pvc
      - name: dockersocket
        hostPath:
          path: /var/run/docker.sock

      containers:
      - name: org4peer2
        image: hyperledger/fabric-peer:x86_64-1.1.0
        command: ["sh", "-c", "sleep 1 && while [ ! -f /shared/status_configtxgen_complete ]; do echo Waiting for configtxgen; sleep 1; done;  peer node start"]
        env:
        - name: CORE_PEER_ADDRESSAUTODETECT
          value: "true"
        - name: CORE_PEER_ID
          value: org4peer2
        - name: CORE_PEER_NETWORKID
          value: nid1
        - name: CORE_PEER_ADDRESS
          value: blockchain-org4peer2:30420
        - name: CORE_PEER_LISTENADDRESS
          value: 0.0.0.0:30420
        - name: CORE_PEER_EVENTS_ADDRESS
          value: 0.0.0.0:30421
        - name: CORE_PEER_GOSSIP_BOOTSTRAP
          value: blockchain-org4peer2:30420
        - name: CORE_PEER_GOSSIP_ORGLEADER
          value: "false"
        - name: CORE_PEER_GOSSIP_SKIPHANDSHAKE
          value: "true"
        - name: CORE_PEER_COMMITTER_ENABLED
          value: "true"
        - name: CORE_PEER_PROFILE_ENABLED
          value: "true"
        - name: CORE_VM_ENDPOINT
          value: unix:///host/var/run/docker.sock
        - name: CORE_PEER_LOCALMSPID
          value: Org4MSP
        - name: CORE_PEER_MSPCONFIGPATH
          value: /shared/crypto-config/peerOrganizations/org4.example.com/peers/peer0.org4.example.com/msp/
        - name: CORE_LOGGING_LEVEL
          value: debug
        - name: CORE_LOGGING_PEER
          value: debug
        - name: CORE_LOGGING_CAUTHDSL
          value: debug
        - name: CORE_LOGGING_GOSSIP
          value: debug
        - name: CORE_LOGGING_LEDGER
          value: debug
        - name: CORE_LOGGING_MSP
          value: debug
        - name: CORE_LOGGING_POLICIES
          value: debug
        - name: CORE_LOGGING_GRPC
          value: debug
        - name: CORE_PEER_TLS_ENABLED
          value: "false"
        - name: CORE_LEDGER_STATE_STATEDATABASE
          value: goleveldb
        - name: FABRIC_CFG_PATH
          value: /etc/hyperledger/fabric/
        - name: ORDERER_URL
          value: blockchain-orderer:31010
        - name: GODEBUG
          value: "netdns=go"
        - name: CORE_VM_DOCKER_ATTACHSTDOUT
          value: "true"
        volumeMounts:
        - mountPath: /shared
          name: sharedvolume
        - mountPath: /host/var/run/docker.sock
          name: dockersocket

---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: blockchain-org5peer1
spec:
  replicas: 1
  template:
    metadata:
      labels:
        name: org5peer1
    spec:
      volumes:
      - name: sharedvolume
        persistentVolumeClaim:
          claimName: shared-pvc
      - name: dockersocket
        hostPath:
          path: /var/run/docker.sock

      containers:
      - name: org5peer1
        image: hyperledger/fabric-peer:x86_64-1.1.0
        command: ["sh", "-c", "sleep 1 && while [ ! -f /shared/status_configtxgen_complete ]; do echo Waiting for configtxgen; sleep 1; done;  peer node start"]
        env:
        - name: CORE_PEER_ADDRESSAUTODETECT
          value: "true"
        - name: CORE_PEER_ID
          value: org5peer1
        - name: CORE_PEER_NETWORKID
          value: nid1
        - name: CORE_PEER_ADDRESS
          value: blockchain-org5peer1:30510
        - name: CORE_PEER_LISTENADDRESS
          value: 0.0.0.0:30510
        - name: CORE_PEER_EVENTS_ADDRESS
          value: 0.0.0.0:30511
        - name: CORE_PEER_GOSSIP_BOOTSTRAP
          value: blockchain-org5peer1:30510
        - name: CORE_PEER_GOSSIP_ORGLEADER
          value: "false"
        - name: CORE_PEER_GOSSIP_SKIPHANDSHAKE
          value: "true"
        - name: CORE_PEER_COMMITTER_ENABLED
          value: "true"
        - name: CORE_PEER_PROFILE_ENABLED
          value: "true"
        - name: CORE_VM_ENDPOINT
          value: unix:///host/var/run/docker.sock
        - name: CORE_PEER_LOCALMSPID
          value: Org5MSP
        - name: CORE_PEER_MSPCONFIGPATH
          value: /shared/crypto-config/peerOrganizations/org5.example.com/peers/peer0.org5.example.com/msp/
        - name: CORE_LOGGING_LEVEL
          value: debug
        - name: CORE_LOGGING_PEER
          value: debug
        - name: CORE_LOGGING_CAUTHDSL
          value: debug
        - name: CORE_LOGGING_GOSSIP
          value: debug
        - name: CORE_LOGGING_LEDGER
          value: debug
        - name: CORE_LOGGING_MSP
          value: debug
        - name: CORE_LOGGING_POLICIES
          value: debug
        - name: CORE_LOGGING_GRPC
          value: debug
        - name: CORE_PEER_TLS_ENABLED
          value: "false"
        - name: CORE_LEDGER_STATE_STATEDATABASE
          value: goleveldb
        - name: FABRIC_CFG_PATH
          value: /etc/hyperledger/fabric/
        - name: ORDERER_URL
          value: blockchain-orderer:31010
        - name: GODEBUG
          value: "netdns=go"
        - name: CORE_VM_DOCKER_ATTACHSTDOUT
          value: "true"
        volumeMounts:
        - mountPath: /shared
          name: sharedvolume
        - mountPath: /host/var/run/docker.sock
          name: dockersocket

---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: blockchain-org5peer2
spec:
  replicas: 1
  template:
    metadata:
      labels:
        name: org5peer2
    spec:
      volumes:
      - name: sharedvolume
        persistentVolumeClaim:
          claimName: shared-pvc
      - name: dockersocket
        hostPath:
          path: /var/run/docker.sock

      containers:
      - name: org5peer2
        image: hyperledger/fabric-peer:x86_64-1.1.0
        command: ["sh", "-c", "sleep 1 && while [ ! -f /shared/status_configtxgen_complete ]; do echo Waiting for configtxgen; sleep 1; done;  peer node start"]
        env:
        - name: CORE_PEER_ADDRESSAUTODETECT
          value: "true"
        - name: CORE_PEER_ID
          value: org5peer2
        - name: CORE_PEER_NETWORKID
          value: nid1
        - name: CORE_PEER_ADDRESS
          value: blockchain-org5peer2:30520
        - name: CORE_PEER_LISTENADDRESS
          value: 0.0.0.0:30520
        - name: CORE_PEER_EVENTS_ADDRESS
          value: 0.0.0.0:30521
        - name: CORE_PEER_GOSSIP_BOOTSTRAP
          value: blockchain-org5peer2:30520
        - name: CORE_PEER_GOSSIP_ORGLEADER
          value: "false"
        - name: CORE_PEER_GOSSIP_SKIPHANDSHAKE
          value: "true"
        - name: CORE_PEER_COMMITTER_ENABLED
          value: "true"
        - name: CORE_PEER_PROFILE_ENABLED
          value: "true"
        - name: CORE_VM_ENDPOINT
          value: unix:///host/var/run/docker.sock
        - name: CORE_PEER_LOCALMSPID
          value: Org5MSP
        - name: CORE_PEER_MSPCONFIGPATH
          value: /shared/crypto-config/peerOrganizations/org5.example.com/peers/peer0.org5.example.com/msp/
        - name: CORE_LOGGING_LEVEL
          value: debug
        - name: CORE_LOGGING_PEER
          value: debug
        - name: CORE_LOGGING_CAUTHDSL
          value: debug
        - name: CORE_LOGGING_GOSSIP
          value: debug
        - name: CORE_LOGGING_LEDGER
          value: debug
        - name: CORE_LOGGING_MSP
          value: debug
        - name: CORE_LOGGING_POLICIES
          value: debug
        - name: CORE_LOGGING_GRPC
          value: debug
        - name: CORE_PEER_TLS_ENABLED
          value: "false"
        - name: CORE_LEDGER_STATE_STATEDATABASE
          value: goleveldb
        - name: FABRIC_CFG_PATH
          value: /etc/hyperledger/fabric/
        - name: ORDERER_URL
          value: blockchain-orderer:31010
        - name: GODEBUG
          value: "netdns=go"
        - name: CORE_VM_DOCKER_ATTACHSTDOUT
          value: "true"
        volumeMounts:
        - mountPath: /shared
          name: sharedvolume
        - mountPath: /host/var/run/docker.sock
          name: dockersocket

---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: blockchain-org6peer1
spec:
  replicas: 1
  template:
    metadata:
      labels:
        name: org6peer1
    spec:
      volumes:
      - name: sharedvolume
        persistentVolumeClaim:
          claimName: shared-pvc
      - name: dockersocket
        hostPath:
          path: /var/run/docker.sock

      containers:
      - name: org6peer1
        image: hyperledger/fabric-peer:x86_64-1.1.0
        command: ["sh", "-c", "sleep 1 && while [ ! -f /shared/status_configtxgen_complete ]; do echo Waiting for configtxgen; sleep 1; done;  peer node start"]
        env:
        - name: CORE_PEER_ADDRESSAUTODETECT
          value: "true"
        - name: CORE_PEER_ID
          value: org6peer1
        - name: CORE_PEER_NETWORKID
          value: nid1
        - name: CORE_PEER_ADDRESS
          value: blockchain-org6peer1:30610
        - name: CORE_PEER_LISTENADDRESS
          value: 0.0.0.0:30610
        - name: CORE_PEER_EVENTS_ADDRESS
          value: 0.0.0.0:30611
        - name: CORE_PEER_GOSSIP_BOOTSTRAP
          value: blockchain-org6peer1:30610
        - name: CORE_PEER_GOSSIP_ORGLEADER
          value: "false"
        - name: CORE_PEER_GOSSIP_SKIPHANDSHAKE
          value: "true"
        - name: CORE_PEER_COMMITTER_ENABLED
          value: "true"
        - name: CORE_PEER_PROFILE_ENABLED
          value: "true"
        - name: CORE_VM_ENDPOINT
          value: unix:///host/var/run/docker.sock
        - name: CORE_PEER_LOCALMSPID
          value: Org6MSP
        - name: CORE_PEER_MSPCONFIGPATH
          value: /shared/crypto-config/peerOrganizations/org6.example.com/peers/peer0.org6.example.com/msp/
        - name: CORE_LOGGING_LEVEL
          value: debug
        - name: CORE_LOGGING_PEER
          value: debug
        - name: CORE_LOGGING_CAUTHDSL
          value: debug
        - name: CORE_LOGGING_GOSSIP
          value: debug
        - name: CORE_LOGGING_LEDGER
          value: debug
        - name: CORE_LOGGING_MSP
          value: debug
        - name: CORE_LOGGING_POLICIES
          value: debug
        - name: CORE_LOGGING_GRPC
          value: debug
        - name: CORE_PEER_TLS_ENABLED
          value: "false"
        - name: CORE_LEDGER_STATE_STATEDATABASE
          value: goleveldb
        - name: FABRIC_CFG_PATH
          value: /etc/hyperledger/fabric/
        - name: ORDERER_URL
          value: blockchain-orderer:31010
        - name: GODEBUG
          value: "netdns=go"
        - name: CORE_VM_DOCKER_ATTACHSTDOUT
          value: "true"
        volumeMounts:
        - mountPath: /shared
          name: sharedvolume
        - mountPath: /host/var/run/docker.sock
          name: dockersocket

---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: blockchain-org6peer2
spec:
  replicas: 1
  template:
    metadata:
      labels:
        name: org6peer2
    spec:
      volumes:
      - name: sharedvolume
        persistentVolumeClaim:
          claimName: shared-pvc
      - name: dockersocket
        hostPath:
          path: /var/run/docker.sock

      containers:
      - name: org6peer2
        image: hyperledger/fabric-peer:x86_64-1.1.0
        command: ["sh", "-c", "sleep 1 && while [ ! -f /shared/status_configtxgen_complete ]; do echo Waiting for configtxgen; sleep 1; done;  peer node start"]
        env:
        - name: CORE_PEER_ADDRESSAUTODETECT
          value: "true"
        - name: CORE_PEER_ID
          value: org6peer2
        - name: CORE_PEER_NETWORKID
          value: nid1
        - name: CORE_PEER_ADDRESS
          value: blockchain-org6peer2:30620
        - name: CORE_PEER_LISTENADDRESS
          value: 0.0.0.0:30620
        - name: CORE_PEER_EVENTS_ADDRESS
          value: 0.0.0.0:30611
        - name: CORE_PEER_GOSSIP_BOOTSTRAP
          value: blockchain-org6peer2:30620
        - name: CORE_PEER_GOSSIP_ORGLEADER
          value: "false"
        - name: CORE_PEER_GOSSIP_SKIPHANDSHAKE
          value: "true"
        - name: CORE_PEER_COMMITTER_ENABLED
          value: "true"
        - name: CORE_PEER_PROFILE_ENABLED
          value: "true"
        - name: CORE_VM_ENDPOINT
          value: unix:///host/var/run/docker.sock
        - name: CORE_PEER_LOCALMSPID
          value: Org6MSP
        - name: CORE_PEER_MSPCONFIGPATH
          value: /shared/crypto-config/peerOrganizations/org6.example.com/peers/peer0.org6.example.com/msp/
        - name: CORE_LOGGING_LEVEL
          value: debug
        - name: CORE_LOGGING_PEER
          value: debug
        - name: CORE_LOGGING_CAUTHDSL
          value: debug
        - name: CORE_LOGGING_GOSSIP
          value: debug
        - name: CORE_LOGGING_LEDGER
          value: debug
        - name: CORE_LOGGING_MSP
          value: debug
        - name: CORE_LOGGING_POLICIES
          value: debug
        - name: CORE_LOGGING_GRPC
          value: debug
        - name: CORE_PEER_TLS_ENABLED
          value: "false"
        - name: CORE_LEDGER_STATE_STATEDATABASE
          value: goleveldb
        - name: FABRIC_CFG_PATH
          value: /etc/hyperledger/fabric/
        - name: ORDERER_URL
          value: blockchain-orderer:31010
        - name: GODEBUG
          value: "netdns=go"
        - name: CORE_VM_DOCKER_ATTACHSTDOUT
          value: "true"
        volumeMounts:
        - mountPath: /shared
          name: sharedvolume
        - mountPath: /host/var/run/docker.sock
          name: dockersocket

create_channel.yaml(configtx.yaml을 사용하여 채널 아티팩트를 생성 한 다음, 채널을 생성)

echo -e "\nCreating channel transaction artifact and a channel"
echo "Running: kubectl create -f ${KUBECONFIG_FOLDER}/create_channel.yaml"
kubectl create -f ${KUBECONFIG_FOLDER}/create_channel.yaml
---
apiVersion: batch/v1
kind: Job
metadata:
  name: createchannel
spec:
  backoffLimit: 1
  template:
    metadata:
      name: createchannel
    spec:
      restartPolicy: "Never"
      volumes:
      - name: sharedvolume
        persistentVolumeClaim:
          claimName: shared-pvc
      containers:
      - name: createchanneltx
        image: hyperledger/fabric-tools:x86_64-1.1.0
        imagePullPolicy: Always # imagePullPolicy는 Pod를 만들때 마다 매번 컨테이너 이미지를 확인해서 새 이미지를 사용하도록 하는 설정이다.  컨테이너 이미지는 한번 다운로드가 되면 노드(Node) 에 저장이 되어 있게 되고, 사용이 되지 않는 이미지 중에 오래된 이미지는 Kublet이 가비지 컬렉션 (Garbage collection) 정책에 따라 이미지를 삭제하게 되는데, 문제는 노드에 이미 다운되어 있는 이미지가 있을 경우 컨테이너 생성시 노드에 이미 다운로드 되어 있는 이미지를 사용한다. 컨테이너 리파지토리에 같은 이름으로 이미지를 업데이트 하거나 심지어 그 이미지를 삭제하더라도 노드에 이미지가 이미 다운로드 되어 있으면 다운로드된 이미지를 사용하기 때문에, 업데이트 부분이 반영이 안된다. 이를 방지하기 위해서 imagePullPolicy:Always로 해주면 컨테이너 생성시마다 이미지 리파지토리를 검사해서 새 이미지를 가지고 오기 때문에, 업데이트된 내용을 제대로 반영할 수 있다.
        command: ["sh", "-c", "cd /shared && pwd && ls && export FABRIC_CFG_PATH=$PWD && configtxgen -profile SixOrgsChannel -outputCreateChannelTx ${CHANNEL_NAME}.tx -channelID ${CHANNEL_NAME} && touch /shared/status_channeltx_complete "]
        env:
        - name: CHANNEL_NAME
          value: channel1
        - name: GODEBUG
          value: "netdns=go"
        volumeMounts:
        - mountPath: /shared
          name: sharedvolume

      - name: createchannel
        image: hyperledger/fabric-peer:x86_64-1.1.0
        imagePullPolicy: Always
        command: ["sh", "-c", "while [ ! -f /shared/status_channeltx_complete ]; do echo Waiting for channeltx; sleep 2; done; peer channel create -o ${ORDERER_URL} -c ${CHANNEL_NAME} -f /shared/${CHANNEL_NAME}.tx && rm /shared/status_channeltx_complete && touch /shared/status_channelcreate_complete"]
        env:
        - name: CHANNEL_NAME
          value: channel1
        - name: ORDERER_URL
          value: blockchain-orderer:31010
        - name: CORE_PEER_ADDRESSAUTODETECT
          value: "false"
        - name: CORE_PEER_NETWORKID
          value: nid1
        - name: CORE_PEER_LOCALMSPID #로컬 MSP 설정
          value: Org1MSP
        - name: CORE_PEER_MSPCONFIGPATH # 트랜잭션을 서명하기 위해 Peer의 인증서를 찾을 수 있는 경로.
          value: /shared/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp/
        - name: CORE_LOGGING_LEVEL
          value: debug
        - name: FABRIC_CFG_PATH # configtx.yaml 파일의 위치
          value: /etc/hyperledger/fabric
        - name: GODEBUG
          value: "netdns=go"
        volumeMounts:
        - mountPath: /shared
          name: sharedvolume

join_channel.yaml - 채널에 모든 피어 조인하기

echo "Running: kubectl create -f ${KUBECONFIG_FOLDER}/join_channel.yaml"
kubectl create -f ${KUBECONFIG_FOLDER}/join_channel.yaml
---
apiVersion: batch/v1
kind: Job
metadata:
  name: joinchannel
spec:
  backoffLimit: 1
  template:
    metadata:
      name: joinchannel
    spec:
      restartPolicy: "Never"
      volumes:
      - name: sharedvolume
        persistentVolumeClaim:
          claimName: shared-pvc
      containers:
      - name: joinchannel1
        image: hyperledger/fabric-peer:x86_64-1.1.0
        imagePullPolicy: Always
        command: ["sh", "-c", "peer channel fetch newest -o ${ORDERER_URL} -c ${CHANNEL_NAME} && peer channel join -b ${CHANNEL_NAME}_newest.block "]
        # peer channel fetch: 클라이언트에서 orderer로부터 블록을 가져올 수 있는 명령어, peer channel join: 채널 join
        env:
        - name: CHANNEL_NAME
          value: channel1
        - name: CORE_PEER_NETWORKID
          value: nid1
        - name: ORDERER_URL
          value: blockchain-orderer:31010
        - name: CORE_PEER_ADDRESS
          value: blockchain-org1peer1:30110
        - name: CORE_PEER_LOCALMSPID
          value: Org1MSP
        - name: CORE_PEER_MSPID
          value: Org1MSP
        - name: CORE_LOGGING_LEVEL
          value: debug
        - name: CORE_PEER_MSPCONFIGPATH
          value: /shared/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
        - name: FABRIC_CFG_PATH
          value: /etc/hyperledger/fabric
        - name: GODEBUG
          value: "netdns=go"
        volumeMounts:
        - mountPath: /shared
          name: sharedvolume

      - name: joinchannel1p2
        image: hyperledger/fabric-peer:x86_64-1.1.0
        imagePullPolicy: Always
        command: ["sh", "-c", "peer channel fetch newest -o ${ORDERER_URL} -c ${CHANNEL_NAME} && peer channel join -b ${CHANNEL_NAME}_newest.block "]
        env:
        - name: CHANNEL_NAME
          value: channel1
        - name: CORE_PEER_NETWORKID
          value: nid1
        - name: ORDERER_URL
          value: blockchain-orderer:31010
        - name: CORE_PEER_ADDRESS
          value: blockchain-org1peer2:30120
        - name: CORE_PEER_LOCALMSPID
          value: Org1MSP
        - name: CORE_PEER_MSPID
          value: Org1MSP
        - name: CORE_LOGGING_LEVEL
          value: debug
        - name: CORE_PEER_MSPCONFIGPATH
          value: /shared/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
        - name: FABRIC_CFG_PATH
          value: /etc/hyperledger/fabric
        - name: GODEBUG
          value: "netdns=go"
        volumeMounts:
        - mountPath: /shared
          name: sharedvolume

      - name: joinchannel2
        image: hyperledger/fabric-peer:x86_64-1.1.0
        imagePullPolicy: Always
        command: ["sh", "-c", "peer channel fetch newest -o ${ORDERER_URL} -c ${CHANNEL_NAME} && peer channel join -b ${CHANNEL_NAME}_newest.block "]
        env:
        - name: CHANNEL_NAME
          value: channel1
        - name: CORE_PEER_NETWORKID
          value: nid1
        - name: ORDERER_URL
          value: blockchain-orderer:31010
        - name: CORE_PEER_ADDRESS
          value: blockchain-org2peer1:30210
        - name: CORE_PEER_LOCALMSPID
          value: Org2MSP
        - name: CORE_PEER_MSPID
          value: Org2MSP
        - name: CORE_LOGGING_LEVEL
          value: debug
        - name: CORE_PEER_MSPCONFIGPATH
          value: /shared/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
        - name: FABRIC_CFG_PATH
          value: /etc/hyperledger/fabric
        - name: GODEBUG
          value: "netdns=go"
        volumeMounts:
        - mountPath: /shared
          name: sharedvolume

      - name: joinchannel2p2
        image: hyperledger/fabric-peer:x86_64-1.1.0
        imagePullPolicy: Always
        command: ["sh", "-c", "peer channel fetch newest -o ${ORDERER_URL} -c ${CHANNEL_NAME} && peer channel join -b ${CHANNEL_NAME}_newest.block "]
        env:
        - name: CHANNEL_NAME
          value: channel1
        - name: CORE_PEER_NETWORKID
          value: nid1
        - name: ORDERER_URL
          value: blockchain-orderer:31010
        - name: CORE_PEER_ADDRESS
          value: blockchain-org2peer2:30220
        - name: CORE_PEER_LOCALMSPID
          value: Org2MSP
        - name: CORE_PEER_MSPID
          value: Org2MSP
        - name: CORE_LOGGING_LEVEL
          value: debug
        - name: CORE_PEER_MSPCONFIGPATH
          value: /shared/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
        - name: FABRIC_CFG_PATH
          value: /etc/hyperledger/fabric
        - name: GODEBUG
          value: "netdns=go"
        volumeMounts:
        - mountPath: /shared
          name: sharedvolume

      - name: joinchannel3
        image: hyperledger/fabric-peer:x86_64-1.1.0
        imagePullPolicy: Always
        command: ["sh", "-c", "peer channel fetch newest -o ${ORDERER_URL} -c ${CHANNEL_NAME} && peer channel join -b ${CHANNEL_NAME}_newest.block "]
        env:
        - name: CHANNEL_NAME
          value: channel1
        - name: CORE_PEER_NETWORKID
          value: nid1
        - name: ORDERER_URL
          value: blockchain-orderer:31010
        - name: CORE_PEER_ADDRESS
          value: blockchain-org3peer1:30310
        - name: CORE_PEER_LOCALMSPID
          value: Org3MSP
        - name: CORE_PEER_MSPID
          value: Org3MSP
        - name: CORE_LOGGING_LEVEL
          value: debug
        - name: CORE_PEER_MSPCONFIGPATH
          value: /shared/crypto-config/peerOrganizations/org3.example.com/users/Admin@org3.example.com/msp
        - name: FABRIC_CFG_PATH
          value: /etc/hyperledger/fabric
        - name: GODEBUG
          value: "netdns=go"
        volumeMounts:
        - mountPath: /shared
          name: sharedvolume

      - name: joinchannel3p2
        image: hyperledger/fabric-peer:x86_64-1.1.0
        imagePullPolicy: Always
        command: ["sh", "-c", "peer channel fetch newest -o ${ORDERER_URL} -c ${CHANNEL_NAME} && peer channel join -b ${CHANNEL_NAME}_newest.block "]
        env:
        - name: CHANNEL_NAME
          value: channel1
        - name: CORE_PEER_NETWORKID
          value: nid1
        - name: ORDERER_URL
          value: blockchain-orderer:31010
        - name: CORE_PEER_ADDRESS
          value: blockchain-org3peer2:30320
        - name: CORE_PEER_LOCALMSPID
          value: Org3MSP
        - name: CORE_PEER_MSPID
          value: Org3MSP
        - name: CORE_LOGGING_LEVEL
          value: debug
        - name: CORE_PEER_MSPCONFIGPATH
          value: /shared/crypto-config/peerOrganizations/org3.example.com/users/Admin@org3.example.com/msp
        - name: FABRIC_CFG_PATH
          value: /etc/hyperledger/fabric
        - name: GODEBUG
          value: "netdns=go"
        volumeMounts:
        - mountPath: /shared
          name: sharedvolume

      - name: joinchannel4
        image: hyperledger/fabric-peer:x86_64-1.1.0
        imagePullPolicy: Always
        command: ["sh", "-c", "peer channel fetch newest -o ${ORDERER_URL} -c ${CHANNEL_NAME} && peer channel join -b ${CHANNEL_NAME}_newest.block "]
        env:
        - name: CHANNEL_NAME
          value: channel1
        - name: CORE_PEER_NETWORKID
          value: nid1
        - name: ORDERER_URL
          value: blockchain-orderer:31010
        - name: CORE_PEER_ADDRESS
          value: blockchain-org4peer1:30410
        - name: CORE_PEER_LOCALMSPID
          value: Org4MSP
        - name: CORE_PEER_MSPID
          value: Org4MSP
        - name: CORE_LOGGING_LEVEL
          value: debug
        - name: CORE_PEER_MSPCONFIGPATH
          value: /shared/crypto-config/peerOrganizations/org4.example.com/users/Admin@org4.example.com/msp
        - name: FABRIC_CFG_PATH
          value: /etc/hyperledger/fabric
        - name: GODEBUG
          value: "netdns=go"
        volumeMounts:
        - mountPath: /shared
          name: sharedvolume

      - name: joinchannel4p2
        image: hyperledger/fabric-peer:x86_64-1.1.0
        imagePullPolicy: Always
        command: ["sh", "-c", "peer channel fetch newest -o ${ORDERER_URL} -c ${CHANNEL_NAME} && peer channel join -b ${CHANNEL_NAME}_newest.block "]
        env:
        - name: CHANNEL_NAME
          value: channel1
        - name: CORE_PEER_NETWORKID
          value: nid1
        - name: ORDERER_URL
          value: blockchain-orderer:31010
        - name: CORE_PEER_ADDRESS
          value: blockchain-org4peer2:30420
        - name: CORE_PEER_LOCALMSPID
          value: Org4MSP
        - name: CORE_PEER_MSPID
          value: Org4MSP
        - name: CORE_LOGGING_LEVEL
          value: debug
        - name: CORE_PEER_MSPCONFIGPATH
          value: /shared/crypto-config/peerOrganizations/org4.example.com/users/Admin@org4.example.com/msp
        - name: FABRIC_CFG_PATH
          value: /etc/hyperledger/fabric
        - name: GODEBUG
          value: "netdns=go"
        volumeMounts:
        - mountPath: /shared
          name: sharedvolume

      - name: joinchannel5
        image: hyperledger/fabric-peer:x86_64-1.1.0
        imagePullPolicy: Always
        command: ["sh", "-c", "peer channel fetch newest -o ${ORDERER_URL} -c ${CHANNEL_NAME} && peer channel join -b ${CHANNEL_NAME}_newest.block "]
        env:
        - name: CHANNEL_NAME
          value: channel1
        - name: CORE_PEER_NETWORKID
          value: nid1
        - name: ORDERER_URL
          value: blockchain-orderer:31010
        - name: CORE_PEER_ADDRESS
          value: blockchain-org5peer1:30510
        - name: CORE_PEER_LOCALMSPID
          value: Org5MSP
        - name: CORE_PEER_MSPID
          value: Org5MSP
        - name: CORE_LOGGING_LEVEL
          value: debug
        - name: CORE_PEER_MSPCONFIGPATH
          value: /shared/crypto-config/peerOrganizations/org5.example.com/users/Admin@org5.example.com/msp
        - name: FABRIC_CFG_PATH
          value: /etc/hyperledger/fabric
        - name: GODEBUG
          value: "netdns=go"
        volumeMounts:
        - mountPath: /shared
          name: sharedvolume

      - name: joinchannel5p2
        image: hyperledger/fabric-peer:x86_64-1.1.0
        imagePullPolicy: Always
        command: ["sh", "-c", "peer channel fetch newest -o ${ORDERER_URL} -c ${CHANNEL_NAME} && peer channel join -b ${CHANNEL_NAME}_newest.block "]
        env:
        - name: CHANNEL_NAME
          value: channel1
        - name: CORE_PEER_NETWORKID
          value: nid1
        - name: ORDERER_URL
          value: blockchain-orderer:31010
        - name: CORE_PEER_ADDRESS
          value: blockchain-org5peer2:30520
        - name: CORE_PEER_LOCALMSPID
          value: Org5MSP
        - name: CORE_PEER_MSPID
          value: Org5MSP
        - name: CORE_LOGGING_LEVEL
          value: debug
        - name: CORE_PEER_MSPCONFIGPATH
          value: /shared/crypto-config/peerOrganizations/org5.example.com/users/Admin@org5.example.com/msp
        - name: FABRIC_CFG_PATH
          value: /etc/hyperledger/fabric
        - name: GODEBUG
          value: "netdns=go"
        volumeMounts:
        - mountPath: /shared
          name: sharedvolume

      - name: joinchannel6
        image: hyperledger/fabric-peer:x86_64-1.1.0
        imagePullPolicy: Always
        command: ["sh", "-c", "peer channel fetch newest -o ${ORDERER_URL} -c ${CHANNEL_NAME} && peer channel join -b ${CHANNEL_NAME}_newest.block "]
        env:
        - name: CHANNEL_NAME
          value: channel1
        - name: CORE_PEER_NETWORKID
          value: nid1
        - name: ORDERER_URL
          value: blockchain-orderer:31010
        - name: CORE_PEER_ADDRESS
          value: blockchain-org6peer1:30610
        - name: CORE_PEER_LOCALMSPID
          value: Org6MSP
        - name: CORE_PEER_MSPID
          value: Org6MSP
        - name: CORE_LOGGING_LEVEL
          value: debug
        - name: CORE_PEER_MSPCONFIGPATH
          value: /shared/crypto-config/peerOrganizations/org6.example.com/users/Admin@org6.example.com/msp
        - name: FABRIC_CFG_PATH
          value: /etc/hyperledger/fabric
        - name: GODEBUG
          value: "netdns=go"
        volumeMounts:
        - mountPath: /shared
          name: sharedvolume

      - name: joinchannel6p2
        image: hyperledger/fabric-peer:x86_64-1.1.0
        imagePullPolicy: Always
        command: ["sh", "-c", "peer channel fetch newest -o ${ORDERER_URL} -c ${CHANNEL_NAME} && peer channel join -b ${CHANNEL_NAME}_newest.block "]
        env:
        - name: CHANNEL_NAME
          value: channel1
        - name: CORE_PEER_NETWORKID
          value: nid1
        - name: ORDERER_URL
          value: blockchain-orderer:31010
        - name: CORE_PEER_ADDRESS
          value: blockchain-org6peer2:30620
        - name: CORE_PEER_LOCALMSPID
          value: Org6MSP
        - name: CORE_PEER_MSPID
          value: Org6MSP
        - name: CORE_LOGGING_LEVEL
          value: debug
        - name: CORE_PEER_MSPCONFIGPATH
          value: /shared/crypto-config/peerOrganizations/org6.example.com/users/Admin@org6.example.com/msp
        - name: FABRIC_CFG_PATH
          value: /etc/hyperledger/fabric
        - name: GODEBUG
          value: "netdns=go"
        volumeMounts:
        - mountPath: /shared
          name: sharedvolume

 

chaincode_install.yaml - 각각의 피어에 체인코드 설치

echo -e "\nCreating installchaincode job"
echo "Running: kubectl create -f ${KUBECONFIG_FOLDER}/chaincode_install.yaml"
kubectl create -f ${KUBECONFIG_FOLDER}/chaincode_install.yaml
---
apiVersion: batch/v1
kind: Job
metadata:
  name: chaincodeinstall
spec:
  backoffLimit: 1
  template:
    metadata:
      name: chaincodeinstall
    spec:
      restartPolicy: "Never"
      volumes:
      - name: sharedvolume
        persistentVolumeClaim:
          claimName: shared-pvc
      containers:
      - name: chaincodeinstall1
        image: hyperledger/fabric-tools:x86_64-1.1.0
        imagePullPolicy: Always
        command: ["sh", "-c", "echo $GOPATH; cp -r /shared/artifacts/chaincode $GOPATH/src/; ls $GOPATH/src; peer chaincode install -n ${CHAINCODE_NAME} -v ${CHAINCODE_VERSION} -p chaincode_example02/"]
        # peer chaincode install: 체인코드 설치
        env:
        - name: CHAINCODE_NAME
          value: "cc"
        - name: CHAINCODE_VERSION
          value: "1.0"
        - name: FABRIC_CFG_PATH
          value: /etc/hyperledger/fabric
        - name: CORE_PEER_MSPCONFIGPATH
          value: /shared/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
        - name: CORE_PEER_LOCALMSPID
          value: Org1MSP
        - name: CORE_PEER_ADDRESS
          value: blockchain-org1peer1:30110
        - name: GODEBUG
          value: "netdns=go"
        volumeMounts:
        - mountPath: /shared
          name: sharedvolume

      - name: chaincodeinstall1p2
        image: hyperledger/fabric-tools:x86_64-1.1.0
        imagePullPolicy: Always
        command: ["sh", "-c", "echo $GOPATH; cp -r /shared/artifacts/chaincode $GOPATH/src/; ls $GOPATH/src; peer chaincode install -n ${CHAINCODE_NAME} -v ${CHAINCODE_VERSION} -p chaincode_example02/"]
        env:
        - name: CHAINCODE_NAME
          value: "cc"
        - name: CHAINCODE_VERSION
          value: "1.0"
        - name: FABRIC_CFG_PATH
          value: /etc/hyperledger/fabric
        - name: CORE_PEER_MSPCONFIGPATH
          value: /shared/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
        - name: CORE_PEER_LOCALMSPID
          value: Org1MSP
        - name: CORE_PEER_ADDRESS
          value: blockchain-org1peer2:30120
        - name: GODEBUG
          value: "netdns=go"
        volumeMounts:
        - mountPath: /shared
          name: sharedvolume

      - name: chaincodeinstall2
        image: hyperledger/fabric-tools:x86_64-1.1.0
        imagePullPolicy: Always
        command: ["sh", "-c", "echo $GOPATH; cp -r /shared/artifacts/chaincode $GOPATH/src/; ls $GOPATH/src; peer chaincode install -n ${CHAINCODE_NAME} -v ${CHAINCODE_VERSION} -p chaincode_example02/"]
        env:
        - name: CHAINCODE_NAME
          value: "cc"
        - name: CHAINCODE_VERSION
          value: "1.0"
        - name: FABRIC_CFG_PATH
          value: /etc/hyperledger/fabric
        - name: CORE_PEER_MSPCONFIGPATH
          value: /shared/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
        - name: CORE_PEER_LOCALMSPID
          value: Org2MSP
        - name: CORE_PEER_ADDRESS
          value: blockchain-org2peer1:30210
        - name: GODEBUG
          value: "netdns=go"
        volumeMounts:
        - mountPath: /shared
          name: sharedvolume

      - name: chaincodeinstall2p2
        image: hyperledger/fabric-tools:x86_64-1.1.0
        imagePullPolicy: Always
        command: ["sh", "-c", "echo $GOPATH; cp -r /shared/artifacts/chaincode $GOPATH/src/; ls $GOPATH/src; peer chaincode install -n ${CHAINCODE_NAME} -v ${CHAINCODE_VERSION} -p chaincode_example02/"]
        env:
        - name: CHAINCODE_NAME
          value: "cc"
        - name: CHAINCODE_VERSION
          value: "1.0"
        - name: FABRIC_CFG_PATH
          value: /etc/hyperledger/fabric
        - name: CORE_PEER_MSPCONFIGPATH
          value: /shared/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
        - name: CORE_PEER_LOCALMSPID
          value: Org2MSP
        - name: CORE_PEER_ADDRESS
          value: blockchain-org2peer2:30220
        - name: GODEBUG
          value: "netdns=go"
        volumeMounts:
        - mountPath: /shared
          name: sharedvolume

      - name: chaincodeinstall3
        image: hyperledger/fabric-tools:x86_64-1.1.0
        imagePullPolicy: Always
        command: ["sh", "-c", "echo $GOPATH; cp -r /shared/artifacts/chaincode $GOPATH/src/; ls $GOPATH/src; peer chaincode install -n ${CHAINCODE_NAME} -v ${CHAINCODE_VERSION} -p chaincode_example02/"]
        env:
        - name: CHAINCODE_NAME
          value: "cc"
        - name: CHAINCODE_VERSION
          value: "1.0"
        - name: FABRIC_CFG_PATH
          value: /etc/hyperledger/fabric
        - name: CORE_PEER_MSPCONFIGPATH
          value: /shared/crypto-config/peerOrganizations/org3.example.com/users/Admin@org3.example.com/msp
        - name: CORE_PEER_LOCALMSPID
          value: Org3MSP
        - name: CORE_PEER_ADDRESS
          value: blockchain-org3peer1:30310
        - name: GODEBUG
          value: "netdns=go"
        volumeMounts:
        - mountPath: /shared
          name: sharedvolume

      - name: chaincodeinstall3p2
        image: hyperledger/fabric-tools:x86_64-1.1.0
        imagePullPolicy: Always
        command: ["sh", "-c", "echo $GOPATH; cp -r /shared/artifacts/chaincode $GOPATH/src/; ls $GOPATH/src; peer chaincode install -n ${CHAINCODE_NAME} -v ${CHAINCODE_VERSION} -p chaincode_example02/"]
        env:
        - name: CHAINCODE_NAME
          value: "cc"
        - name: CHAINCODE_VERSION
          value: "1.0"
        - name: FABRIC_CFG_PATH
          value: /etc/hyperledger/fabric
        - name: CORE_PEER_MSPCONFIGPATH
          value: /shared/crypto-config/peerOrganizations/org3.example.com/users/Admin@org3.example.com/msp
        - name: CORE_PEER_LOCALMSPID
          value: Org3MSP
        - name: CORE_PEER_ADDRESS
          value: blockchain-org3peer2:30320
        - name: GODEBUG
          value: "netdns=go"
        volumeMounts:
        - mountPath: /shared
          name: sharedvolume

      - name: chaincodeinstall4
        image: hyperledger/fabric-tools:x86_64-1.1.0
        imagePullPolicy: Always
        command: ["sh", "-c", "echo $GOPATH; cp -r /shared/artifacts/chaincode $GOPATH/src/; ls $GOPATH/src; peer chaincode install -n ${CHAINCODE_NAME} -v ${CHAINCODE_VERSION} -p chaincode_example02/"]
        env:
        - name: CHAINCODE_NAME
          value: "cc"
        - name: CHAINCODE_VERSION
          value: "1.0"
        - name: FABRIC_CFG_PATH
          value: /etc/hyperledger/fabric
        - name: CORE_PEER_MSPCONFIGPATH
          value: /shared/crypto-config/peerOrganizations/org4.example.com/users/Admin@org4.example.com/msp
        - name: CORE_PEER_LOCALMSPID
          value: Org4MSP
        - name: CORE_PEER_ADDRESS
          value: blockchain-org4peer1:30410
        - name: GODEBUG
          value: "netdns=go"
        volumeMounts:
        - mountPath: /shared
          name: sharedvolume

      - name: chaincodeinstall4p2
        image: hyperledger/fabric-tools:x86_64-1.1.0
        imagePullPolicy: Always
        command: ["sh", "-c", "echo $GOPATH; cp -r /shared/artifacts/chaincode $GOPATH/src/; ls $GOPATH/src; peer chaincode install -n ${CHAINCODE_NAME} -v ${CHAINCODE_VERSION} -p chaincode_example02/"]
        env:
        - name: CHAINCODE_NAME
          value: "cc"
        - name: CHAINCODE_VERSION
          value: "1.0"
        - name: FABRIC_CFG_PATH
          value: /etc/hyperledger/fabric
        - name: CORE_PEER_MSPCONFIGPATH
          value: /shared/crypto-config/peerOrganizations/org4.example.com/users/Admin@org4.example.com/msp
        - name: CORE_PEER_LOCALMSPID
          value: Org4MSP
        - name: CORE_PEER_ADDRESS
          value: blockchain-org4peer2:30420
        - name: GODEBUG
          value: "netdns=go"
        volumeMounts:
        - mountPath: /shared
          name: sharedvolume

      - name: chaincodeinstall5
        image: hyperledger/fabric-tools:x86_64-1.1.0
        imagePullPolicy: Always
        command: ["sh", "-c", "echo $GOPATH; cp -r /shared/artifacts/chaincode $GOPATH/src/; ls $GOPATH/src; peer chaincode install -n ${CHAINCODE_NAME} -v ${CHAINCODE_VERSION} -p chaincode_example02/"]
        env:
        - name: CHAINCODE_NAME
          value: "cc"
        - name: CHAINCODE_VERSION
          value: "1.0"
        - name: FABRIC_CFG_PATH
          value: /etc/hyperledger/fabric
        - name: CORE_PEER_MSPCONFIGPATH
          value: /shared/crypto-config/peerOrganizations/org5.example.com/users/Admin@org5.example.com/msp
        - name: CORE_PEER_LOCALMSPID
          value: Org5MSP
        - name: CORE_PEER_ADDRESS
          value: blockchain-org5peer1:30510
        - name: GODEBUG
          value: "netdns=go"
        volumeMounts:
        - mountPath: /shared
          name: sharedvolume

      - name: chaincodeinstall5p2
        image: hyperledger/fabric-tools:x86_64-1.1.0
        imagePullPolicy: Always
        command: ["sh", "-c", "echo $GOPATH; cp -r /shared/artifacts/chaincode $GOPATH/src/; ls $GOPATH/src; peer chaincode install -n ${CHAINCODE_NAME} -v ${CHAINCODE_VERSION} -p chaincode_example02/"]
        env:
        - name: CHAINCODE_NAME
          value: "cc"
        - name: CHAINCODE_VERSION
          value: "1.0"
        - name: FABRIC_CFG_PATH
          value: /etc/hyperledger/fabric
        - name: CORE_PEER_MSPCONFIGPATH
          value: /shared/crypto-config/peerOrganizations/org5.example.com/users/Admin@org5.example.com/msp
        - name: CORE_PEER_LOCALMSPID
          value: Org5MSP
        - name: CORE_PEER_ADDRESS
          value: blockchain-org5peer2:30520
        - name: GODEBUG
          value: "netdns=go"
        volumeMounts:
        - mountPath: /shared
          name: sharedvolume

      - name: chaincodeinstall6
        image: hyperledger/fabric-tools:x86_64-1.1.0
        imagePullPolicy: Always
        command: ["sh", "-c", "echo $GOPATH; cp -r /shared/artifacts/chaincode $GOPATH/src/; ls $GOPATH/src; peer chaincode install -n ${CHAINCODE_NAME} -v ${CHAINCODE_VERSION} -p chaincode_example02/"]
        env:
        - name: CHAINCODE_NAME
          value: "cc"
        - name: CHAINCODE_VERSION
          value: "1.0"
        - name: FABRIC_CFG_PATH
          value: /etc/hyperledger/fabric
        - name: CORE_PEER_MSPCONFIGPATH
          value: /shared/crypto-config/peerOrganizations/org6.example.com/users/Admin@org6.example.com/msp
        - name: CORE_PEER_LOCALMSPID
          value: Org6MSP
        - name: CORE_PEER_ADDRESS
          value: blockchain-org6peer1:30610
        - name: GODEBUG
          value: "netdns=go"
        volumeMounts:
        - mountPath: /shared
          name: sharedvolume

      - name: chaincodeinstall6p2
        image: hyperledger/fabric-tools:x86_64-1.1.0
        imagePullPolicy: Always
        command: ["sh", "-c", "echo $GOPATH; cp -r /shared/artifacts/chaincode $GOPATH/src/; ls $GOPATH/src; peer chaincode install -n ${CHAINCODE_NAME} -v ${CHAINCODE_VERSION} -p chaincode_example02/"]
        env:
        - name: CHAINCODE_NAME
          value: "cc"
        - name: CHAINCODE_VERSION
          value: "1.0"
        - name: FABRIC_CFG_PATH
          value: /etc/hyperledger/fabric
        - name: CORE_PEER_MSPCONFIGPATH
          value: /shared/crypto-config/peerOrganizations/org6.example.com/users/Admin@org6.example.com/msp
        - name: CORE_PEER_LOCALMSPID
          value: Org6MSP
        - name: CORE_PEER_ADDRESS
          value: blockchain-org6peer2:30620
        - name: GODEBUG
          value: "netdns=go"
        volumeMounts:
        - mountPath: /shared
          name: sharedvolume

chaincode_instantiate.yaml - 채널에 체인코드 인스턴스

echo -e "\nCreating chaincodeinstantiate job"
echo "Running: kubectl create -f ${KUBECONFIG_FOLDER}/chaincode_instantiate.yaml"
kubectl create -f ${KUBECONFIG_FOLDER}/chaincode_instantiate.yaml
---
apiVersion: batch/v1
kind: Job
metadata:
  name: chaincodeinstantiate
spec:
  backoffLimit: 1
  template:
    metadata:
      name: chaincodeinstantiate
    spec:
      restartPolicy: "Never"
      volumes:
      - name: sharedvolume
        persistentVolumeClaim:
          claimName: shared-pvc

      containers:
      - name: chaincodeinstantiate
        image: hyperledger/fabric-tools:x86_64-1.1.0
        imagePullPolicy: Always ## imagePullPolicy는 Pod를 만들때 마다 매번 컨테이너 이미지를 확인해서 새 이미지를 사용하도록 하는 설정이다.  컨테이너 이미지는 한번 다운로드가 되면 노드(Node) 에 저장이 되어 있게 되고, 사용이 되지 않는 이미지 중에 오래된 이미지는 Kublet이 가비지 컬렉션 (Garbage collection) 정책에 따라 이미지를 삭제하게 되는데, 문제는 노드에 이미 다운되어 있는 이미지가 있을 경우 컨테이너 생성시 노드에 이미 다운로드 되어 있는 이미지를 사용한다. 컨테이너 리파지토리에 같은 이름으로 이미지를 업데이트 하거나 심지어 그 이미지를 삭제하더라도 노드에 이미지가 이미 다운로드 되어 있으면 다운로드된 이미지를 사용하기 때문에, 업데이트 부분이 반영이 안된다. 이를 방지하기 위해서 imagePullPolicy:Always로 해주면 컨테이너 생성시마다 이미지 리파지토리를 검사해서 새 이미지를 가지고 오기 때문에, 업데이트된 내용을 제대로 반영할 수 있다.
        command: ["sh", "-c", "peer chaincode instantiate -o blockchain-orderer:31010 -C ${CHANNEL_NAME} -n ${CHAINCODE_NAME} -v ${CHAINCODE_VERSION} -c '{\"Args\":[\"init\",\"a\",\"100\",\"b\",\"200\"]}'"]
        env:
        - name: CHANNEL_NAME
          value: channel1
        - name: CHAINCODE_NAME
          value: "cc"
        - name: CHAINCODE_VERSION
          value: "1.0"
        - name: FABRIC_CFG_PATH
          value: /etc/hyperledger/fabric
        - name: CORE_PEER_MSPCONFIGPATH
          value: /shared/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
        - name: CORE_PEER_LOCALMSPID
          value: Org1MSP
        - name: CORE_PEER_ADDRESS
          value: blockchain-org1peer1:30110
        - name: GODEBUG
          value: "netdns=go"
        volumeMounts:
        - mountPath: /shared
          name: sharedvolume

 

'IT > Block Chain(Hyperledger)' 카테고리의 다른 글

Hyperledger 오더링 서비스(Ordering Service)  (0) 2020.05.07
byfn 2.0 시작하기  (0) 2020.04.28
Caliper 구조  (0) 2018.08.28
Hyperledger Caliper 개요  (0) 2018.08.28
Steem 그리고, Steemit 정의  (1) 2017.12.28