Module 4: Install the demo application and ingress gateway

This demo application is based on the Kiali Travel Demo Tutorial and will deploy several services grouped into three namespaces.

To get a better understanding of the application architecture and components used throughout the lab, please refer to the following page: Understanding the Travel Demo Application
Navigate to the subdirectory: 040-travel-demo-app

Task 1: Create the application namespaces

Create the namespaces for the Kiali Travel Demo with the following command:

apiVersion: v1
kind: Namespace
metadata:
  labels:
    istio-discovery: enabled
  name: travel-agency
spec: {}
---
apiVersion: v1
kind: Namespace
metadata:
  labels:
    istio-discovery: enabled
  name: travel-portal
spec: {}
---
apiVersion: v1
kind: Namespace
metadata:
  labels:
    istio-discovery: enabled
  name: travel-control
spec: {}
oc apply -f 01_1-ns-create.yaml

The namespaces are labeled with the configured istio discovery selector.

Task 2: Create pod monitors

PodMonitor objects must be applied in all mesh namespaces:

oc apply -f 01_2-pod-monitors-create.yaml

Task 3: Deploy the application components

Step 1: Deploy the travel-agency components

oc apply -n travel-agency -f 02_1-travel-agency-app.yaml
secret/mysql-credentials created
service/mysqldb created
deployment.apps/mysqldb-v1 created
deployment.apps/cars-v1 created
service/cars created
deployment.apps/discounts-v1 created
service/discounts created
deployment.apps/flights-v1 created
service/flights created
deployment.apps/hotels-v1 created
service/hotels created
deployment.apps/insurances-v1 created
service/insurances created
deployment.apps/travels-v1 created
service/travels created

Step 2: Deploy the travel-portal components

oc apply -n travel-portal -f 02_2-travel-portal-app.yaml
deployment.apps/voyages created
service/voyages created
deployment.apps/viaggi created
service/viaggi created
deployment.apps/travels created
service/travels created

Step 3: Deploy the travel-control components

oc apply -n travel-control -f 02_3-travel-control-app.yaml
deployment.apps/control created
service/control created

Step 4: Create a Route for the Travel Control Dashboard

oc apply -f 02_4-travel-control-route.yaml

Get the Travel Control Dashboard URL from the Route by running the following command:

echo "https://$(oc get routes -n travel-control route-travel-control -o jsonpath='{.spec.host}')"

Open the Dashboard and verify everything is working.

Please keep the browser window open so that you continuously send requests to the backend.

travel-control-dashboard.png

Task 4: Add the application to the Ambient Mesh

Right now, we have deployed the application components in namespaces, that are "visible" to the Istio control plane (due to discoverySelectors), but the application pods are not enrolled in the data plane.

The application is treated as a standard Kubernetes workload. Even though Istio "knows" about the service, it knows that the specific pod does not have a proxy (ztunnel or sidecar) attached to it.

We can verify this by the following command:

istioctl ztunnel-config workload -n ztunnel
NAMESPACE      POD NAME                        ADDRESS      NODE     WAYPOINT PROTOCOL
travel-agency  cars-v1-75f98c6f58-6g8nv        10.130.1.114 master-0 None     TCP
travel-agency  discounts-v1-6dccdff9ff-dwflq   10.130.1.116 master-0 None     TCP
travel-agency  flights-v1-6b7b99b764-g44mc     10.130.1.117 master-0 None     TCP
travel-agency  hotels-v1-6bcc9b877d-bhbrq      10.129.1.105 master-1 None     TCP
travel-agency  insurances-v1-75cb48b577-nszkq  10.129.1.106 master-1 None     TCP
travel-agency  mysqldb-v1-6657d57779-frcfj     10.130.1.115 master-0 None     TCP
travel-agency  travels-v1-56895446c5-l6qmm     10.128.0.117 master-2 None     TCP
travel-control control-6474d4c775-qt288        10.129.1.107 master-1 None     TCP
travel-portal  travels-6684f75cd5-lfd9m        10.130.1.119 master-0 None     TCP
travel-portal  viaggi-59988c897c-blffl         10.130.1.118 master-0 None     TCP
travel-portal  voyages-6c86bcdb5d-4zfzd        10.128.0.118 master-2 None     TCP

Key columns to watch:

PROTOCOL:

  • HBONE: The workload is part of the Ambient Mesh (mTLS enabled).

  • TCP: The workload is not in the mesh (not part of the dataplane).

WAYPOINT:

  • Shows if there is a Layer 7 Waypoint proxy enforcing policy for that workload.

Now let’s add the application to the Ambient Mesh by labeling the namespaces with istio.io/dataplane-mode=ambient:

oc apply -f 03-ns-add-to-mesh.yaml

Verify that the application is now part of the Mesh:

istioctl ztunnel-config workload -n ztunnel
NAMESPACE      POD NAME                        ADDRESS      NODE     WAYPOINT PROTOCOL
travel-agency  cars-v1-75f98c6f58-6g8nv        10.130.1.114 master-0 None     HBONE
travel-agency  discounts-v1-6dccdff9ff-dwflq   10.130.1.116 master-0 None     HBONE
travel-agency  flights-v1-6b7b99b764-g44mc     10.130.1.117 master-0 None     HBONE
travel-agency  hotels-v1-6bcc9b877d-bhbrq      10.129.1.105 master-1 None     HBONE
travel-agency  insurances-v1-75cb48b577-nszkq  10.129.1.106 master-1 None     HBONE
travel-agency  mysqldb-v1-6657d57779-frcfj     10.130.1.115 master-0 None     HBONE
travel-agency  travels-v1-56895446c5-l6qmm     10.128.0.117 master-2 None     HBONE
travel-control control-6474d4c775-qt288        10.129.1.107 master-1 None     HBONE
travel-portal  travels-6684f75cd5-lfd9m        10.130.1.119 master-0 None     HBONE
travel-portal  viaggi-59988c897c-blffl         10.130.1.118 master-0 None     HBONE
travel-portal  voyages-6c86bcdb5d-4zfzd        10.128.0.118 master-2 None     HBONE

HBONE stands for HTTP-Based Overlay Network Environment. It is the custom tunneling protocol Istio Ambient Mesh uses to transport traffic securely between nodes (Ztunnels) and Waypoint proxies.

After the label is applied, all L4 traffic to and from the ambient mesh is intercepted and secured via mutual TLS (mTLS) by the ztunnel.

Congratulations! You have successfully added the Travel Demo to ambient mesh. No further configuration is required and also no restart of the workloads.

I takes a few minutes until metrics are visible in the Service Mesh Console or Kiali.

Go to Kiali or use the Service Mesh Console plugin to observe the traffic of the Travel Demo application. Navigate to Service Mesh → Traffic Graph, select the 3 travel demo namespaces and have a first look at the Versioned app graph:

kiali-initial-traffic-graph.png

What about Waypoint Proxies?

You can add a waypoint proxy if workloads require any of the following L7 capabilities:

Traffic management: - Advanced HTTP routing, load balancing, circuit breaking, rate limiting, fault injection, retries, and timeouts

Security - Authorization policies based on L7 attributes such as request type or HTTP headers

Observability - HTTP metrics, access logging, and tracing for application traffic

Task 5: Configuring Ingress for the Travel Demo application

As of now, we have exposed the Travel Control Dashboard with an OpenShift route that sends traffic directly to the control service in plaintext.

In the next section, we will configure an Ingress Gateway in the Ambient Mesh to securely expose the Travel demo application.

The objective is to configure the following setup:

External traffic (TLS)-> Ingress Gateway (mTLS)-> Waypoint Proxy (mTLS)-> control service.

In this setup, it is recommended to:

  • apply minimal routing logic at the Ingress Gateway and

  • apply all the other logic and policies at the waypoint proxy.

Step 1: Create an Ingress Gateway

A gateway resource configures a load balancer to receive incoming traffic from outside the mesh or send traffic outside the mesh. It defines ports, protocols, and accepted hosts.

The gateway resource defines the following attributes:

  • Port configuration: number, name, protocol

  • Accepted hostnames: can use wildcards

  • TLS settings: for HTTPS traffic

  • Selector: to specify which gateway pods apply this configuration

A gateway by itself does not route traffic to backend services. You must bind a HTTPRoute or virtual service to the gateway to define routing rules.

The following configuration is defining a basic Ingress Gateway and an HTTPRoute using the Kubernetes Gateway API, which Istio fully supports and implements. It’s essentially setting up the public entry point for HTTP traffic and routing all incoming requests to the control service.

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: travel-gateway
  namespace: travel-control
spec:
  gatewayClassName: istio
  listeners:
  - name: default
    port: 80
    protocol: HTTP
    allowedRoutes:
      namespaces:
        from: All
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: travel-gateway-default-route
  namespace: travel-control
spec:
  parentRefs:
  - name: travel-gateway
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /
    backendRefs:
    - name: control
      port: 8080
oc apply -f 04_3-ingress-gateway-create.yaml

Step 2: Create a Waypoint Proxy

Create a waypoint proxy in the travel-control namespace:

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: travel-control-waypoint
  namespace: travel-control
  labels:
    istio.io/waypoint-for: service
spec:
  gatewayClassName: istio-waypoint
  listeners:
  - name: mesh
    port: 15008
    protocol: HBONE
oc apply -f 04_1-control-waypoint-create.yaml

Step 3: Label the travel-control namespace to use the waypoint

Now label the namespace to enroll all services in the travel-control namespace to use this waypoint.

apiVersion: v1
kind: Namespace
metadata:
  labels:
    istio-discovery: enabled
    istio.io/dataplane-mode: ambient
    istio.io/use-waypoint: travel-control-waypoint
  name: travel-control
spec: {}
oc apply -f 04_2-label-ns-for-waypoint.yaml

Step 4: Label the control service

Istio is sending traffic from the ingress gateway to the destination directly, even if that specific destination is enrolled in a waypoint.

We can enable ingress waypoint routing on a service, such that traffic will be sent from the ingress gateway to the configured waypoint first, not to the destination service.

In order to enable ingress waypoint routing, label the control service.

The traffic entering the Ingress Gateway will then be forwarded to the Waypoint proxy for L7 policy enforcement.

apiVersion: v1
kind: Service
metadata:
  name: control
  namespace: travel-control
  labels:
    app: control
    istio.io/ingress-use-waypoint: "true"
spec:
  ports:
    - name: http
      port: 8080
  selector:
    app: control
oc apply -f 04_4-label-ingress-use-waypoint.yaml

Step 5: Create an example waypoint policy

Deploy an example routing policy that is enforced at the ingress waypoint proxy:

oc apply -f 05_1-waypoint-routing.yaml

Step 6: Expose the Ingress Gateway

In the last step, expose the Ingress Gateway with an OpenShift Route to be accessible from outside the cluster:

oc apply -f 05-ingress-gateway-route.yaml

You can now access the Travel Control Dashboard through the Service Mesh Ingress Gateway:

echo "https://$(oc get routes -n travel-control travel-gateway -o jsonpath='{.spec.host}')"
Again, please keep the browser window open so that you continuously send requests to the backend.

Clean up the previous route to the control service:

oc delete -f 02_4-travel-control-route.yaml

Task 6: Observe the Travel Demo application

Go to Kiali or use the Service Mesh Console plugin to observe the traffic of the Travel Demo application. Navigate to Service Mesh → Traffic Graph, select the 3 travel demo namespaces and have a look at the Versioned app graph

kiali-traffic-graph.png

In the OpenShift Console, select the travel-agency project and navigate to Workloads → Deployments. Select .i.e the cars-v1 deployment and click on the Service Mesh tab:

ocp-deployment-ossm-tab.png

In the OpenShift Console, go to Observe → Metrics and run the query: istio_tcp_connections_opened_total to verify that ztunnel uses mTLS:

ocp-ossm-metrics.png

Task 7: Enable Tracing for the Ingress Gateway and Waypoint Proxy

The following Telemetry resources configure tracing for the travel-gateway and travel-control-waypoint in the travel-control namespace.

It tells Istio to use the OpenTelemetry provider named otel when emitting traces.

It enables probabilistic sampling, capturing 50% of requests that pass through that Gateway or waypoint. Other workloads or gateways are not affected unless they have their own Telemetry config.

apiVersion: telemetry.istio.io/v1
kind: Telemetry
metadata:
  name: telemetry-gateway
  namespace: travel-control
spec:
  targetRefs:
  - kind: Gateway
    name: travel-gateway
    group: gateway.networking.k8s.io
  tracing:
  - providers:
    - name: "otel"
    randomSamplingPercentage: 50
---
apiVersion: telemetry.istio.io/v1
kind: Telemetry
metadata:
  name: telemetry-waypoint
  namespace: travel-control
spec:
  targetRefs:
  - kind: Gateway
    name: travel-control-waypoint
    group: gateway.networking.k8s.io
  tracing:
  - providers:
    - name: "otel"
    randomSamplingPercentage: 50
oc apply -f 07-enable-tracing.yaml

After a few minutes, you should be able to see traces in the Jaeger UI:

jaeger-traces.png

Congratulations! You have successfully deployed the Kiali Travel Demo application in Ambient Mesh with an Ingress Gateway and Waypoint Proxy!