Bookmark this page

Guided Exercise: Configuring Service Discovery

In this exercise, you will use Red Hat 3scale API Management service discovery capabilities to automatically set up 3scale API Management products and backends from applications deployed on OpenShift.

Outcomes

You should be able to:

  • Configure a Red Hat OpenShift Container Platform (RHOCP) service to make it discoverable by 3scale.

  • Import a discovered OpenShift service to automatically create a 3scale product and 3scale backend.

  • Make the product accessible through the staging APIcast gateway.

As the student user on the workstation machine, use the lab command to prepare your system for this exercise.

[student@workstation ~]$ lab start applications-discovery

Procedure 2.4. Instructions

  1. Create an OpenShift project called library and deploy the sample application books-api from the Git repository.

    1. Log in to RHOCP as the admin user.

      [student@workstation ~]$ oc login -u=admin -p=redhat \
        --server=https://api.ocp4.example.com:6443
      Login successful.
    2. Create the library project.

      [student@workstation ~]$ oc new-project library
      Now using project "library" on server "https://api.ocp4.example.com:6443".
      ...output omitted...
    3. Deploy the books-api sample application and name it books-api.

      [student@workstation ~]$ oc new-app \
        --name=books-api \
        --context-dir=library/books-api \
        --build-env NODE_ENV=development \
        https://github.com/RedHatTraining/DO240-apps.git
      ...output omitted...
        --> Success
          Build scheduled, use 'oc logs -f buildconfig/books-api' to track its progress.
      ...output omitted...
  2. Make the service discoverable from 3scale. Add the required metadata to books-api, ensure service discovery is enabled, and give the amp service account view permissions to the library project.

    1. Add the service label discovery.3scale.net: "true".

      [student@workstation ~]$ oc label svc/books-api \
        discovery.3scale.net="true"
      service/books-api labeled
    2. Add the service annotations discovery.3scale.net/scheme: "http" and discovery.3scale.net/port: "8080".

      [student@workstation ~]$ oc annotate svc/books-api  \
        discovery.3scale.net/port="8080"
      service/books-api annotated
      [student@workstation ~]$ oc annotate svc/books-api \
        discovery.3scale.net/scheme="http"
      service/books-api annotated
    3. Verify that the books-api service has been modified accordingly.

      [student@workstation ~]$ oc get service books-api -o yaml
      
      apiVersion: v1
      kind: Service
      metadata:
        annotations:
          openshift.io/generated-by: OpenShiftNewApp
          discovery.3scale.net/scheme: http
          discovery.3scale.net/port: "8080"
        labels:
          app: books-api
          app.kubernetes.io/component: books-api
          app.kubernetes.io/instance: books-api
          discovery.3scale.net: "true"
        name: books-api
        namespace: library
      spec:
      ...output omitted...
    4. Validate that 3scale service discovery is enabled. Describe the system configmap in the 3scale project and, under service_discovery.yml, verify that the following values show for the keys production.enabled, production.bearer_token, and production.authentication_method.

      [student@workstation ~]$ oc describe configmap system -n 3scale
      ...output omitted...
      service_discovery.yml:
      
        production:
          enabled: <%= cluster_token_file_exists = File.exists?(cluster_token_file_path ='/var/run/secrets/kubernetes.io/serviceaccount/token') %>
          bearer_token: "<%= File.read(cluster_token_file_path) if cluster_token_file_exists %>"
          authentication_method: service_account
      ...output omitted...
    5. Grant the 3scale amp service account with view permissions on the library project so that 3scale can access the books-api service metadata.

      [student@workstation ~]$ oc policy add-role-to-user \
        view system:serviceaccount:3scale:amp -n library
      clusterrole.rbac.authorization.k8s.io/view added: "system:serviceaccount:3scale:amp"
    6. Run the ls-discoverable.sh script from the ~/DO240-apps/scripts directory to verify that the books-api service has the correct metadata. Also, verify that the 3scale amp service account has access to the library project.

      The ls-discoverable.sh script lists services in all namespaces that have the label discovery.3scale.net set to true and have the required 3scale annotations. You must verify that the annotations values are correct because the script only determines the annotation existence.

      [student@workstation ~]$ ~/DO240-apps/scripts/ls-discoverable.sh
      {
        "service-name": "books-api",
        "service-namespace": "library",
        "labels": {
          "app": "books-api",
          "app.kubernetes.io/component": "books-api",
          "app.kubernetes.io/instance": "books-api",
          "discovery.3scale.net": "true"
        },
        "annotations": {
          "discovery.3scale.net/port": "8080",
          "discovery.3scale.net/scheme": "http",
          "openshift.io/generated-by": "OpenShiftNewApp"
        }
      }

      If ls-discoverable.sh does not print anything, verify that you added the required metadata correctly.

      Run the following command to validate that 3scale can access your service definition.

      [student@workstation ~]$ oc get rolebinding -o wide -A \
        | grep -E 'NAME|ClusterRole/view|3scale/amp'
      NAMESPACE  NAME   ROLE               AGE     USERS   GROUPS   SERVICEACCOUNTS
      library    view   ClusterRole/view   5d22h                    3scale/amp

      From the previous command note that the amp service account has the ClusterRole/view in the library namespace. Therefore, our service is visible from 3scale.

  3. Import the 3scale product and backend by using the 3scale Admin Portal.

    1. Navigate to https://3scale-admin.apps.ocp4.example.com to access the Admin Portal by using the credentials provided in previous sections.

    2. Click Products on the top pane's drop-down menu to go to the products page.

      Figure 2.20: 3scale tenant administration portal
    3. Click Create Product.

      Figure 2.21: 3scale products page
    4. In the New Product form, select Import from OpenShift. This populates the Namespace and Name drop-down menus with the discovered services. Select books-api in the Name selector field and click Create Product.

      Note

      If services do not show in the Namespace drop-down menu, verify that the label and the annotations are correct. Also, validate that the 3scale amp service account has view permissions on your service namespace.

      Figure 2.22: 3scale new product page
    5. Go to the products page and verify that 3scale imported the discovered service.

      Figure 2.23: 3scale imported product
  4. To access the books-api through 3scale, create an application plan and an application by using 3scale Toolbox CLI. Use the 3scale-tenant remote configured in previous sections.

    Note

    The Toolbox CLI has the -h help option, which provides reference information for 3scale commands and subcommands.

    To find out which arguments you need to create an application, you can execute the following command.

    [student@workstation ~]$ 3scale application create -h

    Note

    The 3scale alias created in previous sections uses the -k option because the 3scale Toolbox CLI container image does not have the proper certificate installed. If you get SSL certificate errors then you can either use the -k to avoid verifying the certificate's validity or install a valid certificate.

    1. Create an application plan called library_basic_plan by using the 3scale Toolbox CLI in the command line.

      [student@workstation ~]$ 3scale application-plan create \
        3scale-tenant library-books-api library_basic_plan
      Created application plan id: 13. Default: false; Disabled: false
    2. Create an application on the default john account, with the name library-app, and assign it the library_basic_plan.

      [student@workstation ~]$ 3scale application create \
        3scale-tenant john library-books-api library_basic_plan library-app
      Created application id: 7
  5. Make a curl request to the /books endpoint in the staging APIcast service to determine whether we can reach the API through 3scale.

    1. Go to the books-api product page in the 3scale Admin Portal. Then, go to IntegrationConfiguration and scroll down to the Staging APIcast section to copy the example curl command.

      Figure 2.24: Staging APIcast configuration
    2. Edit the copied curl command to send a request to the /books endpoint.

      [student@workstation ~]$ curl \
        https://library-books-api-3scale-apicast-staging.apps.ocp4.example.com:443/books?user_key=YOUR_USER_KEY
      [{"title":"Frankenstein", ...
      ...output omitted...
  6. Update the books-api OpenShift service port to 8181. Repeat the curl request to see it fail.

    1. Edit the books-api OpenShift service to make it listen on port 8181.

      [student@workstation ~]$ oc edit service books-api
      ...output omitted...
      spec:
        ports:
        - name: 8080-tcp
          port: 8181
          protocol: TCP
          targetPort: 8080
    2. Execute the curl command to verify that we can no longer reach books-api.

      [student@workstation ~]$ curl \
        https://library-books-api-3scale-apicast-staging.apps.ocp4.example.com:443/books?user_key=YOUR_USER_KEY
      <html>
      <head><title>502 Bad Gateway</title></head>
      <body>
      <center><h1>502 Bad Gateway</h1></center>
      <hr><center>openresty</center>
      </body>
      </html>
    3. Find the pod running the APIcast staging service.

      [student@workstation ~]$ oc get pods -l threescale_component=apicast -n 3scale
      NAME                         READY   STATUS    RESTARTS   AGE
      apicast-production-1-j2jsl   1/1     Running   4          3d18h
      apicast-staging-1-s8tq8      1/1     Running   4          3d18h
    4. Inspect the logs in the APIcast staging service to see why it fails.

      [student@workstation ~]$ oc logs apicast-staging-1-s8tq8 -n 3scale \
        | grep "No route to host"
      ...output omitted...
      ... [error] 22#22: \*1385 connect() failed (113: No route to host) ... upstream: "http://172.30.204.151:8080/books?user_key=6a...
      ...output omitted...

      From the previous log, notice that 3scale is trying to reach our service on port 8080 and APIcast can not find anything on that port.

      We can search for our books-api service to verify that it is running on port 8181.

      [student@workstation ~]$ oc get service books-api
      NAME        TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
      books-api   ClusterIP   172.30.204.151   <none>        8181/TCP   3d18h
    5. Revert the service port to its original value and send another request to see it succeed.

      [student@workstation ~]$ oc edit service books-api
      ...output omitted...
      spec:
        ports:
        - name: 8080-tcp
          port: 8080
          protocol: TCP
          targetPort: 8080
      ...output omitted...
      
      [student@workstation ~]$ curl \
        https://library-books-api-3scale-apicast-staging.apps.ocp4.example.com:443/books?user_key=YOUR_USER_KEY
      [{"title":"Frankenstein", ...output omitted...

Finish

On the workstation machine, use the lab command to complete this exercise. This is important to ensure that resources from previous exercises do not impact upcoming exercises.

[student@workstation ~]$ lab finish applications-discovery

This concludes the guided exercise.

Revision: do240-2.11-40390f6