5 Provision an Instance

This section describes how to provision your Oracle Blockchain Platform instance using Blockchain Platform Manager.

Before You Create an Oracle Blockchain Platform Instance

Before you provision Oracle Blockchain Platform, decide if a developer or enterprise instance meets your needs.

Deciding Which Provisioning Shape to Use

When provisioning an instance, you choose between two configurations. Migration between these options isn't supported currently.

Configuration Features
Developer

Recommended use for this starter shape is development and evaluation.

  • 1 Fabric-CA node
  • 3-node Fabric Ordering Service Network
  • 1-node repository for instance metadata
  • Dynamically managed chaincode execution containers
  • Console service for operations web user interface
  • REST proxy service for RESTful API
  • LDAP server integration for authentication and role management
Enterprise

Highly available instance configuration, with higher replica count for each service.

  • 3 Fabric-CA nodes
  • 3-node Fabric Ordering Service Network
  • 3-node cluster repository for high availability of instance metadata
  • Dynamically managed chaincode execution containers
  • Console service for operations web user interface
  • Multiple replicas for REST proxy service for RESTful API
  • LDAP server integration for authentication and role management

Provision an Instance using the Blockchain Platform Manager

To create a blockchain founder or participant instance in Blockchain Platform Manager, use the Create New Instance wizard.

There are two types of Oracle Blockchain Platform instances you can provision:
  • Founder organization: a complete blockchain environment, including a new network to which participants can join later on.

  • Participant instance: if there is already a founder organization you want to join, you can create a participant instance if your credentials provide you with access to the network. Note that a participant cannot function on its own.

  1. In Blockchain Platform Manager, open the Instances page.
  2. Select Create Instance.
  3. Complete the following fields:
    Field Description
    Instance Name

    Enter a name for your Oracle Blockchain Platform instance.

    The service instance name:

    • Must contain one or more characters.
    • Must not exceed 15 characters.
    • Must start with an ASCII letter: a to z.
    • Must contain only ASCII letters or numbers.
    • Must not contain a hyphen.
    • Must not contain any other special characters.
    • Must be unique within the identity domain.
    Description

    Optional.

    Enter a short description of the Oracle Blockchain Platform instance.

    Domain Name

    Enter the domain name for the cluster.

    The hostnames generated for the Blockchain Instance services make use of the domain name and the instance name as parent domain and sub domain respectively.

    Role

    Select Founder to create a complete blockchain environment. This instance becomes the founder organization and you can onboard new participants in the network later.

    Select Participant to create an instance that will join an existing blockchain network created elsewhere before this instance can be used.

    Configuration
    Select a provisioning shape which meets the needs of your deployment:
    • Developer
    • Enterprise
    Peers

    Specify the number of peer nodes to be initially created in this service instance. You can create additional peer nodes in the Oracle Blockchain Platform console at a later time.

  4. Click Create Instance.

Provisioning Postrequisites

Before accessing the Oracle Blockchain Platform service console, configure the hostname resolution for the blockchain instance services, similar to what you did earlier for the Blockchain Platform Manager hostnames. Use the following command to get the list of hostnames for the created blockchain instance:
kubectl get virtualservice -n <instance-namespace> -o json | jq -r
      .items[].spec.hosts[0]
Before accessing the Oracle Blockchain Platform service console, configure the hostname resolution for the blockchain instance services, similar to what you did earlier for the Blockchain Platform Manager hostnames. Use the following command to get the list of hostnames for the created blockchain instance:
kubectl get virtualservice -n <instance-namespace> -o json | jq -r
      .items[].spec.hosts[0]

After you create an Oracle Blockchain Platform Enterprise Edition instance, you must configure DNS so that public host names of the components are resolvable from the OpenShift Local network.

After you create an instance, the instance name and parent domain are used as the subdomain for the Oracle Blockchain Platform Enterprise Edition components. You must set up DNS forwarding on the default DNS configuration for OpenShift, so that DNS requests are forwarded to the custom DNS pod where the exposed services are resolved. Complete the following steps to configure DNS forwarding.
  1. Run the following command.
    oc new-project obp-coredns
  2. Deploy a custom coredns server in the obp-coredns namespace by running the following command.
    kubectl apply -f <coredns-deployment-yaml-file>
    Use the following manifest file with the command.
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: coredns
      namespace: obp-coredns
    data:
      Corefile: |-
        .:1053 {
          errors
          health {
            lameduck 5s
          }
          ready
          kubernetes cluster.local in-addr.arpa ip6.arpa {
            pods insecure
            fallthrough in-addr.arpa ip6.arpa
          }
          prometheus :9153
          forward . /etc/resolv.conf
          cache 30
          loop
          reload
          loadbalance
        }
        import custom/*.server
     
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: obp-coredns
      name: obp-coredns
      namespace: obp-coredns
    spec:
      progressDeadlineSeconds: 600
      replicas: 1
      revisionHistoryLimit: 10
      selector:
        matchLabels:
          app: obp-coredns
      strategy:
        type: RollingUpdate
      template:
        metadata:
          labels:
            app: obp-coredns
        spec:
          containers:
          - args:
            - -conf
            - /etc/coredns/Corefile
            image: docker.io/coredns/coredns:latest
            imagePullPolicy: IfNotPresent
            livenessProbe:
              failureThreshold: 5
              httpGet:
                path: /health
                port: 8080
                scheme: HTTP
              initialDelaySeconds: 60
              periodSeconds: 10
              successThreshold: 1
              timeoutSeconds: 5
            name: coredns
            ports:
            - containerPort: 1053
              name: dns
              protocol: UDP
            - containerPort: 1053
              name: dns-tcp
              protocol: TCP
            - containerPort: 9153
              name: metrics
              protocol: TCP
            readinessProbe:
              failureThreshold: 3
              httpGet:
                path: /ready
                port: 8181
                scheme: HTTP
              periodSeconds: 10
              successThreshold: 1
              timeoutSeconds: 1
            resources:
              limits:
                memory: 170Mi
              requests:
                cpu: 100m
                memory: 70Mi
            securityContext:
              allowPrivilegeEscalation: false
              capabilities:
                add:
                - NET_BIND_SERVICE
                drop:
                - all
              readOnlyRootFilesystem: true
            terminationMessagePath: /dev/termination-log
            terminationMessagePolicy: File
            volumeMounts:
            - mountPath: /etc/coredns
              name: config-volume
              readOnly: true
            - mountPath: /etc/coredns/custom
              name: custom-config-volume
              readOnly: true
          dnsPolicy: Default
          restartPolicy: Always
          schedulerName: default-scheduler
          securityContext: {}
          serviceAccount: obp-coredns
          serviceAccountName: obp-coredns
          terminationGracePeriodSeconds: 30
          volumes:
          - configMap:
              defaultMode: 420
              items:
              - key: Corefile
                path: Corefile
              name: coredns
            name: config-volume
          - configMap:
              defaultMode: 420
              name: coredns-custom
              optional: true
            name: custom-config-volume
     
    ---
    apiVersion: v1
    kind: Service
    metadata:
      labels:
        app: obp-coredns
      name: obp-coredns
      namespace: obp-coredns
    spec:
      ports:
      - name: dns
        port: 53
        protocol: UDP
        targetPort: 1053
      - name: dns-tcp
        port: 53
        protocol: TCP
        targetPort: 1053
      - name: metrics
        port: 9153
        protocol: TCP
        targetPort: 9153
      selector:
        app: obp-coredns
      sessionAffinity: None
      type: ClusterIP
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: obp-coredns
      namespace: obp-coredns
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: obp-coredns
    rules:
    - apiGroups:
      - ""
      resources:
      - endpoints
      - services
      - pods
      - namespaces
      verbs:
      - list
      - watch
    - apiGroups:
      - ""
      resources:
      - nodes
      verbs:
      - get
    - apiGroups:
      - discovery.k8s.io
      resources:
      - endpointslices
      verbs:
      - list
      - watch
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: obp-coredns
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: obp-coredns
    subjects:
    - kind: ServiceAccount
      name: obp-coredns
      namespace: obp-coredns
    
  3. Create a coredns-custom-configmap file in YAML format for your blockchain instance.
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: coredns-custom
      namespace: obp-coredns
    data:
      obp.server: |2
     
        <instanceName>.<domain>:1053 {
            log
            kubernetes cluster.local in-addr.arpa ip6.arpa {
                pods insecure
                fallthrough in-addr.arpa ip6.arpa
            }
            rewrite stop {
                name regex (.*)\.<instanceName>\.<domain>\.com istio-ingressgateway.istio-system.svc.cluster.local answer auto
            }
            forward . /etc/resolv.conf
        }
    
    In the previous example, <instanceName> is the name of the instance and <domain> is the domain passed when creating the instance.
  4. Run the following command to apply the custom ConfigMap object.
    kubectl apply -f <coredns-custom-configmap-yaml-file>
  5. Run the following command to get the cluster IP address. Record the IP address.
    kubectl get svc -n obp-coredns
  6. Run the following command to edit the OpenShift DNS custom resource.
    kubectl edit dnses.operator/default
  7. Update the zones section of the DNS custom resource to use your instance and domain names, as shown in the following example.
    ## Add the following section to the dns custom resource under spec
      servers:
      - forwardPlugin:
          policy: Random
          upstreams:
          - 192.0.2.233
        name: obp-server
        zones:
        - <instanceName>.<domain>
    In the previous example, <instanceName> is the name of the instance and <domain> is the parent domain.
  8. To add new instances, add entries to the coredns-custom-configmap file and update the OpenShift DNS custom resource for the domain of the new instance as shown in the following example:
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: coredns-custom
      namespace: obp-coredns
    data:
      obp.server: |2
     
        myobp.example.com:1053 {
            log
            kubernetes cluster.local in-addr.arpa ip6.arpa {
                pods insecure
                fallthrough in-addr.arpa ip6.arpa
            }
            rewrite stop {
                name regex (.*)\.myobp\.example\.com istio-ingressgateway.istio-system.svc.cluster.local answer auto
            }
            forward . /etc/resolv.conf
        }
     
        otherobp.example.org:1053 {
            log
            kubernetes cluster.local in-addr.arpa ip6.arpa {
                pods insecure
                fallthrough in-addr.arpa ip6.arpa
            }
            rewrite stop {
                name regex (.*)\.otherobp\.example\.org istio-ingressgateway.istio-system.svc.cluster.local answer auto
            }
            forward . /etc/resolv.conf
        }
    
    
    
    ## Edit the Openshift's DNS custom resource
    kubectl edit dnses.operator/default
     
    ## Add the new instance domain to the existing .spec.servers.zones
      servers:
      - forwardPlugin:
          policy: Random
          upstreams:
          - 192.0.2.233
        name: obp-server
        zones:
        - myobp.example.com
        - otherobp.example.org
    You must stop and restart the Blockchain Platform instance using Blockchain Platform Manager for DNS changes to take effect.

Configure DNS

After you create an Oracle Blockchain Platform Enterprise Edition instance, you must configure DNS so that public host names of the components are resolvable from the OpenShift Local network.

After you create an instance, the instance name and parent domain are used as the subdomain for the Oracle Blockchain Platform Enterprise Edition components. You must set up DNS forwarding on the default DNS configuration for OpenShift, so that DNS requests are forwarded to the custom DNS pod where the exposed services are resolved. Complete the following steps to configure DNS forwarding.
  1. Run the following command.
    oc new-project obp-coredns
  2. Deploy a custom coredns server in the obp-coredns namespace by running the following command.
    kubectl apply -f <coredns-deployment-yaml-file>
    Use the following manifest file with the command.
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: coredns
      namespace: obp-coredns
    data:
      Corefile: |-
        .:1053 {
          errors
          health {
            lameduck 5s
          }
          ready
          kubernetes cluster.local in-addr.arpa ip6.arpa {
            pods insecure
            fallthrough in-addr.arpa ip6.arpa
          }
          prometheus :9153
          forward . /etc/resolv.conf
          cache 30
          loop
          reload
          loadbalance
        }
        import custom/*.server
     
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: obp-coredns
      name: obp-coredns
      namespace: obp-coredns
    spec:
      progressDeadlineSeconds: 600
      replicas: 1
      revisionHistoryLimit: 10
      selector:
        matchLabels:
          app: obp-coredns
      strategy:
        type: RollingUpdate
      template:
        metadata:
          labels:
            app: obp-coredns
        spec:
          containers:
          - args:
            - -conf
            - /etc/coredns/Corefile
            image: docker.io/coredns/coredns:latest
            imagePullPolicy: IfNotPresent
            livenessProbe:
              failureThreshold: 5
              httpGet:
                path: /health
                port: 8080
                scheme: HTTP
              initialDelaySeconds: 60
              periodSeconds: 10
              successThreshold: 1
              timeoutSeconds: 5
            name: coredns
            ports:
            - containerPort: 1053
              name: dns
              protocol: UDP
            - containerPort: 1053
              name: dns-tcp
              protocol: TCP
            - containerPort: 9153
              name: metrics
              protocol: TCP
            readinessProbe:
              failureThreshold: 3
              httpGet:
                path: /ready
                port: 8181
                scheme: HTTP
              periodSeconds: 10
              successThreshold: 1
              timeoutSeconds: 1
            resources:
              limits:
                memory: 170Mi
              requests:
                cpu: 100m
                memory: 70Mi
            securityContext:
              allowPrivilegeEscalation: false
              capabilities:
                add:
                - NET_BIND_SERVICE
                drop:
                - all
              readOnlyRootFilesystem: true
            terminationMessagePath: /dev/termination-log
            terminationMessagePolicy: File
            volumeMounts:
            - mountPath: /etc/coredns
              name: config-volume
              readOnly: true
            - mountPath: /etc/coredns/custom
              name: custom-config-volume
              readOnly: true
          dnsPolicy: Default
          restartPolicy: Always
          schedulerName: default-scheduler
          securityContext: {}
          serviceAccount: obp-coredns
          serviceAccountName: obp-coredns
          terminationGracePeriodSeconds: 30
          volumes:
          - configMap:
              defaultMode: 420
              items:
              - key: Corefile
                path: Corefile
              name: coredns
            name: config-volume
          - configMap:
              defaultMode: 420
              name: coredns-custom
              optional: true
            name: custom-config-volume
     
    ---
    apiVersion: v1
    kind: Service
    metadata:
      labels:
        app: obp-coredns
      name: obp-coredns
      namespace: obp-coredns
    spec:
      ports:
      - name: dns
        port: 53
        protocol: UDP
        targetPort: 1053
      - name: dns-tcp
        port: 53
        protocol: TCP
        targetPort: 1053  
      - name: metrics
        port: 9153
        protocol: TCP
        targetPort: 9153
      selector:
        app: obp-coredns
      sessionAffinity: None
      type: ClusterIP
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: obp-coredns
      namespace: obp-coredns
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: obp-coredns
    rules:
    - apiGroups:
      - ""
      resources:
      - endpoints
      - services
      - pods
      - namespaces
      verbs:
      - list
      - watch
    - apiGroups:
      - ""
      resources:
      - nodes
      verbs:
      - get
    - apiGroups:
      - discovery.k8s.io
      resources:
      - endpointslices
      verbs:
      - list
      - watch
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: obp-coredns
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: obp-coredns
    subjects:
    - kind: ServiceAccount
      name: obp-coredns
      namespace: obp-coredns
    
  3. Create a coredns-custom-configmap file in YAML format for your blockchain instance.
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: coredns-custom
      namespace: obp-coredns
    data:
      obp.server: |2
     
        <instanceName>.<domain>:1053 {
            log
            kubernetes cluster.local in-addr.arpa ip6.arpa {
                pods insecure
                fallthrough in-addr.arpa ip6.arpa
            }
            rewrite stop {
                name regex (.*)\.<instanceName>\.<domain>\ istio-ingressgateway.istio-system.svc.cluster.local answer auto
            }
            forward . /etc/resolv.conf
        }
    
    In the previous example, <instanceName> is the name of the instance and <domain> is the parent domain.
  4. Run the following command to apply the custom ConfigMap object.
    kubectl apply -f <coredns-custom-configmap-yaml-file>
  5. Run the following command to get the cluster IP address. Record the IP address.
    kubectl get svc -n obp-coredns
  6. Run the following command to edit the OpenShift DNS custom resource.
    kubectl edit dnses.operator/default
  7. Update the zones section of the DNS custom resource to use your instance and domain names, as shown in the following example.
    ## Add the following section to the dns custom resource under spec
      servers:
      - forwardPlugin:
          policy: Random
          upstreams:
          - 192.0.2.233
        name: obp-server
        zones:
        - <instanceName>.<domain>
    In the previous example, <instanceName> is the name of the instance and <domain> is the parent domain.
  8. To add new instances, add entries to the coredns-custom-configmap file and update the OpenShift DNS custom resource for the domain of the new instance as shown in the following example.
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: coredns-custom
      namespace: obp-coredns
    data:
      obp.server: |2
     
        myobp.example.com:1053 {
            log
            kubernetes cluster.local in-addr.arpa ip6.arpa {
                pods insecure
                fallthrough in-addr.arpa ip6.arpa
            }
            rewrite stop {
                name regex (.*)\.myobp\.example\.com istio-ingressgateway.istio-system.svc.cluster.local answer auto
            }
            forward . /etc/resolv.conf
        }
     
        otherobp.example.org:1053 {
            log
            kubernetes cluster.local in-addr.arpa ip6.arpa {
                pods insecure
                fallthrough in-addr.arpa ip6.arpa
            }
            rewrite stop {
                name regex (.*)\.otherobp\.example\.org istio-ingressgateway.istio-system.svc.cluster.local answer auto
            }
            forward . /etc/resolv.conf
        }
    
    
    
    ## Edit the Openshift's DNS custom resource
    kubectl edit dnses.operator/default
     
    ## Add the new instance domain to the existing .spec.servers.zones
      servers:
      - forwardPlugin:
          policy: Random
          upstreams:
          - 192.0.2.233
        name: obp-server
        zones:
        - myobp.example.com
        - otherobp.example.org
    You must stop and restart the instance for DNS changes to take effect.
Before accessing the Oracle Blockchain Platform service console, configure the hostname resolution for the blockchain instance services, similar to what you did earlier for the Blockchain Platform Manager hostnames. Use the following command to get the list of hostnames for the created blockchain instance:
kubectl get virtualservice -n <instance-namespace> -o json | jq -r
      .items[].spec.hosts[0]

Add Additional Nodes to Cluster

It's possible for the instance creation to fail due to insufficient nodes in the cluster. If this occurs, you may need to add more nodes to the cluster.
  1. Run the following command to check for pods in the Pending state:
    kubectl get pods -n <instancename> | grep Pending
    Additionally you can check for no pods being available:
    kubectl get pods -n instancename
  2. Next, check the available worker nodes:
    kubectl get nodes | grep worker
  3. To check if there are nodes available to take new pods, run the following command against each worker node:
    kubectl describe node $<worker_node>
    where <worker_node> is the name of a worker node. Ensure that the worker node does not exceed 100% capacity.
  4. To add additional nodes, first get the number of MachineSets in the cluster:
    oc get machinesets -n openshift-machine-api
  5. For any MachineSets with fewer than 2 nodes, try upscaling them.
    oc scale --replicas=2 machineset <obpee00-qtthx-worker-eastus2> -n openshift-machine-api
    where <obpee00-qtthx-worker-eastus2> is an example name of a MachineSet you want to upscale to 2 nodes.
  6. Query the MachineSets again until the list of ready and available nodes reaches the number of nodes you've selected.
  7. You can now redeploy your failed instances.

Once your instance has been created and is listed in the Instances list, you can launch the service console from the menu next to the instance name. Use the console to configure your network as described in What's the Console? in Using Oracle Blockchain Platform.