Setting up Red Hat Connectivity Link using the OpenShift Console
Prerequisites
- OpenShift 4.16 or 4.17 with admin privileges.
oc
orkubectl
installed.- Log into the OpenShift cluster from your local terminal.
- 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.
Download the pull secret from the Red Hat Hybrid Cloud Console (Figure 1).
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.
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>
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
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.
- Navigate to the OperatorHub.
- Search for the OpenShift Service Mesh 3.0 operator.
Install the Operator with all the default values (Figure 2).
Figure 2: Install the operator. Wait until the Operator is installed (Figure 3).
Figure 3: The operator is ready for use. 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).Figure 4: Find the istio-system project. - Click on the Create Istio button and toggle to the YAML view of the definition.
Click the Create button with default values and wait till the status turns to Healthy (Figure 5).
Figure 5: Status is healthy.
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.
- Navigate to the Operator Hub and search for the
cert-manager
Operator. Install the operator with the default values (Figure 6).
Figure 6: Select the cert-manager operator. - Click on the
cert-manager
for OpenShift and navigate to the ClusterIssuer tab. Click Create ClusterIssuer (Figure 7).
Figure 7: Create a ClusterIssuer. Navigate to YAML view to examine and replace the YAML with:
apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: selfsigned spec: selfSigned: {}
- Click the Create button.
- Navigate to the
kuadrant-system
namespace. Search from Red Hat Connectivity link operator from the Operator Hub (Figure 8).
Figure 8: rhcl-operator-hub - Choose the 1.0.2 version. Click on the install button with all the default values.
After the operator installation is complete, click on View Operator then navigate to the Kuadrant resource tab from the operator view. (Figure 9).
Figure 9: Create the Kuadrant resource 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: {}
Wait for the resource to be ready (Figure 10).
Figure 10: Kuadrant resource status list. - Enable the OpenShift Plug-in, which enables us to create all the resources and policies from a centralized location.
- Navigate to Home > Overview.
Click on Dynamic Plugins, then select the View All link (Figure 11).
Figure 11: Select the View All link. Click on the edit icon on the right of
kuadrant-console-plugin
(Figure 12).Figure 12: Click on the edit icon. Enable the plugin and select Save (Figure 13). Wait for a few seconds to a minute, until you are prompted to refresh the console.
Figure 13: Prompt to refresh the console. Refresh your browser once you get that prompt (Figure 14).
Figure 14: Refresh your browser.
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.
- If your plugin installation is successful, you will see the Connectivity Link option on your console.
From the Administrator perspective, navigate to Connectivity Link > Overview (Figure 15).
Figure 15: Go to the Overview. Click on Create Gateway (Figure 16).
Figure 16: Click on Create Gateway. 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
Figure 17: Replace the YAML and select Create. Navigate back to the Connectivity Link > Overview and click on Create HTTPRoute (Figure 18).
Figure 18: Create HTTPRoute. 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: /
Figure 19: Replace the YAML, then select Create.
A TLS policy targets Gateway API networking resources Gateways to provide TLS for gateway listeners by managing the lifecycle of TLS certificates using CertManager.
From the Connectivity Link Overview page, click on Create Policy and select TLS Policy (Figure 20).
Figure 20: Select TLS Policy. 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
- Select Create.
Make sure the status of the TLS policy is Enforced (Figure 21).
Figure 21: TLS policy status should be enforced. 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}')
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.
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
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.
From the Connectivity Link Overview, click on Create Policy and select Auth Policy (Figure 22).
Figure 22: Add Custom Resource using OpenShift console. 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
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
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.
- First, create some sample API keys as secrets.
From your OpenShift console, click on the + icon and add this YAML to create the secret (Figure 23).
Figure 23: Select Create Policy then Auth Policy. 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.
From the Connectivity Link overview, click on Create Policy then select Auth Policy (Figure 24).
Figure 24: Select Create Policy then RateLimit Policy. 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
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
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"
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.
From the Connectivity Link overview, click on Create Policy then select RateLimit Policy (Figure 25).
Figure 25: Select Create Policy then RateLimit Policy. 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
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
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.