Skip to content
This repository has been archived by the owner on Feb 22, 2022. It is now read-only.

Commit

Permalink
Implement Hyperledger Fabric Orderer chart (#6163)
Browse files Browse the repository at this point in the history
* Implement hlf-ord chart

Signed-off-by: Alejandro Vicente Grabovetsky <sasha@aid.technology>

* Small edits in README.md and values.yaml

Signed-off-by: Alejandro Vicente Grabovetsky <sasha@aid.technology>

* Move chart from incubator to stable

Signed-off-by: Alejandro Vicente Grabovetsky <sasha@aid.technology>

* Align with persistence best-practices and fix deployment apiVersion

Signed-off-by: Alejandro Vicente Grabovetsky <sasha@aid.technology>

* Move persistent data location to default Hyperledger /var/persistence

Signed-off-by: Alejandro Vicente Grabovetsky <sasha@aid.technology>
  • Loading branch information
alexvicegrab authored and k8s-ci-robot committed Jun 28, 2018
1 parent 02dc414 commit 54bd619
Show file tree
Hide file tree
Showing 11 changed files with 516 additions and 0 deletions.
21 changes: 21 additions & 0 deletions stable/hlf-ord/.helmignore
@@ -0,0 +1,21 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*~
# Various IDEs
.project
.idea/
*.tmproj
19 changes: 19 additions & 0 deletions stable/hlf-ord/Chart.yaml
@@ -0,0 +1,19 @@
apiVersion: v1
description: Hyperledger Fabric Orderer chart (these charts are created by AID:Tech and are currently not directly associated with the Hyperledger project)
name: hlf-ord
version: 1.0.8
appVersion: 1.1.0
keywords:
- blockchain
- hyperledger
- fabric
home: http://hyperledger-fabric.readthedocs.io
sources:
- https://github.com/hyperledger/fabric
maintainers:
- name: alexvicegrab
email: sasha@aid.technology
- name: nicolapaoli
email: nicola@aid.technology
## Icon not included while sorting out trademark question with Hyperledger project
# icon: https://www.hyperledger.org/wp-content/uploads/2018/04/fabric-logo.png
117 changes: 117 additions & 0 deletions stable/hlf-ord/README.md
@@ -0,0 +1,117 @@
# Hyperledger Fabric Orderer

[Hyperledger Fabric Orderer](http://hyperledger-fabric.readthedocs.io/) is the node type responsible for "consensus" for the [Hyperledger](https://www.hyperledger.org/) Fabric permissioned blockchain framework.

## TL;DR;

```bash
$ helm install stable/hlf-ord
```

## Introduction

The Hyperledger Fabric Orderer can be installed as either a `solo` orderer (for development), or a `kafka` orderer (for crash fault tolerant consensus).

This Orderer can receive transaction endorsements and package them into blocks to be distributed to the nodes of the Hyperledger Fabric network.

Learn more about deploying a production ready consensus framework based on Apache [Kafka](https://hyperledger-fabric.readthedocs.io/en/release-1.1/kafka.html?highlight=orderer). Minimally, you will need to set these options:

```
"default.replication.factor": 4 # given a 4 node Kafka cluster
"unclean.leader.election.enable": false
"min.insync.replicas": 3 # to permit one Kafka replica to go offline
"message.max.bytes": "103809024" # 99 * 1024 * 1024 B
"replica.fetch.max.bytes": "103809024" # 99 * 1024 * 1024 B
"log.retention.ms": -1 # Since we need to keep logs indefinitely for the HL Fabric Orderer
```

## Prerequisites

- Kubernetes 1.9+
- PV provisioner support in the underlying infrastructure.
- Two K8S secrets containing:
- the genesis block for the Orderer
- the certificate of the Orderer Organisation Admin
- A running [Kafka Chart](https://github.com/kubernetes/charts/tree/master/incubator/kafka) if you are using the `kafka` consensus mechanism.

## Installing the Chart

To install the chart with the release name `ord1`:

```bash
$ helm install stable/hlf-ord --name ord1
```

The command deploys the Hyperledger Fabric Orderer on the Kubernetes cluster in the default configuration. The [Configuration](#configuration) section lists the parameters that can be configured during installation.

### Custom parameters

Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example:

```bash
$ helm install stable/hlf-ord --name ord1 --set caUsername=ord1,caPassword=secretpassword
```

The above command specifies (but does not register/enroll) an Orderer username of `ord1` with password `secretpassword`.

Alternatively, a YAML file can be provided while installing the chart. This file specifies values to override those provided in the defualt values.yaml. For example,

```bash
$ helm install stable/hlf-ord --name ord1 -f my-values.yaml
```

## Updating the chart

When updating the chart, make sure you provide the `caPassword`, otherwise `helm update` will generate a new random (and invalid) password.

```bash
$ export CA_PASSWORD=$(kubectl get secret --namespace {{ .Release.Namespace }} ord1-hlf-ord -o jsonpath="{.data.CA_PASSWORD}" | base64 --decode; echo)
$ helm upgrade ord1 stable/hlf-ord --set caPassword=$CA_PASSWORD
```

## Uninstalling the Chart

To uninstall/delete the `ord1` deployment:

```bash
$ helm delete ord1
```

The command removes all the Kubernetes components associated with the chart and deletes the release.

## Configuration

The following table lists the configurable parameters of the Hyperledger Fabric Orderer chart and default values.

| Parameter | Description | Default |
| ---------------------------------- | ------------------------------------------------ | ---------------------------------------------------------- |
| `image.repository` | `hlf-ord` image repository | `hyperledger/fabric-orderer` |
| `image.tag` | `hlf-ord` image tag | `x86_64-1.1.0` |
| `image.pullPolicy` | Image pull policy | `IfNotPresent` |
| `service.port` | TCP port | `7050` |
| `service.type` | K8S service type exposing ports, e.g. `ClusterIP`| `ClusterIP` |
| `persistence.accessMode` | Use volume as ReadOnly or ReadWrite | `ReadWriteOnce` |
| `persistence.annotations` | Persistent Volume annotations | `{}` |
| `persistence.size` | Size of data volume (adjust for production!) | `1Gi` |
| `persistence.storageClass` | Storage class of backing PVC | `default` |
| `caAddress` | Address of CA to register/enroll with | `hlf-ca.local` |
| `caUsername` | Username for registering/enrolling with CA | `ord1` |
| `caPassword` | Password for registering/enrolling with CA | Random 24 alphanumeric characters |
| `ord.type` | Type of Orderer (`solo` or `kafka`) | `solo` |
| `ord.mspID` | ID of MSP the Orderer belongs to | `OrdererMSP` |
| `secrets.genesis` | Secret containing Genesis Block for orderer | `hlf--genesis` |
| `secrets.adminCert` | Secret containing Orderer Org admin certificate | `hlf--ord-admincert` |
| `resources` | CPU/Memory resource requests/limits | `{}` |
| `nodeSelector` | Node labels for pod assignment | `{}` |
| `tolerations` | Toleration labels for pod assignment | `[]` |
| `affinity` | Affinity settings for pod assignment | `{}` |

## Persistence

The volume stores the Fabric Orderer data and configurations at the `/var/hyperledger` path of the container.

The chart mounts a [Persistent Volume](http://kubernetes.io/docs/user-guide/persistent-volumes/) at this location. The volume is created using dynamic volume provisioning through a PersistentVolumeClaim managed by the chart.

## Feedback and feature requests

This is a work in progress and we are happy to accept feature requests. We are even happier to accept pull requests implementing improvements :-)
26 changes: 26 additions & 0 deletions stable/hlf-ord/templates/NOTES.txt
@@ -0,0 +1,26 @@
Run the following commands to...
1. Get the name of the pod running the Fabric Orderer:
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ include "hlf-ord.name" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")

2. Get the application URL by running these commands:
{{- if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "hlf-ord.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get svc -w {{ include "hlf-ord.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "hlf-ord.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo http://$SERVICE_IP:{{ .Values.service.port }}
{{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ include "hlf-ord.name" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl port-forward $POD_NAME 8080:7050
{{- end }}

3. Obtain CA_USERNAME and CA_PASSWORD to register identity with CA:
export CA_USERNAME=$(kubectl get secret --namespace {{ .Release.Namespace }} {{ include "hlf-ord.fullname" . }} -o jsonpath="{.data.CA_USERNAME}" | base64 --decode; echo)
export CA_PASSWORD=$(kubectl get secret --namespace {{ .Release.Namespace }} {{ include "hlf-ord.fullname" . }} -o jsonpath="{.data.CA_PASSWORD}" | base64 --decode; echo)

4. Update the chart without resetting a password (requires running step 3):
helm upgrade {{ .Release.Name }} stable/hlf-ord --namespace {{ .Release.Namespace }} -f my-values.yaml --set caUsername=$CA_USERNAME,caPassword=$CA_PASSWORD
45 changes: 45 additions & 0 deletions stable/hlf-ord/templates/_helpers.tpl
@@ -0,0 +1,45 @@
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "hlf-ord.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}

{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "hlf-ord.fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- if contains $name .Release.Name -}}
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{- end -}}

{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "hlf-ord.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}

{{- /*
Credit: @technosophos
https://github.com/technosophos/common-chart/
labels.standard prints the standard Helm labels.
The standard labels are frequently used in metadata.
*/ -}}
{{- define "labels.standard" -}}
app: {{ include "hlf-ord.name" . }}
heritage: {{ .Release.Service | quote }}
release: {{ .Release.Name | quote }}
chart: {{ include "hlf-ord.chart" . }}
{{- end -}}
32 changes: 32 additions & 0 deletions stable/hlf-ord/templates/configmap--ord.yaml
@@ -0,0 +1,32 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "hlf-ord.fullname" . }}--ord
labels:
{{ include "labels.standard" . | indent 4 }}
data:
## Environmental variable defining which version of tools to obtain (for fabric-ca-client)
HLF_TOOLS_BUILD: linux-amd64-1.1.0
## Location where fabric-ca-client configuration is saved
FABRIC_CA_CLIENT_HOME: /var/hyperledger/fabric-ca-client
## Orderer defaults
ORDERER_CFG_PATH: /var/hyperledger/config
ORDERER_GENERAL_LEDGERTYPE: file
ORDERER_FILELEDGER_LOCATION: /var/hyperledger/ledger
ORDERER_GENERAL_BATCHTIMEOUT: 1s
ORDERER_GENERAL_BATCHSIZE_MAXMESSAGECOUNT: "10"
ORDERER_GENERAL_MAXWINDOWSIZE: "1000"
ORDERER_GENERAL_ORDERERTYPE: {{ .Values.ord.type }}
ORDERER_GENERAL_LISTENADDRESS: 0.0.0.0
ORDERER_GENERAL_LISTENPORT: "7050"
ORDERER_GENERAL_LOGLEVEL: debug
ORDERER_GENERAL_LOCALMSPDIR: /var/hyperledger/msp
ORDERER_GENERAL_LOCALMSPID: {{ .Values.ord.mspID }}
ORDERER_GENERAL_GENESISMETHOD: file
ORDERER_GENERAL_GENESISFILE: /hl_config/genesis/genesis.block
ORDERER_GENERAL_GENESISPROFILE: initial
ORDERER_GENERAL_TLS_ENABLED: "false"
ORDERER_GENERAL_TLS_CERTIFICATE: "/var/hyperledger/tls/tls.crt"
ORDERER_GENERAL_TLS_PRIVATEKEY: "/var/hyperledger/tls/tls.key"
GODEBUG: "netdns=go"
ADMIN_MSP_PATH: /var/hyperledger/admin_msp
133 changes: 133 additions & 0 deletions stable/hlf-ord/templates/deployment.yaml
@@ -0,0 +1,133 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "hlf-ord.fullname" . }}
labels:
{{ include "labels.standard" . | indent 4 }}
spec:
replicas: 1
selector:
matchLabels:
app: {{ include "hlf-ord.name" . }}
release: {{ .Release.Name }}
template:
metadata:
labels:
{{ include "labels.standard" . | indent 8 }}
spec:
volumes:
- name: data
{{- if .Values.persistence.enabled }}
persistentVolumeClaim:
claimName: {{ .Values.persistence.existingClaim | default (include "hlf-ord.fullname" .) }}
{{- else }}
emptyDir: {}
{{- end }}
- name: genesis
secret:
secretName: {{ .Values.secrets.genesis }}
- name: admin-cert
secret:
secretName: {{ .Values.secrets.adminCert }}
containers:
- name: orderer
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: ord-port
containerPort: 7050
protocol: TCP
# TODO: Add liveness and readiness probes
command:
- sh
- -c
- |
# Download Fabric CA-client if it does not exist
if [ ! -f /bin/fabric-ca-client ]
then
if [ ! -f /var/hyperledger/fabric-ca-${HLF_TOOLS_BUILD}.tar.gz ]
then
# Curl is needed to download Fabric CA-client
apt update
apt install curl -y
echo "Downloading Fabric CA-client"
curl -f -s -C - https://nexus.hyperledger.org/content/repositories/releases/org/hyperledger/fabric-ca/hyperledger-fabric-ca/${HLF_TOOLS_BUILD}/hyperledger-fabric-ca-${HLF_TOOLS_BUILD}.tar.gz > /var/hyperledger/fabric-ca-${HLF_TOOLS_BUILD}.tar.gz
fi
echo "Unzipping Fabric CA-client"
tar xzf /var/hyperledger/fabric-ca-${HLF_TOOLS_BUILD}.tar.gz -C /
fi
while [ ! -f ${ORDERER_GENERAL_LOCALMSPDIR}/signcerts/cert.pem ];
do
echo ">\033[0;35m fabric-ca-client enroll -d -u http://${CA_USERNAME}:${CA_PASSWORD}@${CA_ADDRESS} -M ${ORDERER_GENERAL_LOCALMSPDIR} \033[0m"
fabric-ca-client enroll -d -u http://${CA_USERNAME}:${CA_PASSWORD}@${CA_ADDRESS} -M ${ORDERER_GENERAL_LOCALMSPDIR}
if [ ! -f ${ORDERER_GENERAL_LOCALMSPDIR}/signcerts/cert.pem ]
then
echo ">\033[0;31m Unable to enroll Orderer, make sure you have registered them first \(sleeping 180 seconds and re-trying\) \033[0m"
sleep 180
fi
done
echo ">\033[0;32m Copy admincerts to ${ORDERER_GENERAL_LOCALMSPDIR}/admincerts \033[0m"
mkdir -p ${ORDERER_GENERAL_LOCALMSPDIR}/admincerts
cp /hl_config/admin/signcerts/* ${ORDERER_GENERAL_LOCALMSPDIR}/admincerts
echo ">\033[0;32m Setup admin certificates in ${ADMIN_MSP_PATH} \033[0m"
mkdir -p ${ADMIN_MSP_PATH} ${ADMIN_MSP_PATH}/cacerts ${ADMIN_MSP_PATH}/intermediatecerts
cp -L -r /hl_config/admin/* ${ADMIN_MSP_PATH}
cp ${ORDERER_GENERAL_LOCALMSPDIR}/cacerts/* ${ADMIN_MSP_PATH}/cacerts
cp ${ORDERER_GENERAL_LOCALMSPDIR}/intermediatecerts/* ${ADMIN_MSP_PATH}/intermediatecerts
# Create TLS certificate for Orderer
if [ ! -f ${ORDERER_GENERAL_TLS_PRIVATEKEY} ]
then
echo ">\033[0;35m fabric-ca-client enroll -d --enrollment.profile tls -u http://${CA_USERNAME}:${CA_PASSWORD}@http://${CA_ADDRESS} -M /tmp/tls --csr.hosts {{ include "hlf-ord.fullname" . }} \033[0m"
fabric-ca-client enroll -d --enrollment.profile tls -u http://${CA_USERNAME}:${CA_PASSWORD}@${CA_ADDRESS} -M /tmp/tls --csr.hosts {{ include "hlf-ord.fullname" . }}
mkdir -p $(dirname $ORDERER_GENERAL_TLS_PRIVATEKEY)
cp /tmp/tls/keystore/* $ORDERER_GENERAL_TLS_PRIVATEKEY
mkdir -p $(dirname $ORDERER_GENERAL_TLS_CERTIFICATE)
cp /tmp/tls/signcerts/* $ORDERER_GENERAL_TLS_CERTIFICATE
rm -rf /tmp/tls
fi
# Create directories to avoid restarts
mkdir -p ${ORDERER_FILELEDGER_LOCATION}
mkdir -p ${ORDERER_FILELEDGER_LOCATION}/index
echo ">\033[0;35m orderer \033[0m"
orderer
envFrom:
- secretRef:
name: {{ include "hlf-ord.fullname" . }}
- configMapRef:
name: {{ include "hlf-ord.fullname" . }}--ord
ports:
- name: ord-port
containerPort: 7050
protocol: TCP
volumeMounts:
- mountPath: /var/hyperledger
name: data
- mountPath: /hl_config/genesis
name: genesis
- mountPath: /hl_config/admin/admincerts
name: admin-cert
- mountPath: /hl_config/admin/signcerts
name: admin-cert
resources:
{{ toYaml .Values.resources | indent 12 }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{ toYaml . | indent 8 }}
{{- end }}

0 comments on commit 54bd619

Please sign in to comment.