Getting started Community Training Tutorials Documentation APIs, AI & Tools
k3d cluster create demo-istio --k3s-arg "--disable=traefik@server:0" --port '80:80@server:0' --port '443:443@server:0'
To leverage Omni Gateway policies, logging, and metrics from the Anypoint Platform control plane, integrate Omni Gateway into your Istio Service Mesh. Deploy Omni Gateway as an ingress gateway to manage ingress north-south cluster traffic and internal east-west traffic inside the cluster.
To integrate Omni Gateway, use the following architecture diagram and tutorial. Omni Gateway is integrated by using a modified version of the Istio Bookinfo sample application. In the Omni Gateway integration:
An Istio virtual service forwards all ingress north-south traffic to Omni Gateway.
Direct access to the bookinfo name space is restricted. All external traffic into the bookinfo namespace must come from the flex namespace. Istio automatically configures mTLS configuration between the bookinfo and flex.
Omni Gateway protects and monitors the exposed product page service from ingress traffic with an API instance.
The Istio sidecar intercepts east-west traffic between the product page service and the reviews service. Omni Gateway acts as an ingress gateway managing incoming traffic to the reviews service.

| In the diagram, Omni Gateway is running in Connected Mode. If Omni Gateway runs in Local Mode, the Anypoint Platform control plane is absent. |
To configure the architecture:
Create a Kubernetes cluster for this demo or skip this step if you already have a cluster you want to use:
k3d cluster create demo-istio --k3s-arg "--disable=traefik@server:0" --port '80:80@server:0' --port '443:443@server:0'
Add the Omni Gateway and Istio Helm repositories:
helm repo add istio https://istio-release.storage.googleapis.com/charts \
&& helm repo add flex-gateway https://flex-packages.anypoint.mulesoft.com/helm \
&& helm repo up
Install Istio:
Install the Istio base chart that contains the cluster-wide Custom Resource Definitions (CRDs) that must be installed before deploying the Istio control plane:
helm upgrade -i --wait --create-namespace -n istio-system istio-base istio/base --version 1.21.2 --set defaultRevision=default
Install the Istio discovery chart that deploys the istiod service:
helm upgrade -i --wait --create-namespace -n istio-system istiod istio/istiod --version 1.21.2
Install an Istio ingress gateway:
helm upgrade -i --wait --create-namespace -n istio-system istio-ingress istio/gateway --version 1.21.2
Install Omni Gateway:
Create the namespace and set up the label to enable the sidecar injection:
kubectl create ns flex && kubectl label ns flex istio-injection=enabled --overwrite
Install Omni Gateway:
helm upgrade -i --wait -n flex --version 1.7.0 flex flex-gateway/flex-gateway \
--set gateway.scope=Namespace \
--set gateway.mode=connected \
--set service.type=ClusterIP \
--set service.http.port=8081 \
--set service.https.enabled=false \
--set-file registration.content=registration.yaml
List all services and API instances previously created:
kubectl -n flex get svc
Install the bookinfo application:
Enable Istio label injection in the default namespace and install the bookinfo application:
kubectl create ns bookinfo \
&& kubectl label ns bookinfo istio-injection=enabled --overwrite \
&& kubectl -n bookinfo apply -l version!=v2,version!=v3 -f https://raw.githubusercontent.com/istio/istio/release-1.20/samples/bookinfo/platform/kube/bookinfo.yaml
Check the pod status:
kubectl -n bookinfo get pods
Install the sleep application to test traffic:
Create the test namespace and install the sleep application:
kubectl create ns test \
&& kubectl label ns test istio-injection=enabled --overwrite \
&& kubectl -n test apply -f https://raw.githubusercontent.com/istio/istio/release-1.20/samples/sleep/sleep.yaml
Check the status of the pods:
kubectl -n test get pods
Intercept ingress north-south traffic to protect services from external traffic.
To intercept ingress north-south traffic:
Create the Omni Gateway ingress API instance to forward all ingress north-south traffic in the bookinfo namespace to the productpage service:
Local Mode:
cat <<EOF | kubectl apply -f -
---
apiVersion: gateway.mulesoft.com/v1alpha1
kind: ApiInstance
metadata:
name: ingress
namespace: flex
spec:
address: http://0.0.0.0:8081/ingress/
services:
productpage:
address: http://productpage.bookinfo.svc:9080
EOF
Connected Mode:
To add an API instance in Connected Mode, see Adding an Omni Gateway API Instance.
Configure the API instance with the following downstream parameters:
Protocol: HTTP
Port: 8081
Base Path: /ingress/
Configure the API instance with the following upstream parameters:
Route label: productpage
Upstream URL: http://productpage.bookinfo.svc:9080
Create the flex Istio ingress gateway to forward the ingress traffic to Omni Gateway using a Istio virtual service:
Create the Omni Gateway:
cat <<EOF | kubectl apply -f -
---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: flex
namespace: flex
spec:
selector:
app: istio-ingress
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: flex
namespace: flex
spec:
hosts:
- "*"
gateways:
- flex
http:
- route:
- destination:
host: flex
port:
number: 8081
rewrite:
uri: /ingress/
EOF
Wait a few seconds (approximately 10) and send a test request to the /api/v1/products/1 page:
curl -v http://localhost/api/v1/products/1
Ensure you receive this output:
< HTTP/1.1 200 OK
< server: istio-envoy
< date: Tue, 27 Feb 2024 22:06:33 GMT
< content-type: application/json
< content-length: 195
< x-envoy-upstream-service-time: 8
<
* Connection #0 to host localhost left intact
{"id": 2, "author": "William Shakespeare", "year": 1595, "type": "paperback", "pages": 200, "publisher": "PublisherA", "language": "English", "ISBN-10": "1234567890", "ISBN-13": "123-1234567890"}
Protect the Omni Gateway API instance by applying the Basic Authentication policy:
Add the policy:
cat <<EOF | kubectl apply -f -
---
apiVersion: gateway.mulesoft.com/v1alpha1
kind: ApiInstance
metadata:
name: ingress
namespace: flex
spec:
address: http://0.0.0.0:8081/ingress/
services:
productpage:
address: http://productpage.bookinfo.svc:9080
policies:
- policyRef:
name: http-basic-authentication-flex
config:
username: user1
password: password1
EOF
Wait a few seconds (approximately 10) and send a test request:
curl -v http://localhost/
Make sure you receive a 401 response.
Add the Message Logging policy to log traffic:
cat <<EOF | kubectl apply -f -
---
apiVersion: gateway.mulesoft.com/v1alpha1
kind: ApiInstance
metadata:
name: ingress
namespace: flex
spec:
address: http://0.0.0.0:8081/ingress/
services:
productpage:
address: http://productpage.bookinfo.svc:9080
policies:
- policyRef:
name: http-basic-authentication-flex
config:
username: user1
password: password1
- policyRef:
name: message-logging-flex
config:
loggingConfiguration:
- itemName: "Request"
itemData:
message: "#['> ' ++ attributes.version ++ ' ' ++ attributes.method ++ ' ' ++ attributes.headers.host ++ attributes.requestUri]"
level: "INFO"
firstSection: true
- itemName: "Response"
itemData:
message: "#['< Status=' ++ attributes.statusCode ++ ' Length=' ++ (attributes.headers['content-length'] default 'none') ++ ' Time=' ++ (attributes.headers['x-envoy-upstream-service-time'] default 'none')]"
level: "INFO"
secondSection: true
order: 0
EOF
Use Omni Gateway to intercept east-west traffic between services and protect them with policies.
To intercept east-west traffic:
Create the bookinfo-reviews API instance to forward the east-west traffic to the reviews service:
Local Mode:
cat <<EOF | kubectl apply -f -
---
apiVersion: gateway.mulesoft.com/v1alpha1
kind: ApiInstance
metadata:
name: bookinfo-reviews
namespace: flex
spec:
address: http://0.0.0.0:8081/bookinfo/reviews/
services:
upstream:
address: http://reviews.bookinfo.svc:9080
policies:
- policyRef:
name: message-logging-flex
config:
loggingConfiguration:
- itemName: "Request"
itemData:
message: "#['> ' ++ attributes.version ++ ' ' ++ attributes.method ++ ' ' ++ attributes.headers.host ++ attributes.requestUri]"
level: "INFO"
firstSection: true
- itemName: "Response"
itemData:
message: "#['< Status=' ++ attributes.statusCode ++ ' Length=' ++ (attributes.headers['content-length'] default 'none') ++ ' Time=' ++ (attributes.headers['x-envoy-upstream-service-time'] default 'none')]"
level: "INFO"
secondSection: true
EOF
Connected Mode:
To add an API instance in Connected Mode, see Adding an Omni Gateway API Instance.
Configure the API instance with these downstream parameters:
Protocol: HTTP
Port: 8081
Base Path: /bookinfo/reviews/
Configure the API instance with these upstream parameters:
Route label: reviews
Upstream URL: http://reviews.bookinfo.svc:9080
Intercept the traffic between the productpage service and the reviews service and forward it to the flex service:
Create the Istio API instance:
cat <<EOF | kubectl apply -f -
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo-reviews
namespace: istio-system
spec:
hosts:
- reviews.bookinfo.svc.cluster.local
http:
- match:
- sourceLabels:
app: flex
route:
- destination:
host: reviews.bookinfo.svc.cluster.local
port:
number: 9080
- route:
- destination:
host: flex.flex.svc.cluster.local
port:
number: 8081
rewrite:
uri: /bookinfo/reviews/
EOF
Send a test request with the user1 username and password1 password to the /productpage:
curl -v -u user1:password1 http://localhost/productpage
Check the Omni Gateway logs to ensure the request sent from the productpage service to the reviews service passed through Omni Gateway. The logs appear similar to:
[flex-gateway-envoy][info] wasm log productpage-message-logging-flex-2.flex.productpage.flex.svc main: [policy: productpage-message-logging-flex-2.flex][api: productpage.flex.svc][req: 6e1f7c32-918d-4b6a-af3f-36a4430f80ae] [accessLog] > HTTP/1.1 GET localhost/ingress/productpage
[flex-gateway-envoy][info] wasm log bookinfo-reviews-message-logging-flex-1.flex.bookinfo-reviews.flex.svc main: [policy: bookinfo-reviews-message-logging-flex-1.flex][api: bookinfo-reviews.flex.svc][req: b23e9c64-a2aa-4464-8984-d1dd6c18f7ea] [accessLog] > HTTP/1.1 GET reviews:9080/bookinfo/reviews/reviews/0
| Use the standard output logs for a quick log check. To learn how to view standard output logs, see Viewing Standard Output Logs. |
Apply the Rate Limiting policy to the bookinfo-reviews API instance to protect the reviews service:
cat <<EOF | kubectl apply -f -
---
apiVersion: gateway.mulesoft.com/v1alpha1
kind: ApiInstance
metadata:
name: bookinfo-reviews
namespace: flex
spec:
address: http://0.0.0.0:8081/bookinfo/reviews/
services:
upstream:
address: http://reviews.bookinfo.svc:9080
policies:
- policyRef:
name: message-logging-flex
config:
loggingConfiguration:
- itemName: "Request"
itemData:
message: "#['> ' ++ attributes.version ++ ' ' ++ attributes.method ++ ' ' ++ attributes.headers.host ++ attributes.requestUri]"
level: "INFO"
firstSection: true
- itemName: "Response"
itemData:
message: "#['< Status=' ++ attributes.statusCode ++ ' Length=' ++ (attributes.headers['content-length'] default 'none') ++ ' Time=' ++ (attributes.headers['x-envoy-upstream-service-time'] default 'none')]"
level: "INFO"
secondSection: true
order: 0
- policyRef:
name: rate-limiting-flex
config:
rateLimits:
- timePeriodInMilliseconds: 60000
maximumRequests: 2
exposeHeaders: true
EOF
Restrict direct access to the bookinfo service:
Restrict access:
cat <<EOF | kubectl apply -f -
---
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: flex-allow
namespace: bookinfo
spec:
action: ALLOW
rules:
- from:
- source:
namespaces:
- flex
- bookinfo
EOF
Send a test request from the test namespace to the details service:
kubectl -n test exec -ti -c sleep $(kubectl -n test get pod --no-headers -o=name) -- curl -v details.bookinfo:9080/details/0
Make sure you receive this 403 forbidden response:
< HTTP/1.1 403 Forbidden
< content-length: 19
< content-type: text/plain
< date: Thu, 09 May 2024 15:51:11 GMT
< server: envoy
< x-envoy-upstream-service-time: 0
<
* Connection #0 to host details.bookinfo left intact
RBAC: access denied
Send this request to the details service to find out how to access the bookinfo service from the flex namespace:
kubectl -n flex exec -ti -c app $(kubectl -n flex get pod --no-headers -o=name) -- flexctl check http http://details.bookinfo:9080/details/0
Make sure you receive this response:
[flexctl][info] Access to http address 'http://details.bookinfo:9080/details/0': ok