TT Lab
Get started
Learn Learning paths Courses

ICA — Istio Certified Associate

Connecting Gateways and External Services

Continue in TT Lab

Goal

You learn the division of labor in which a Gateway declares the entry point and a VirtualService attaches routing, and you try widening and narrowing the mesh boundary with a ServiceEntry and a Sidecar.

Why it matters

Ingress is where incidents are most frequent in a mesh. The cause is usually one of three. The Gateway's hosts and the VirtualService's hosts do not overlap, the gateways field is missing so the rule applies only inside the mesh, or the Secret that credentialName points to is in a different namespace from the gateway Pod. In all three, the apply succeeds and only the traffic silently fails, so an eye for reading manifests is the only line of defense.

A ServiceEntry and a Sidecar are tools in opposite directions. One brings services outside the mesh inside and attaches policy and observability, and the other reduces the scope a sidecar needs to know and saves memory. The fact that the standard prescription for Envoy memory problems in a large mesh is the Sidecar resource comes up both on the exam and in practice.

You actually apply the basic Kubernetes resources and write the Istio CRDs as files under /root/ica-gateway/.

Steps

  1. Create the namespace ica-gateway and attach the label istio-injection=enabled.
  2. In the namespace ica-gateway, deploy a Deployment shop-api with 2 replicas (image nginx:1.27-alpine, Pod label app=shop-api), and create a Service of the same name shop-api with port 8080 and port name http.
  3. In the namespace ica-gateway, create a Secret shop-tls of type kubernetes.io/tls. The keys are the two tls.crt and tls.key, and the values may be placeholder strings.
  4. In /root/ica-gateway/gw-shop.yaml, write a Gateway shop-gateway. spec.selector is istio: ingressgateway and there are two servers. The first is port 443 / protocol HTTPS / hosts shop.example.com / tls.mode: SIMPLE / tls.credentialName: shop-tls. The second is port 15443 / protocol TLS / hosts legacy.example.com / tls.mode: PASSTHROUGH and does not have a credentialName.
  5. In /root/ica-gateway/vs-shop.yaml, write a VirtualService. hosts is shop.example.com, gateways is shop-gateway, and the http routing target is port 8080 of shop-api.ica-gateway.svc.cluster.local.
  6. In /root/ica-gateway/se-payment.yaml, write a ServiceEntry external-pg. hosts is api.pgprovider.example, location is MESH_EXTERNAL, resolution is DNS, and ports are number 443 / name https / protocol TLS.
  7. In /root/ica-gateway/sidecar-default.yaml, write a Sidecar. metadata.name is default, metadata.namespace is ica-gateway, and put exactly three entries in spec.egress[0].hosts. Its own namespace (./*), the control plane (istio-system/*), and the external host registered in step 6 (*/api.pgprovider.example).

Notes

Creating the gateway lab namespace

Create the namespace ica-gateway and attach the label istio-injection=enabled.

You must attach the automatic injection label too so that the workloads in the next steps enter the mesh.

Preparing the backend the gateway will send to

In the namespace ica-gateway, deploy a Deployment shop-api with 2 replicas (image nginx:1.27-alpine, Pod label app=shop-api), and create a Service of the same name shop-api with port 8080 and port name http.

A gateway only receives traffic. A routing target exists only when there is first a workload that actually responds and a Service that groups it.

Creating a TLS Secret

In the namespace ica-gateway, create a Secret shop-tls of type kubernetes.io/tls. The keys are the two tls.crt and tls.key, and the values may be placeholder strings.

The type matters. credentialName recognizes only Secrets of type kubernetes.io/tls, and there must be the two keys tls.crt and tls.key inside. This lab environment has no CA, so you may fill them with placeholder strings.

Putting two TLS modes in one Gateway

In /root/ica-gateway/gw-shop.yaml, write a Gateway shop-gateway. spec.selector is istio: ingressgateway and there are two servers. The first is port 443 / protocol HTTPS / hosts shop.example.com / tls.mode: SIMPLE / tls.credentialName: shop-tls. The second is port 15443 / protocol TLS / hosts legacy.example.com / tls.mode: PASSTHROUGH and does not have a credentialName.

A server that terminates TLS and a server that passes it through have different protocol notations. The side that does not terminate does not parse HTTP, so it is not HTTPS, and it does not need to hold a certificate either.

Binding the VirtualService to the gateway

In /root/ica-gateway/vs-shop.yaml, write a VirtualService. hosts is shop.example.com, gateways is shop-gateway, and the http routing target is port 8080 of shop-api.ica-gateway.svc.cluster.local.

A binding requires both conditions together. The name must be in the gateways field, and the hosts must overlap the Gateway's server hosts. Write the port number in the destination too.

Registering an external payment API in the mesh

In /root/ica-gateway/se-payment.yaml, write a ServiceEntry external-pg. hosts is api.pgprovider.example, location is MESH_EXTERNAL, resolution is DNS, and ports are number 443 / name https / protocol TLS.

Since it is a service outside the mesh, the location value is fixed, and if you did not write endpoints, you must tell it how to resolve the name. The protocol of port 443 is TLS.

Narrowing the field of view with a Sidecar

In /root/ica-gateway/sidecar-default.yaml, write a Sidecar. metadata.name is default, metadata.namespace is ica-gateway, and put exactly three entries in spec.egress[0].hosts. Its own namespace (./*), the control plane (istio-system/*), and the external host registered in step 6 (*/api.pgprovider.example).

To serve as the namespace default, the name is fixed. Leave exactly three in the egress hosts: its own namespace, the control plane, and the external host registered in step 6. For the external host, use a wildcard in the namespace position.