Setting up Red Hat Connectivity Link using the OpenShift Console

Prerequisites

  1. OpenShift 4.16 or 4.17 with admin privileges. 
  2. oc or kubectl installed.
  3. Log into the OpenShift cluster from your local terminal.
  4. Credentials to download images from Red Hat Registry. If you don’t already have one, register for a Red Hat account and download your credentials using this link.
  5. Download the pull secret from the Red Hat Hybrid Cloud Console (Figure 1).

    Download pull secret for registry access
    Figure 1: Download the pull secret
    Figure 1: Download the pull secret.

    Note: If you do not land on the Pull Secret page even after registering and signing in using the new account, click here.

  6. In the ingress-gateway namespace, create a secret using the file downloaded in the prior step. Ensure you update the file path at the end of the command accordingly.

    oc create secret docker-registry wasm-plugin-pull-secret -n ingress-gateway --from-file=.dockerconfigjson=<Replace with the path of the file where you downloaded the registry credentials>
  7. Create all the required namespaces.

    oc new-project istio-system
    oc new-project ingress-gateway
    oc new-project node-api
    oc new-project kuadrant-system

Install the OpenShift Service Mesh 3.0 operator

We are going to use Istio as the Gateway API provider in this example, and the OpenShift Service Mesh 3.0 operator provides the Istio Gateway API installation.

  1. Navigate to the OperatorHub. 
  2. Search for the OpenShift Service Mesh 3.0 operator. 
  3. Install the Operator with all the default values (Figure 2).

    The Install Operator landing page.
    Figure 2: Install the operator.
  4. Wait until the Operator is installed (Figure 3).

    When the operator is installed, you’ll get a message telling you it’s ready.
    Figure 3: The operator is ready for use.
  5. Navigate to the OpenShift Service Mesh operator from the Installed Operators section then to the Istio section. Make sure you are on the istio-system project (Figure 4).

    The Installed Operators tab listing the provided APIs.
    Figure 4: Find the istio-system project.
  6. Click on the Create Istio button and toggle to the YAML view of the definition.
  7. Click the Create button with default values and wait till the status turns to Healthy (Figure 5).

    The Istio dashboard indicates the status is Healthy.
    Figure 5: Status is healthy.

Deploy the Gateway API CRDs

Enable the CRDs by running the following command on your terminal where you are logged into your cluster:

oc get crd gateways.gateway.networking.k8s.io &> /dev/null || { oc kustomize "github.com/kubernetes-sigs/gateway-api/config/crd?ref=v1.0.0" | oc apply -f -; }

Deploy the sample Workload

We’ll deploy a simple Node.js API on OpenShift which returns a list of books. We’ll connect, secure, and protect this API using the Red Hat Connectivity link in the subsequent steps.

Deploy the service.

oc project node-api
oc new-app quay.io/vravula_redhat/node-api:test

Deploy the Cert Manager Operator

Cert Manager manages TLS certificates for our components and the Gateways. It consumes Certificate resources created by the Connectivity Link operator in response to the TLSPolicy.

  1. Navigate to the Operator Hub and search for the cert-manager Operator. 
  2. Install the operator with the default values (Figure 6).

    Select the cert-manager operator and install with the default values.
    Figure 6: Select the cert-manager operator.
  3. Click on the cert-manager for OpenShift and navigate to the ClusterIssuer tab.
  4. Click Create ClusterIssuer (Figure 7).

    The ClusterIssuer tab.
    Figure 7: Create a ClusterIssuer.
  5. Navigate to YAML view to examine and replace the YAML with:

    apiVersion: cert-manager.io/v1
    kind: ClusterIssuer
    metadata:
     name: selfsigned
    spec:
     selfSigned: {} 
  6. Click the Create button.

Install the Red Hat Connectivity Link Operator

  1. Navigate to the kuadrant-system namespace. 
  2. Search from Red Hat Connectivity link operator from the Operator Hub (Figure 8).

    rhcl-operator-hub
    Figure 8: rhcl-operator-hub
  3. Choose the 1.0.2 version. Click on the install button with all the default values.
  4. After the operator installation is complete, click on View Operator then navigate to the Kuadrant resource tab from the operator view. (Figure 9).

    Kuadrant resource tab from the operator view .
    Figure 9: Create the Kuadrant resource
  5. Create a new Kuadrant resource by replacing the existing YAML with the one below.

    kind: Kuadrant
    apiVersion: kuadrant.io/v1beta1
    metadata:
     name: kuadrant
     namespace: kuadrant-system
    spec: {}
  6. Wait for the resource to be ready (Figure 10).

    The resource is Ready.
    Figure 10: Kuadrant resource status list.
  7. Enable the OpenShift Plug-in, which enables us to create all the resources and policies from a centralized location.
  8. Navigate to Home > Overview.
  9. Click on Dynamic Plugins, then select the View All link (Figure 11).

    Select the View All link.
    Figure 11: Select the View All link.
  10. Click on the edit icon on the right of kuadrant-console-plugin (Figure 12).

    Click on the edit icon.
    Figure 12: Click on the edit icon.
  11. Enable the plugin and select Save (Figure 13). Wait for a few seconds to a minute, until you are prompted to refresh the console.

    The prompt to refresh the console.
    Figure 13: Prompt to refresh the console.
  12. Refresh your browser once you get that prompt (Figure 14).

    Refresh your browser.
    Figure 14: Refresh your browser.

Deploy the Gateway and HTTP Route

This is the gateway through which we allow ingress traffic into the cluster. In the below YAML, the Gateway represents the instantiation of a logical load balancer and the Gateway Class defines the load balancer template when users create a Gateway.

  1. If your plugin installation is successful, you will see the Connectivity Link option on your console.
  2. From the Administrator perspective, navigate to Connectivity Link > Overview (Figure 15).

    The Overview tab is underneath Connectivity Link on the left-side menu.
    Figure 15: Go to the Overview.
  3. Click on Create Gateway (Figure 16).

    Click on Create Gateway.
    Figure 16: Click on Create Gateway.
  4. Replace the existing boilerplate YAML with the gateway definition below and select Create (Figure 17).

    apiVersion: gateway.networking.k8s.io/v1
    kind: Gateway
    metadata:
     name: prod-web
     namespace: ingress-gateway
    spec:
     gatewayClassName: istio
     listeners:
       - allowedRoutes:
           namespaces:
             from: All
         name: api
         hostname: "*.com"
         port: 443
         protocol: HTTPS
         tls:
           mode: Terminate
           certificateRefs:
             - name: node-local-tls
               kind: Secret
    Replace the YAML and select Create.
    Figure 17: Replace the YAML and select Create.
  5. Navigate back to the Connectivity Link > Overview and click on Create HTTPRoute (Figure 18).

    Create HTTPRoute.
    Figure 18: Create HTTPRoute.
  6. Replace the YAML with the HTTPRoute definition below and select Create (Figure 19). Make sure the status is Enforced for both the gateway and HTTP Route.

    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
     name: node-api
     namespace: node-api
    spec:
     parentRefs:
       - group: gateway.networking.k8s.io
         kind: Gateway
         name: prod-web
         namespace: ingress-gateway
     rules:
       - backendRefs:
           - group: ''
             kind: Service
             name: node-api
             namespace: node-api
             port: 8080
             weight: 1
         matches:
           - path:
               type: PathPrefix
               value: /
    Replace the YAML, then select Create.
    Figure 19: Replace the YAML, then select Create.

Create a TLS Policy

A TLS policy targets Gateway API networking resources Gateways to provide TLS for gateway listeners by managing the lifecycle of TLS certificates using CertManager.

  1. From the Connectivity Link Overview page, click on Create Policy and select TLS Policy (Figure 20).

    Select TLS Policy.
    Figure 20: Select TLS Policy.
  2. Switch to the YAML view and replace the existing YAML with the following TLS Policy YAML:

    apiVersion: kuadrant.io/v1
    kind: TLSPolicy
    metadata:
     name: prod-web-tls
     namespace: ingress-gateway
    spec:
     targetRef:
       name: prod-web
       group: gateway.networking.k8s.io
       kind: Gateway
     issuerRef:
       group: cert-manager.io
       kind: ClusterIssuer
       name: selfsigned
  3. Select Create.
  4. Make sure the status of the TLS policy is Enforced (Figure 21).

    TLS policy status should be enforced.
    Figure 21: TLS policy status should be enforced.
  5. Get the gateway hostname by running the following command from your terminal where you are logged into the OpenShift Cluster:

    export INGRESS_HOST=$(oc get gtw prod-web -n ingress-gateway -o jsonpath='{.status.addresses[0].value}')
  6. Check the address of your gateway.

    echo $INGRESS_HOST

    Note: If you do not see a value here or see an error status message waiting for address assignment, double-check if your cluster has a default load balancer that can assign an address to your gateway. 

  7. Make a call to the gateway. You should be able to access the API. It is protected by TLS policy. Make note of https in the URL. This shows that the TLS policy has been applied.

    curl -v -k https://$INGRESS_HOST/books

Auth policy: Create a Deny all auth policy at the gateway level

Creating a deny-all auth policy at the gateway level establishes a zero-trust auth policy. The Development teams should create a specific auth policy for the routes they'd like to provide access to. With Connectivity Link, you can add policies both at the gateway level or at the HTTPRoute (service) level.

  1. From the Connectivity Link Overview, click on Create Policy and select Auth Policy (Figure 22).

    Add Custom Resource using OpenShift console
    Figure 22: Add Custom Resource using OpenShift console.
  2. Replace the existing boilerplate YAML with the below Auth policy definition. Notice the spec.target.Ref where we are targeting the gateway. Make sure the status shows up as Enforced.

    apiVersion: kuadrant.io/v1
    kind: AuthPolicy
    metadata:
     name: prod-web-deny-all
     namespace: ingress-gateway
    spec:
     rules:
       authorization:
         deny-all:
           metrics: false
           opa:
             allValues: false
             rego: allow = false
           priority: 0
       response:
         unauthorized:
           body:
             value: |
               {
                 "error": "Forbidden",
                 "message": "Access denied by default by the gateway operator. If you are the administrator of the service, create a specific auth policy for the route."
               }
           headers:
             content-type:
               value: application/json
     targetRef:
       group: gateway.networking.k8s.io
       kind: Gateway
       name: prod-web
  3. Try to access the API again and you should see a 403 error and an error message stating  "error": "Forbidden",
     "message": "Access denied by default by the gateway operator. If you are the administrator of the service, create a specific auth policy for the route." This shows that the gateway is secure by default and has a zero trust policy. 

    curl -k -w "%{http_code}" https://$INGRESS_HOST/books

Create an API key-based auth policy for the API

Now imagine that you are a development team and you want to provide a key-based access to your API. You can create an API key-based auth policy specific for the API.

  1. First, create some sample API keys as secrets. 
  2. From your OpenShift console, click on the + icon and add this YAML to create the secret (Figure 23).

    Select Create Policy then Auth Policy.
    Figure 23: Select Create Policy then Auth Policy.
  3. Add the following YAML and select Create to create the secrets

    apiVersion: v1
    kind: Secret
    metadata:
     name: api-key-regular-user
     namespace: kuadrant-system
     labels:
       authorino.kuadrant.io/managed-by: authorino
    stringData:
     api_key: iamaregularuser
    type: Opaque
    ---
    apiVersion: v1
    kind: Secret
    metadata:
     name: api-key-admin-user
     namespace: kuadrant-system
     labels:
       authorino.kuadrant.io/managed-by: authorino
     annotations:
       kuadrant.io/groups: admins
    stringData:
     api_key: iamanadmin
    type: Opaque

    Note: This is just a simple example with string based keys. You can also use an OIDC provider to authenticate the users. 

  4. From the Connectivity Link overview, click on Create Policy then select Auth Policy (Figure 24).

    Select Create Policy then RateLimit Policy.
    Figure 24: Select Create Policy then RateLimit Policy.
  5. Replace the existing boilerplate YAML with the below Auth policy definition. Notice the spec.target.Ref where we are targeting the HTTPRoute. Make sure the status shows up as Enforced on the Connectivity link overview page.

    apiVersion: kuadrant.io/v1
    kind: AuthPolicy
    metadata:
     name: node-api-allow-key
     namespace: node-api
    spec:
     targetRef:
       group: gateway.networking.k8s.io
       kind: HTTPRoute
       name: node-api
     rules:
       authentication:
         "api-key-authn":
           apiKey:
             selector: {}
           credentials:
             queryString:
               name: apikey
  6. Now access the API without the key. You should see a 401 error and the access should be denied.

    curl -k -w "%{http_code}\n" https://$INGRESS_HOST/books
  7. Now access it with the API key and it should return a list of books along with the HTTP code 200

    curl -k -w "\n%{http_code}\n" "https://$INGRESS_HOST/books?apikey=iamaregularuser"

Create a rate limit policy at the gateway level

Rate Limit policy targets Gateway API networking resources such as HTTPRoutes and Gateways, using these resources to obtain additional context, i.e., which traffic workload (HTTP attributes, hostnames, user attributes, etc) to rate limit

In our example, we are going to rate-limit at the gateway level.

  1. From the Connectivity Link overview, click on Create Policy then select RateLimit Policy (Figure 25).

    Select Create Policy then RateLimit Policy.
    Figure 25: Select Create Policy then RateLimit Policy.
  2. Replace the existing boilerplate YAML with the below Rate Limit policy definition. Notice the spec.limits.rates which defines the limits and time period. Make sure the status shows up as Enforced on the Connectivity link overview page.

    apiVersion: kuadrant.io/v1
    kind: RateLimitPolicy
    metadata:
     name: prod-web-rlp-lowlimits
     namespace: ingress-gateway
    spec:
     limits:
       default-limits:
         rates:
           - limit: 3
             window: 10s
     targetRef:
       group: gateway.networking.k8s.io
       kind: Gateway
       name: prod-web
  3. Now access the API more than 3 times within 10 seconds to violate the rate limits and you should see a 429 with a Too many requests message after the first 3 calls.

    for i in {1..10}; do curl -k -w "\n%{http_code}\n" "https://$INGRESS_HOST/books?apikey=iamaregularuser"; done

Conclusion

This is a quick guide to set up the Red Hat Connectivity Link on OpenShift. For a more in-depth deeper dive, please refer to the Red Hat Connectivity Link Solution Pattern or the product documentation.