Table of Contents
Different scenarios integrating APIcast with istio using example Bookinfo APP.
Let's use the Bookinfo APP and a Standard Istio deployment:
┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│Openshift │
│ │
│ ┌───────────────────────────────────────────────────────────────────────────────┐ │
│ │ Service Mesh │ │
│ │ │ │
│ │ ┌─────────────┐ │ │
│ │ │ │ │ │
│ │ │ │ │ │
│ │ ┌──▶│ Reviews │ │ │
│ │ │ │ │ │ │
│ │ │ │ │ ┌────┴─────────┐ │
┌──────┴────────┐ ┌─────────┴──────┐ ┌────────────────┐ │ └─────────────┘ │ │ │
│ │ │ │ │ │ │ │ Istio Egress │ │
│ Openshift │ │ Istio Ingress │ │ │ │ │ Gateway │ │
│Haproxy Router │───▶│ Gateway │─────▶│ Product Page │───┤ │ │ │
│ │ │ │ │ │ │ └────┬─────────┘ │
└──────┬────────┘ └─────────┬──────┘ │ │ │ │ │
│ │ └────────────────┘ │ │ │
│ │ │ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ │ │ │ │ │ │
│ │ │ │ │ │ │ │ │
│ │ └──▶│ Details │───────▶│ Ratings │ │ │
│ │ │ │ │ │ │ │
│ │ │ │ │ │ │ │
│ │ └─────────────┘ └─────────────┘ │ │
│ │ │ │
│ └───────────────────────────────────────────────────────────────────────────────┘ │
│ │
│ │
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
The bookinfo app has a single point of entry, the "Product Page" service. This service exposes a web page, and the Bookinfo API via: /api/v1/products
.
For example:
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│Openshift │
│ ┌───────────────────────────────────────────────────────────────────────────────┐ │
│ │ Service Mesh │ │
│ │ │ │
│ │ ┌─────────────┐ │ │
│ │ │ │ │ │
│ │ ┌───▶│ Reviews │ │ │
│ │ │ │ │ │ │
┌───┴───────────┐ ┌───────┴────────┐ ┌────────────────┐ │ └─────────────┘ │ │
│ │ │ │ │ │ │ │ │
│ Openshift │ │ Istio Ingress │ │ │ │ │ │
─────────▶│Haproxy Router │───────▶│ Gateway │──┬──▶│ Product Page │───┤ │ │
│ │ │ │ │ │ │ ┌─────────────┐ ┌─────────────┐ │ │
└───┬───────────┘ └───────┬────────┘ │ │ │ │ │ │ │ │ │ │
│ │ └────────────────┘ │ │ │ │ │ │ │
│ │ ─ ─ ─ ┘ ▲ └───▶│ Details │────▶│ Ratings │ │ │
│ │ │ │ │ │ │ │ │
│ │ └ ─ │ │ │ │ │ │
│ │ │ ┌────────────────┐ │ └─────────────┘ └─────────────┘ │ │
│ │ │ │ │ │
│ │ └ ▶│ APIcast │─ ┘ │ │
│ │ │ │ │ │
│ │ └────────────────┘ │ │
│ │ │ │ │
│ │ └────────────────────────┐ │ │
│ │ ▼ │ │
│ │ ┌──────────────┐ │ │
│ │ │ │ │ │
│ │ │ Istio Egress │ │ │
│ └─────────────────────────────────┤ Gateway ├──────────────────────────────┘ │
│ │ │ │
│ └──────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────┐ │
│ │ │ │
│ │ 3scale Control Plane │ │
│ │ │ │
│ └──────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
- - - - - API traffic.
Add needed perms:
oc adm policy add-scc-to-user anyuid -z istio-ingress-service-account
oc adm policy add-scc-to-user privileged -z istio-ingress-service-account
oc adm policy add-scc-to-user anyuid -z istio-egress-service-account
oc adm policy add-scc-to-user privileged -z istio-egress-service-account
oc adm policy add-scc-to-user anyuid -z istio-pilot-service-account
oc adm policy add-scc-to-user privileged -z istio-pilot-service-account
oc adm policy add-scc-to-user anyuid -z default
oc adm policy add-scc-to-user privileged -z default
oc adm policy add-cluster-role-to-user cluster-admin -z default
(NOT SURE IF THOSE ARE STILL NEEDED )
Deploy the bookinfo app:
oc create -f istio/samples/bookinfo/kube/bookinfo.yaml
Patch all the deployments:
oc patch deployment reviews-v1 -p '{"spec":{"template":{"metadata":{"annotations":{"sidecar.istio.io/inject": "true"}}}}}'
oc patch deployment reviews-v2 -p '{"spec":{"template":{"metadata":{"annotations":{"sidecar.istio.io/inject": "true"}}}}}'
oc patch deployment reviews-v3 -p '{"spec":{"template":{"metadata":{"annotations":{"sidecar.istio.io/inject": "true"}}}}}'
oc patch deployment ratings-v1 -p '{"spec":{"template":{"metadata":{"annotations":{"sidecar.istio.io/inject": "true"}}}}}'
oc patch deployment productpage-v1 -p '{"spec":{"template":{"metadata":{"annotations":{"sidecar.istio.io/inject": "true"}}}}}'
oc patch deployment details-v1 -p '{"spec":{"template":{"metadata":{"annotations":{"sidecar.istio.io/inject": "true"}}}}}'
Deploy the gateway rules:
oc create -f istio/samples/bookinfo/routing/bookinfo-gateway.yaml
Let's review what the file bookinfo-gateway.yaml
has:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo
spec:
hosts:
- "*"
gateways:
- bookinfo-gateway
http:
- match:
- uri:
exact: /productpage
- uri:
exact: /login
- uri:
exact: /logout
- uri:
prefix: /api/v1/products
route:
- destination:
host: productpage
port:
number: 9080
As you can see, it defines a catch all host, and how to reach different paths of the bookinfo path.
Now, try to reach the webpage, by default, the istio deployment exposes the istio-ingressgateway-istio-system
route:
curl -v http://istio-ingressgateway-istio-system.54.246.187.215.nip.io/productpage
And the API:
curl http://istio-ingressgateway-istio-system.54.246.187.215.nip.io/api/v1/products
If you get back the webpage and the API of bookinfo, let's continue.
The istio service mesh doesn't allow traffic to go outside the mesh unless those are specified, so we need to define those external services:
For that, we will use ServiceEntry
objects, and define two different services, the 3scale-admin portal (admin UI) host, and the 3scale Backend host.
For 3scale-admin:
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: 3scale-admin
spec:
hosts:
- 3scale-admin.54.246.187.215.nip.io (Adjust to your 3scale installation)
ports:
- number: 443
name: https
protocol: HTTPS
For 3scale backend:
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: 3scale-backend
spec:
hosts:
- backend-3scale.54.246.187.215.nip.io (Adjust to your 3scale installation)
ports:
- number: 443
name: https
protocol: HTTPS
This way, APIcast will be able to retrieve the config file, and report/auth to 3scale Backend.
We need to create the apicast-configuration-url-secret
secret, this secret contains the Access Token
and the 3scale admin portal URL
, so APIcast can authorize with 3scale and download it's configuration.
Create the secret, modify those default values and use your own:
oc secret new-basicauth apicast-configuration-url-secret --password=https://**AccessToken**@**3scalePortalURL**
For example, in our case:
oc secret new-basicauth apicast-configuration-url-secret --password=https://837d30f7684b81d3bf23ddb399e6cf635de343032e366a29f9fece0ccb277dd1@3scale-admin.54.246.187.215.nip.io
Deploy APIcast:
oc new-app -f https://raw.githubusercontent.com/3scale/apicast/master/openshift/apicast-template.yml
Patch the DeploymentConfig of APIcast to add the istio sidecar container:
oc patch deploymentconfig apicast -p '{"spec":{"template":{"metadata":{"annotations":{"sidecar.istio.io/inject": "true"}}}}}'
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo
spec:
hosts:
- "*"
gateways:
- bookinfo-gateway
http:
- match:
- uri:
exact: /productpage
- uri:
exact: /login
- uri:
exact: /logout
- uri:
prefix: /api/v1/products
route:
- destination:
host: productpage
port:
number: 9080
Changes to:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo
spec:
hosts:
- "*"
gateways:
- bookinfo-gateway
http:
- match:
- uri:
exact: /productpage
- uri:
exact: /login
- uri:
exact: /logout
route:
- destination:
host: productpage
port:
number: 9080
- match:
- uri:
prefix: /api/v1/products
route:
- destination:
host: apicast
port:
number: 8080
So let's recap, our setup:
- 3scale Admin Portal: https://3scale-admin.54.246.187.215.nip.io
- 3scale Backend: https://backend-3scale.54.246.187.215.nip.io
- Istio Gateway Route: http://istio-ingressgateway-istio-system.54.246.187.215.nip.io
Now let's review how to configure APIcast integration in the 3scale admin page:
- Private Base URL: http://productpage:9080
- Staging Public Base URL: http://istio-ingressgateway-istio-system.54.246.187.215.nip.io
- Production Public Base URL: http://istio-ingressgateway-istio-system.54.246.187.215.nip.io
- API test GET request: /api/v1/products
Integration page:
After promoting it:
The test call can fail at first, just promote it to "production" and redeploy APIcast, or wait until it gets the new configuration.
Without credentials:
curl "http://istio-ingressgateway-istio-system.54.246.187.215.nip.io:80/api/v1/products"
Authentication parameters missing
With credentials:
curl "http://istio-ingressgateway-istio-system.54.246.187.215.nip.io:80/api/v1/products?user_key=24b87031628106c7ecefa77ad0876965"
[{"descriptionHtml": "<a href=\"https://en.wikipedia.org/wiki/The_Comedy_of_Errors\">Wikipedia Summary</a>: The Comedy of Errors is one of <b>William Shakespeare's</b> early plays. It is his shortest and one of his most farcical comedies, with a major part of the humour coming from slapstick and mistaken identity, in addition to puns and word play.", "id": 0, "title": "The Comedy of Errors"}]