Istio set up

Istio is a service mesh that provides a secure, high-performance networking platform for microservices and applications running on Kubernetes.

Node port solutions can work in the short term, but they are not long-term solutions, neither for production, as they require opening up multiple ports to the public internet.

The following diagram represents the architecture with Istio configured Istio

As you can see, we can note the following:

  • The Istio service mesh is running in the Kubernetes cluster
  • The service only has one port exposed, which is the port of the Istio ingress gateway service.
  • The ingress gateway routes the traffic to the peer, OSN or CA depending on the request.

Installing istio#

You can refer to your version of choice by going to this tutorial from the istio docs to get Istio installed in your Kubernetes cluster.

Alternatively, you can just execute this command to install the latest Istio version in your Kubernetes cluster:

curl -L https://istio.io/downloadIstio | sh - # download istioctl CLI
istioctl install --set profile=default -y # install Istio

Locate the public IP or hostname of the ingress gateway#

Running on KinD/Minikube#

PUBLIC_IP=$(kubectl get nodes -o jsonpath='{.items[0].status.addresses[?(@.type=="InternalIP")].address}')
# get node port
PORT=$(kubectl get svc istio-ingressgateway -n istio-system -o jsonpath='{.spec.ports[?(@.name=="https")].nodePort}')

Running with load balancer IP#

PUBLIC_IP=$(kubectl get svc istio-ingressgateway -n istio-system -o json | jq -r '.status.loadBalancer.ingress[0].ip')
PORT=443

Running with load balancer hostname#

PUBLIC_HOSTNAME=$(kubectl get svc istio-ingressgateway -n istio-system -o json | jq -r '.status.loadBalancer.ingress[0].hostname')
PORT=443

Set up DNS#

Local DNS set up in Linux/Mac (for MiniKube and KinD)#

Open up /etc/hosts

<PUBLIC_IP> peer0.org1.example.com
<PUBLIC_IP> ord1.ord-org.example.com
# and so on

Set up DNS in your DNS provider#

You will need to point the domain names you will use to the public IP of the ingress gateway, with either a A record, if you got a public IP, or a CNAME, if you got an ingress hostname

Set up the network#

Deploying a Certificate Authority#

kubectl hlf ca create --storage-class=standard --capacity=2Gi --name=org1-ca \
--enroll-id=enroll --enroll-pw=enrollpw
kubectl wait --timeout=180s --for=condition=Running fabriccas.hlf.kungfusoftware.es --all
# register user for the peers
kubectl hlf ca register --name=org1-ca --user=peer --secret=peerpw --type=peer \
--enroll-id enroll --enroll-secret=enrollpw --mspid Org1MSP

Create the peer#

PEER1_DOMAIN=peer0.org1.example.com # domain for the peer
ISTIO_INGRESSGATEWAY=ingressgateway # name of the ingress gateway, in case there are many
ISTIO_GW_PORT=443 # port of the ingress gateway
kubectl hlf peer create --storage-class=standard --enroll-id=peer --mspid=Org1MSP \
--enroll-pw=peerpw --capacity=5Gi --name=org1-peer0 --ca-name=org1-ca.default \
--hosts=$PEER1_DOMAIN --istio-ingressgateway=$ISTIO_INGRESSGATEWAY --istio-port=$ISTIO_GW_PORT
kubectl wait --timeout=180s --for=condition=Running fabricpeers.hlf.kungfusoftware.es --all

If we inspect the virtual services and gateways of Istio, we must see a record per peer.

kubectl get virtualservices.networking.istio.io -A # list all virtual services
kubectl get gateways.networking.istio.io -A # list all gateways

To test that you can connect to the peer, you can use the following command to test directly from the command line(this test doesn't require DNS records to be set up):

echo "PUBLIC_IP=$PUBLIC_IP PORT=$PORT DOMAIN=$PEER1_DOMAIN"
openssl s_client -connect $PUBLIC_IP:$PORT -servername $PEER1_DOMAIN -showcerts </dev/null

Create the Certificate Authority for the orderer#

kubectl hlf ca create --storage-class=standard --capacity=2Gi --name=ord-ca \
--enroll-id=enroll --enroll-pw=enrollpw
kubectl wait --timeout=180s --for=condition=Running fabriccas.hlf.kungfusoftware.es --all
kubectl hlf ca register --name=ord-ca --user=orderer --secret=ordererpw \
--type=orderer --enroll-id enroll --enroll-secret=enrollpw --mspid=OrdererMSP

Deploying the Orderer nodes node#

ORD1_DOMAIN=ord1.org1-node.example.com # domain for the orderer
ISTIO_INGRESSGATEWAY=ingressgateway # name of the ingress gateway, in case there are many
ISTIO_GW_PORT=443
kubectl hlf ordnode create --storage-class=standard --enroll-id=orderer --mspid=OrdererMSP \
--enroll-pw=ordererpw --capacity=2Gi --name=ord-node1 --ca-name=ord-ca.default \
--hosts=$ORD1_DOMAIN --istio-ingressgateway=$ISTIO_INGRESSGATEWAY --istio-port=$ISTIO_GW_PORT
kubectl wait --timeout=180s --for=condition=Running fabricorderernodes.hlf.kungfusoftware.es --all

Testing orderer node connection#

echo "PUBLIC_IP=$PUBLIC_IP PORT=$PORT DOMAIN=$ORD1_DOMAIN"
openssl s_client -connect $PUBLIC_IP:$PORT -servername $ORD1_DOMAIN -showcerts </dev/null

Create the Certificate Authority with Istio#

CA_ORG2=ca.org2.example.com # domain for the orderer
ISTIO_INGRESSGATEWAY=ingressgateway # name of the ingress gateway, in case there are many
ISTIO_GW_PORT=443
kubectl hlf ca create --storage-class=standard --capacity=2Gi --name=org2-ca \
--enroll-id=enroll --enroll-pw=enrollpw \
--hosts=$CA_ORG2 --istio-ingressgateway=$ISTIO_INGRESSGATEWAY --istio-port=$ISTIO_GW_PORT
kubectl wait --timeout=180s --for=condition=Running fabriccas.hlf.kungfusoftware.es --all

Testing CA node connection#

echo "PUBLIC_IP=$PUBLIC_IP PORT=$PORT DOMAIN=$CA_ORG2"
openssl s_client -connect $PUBLIC_IP:$PORT -servername $CA_ORG2 -showcerts </dev/null