Gateways
Gateways and OpenShift Service Mesh
Abstract
Chapter 1. About gateways
Manage ingress and egress traffic at the mesh edge by using gateway injection or the Kubernetes Gateway API to deploy standalone Envoy proxies across sidecar and ambient architectures.
1.1. Understanding gateways
A gateway is a standalone Envoy proxy deployment and an associated Kubernetes service operating at the edge of a service mesh. You can configure a gateway to give fine-grained control over the traffic that enters or leaves the mesh.
In Red Hat OpenShift Service Mesh, you can install gateways by using gateway injection or by using the Gateway API. Red Hat OpenShift Service Mesh supports different gateway configurations based on the deployment mode. You can deploy gateways by using gateway injection and configure them with Istio Gateway and VirtualService resources in sidecar mode or with Kubernetes Gateway API resources in both sidecar and ambient modes.
1.2. About gateway injection
You can install a gateway by applying labels and annotations to Kubernetes Deployment and Service resources, triggering the Istio control plane to inject and configure the gateway proxy.
Gateway injection relies upon the same mechanism as sidecar injection to inject the Envoy proxy into gateway pods. To install a gateway by using gateway injection, you create a Kubernetes Deployment object and an associated Kubernetes Service object in a namespace that is visible to the Istio control plane. When creating the Deployment object, you apply labels and annotations so the Istio control plane injects and configures a proxy to act as a gateway. After installing the gateway, you configure it to control ingress and egress traffic by using the Istio Gateway and VirtualService resources.
1.2.1. Installing a gateway by using gateway injection
Install a gateway by using gateway injection to deploy and configure an Envoy proxy for managing traffic at the edge of the mesh.
You can use this procedure to create ingress or egress gateways.
Prerequisites
- You have installed the OpenShift Service Mesh Operator version 3.0 or later.
- You have created an Istio control plane.
-
You have created an
IstioCNIresource.
Procedure
Create a namespace that you will use to install the gateway.
$ oc create namespace <gateway_namespace>
NoteInstall the gateway and the Istio control plane in different namespaces.
You can install the gateway in a dedicated gateway namespace. This approach allows many applications in different namespaces to share the same gateway. Or, you can install the gateway in an application namespace. In this approach, the gateway acts as a dedicated gateway for the application in that namespace.
Create a YAML file named
secret-reader.ymlthat defines the service account, role, and role binding for the gateway deployment, similar to the following example:apiVersion: v1 kind: ServiceAccount metadata: name: secret-reader namespace: <gateway_namespace> --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: secret-reader namespace: <gateway_namespace> rules: - apiGroups: [""] resources: ["secrets"] verbs: ["get", "watch", "list"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: secret-reader namespace: <gateway_namespace> roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: secret-reader subjects: - kind: ServiceAccount name: secret-readerThese settings enable the gateway to read secrets so that it can obtain TLS credentials.
Apply the YAML file by running the following command:
$ oc apply -f secret-reader.yml
Create a YAML file named
gateway-deployment.ymlthat defines the KubernetesDeploymentobject for the gateway, similar to the following example:apiVersion: apps/v1 kind: Deployment metadata: name: <gateway_name> namespace: <gateway_namespace> spec: selector: matchLabels: istio: <gateway_name> template: metadata: annotations: inject.istio.io/templates: gateway labels: istio: <gateway_name> sidecar.istio.io/inject: "true" spec: containers: - name: istio-proxy image: auto securityContext: capabilities: drop: - ALL allowPrivilegeEscalation: false privileged: false readOnlyRootFilesystem: true runAsNonRoot: true ports: - containerPort: 15090 protocol: TCP name: http-envoy-prom resources: limits: cpu: 2000m memory: 1024Mi requests: cpu: 100m memory: 128Mi securityContext: sysctls: - name: net.ipv4.ip_unprivileged_port_start value: "0" serviceAccountName: secret-reader-
spec.template.annotations.inject.istio.io/templatesindicates that the Istio control plane uses the gateway injection template instead of the default sidecar template. -
spec.template.labels.istioensures that you set a unique label for the gateway deployment. IstioGatewayresources require a unique label to select gateway workloads. -
spec.template.labels.sidecar.istio.io/injectenables gateway injection by setting this label totrue. If the name of the Istio resource is notdefaultyou must use theistio.io/rev: <istio_revision>label instead, where the revision represents the active revision of the Istio resource. -
spec.template.spec.containers.imagesets the image field toautoso that the image automatically updates each time the pod starts. -
spec.template.spec.serviceAccountNamesets theserviceAccountNameto the name of theServiceAccountcreated previously.
-
Apply the YAML file by running the following command:
$ oc apply -f gateway-deployment.yml
Verify that the gateway
Deploymentrollout was successful by running the following command:$ oc rollout status deployment/<gateway_name> -n <gateway_namespace>
You should see output similar to the following example:
Waiting for deployment "<gateway_name>" rollout to finish: 0 of 1 updated replicas are available... deployment "<gateway_name>" successfully rolled out
Create a YAML file named
gateway-service.ymlthat has the KubernetesServiceobject for the gateway.apiVersion: v1 kind: Service metadata: name: <gateway_name> namespace: <gateway_namespace> spec: type: ClusterIP 1 selector: istio: <gateway_name> 2 ports: - name: status-port port: 15021 protocol: TCP targetPort: 15021 - name: http2 port: 80 protocol: TCP targetPort: 80 - name: https port: 443 protocol: TCP targetPort: 443
-
spec.typesets the type of the gatewayServiceobject. Settingspec.typetoClusterIPrestricts gateway Service access to the internal cluster network. If the gateway has to handle ingress traffic from outside the cluster, setspec.typetoLoadBalancer. Or, you can use OpenShift Routes. -
spec.selectorsets theselectorto the unique label or set of labels specified in the pod template of the gateway deployment that you created previously.
-
Apply the YAML file by running the following command:
$ oc apply -f gateway-service.yml
Verify that the gateway service is targeting the endpoint of the gateway pods by running the following command:
$ oc get endpoints <gateway_name> -n <gateway_namespace>
You should see output similar to the following example:
Example output:
NAME ENDPOINTS AGE <gateway_name> 10.131.0.181:8080,10.131.0.181:8443 1m
Optional: Create a YAML file named
gateway-hpa.ymlthat defines a horizontal pod autoscaler for the gateway. The following example sets the minimum replicas to2and the maximum replicas to5and scales the replicas up when average CPU usage exceeds 80% of the CPU resource limit. The gateway deployment’s pod template specifies this limit.apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: <gateway_name> namespace: <gateway_namespace> spec: minReplicas: 2 maxReplicas: 5 metrics: - resource: name: cpu target: averageUtilization: 80 type: Utilization type: Resource scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: <gateway_name>-
spec.scaleTargetRef.namespecifies the name of the gateway deployment created previously.
-
Optional: Apply the YAML file by running the following command:
$ oc apply -f gateway-hpa.yml
Optional: Create a YAML file named
gateway-pdb.ymlthat defines a pod disruption budget for the gateway. The following example allows gateway pods eviction only when at least 1 healthy gateway pod will remain on the cluster after the eviction:apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: <gateway_name> namespace: <gateway_namespace> spec: minAvailable: 1 selector: matchLabels: istio: <gateway_name>-
spec.selector.matchLabelsspecifies the unique label or set of labels specified in the pod template of the gateway deployment created previously.
-
Optional: Apply the YAML file by running the following command:
$ oc apply -f gateway-pdb.yml
Chapter 2. Getting traffic into a mesh
Route external traffic to mesh services by configuring Istio gateway proxies and exposing them through LoadBalancer services or OpenShift routes.
2.1. About ingress traffic routing approaches
Red Hat OpenShift Service Mesh offers two approaches to configure ingress traffic routing to services in the mesh. The approach depends on the service mesh deployment mode and traffic management requirements.
- Ingress routing with gateway injection and Istio APIs
-
When you install a gateway by using gateway injection, you can configure it to receive ingress traffic by using the Istio
GatewayandVirtualServiceresources in combination.
The gateway injection approach is compatible with sidecar-based service mesh deployments where you enable sidecar injection in namespaces by using the istio-injection=enabled label or the istio.io/rev=<revision> label.
- Ingress routing with Kubernetes Gateway API
-
The Kubernetes Gateway API provides a standardized approach for configuring ingress traffic routing using native Kubernetes resources. With this approach, you use
GatewayandHTTPRoute(orGRPCRoute) resources to configure how traffic enters the mesh and routes to services.
While Istio Gateway and VirtualService resources support certain ingress use cases in ambient mode, the recommended approach is to use the Kubernetes Gateway API, which provides full support and integration with ambient. You can also use the Gateway API with sidecar-based deployments.
2.2. Exposing a service by using the Istio Gateway and VirtualService resources
Expose mesh services to external traffic by configuring injected gateways with Istio Gateway and VirtualService resources to route traffic from outside the cluster.
You can set the gateway Service type to LoadBalancer to allow traffic from outside the cluster.
Prerequisites
- You have installed Istio gateways using gateway injection.
-
You are using the Istio
GatewayandVirtualServiceresources. -
You have existing
VirtualServiceconfigurations and do not plan on migrating to ambient mode.
Procedure
Create namespace called
httpbinby running the following command:$ oc create namespace httpbin
Enable sidecar injection in the namespace. If you are using the
InPlaceupgrade strategy, run the following command:$ oc label namespace httpbin istio-injection=enabled
NoteIf you are using the
RevisionBasedupgrade strategy, run the following commands:To find your
<revision-name>, run the following command:$ oc get istiorevisions.sailoperator.io
You should see output similar to the following example:
NAME TYPE READY STATUS IN USE VERSION AGE default Local True Healthy True v1.24.3 3m33s
Label the namespace with the revision name to enable sidecar injection:
$ oc label namespace httpbin istio.io/rev=default
Deploy a sample service named
httpbinby running the following command:$ oc apply -n httpbin -f https://raw.githubusercontent.com/openshift-service-mesh/istio/refs/heads/master/samples/httpbin/httpbin.yaml
Create a YAML file named
httpbin-gw.yamlthat defines an IstioGatewayresource. This resource configures gateway proxies to expose port 80 (HTTP) for the host,httpbin.example.com.You can see the following example configuration for reference:
apiVersion: networking.istio.io/v1 kind: Gateway metadata: name: httpbin-gateway namespace: httpbin spec: selector: istio: <gateway_name> servers: - port: number: 80 name: http protocol: HTTP hosts: - httpbin.example.com-
spec.selectorspecifies the unique label or set of labels in the pod template of the gateway proxyDeployment. By default, the IstioGatewayresource configuration will apply to matching gateway pods in all namespaces. -
spec.servers.hostsspecifies a list of addresses that the clients use when attempting to access a mesh service at the associated port.
-
Apply the YAML file by running the following command:
$ oc apply -f httpbin-gw.yaml
Create a YAML file named
httpbin-vs.yamlfor aVirtualService. TheVirtualServicedefines the rules that route traffic from the gateway proxy to thehttpbinservice.You can see the following example configuration for reference:
apiVersion: networking.istio.io/v1 kind: VirtualService metadata: name: httpbin namespace: httpbin spec: hosts: - httpbin.example.com gateways: - httpbin-gateway http: - match: - uri: prefix: /status - uri: prefix: /headers route: - destination: port: number: 8000 host: httpbin-
spec.hoststhe destinationhostsfor theVirtualServicerouting rules. The IstioGatewayresource must expose the hosts that you bind to theVirtualService. -
spec.gatewaysbinds theVirtualServiceto the IstioGatewayresource created in the previous step by adding theGatewayname to the list of gateways. -
spec.http.routeroute matching traffic to thehttpbinservice deployed earlier by defining adestinationthat includes thehostandportof thehttpbinService.
-
Apply the YAML file by running the following command:
$ oc apply -f httpbin-vs.yaml
For verification purposes, create a namespace for a
curlclient by running the following command:$ oc create namespace curl
Deploy the
curlclient by running the following command:$ oc apply -n curl -f https://raw.githubusercontent.com/openshift-service-mesh/istio/refs/heads/master/samples/curl/curl.yaml
Set a
CURL_PODvariable with the name of thecurlpod by running the following command:$ CURL_POD=$(oc get pods -n curl -l app=curl -o jsonpath='{.items[*].metadata.name}')Using the
curlclient, send a request to the/headersendpoint of thehttpbinapplication through the ingress gatewayServiceresource. Set theHostheader of the request tohttpbin.example.comto match the host that the IstioGatewayandVirtualServiceresources specify. Run the followingcurlcommand to send the request:$ oc exec $CURL_POD -n curl -- \ curl -s -I \ -H Host:httpbin.example.com \ <gateway_name>.<gateway_namespace>.svc.cluster.local/headersThe response should have a
200 OK HTTPstatus indicating that the request was successful.HTTP/1.1 200 OK server: istio-envoy ...
Send a curl request to an endpoint that does not have a corresponding URI prefix match defined in the
httpbinVirtualServiceby running the following command:$ oc exec $CURL_POD -n curl -- \ curl -s -I \ -H Host:httpbin.example.com \ <gateway_name>.<gateway_namespace>.svc.cluster.local/getThe response should return a
404 Not Foundstatus as thehttpbinVirtualServiceresource lacks a matching URI prefix for the/getendpoint.HTTP/1.1 404 Not Found server: istio-envoy ...
Expose the gateway proxy to traffic outside the cluster by setting the
Servicetype toLoadBalancer:$ oc patch service <gateway_name> -n <gateway_namespace> -p '{"spec": {"type": "LoadBalancer"}}'NoteOpenShift Routes can also expose a gateway to traffic outside the cluster. For more information, see "Exposing a gateway to traffic outside the cluster using OpenShift Routes".
Verify that you can access the
httpbinservice from outside the cluster when using the external hostname or IP address of the gatewayServiceresource. Ensure that you set theINGRESS_HOSTvariable appropriately for the environment that your cluster is running in.If the cluster runs on AWS, set the
INGRESS_HOSTvariable by running the following command:$ INGRESS_HOST=$(oc get service <gateway_name> -n <gateway_namespace> -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')If the cluster runs on GCP or Azure, set the
INGRESS_HOSTvariable by running the following command:$ INGRESS_HOST=$(oc get service <gateway_name> -n <gateway_namespace> -o jsonpath='{.status.loadBalancer.ingress[0].ip}')Send a
curlrequest to thehttpbinservice using the host of the gateway by running the following command:$ curl -s -I -H Host:httpbin.example.com http://$INGRESS_HOST/headers
-
Verify that the response has the
HTTP/1.1 200 OKstatus, which indicates that the request was successful.
2.3. About exposing services to traffic outside a cluster
To enable traffic from outside an OpenShift cluster to access services in a mesh, you must expose a gateway proxy by either setting its Service type to LoadBalancer or by using the OpenShift Router.
Using Kubernetes load balancing to handle incoming traffic directly through the inbound gateway can reduce latency associated with data encryption. By managing encryption at the inbound gateway, you avoid the intermediate decryption and re-encryption steps within the mesh that often add latency. This approach encrypts and decrypts mesh traffic only once, which is generally more efficient.
The OpenShift Router provides a standard approach for managing ingress traffic, and you can use the router to manage certificates for all cluster ingress traffic by using the same methods. However, the OpenShift Router introduces an additional hop between the inbound traffic and the mesh applications. Typically, you route the traffic by decrypting it at the router and then re-encrypting it at the service mesh ingress gateway, which introduces latency.
2.3.1. Exposing a gateway to traffic outside the cluster by using OpenShift Routes
You can expose a gateway to traffic outside the cluster by using OpenShift Routes. This approach provides an alternative to using Kubernetes LoadBalancer service when you have to expose gateways to traffic outside the cluster.
Prerequisites
-
You have completed the procedure, "Exposing a Service by using the Istio
GatewayandVirtualServiceresources".
Procedure
Ensure that you set the
Servicetype toClusterIPby running the following command:$ oc patch service <gateway_name> -n <gateway_namespace> -p '{"spec": {"type": "ClusterIP"}}'Create a YAML file named
httpbin-route.yamlthat defines aRoutefor thehttpbinservice similar to the following example:apiVersion: route.openshift.io/v1 kind: Route metadata: name: httpbin namespace: <gateway_namespace> spec: host: httpbin.example.com port: targetPort: http2 to: kind: Service name: <gateway_name> weight: 100 wildcardPolicy: NoneApply the YAML file by running the following command:
$ oc apply -f httpbin-route.yaml
Verify that you can access the
httpbinservice from outside the cluster through the ingress router. Ensure that you set theINGRESS_HOSTvariable appropriately for the environment that your cluster is running in.If the cluster runs on AWS, set the
INGRESS_HOSTvariable by running the following command:$ INGRESS_HOST=$(oc get service router-default -n openshift-ingress -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')If the cluster runs on GCP or Azure, set the
INGRESS_HOSTvariable by running the following command:$ INGRESS_HOST=$(oc get service router-default -n openshift-ingress -o jsonpath='{.status.loadBalancer.ingress[0].ip}')Send a
curlrequest to thehttpbinservice using the host of the ingress router by running the following command:$ curl -s -I -H Host:httpbin.example.com http://$INGRESS_HOST/headers
-
Verify that the response has the
HTTP/1.1 200 OKstatus, which indicates that the request was successful.
2.4. Exposing a service by using the Kubernetes Gateway API in sidecar mode
You can use the Kubernetes Gateway API to create Gateway and HTTPRoute resources and deploy a gateway. The resources configure the gateway to expose a service in the mesh to traffic outside the mesh.
Prerequisites
-
You have logged in to the OpenShift Container Platform web console as a user with the
cluster-adminrole. - You installed the Red Hat OpenShift Service Mesh Operator.
-
You have deployed the
Istioresource.
Procedure
Create a namespace called
httpbinby running the following command:$ oc create namespace httpbin
When using sidecar injection instead of ambient mode, you must enable the sidecar injection in the namespace:
For the
InPlaceupgrade strategy, run the following command:$ oc label namespace httpbin istio-injection=enabled
For the
RevisionBasedupgrade strategy, run the following command:$ oc label namespace httpbin istio.io/rev=<revision-name>
Deploy a sample service named
httpbinby running the following command:$ oc apply -n httpbin -f https://raw.githubusercontent.com/openshift-service-mesh/istio/refs/heads/master/samples/httpbin/httpbin.yaml
Create a YAML file named
httpbin-gw.yamlthat defines a Kubernetes Gateway resource, similar to the following example:apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: httpbin-gateway namespace: httpbin spec: gatewayClassName: istio listeners: - name: default hostname: "httpbin.example.com" port: 80 protocol: HTTP allowedRoutes: namespaces: from: All"httpbin.example.com"- Specifies the virtual hostname that clients use when attempting to access a mesh service on the associated port.
The
HTTPRouteresource specifies the rules that route traffic from the gateway proxy to thehttpbinservice.Apply the YAML file by running the following command:
$ oc apply -f httpbin-gw.yaml
Create a YAML file named
httpbin-ingress-hr.yamlthat defines anHTTPRouteresource for the ingress gateway, similar to the following example:apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: httpbin-ingress namespace: httpbin spec: parentRefs: - name: httpbin-gateway namespace: httpbin hostnames: - "httpbin.example.com" rules: - matches: - path: type: PathPrefix value: /status - path: type: PathPrefix value: /headers - backendRefs: - name: httpbin port: 8000-
spec.parentRefsbinds theHTTPROUTEresource to the KubernetesGatewayresource you created in the previous step. -
spec.rules.backendRefsroutes the matching traffic to thehttpbinservice by defining abackendRefsthat includes the name and port of thehttpbinservice.
The
HTTPRouteresource specifies the rules that route traffic from the gateway proxy to thehttpbinservice.-
Apply the YAML file by running the following command:
$ oc apply -f httpbin-ingress-hr.yaml
Ensure that the Gateway API service is ready and has an allocated address by running the following command:
$ oc wait --for=condition=programmed gtw httpbin-gateway -n httpbin
Verification
Create a namespace for a
curlclient by running the following command:$ oc create namespace curl
Deploy a
curlclient by running the following command:$ oc apply -n curl -f https://raw.githubusercontent.com/openshift-service-mesh/istio/refs/heads/master/samples/curl/curl.yaml
Set a
CURL_PODvariable with the name of thecurlpod by running the following command:$ CURL_POD=$(oc get pods -n curl -l app=curl -o jsonpath='{.items[*].metadata.name}')Using the
curlclient, send a request to the/headersendpoint of thehttpbinapplication through the ingress gatewayServiceresource. Set the Host header of the request tohttpbin.example.comto match the host that the Kubernetes Gateway andHTTPROUTEresources specify. Send thecurlrequest by running the following command:$ oc exec $CURL_POD -n curl -- \ curl -s -I \ -H Host:httpbin.example.com \ <gateway_name>-istio.<gateway_namespace>.svc.cluster.local/headersThe response should return a
200 OKHTTP status, which indicates that the request was successful, similar to the following example:HTTP/1.1 200 OK server: istio-envoy ...
Send a
curlrequest to an endpoint that does not have a corresponding Uniform Resource Identifier (URI) prefix match defined in thehttpbinHTTPROUTEby running the following command:$ oc exec $CURL_POD -n curl -- \ curl -s -I \ -H Host:httpbin.example.com \ <gateway_name>-istio.<gateway_namespace>.svc.cluster.local/getThe response returns a
404 Not Foundstatus, as expected, because the/getendpoint does not have a matching URI prefix in thehttpbinHTTPROUTEresource, similar to the following example:HTTP/1.1 404 Not Found server: istio-envoy ...
Expose the gateway proxy to traffic outside the cluster by setting the
Servicetype toLoadBalancer. Run the following command:$ oc patch service <gateway_name>-istio -n <gateway_namespace> -p '{"spec": {"type": "LoadBalancer"}}'NoteOpenShift Routes can also expose a gateway to traffic outside the cluster. For more information, see "Exposing a gateway to traffic outside the cluster using OpenShift Routes".
Verify that you can access the
httpbinservice from outside the cluster when using the external hostname or IP address of the gateway Service resource. Ensure that you set theINGRESS_HOSTvariable appropriately for the environment in which your cluster is running.Set the
INGRESS_HOSTvariable by running the following command:$ export INGRESS_HOST=$(oc get gtw <gateway_name> -n <gateway_namespace> -o jsonpath='{.status.addresses[0].value}')Set the
INGRESS_PORTvariable by running the following command:$ INGRESS_PORT=$(oc get gtw <gateway_name> -n <gateway_namespace> -o jsonpath='{.spec.listeners[?(@.name=="http")].port}')Using the gateway host, send a
curlrequest to thehttpbinservice by running the following command:$ curl -s -I -H Host:httpbin.example.com http://$INGRESS_HOST:$INGRESS_PORT/headers
-
Verify that the response has the
HTTP/1.1 200 OKstatus, which indicates that the request was successful.
2.5. About ingress traffic routing approaches in ambient mode
When using the Istio ambient mode, you can use the Kubernetes Gateway API to configure ingress traffic routing.
- Waypoint proxies for Layer 7 routing
-
You can deploy a waypoint proxy in the namespace that has your service to apply Layer 7 (L7) routing policies, such as path-based routing or header matching. In ambient mode, waypoint proxies process L7 traffic and enforce
HTTPRouteandGRPCRouterules.
Service Mesh classifies VirtualService resources as Technology Preview (TP) in ambient mode. Therefore, you should not mix them with Gateway API configuration. The recommended approach in ambient mode is to use Kubernetes Gateway API resources.
2.6. Exposing a service by using the Kubernetes Gateway API in ambient mode
You can use the Kubernetes Gateway API to create Gateway and HTTPRoute resources and deploy a gateway in ambient mode. The resources configure the gateway to expose a service in the mesh to traffic outside the mesh.
Prerequisites
-
You have logged in to the OpenShift Container Platform web console as a user with the
cluster-adminrole. - You have installed the Red Hat OpenShift Service Mesh Operator.
-
You have deployed the
Istioresource. - You use the Kubernetes-native Gateway API resources.
- You are either using the Istio ambient mode or planning on migrating to the ambient mode.
Service Mesh recommends the Kubernetes Gateway API for ingress configuration in ambient mode (istio.io/dataplane-mode=ambient), because Istio Gateway and VirtualService resources lack full compatibility.
Procedure
Create a namespace called
httpbinby running the following command:$ oc create namespace httpbin
Apply the label for ambient mode by running the following command:
$ oc label namespace httpbin istio.io/dataplane-mode=ambient
Deploy a sample service named
httpbinby running the following command:$ oc apply -n httpbin -f https://raw.githubusercontent.com/openshift-service-mesh/istio/refs/heads/master/samples/httpbin/httpbin.yaml
Deploy a waypoint proxy by creating a YAML file named
httpbin-waypoint.yaml, similar to the following example:apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: httpbin-waypoint namespace: httpbin labels: istio.io/waypoint-for: service spec: gatewayClassName: istio-waypoint listeners: - name: mesh port: 15008 protocol: HBONEApply the YAML file by running the following command:
$ oc apply -f httpbin-waypoint.yaml
Enable ingress waypoint routing on the
httpbinservice by running the following command:$ oc label service httpbin -n httpbin istio.io/ingress-use-waypoint=true
The label ensures that the ingress gateway routes traffic through the waypoint proxy, which applies its Layer 7 (L7) policies to the traffic before it reaches the
httpbinservice.Apply the waypoint label to the namespace so that all the services inside the namespace routes through the waypoint, by running the following command:
$ oc label ns httpbin istio.io/use-waypoint=httpbin-waypoint
Create a YAML file named
httpbin-gw.yamlthat defines a Kubernetes Gateway resource. This resource configures gateway proxies to expose port 80 (HTTP) for the host,httpbin.example.com.apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: httpbin-gateway namespace: httpbin spec: gatewayClassName: istio listeners: - name: default hostname: "httpbin.example.com" port: 80 protocol: HTTP allowedRoutes: namespaces: from: All"httpbin.example.com"- Specifies the virtual hostname that clients use when attempting to access a mesh service on the associated port.
Apply the YAML file by running the following command:
$ oc apply -f httpbin-gw.yaml
Create a YAML file named
httpbin-ingress-hr.yamlthat defines anHTTPRouteresource for the ingress gateway, similar to the following example:apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: httpbin-ingress namespace: httpbin spec: parentRefs: - name: httpbin-gateway namespace: httpbin hostnames: - "httpbin.example.com" rules: - backendRefs: - name: httpbin port: 8000-
spec.parentRefsbinds theHTTPROUTEresource to the Kubernetes Gateway resource that you created in the previous step. -
spec.rules.backendRefsroutes the matching traffic to thehttpbinservice by defining abackendRefsthat includes the name and port of thehttpbinservice.
The
HTTPRouteresource specifies the rules that route traffic from the gateway proxy to thehttpbinservice.-
Apply the YAML file by running the following command:
$ oc apply -f httpbin-ingress-hr.yaml
Create a YAML file named
httpbin-waypoint-hr.yamlthat defines anHTTPRouteresource for the waypoint proxy.apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: httpbin-waypoint-route namespace: httpbin spec: parentRefs: - group: "" kind: service name: httpbin namespace: httpbin rules: - matches: - path: type: PathPrefix value: /status - path: type: PathPrefix value: /headers backendRefs: - name: httpbin port: 8000-
spec.parentRefsbinds theHTTPRouteresource to thehttpbinservice. When combined with theistio.io/ingress-use-waypoint=truelabel on the service, theHTTPRouteconfigures the L7 routing rules that the waypoint proxy will enforce for traffic destined to that service. -
spec.rules.backendRefsroutes the matching traffic to thehttpbinservice by defining abackendRefsthat includes the name and port of thehttpbinservice.
-
Apply the YAML file by running the following command:
$ oc apply -f httpbin-waypoint-hr.yaml
NoteIn this example use case, traffic from the ingress gateway flows through the waypoint proxy because of the
istio.io/ingress-use-waypoint=truelabel. TheHTTPRouteresource then applies path-based routing policies before the traffic reaches the httpbin service.Ensure that the waypoint proxy is ready by running the following command:
$ oc wait --for=condition=programmed gtw httpbin-waypoint -n httpbin
Verification
Create a namespace for a
curlclient by running the following command:$ oc create namespace curl
Deploy a
curlclient by running the following command:$ oc apply -n curl -f https://raw.githubusercontent.com/openshift-service-mesh/istio/refs/heads/master/samples/curl/curl.yaml
Apply the label for ambient mode to the
curlnamespace by running the following command:$ oc label namespace curl istio.io/dataplane-mode=ambient
Set a
CURL_PODvariable with the name of thecurlpod by running the following command:$ CURL_POD=$(oc get pods -n curl -l app=curl -o jsonpath='{.items[*].metadata.name}')Using the
curlclient, send a request to the/headersendpoint of thehttpbinapplication through the ingress gatewayServiceresource. Set the Host header of the request tohttpbin.example.comto match the host that the Kubernetes Gateway andHTTPROUTEresources specify. Send thecurlrequest by running the following command:$ oc exec $CURL_POD -n curl -- \ curl -s -I \ -H Host:httpbin.example.com \ httpbin-gateway-istio.httpbin.svc.cluster.local/headersThe response should return a
200 OKHTTP status, which indicates that the request was successful, similar to the following example:HTTP/1.1 200 OK server: istio-envoy ...
Send a
curlrequest to an endpoint that does not have a corresponding Uniform Resource Identifier (URI) prefix match defined in thehttpbinHTTPROUTEby running the following command:$ oc exec $CURL_POD -n curl -- \ curl -s -I \ -H Host:httpbin.example.com \ httpbin-gateway-istio.httpbin.svc.cluster.local/getThe response returns a
404 Not Foundstatus, as expected, because the/getendpoint does not have a matching URI prefix in thehttpbinHTTPROUTEresource, similar to the following example:HTTP/1.1 404 Not Found server: istio-envoy ...
Expose the gateway proxy to traffic outside the cluster by setting the
Servicetype toLoadBalancer. Run the following command:$ oc patch service httpbin-gateway-istio -n httpbin -p '{"spec": {"type": "LoadBalancer"}}'NoteOpenShift Routes can also expose a gateway to traffic outside the cluster. For more information, see "Exposing a gateway to traffic outside the cluster using OpenShift Routes".
Verify that the you can access the
httpbinservice from outside the cluster when using the external hostname or IP address of the gateway Service resource. Ensure that you set theINGRESS_HOSTvariable appropriately for the environment in which your cluster is running.Set the
INGRESS_HOSTvariable by running the following command:$ export INGRESS_HOST=$(oc get gtw httpbin-gateway -n httpbin -o jsonpath='{.status.addresses[0].value}')Set the
INGRESS_PORTvariable by running the following command:$ INGRESS_PORT=$(oc get gtw httpbin-gateway -n httpbin -o jsonpath='{.spec.listeners[?(@.name=="http")].port}')Using the gateway host, send a
curlrequest to thehttpbinservice by running the following command:$ curl -s -I -H Host:httpbin.example.com http://$INGRESS_HOST:$INGRESS_PORT/headers
-
Verify that the response has the
HTTP/1.1 200 OKstatus, which indicates that the request was successful.
2.7. Additional resources
- About gateway injection
- Content from istio.io is not included.Istio Gateway resource API reference (Istio documentation)
- Content from istio.io is not included.VirtualService API reference (Istio documentation)
- Creating an HTTP-based Route
- Content from kubernetes.io is not included.Kubernetes Gateway API concept (Kubernetes documentation)
Chapter 3. Directing outbound traffic through a gateway
Using Istio APIs, you configure gateway proxies, installed through gateway injection, to direct traffic bound for an external service.
3.1. About directing egress traffic through a gateway
You can configure a gateway installed through gateway injection as an exit point for traffic leaving the service mesh. It acts as a forward proxy for requests sent to services external to the mesh.
- Egress gateway
An egress gateway acts as a forward proxy and serves as the exit point for traffic exiting the service mesh toward external services. You can configure an egress gateway to fulfill security requirements:
- Traffic Restrictions: In environments with strict traffic restrictions, an egress gateway ensures all outbound traffic flows through a dedicated set of nodes.
- Network Policy Enforcement: When network policies prevent application nodes from directly accessing external services, the egress gateway handles the external access.
In these scenarios, you deploy gateway proxies on dedicated egress nodes that can access external services. You can then enforce strict network policies or add monitoring to these nodes to enhance security.
- Configure egress traffic
You can configure a gateway installed through gateway injection to direct the egress traffic by combining the following Istio resources:
-
The
ServiceEntryadds the external service to the Istio service registry. You can then apply Istio features, such as monitoring and routing rules, to traffic heading toward that external service. -
Use the
Gateway,VirtualService, andDestinationRuleresources to set up rules that route traffic from the mesh to the external service using the gateway proxy.
-
The
- Egress routing in ambient mode
If your deployment uses ambient mode, you must configure egress routing using the Kubernetes Gateway API instead of Istio
GatewayandVirtualServiceresources. The Kubernetes Gateway API provides a standardized, Kubernetes-native method for defining how traffic exits the mesh and reaches external services.You can use
GatewayandHTTPRoute(orGRPCRoute) resources to route mesh traffic to destinations outside the cluster. Service Mesh fully supports the Gateway API in ambient mode, and you can also use it with sidecar-based deployments, providing a consistent configuration model for both ingress and egress routing.
3.2. Directing egress traffic through a gateway using Istio APIs
Use Istio APIs to direct outbound HTTP traffic through a gateway that you installed using gateway injection.
Prerequisites
- You have installed a gateway using gateway injection.
Procedure
Create a namespace called
curlby running the following command:$ oc create namespace curl
Depending on the update strategy you are using, enable sidecar injection in the namespace by running the appropriate commands:
If you are using the
InPlaceupdate strategy, run the following command:$ oc label namespace curl istio-injection=enabled
If you are using the
RevisionBasedupdate strategy, run the following commands:Display the revision name by running the following command:
$ oc get istiorevisions.sailoperator.io
You should see output similar to the following example:
NAME TYPE READY STATUS IN USE VERSION AGE default Local True Healthy True v1.24.3 3m33s
Label the namespace with the revision name to enable sidecar injection by running the following command:
$ oc label namespace curl istio.io/rev=default
Deploy a
curlapplication by running the following command:$ oc apply -n curl -f https://raw.githubusercontent.com/openshift-service-mesh/istio/refs/heads/master/samples/curl/curl.yaml
Export a
CURL_PODenvironment variable and initialize it with the name of the curl pod by running the following command:$ export CURL_POD=$(oc get pod -n curl -l app=curl -o jsonpath='{.items[0].metadata.name}')Create a YAML file named
http-se.yamlthat directs traffic from the mesh to an external service. The following example defines aServiceEntryfor a URL:apiVersion: networking.istio.io/v1 kind: ServiceEntry metadata: name: egress-se namespace: curl spec: hosts: - docs.redhat.com ports: - number: 80 name: http-port protocol: HTTP location: MESH_EXTERNAL resolution: DNSApply the YAML file by running the following command:
$ oc apply -f http-se.yaml
Ensure that you applied the
ServiceEntryconfiguration correctly. Send an HTTP request to the host that you specified in the previous step by running the following command:$ oc exec "$CURL_POD" -n curl -c curl -- curl -sSL -o /dev/null -D - http://docs.redhat.com
This command should return HTTP status codes, such as
301(redirect) or200(success), indicating that the connection works.Create a YAML file named
http-gtw.yamlthat creates an egressGatewayand routes traffic from the mesh to the host specified for the external service, similar to the following example:apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: egress-gw namespace: <gateway_namespace> # Namespace where the egress gateway is deployed spec: selector: istio: <gateway_name> # Selects the egress-gateway instance to handle this traffic servers: - port: number: 80 name: http protocol: HTTP hosts: - docs.redhat.com # External service host, not a full URL. --- apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: egress-dr namespace: <gateway_namespace> # Namespace where the egress gateway is deployed spec: host: <gateway_name>.<gateway_namespace>.svc.cluster.local subsets: - name: rh-docsApply the YAML file by running the following command:
$ oc apply -f http-gtw.yaml
Create a YAML file named
http-vs.yamlthat sets up aVirtualServiceto manage the flow of traffic from the application sidecars through the egress gateway to the external host, similar to the following example:apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: egress-vs namespace: curl # Namespace where the curl pod is running spec: hosts: - docs.redhat.com # External service host, not a full URL. gateways: - mesh - <gateway_namespace>/egress-gw # Egress gateway name defined in the file that you used in the previous step. http: - match: - gateways: - mesh port: 80 route: - destination: host: <gateway_name>.<gateway_namespace>.svc.cluster.local subset: rh-docs port: number: 80 weight: 100 - match: - gateways: - <gateway_namespace>/egress-gw # Egress gateway name defined in the file that you used in the previous step. port: 80 route: - destination: host: docs.redhat.com port: number: 80 weight: 100Apply the YAML file by running the following command:
$ oc apply -f http-vs.yaml
Resend the HTTP request to the URL:
$ oc exec "$CURL_POD" -n curl -c curl -- curl -sSL -o /dev/null -D - http://docs.redhat.com
The terminal should display information similar to the following output:
... HTTP/1.1 301 Moved Permanently ... location: <example_url> ... HTTP/2 200 Content-Type: text/html; charset=utf-8
Ensure that the gateway routed the request by running the following command:
$ oc logs deployment/<gateway_name> -n <gateway_namespace> | tail -1
NoteYou must enable access logging for this verification step to work. You can enable access logging to the standard output by setting the
spec.values.meshConfig.accessLogFilefield to/dev/stdoutin the Istio resource.The terminal should display information similar to the following output:
[2024-11-07T14:35:52.428Z] "GET / HTTP/2" 301 - via_upstream - "-" 0 0 24 24 "10.128.2.30" "curl/8.11.0" "79551af2-341b-456d-b414-9220b487a03b" "docs.redhat.com" "23.55.176.201:80" outbound|80||docs.redhat.com 10.128.2.29:49766 10.128.2.29:80 10.128.2.30:38296 -
3.3. Directing egress traffic through a gateway by using the Kubernetes Gateway API
Use the Kubernetes Gateway API to direct outbound HTTP traffic through an egress gateway.
Prerequisites
- You installed an Istio control plane.
-
You configured the
IstioandIstioCNIresources.
Procedure
Optional: Enable the Kubernetes Gateway API custom resource definitions (CRDs).
NoteAs of Kubernetes 1.28 and OpenShift Container Platform 4.18 or earlier version of Red Hat OpenShift Service Mesh, the Kubernetes Gateway API CRDs are not available by default and you must install the CRDs before you can use them. OpenShift Container Platform 4.19 and later versions install the CRDs by default.
Create a YAML file named
gateway-cr.yamlthat enables the Kubernetes Gateway API CRDs, similar to the following example:apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: bookinfo-gateway spec: gatewayClassName: istio listeners: - name: http port: 80 protocol: HTTP allowedRoutes: namespaces: from: Same --- apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: bookinfo spec: parentRefs: - name: bookinfo-gateway rules: - matches: - path: type: Exact value: /productpage - path: type: PathPrefix value: /static - path: type: Exact value: /login - path: type: Exact value: /logout - path: type: PathPrefix value: /api/v1/products backendRefs: - name: productpage port: 9080Apply the YAML file by running the following command:
$ oc apply -f gateway-cr.yaml
Create a namespace called
egress-gatewayby running the following command:$ oc create namespace egress-gateway
Apply the
istio-injectionlabel to the namespace by running the following command:$ oc label namespace egress-gateway istio-injection=enabled
Create a YAML file named
egress-gateway-cr.yamlthat defines the egress gateway, similar to the following example:# ServiceEntry to allow traffic to httpbin.org apiVersion: networking.istio.io/v1 kind: ServiceEntry metadata: name: httpbin-ext spec: hosts: - httpbin.org ports: - number: 80 name: http protocol: HTTP location: MESH_EXTERNAL resolution: DNS --- # Gateway API Gateway for egress apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: httpbin-egress-gateway annotations: networking.istio.io/service-type: ClusterIP spec: gatewayClassName: istio listeners: - name: http hostname: httpbin.org port: 80 protocol: HTTP allowedRoutes: namespaces: from: Same --- # HTTPRoute to direct traffic from sidecars to the egress gateway apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: direct-httpbin-to-egress-gateway spec: parentRefs: - kind: ServiceEntry group: networking.istio.io name: httpbin-ext rules: - backendRefs: - name: httpbin-egress-gateway-istio port: 80 --- # HTTPRoute to forward traffic from the egress gateway to httpbin.org apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: forward-httpbin-from-egress-gateway spec: parentRefs: - name: httpbin-egress-gateway hostnames: - httpbin.org rules: - backendRefs: - kind: Hostname group: networking.istio.io name: httpbin.org port: 80Apply the YAML file by running the following command:
$ oc apply -f egress-gateway-cr.yaml
Verification
Verify the status of the gateway configuration by running the following command:
$ oc describe gateway -n egress-gateway
The
Statuscolumn displaysProgrammedto indicate the required output.Create a
curlpod in theegress-gatewaynamespace by running the following command:$ oc run test-pod --image=curlimages/curl:latest -n egress-gateway --rm -it --restart=Never -- sh
By using the
curlclient, verify that you can accesshttpbin.orgthrough the egress gateway by entering following command:$ curl -v http://httpbin.org/get
The required output shows a response from
httpbin.orgthat indicates egress traffic routes through the configured gateway.
3.4. Directing egress traffic through a gateway using the Kubernetes Gateway API in ambient mode
Use the Kubernetes Gateway API and waypoint proxy to direct outbound HTTP traffic through an egress gateway.
Prerequisites
- You have installed the OpenShift Service Mesh Operator version 3.2 or later.
-
You configured the
IstioandIstioCNIresources with ambient profile. -
You have created a
Ztunnelresource.
Procedure
Optional: Enable the {k8} Gateway API custom resource definitions (CRDs).
NoteAs of Kubernetes 1.28 and OpenShift Container Platform 4.18 or earlier version of Red Hat OpenShift Service Mesh, the Kubernetes Gateway API CRDs are not available by default and you must install the CRDs before you can use them. OpenShift Container Platform 4.19 and later versions install the CRDs by default.
Create a namespace called
egress-gatewayby running the following command:$ oc create namespace egress-gateway
Apply the ambient mode label to the namespace by running the following command:
$ oc label namespace egress-gateway istio.io/dataplane-mode=ambient
Create a YAML file named
egress-se.yamlthat defines theServiceEntry, similar to the following example:apiVersion: networking.istio.io/v1 kind: ServiceEntry metadata: name: httpbin-ext namespace: egress-gateway labels: istio.io/use-waypoint: waypoint spec: hosts: - httpbin.org ports: - number: 80 name: http protocol: HTTP resolution: DNSApply the YAML file by running the following command:
$ oc apply -f egress-se.yaml
Create a YAML file named
waypoint.yamlthat creates a waypoint proxy inegress-gatewaynamespace similar to the following example:apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: waypoint namespace: egress-gateway labels: istio.io/gateway-for: service spec: gatewayClassName: istio-waypoint listeners: - name: mesh port: 15008 protocol: HBONEApply the YAML file by running the following command:
$ oc apply -f waypoint.yaml
NoteAs an alternate to creating the
waypoint.yamlYAML file, you can also set up waypoint proxy by running the following command:$ istioctl waypoint apply --enroll-namespace --name waypoint --namespace egress-gateway
When you use the
--enroll-namespaceoption, all services in theegress-gatewaynamespace (includingServiceEntries), will route their traffic through the waypoint.
Verification
Verify the status of the gateway configuration by running the following command:
$ oc get gateways.gateway.networking.k8s.io waypoint -n egress-gateway
The
PROGRAMMEDcolumn showsTruewhen the configuration succeeds, similar to the following example:NAME CLASS ADDRESS PROGRAMMED AGE waypoint istio-waypoint 172.30.227.148 True 9s
Create a
curlpod in theegress-gatewaynamespace by running the following command:$ oc run test-pod --image=curlimages/curl:latest -n egress-gateway --rm -it --restart=Never -- sh
By using the
curlclient, verify that you can accesshttpbin.orgthrough the egress gateway by running the following command:$ curl -v http://httpbin.org/get
The output shows a response from
httpbin.orgservice that indicates egress traffic routes through the configured gateway. The ztunnel logs should show traffic routed through the waypoint. The terminal should display information similar to the following output:2025-10-24T08:08:35.242159Z info access connection complete src.addr=[fd01:0:0:5::b0]:56288 src.workload="test-pod" src.namespace="egress-gateway" src.identity="spiffe://cluster.local/ns/egress-gateway/sa/default" dst.addr=[fd01:0:0:5::af]:15008 dst.hbone_addr=[2001:2::2]:80 dst.service="httpbin.org" dst.workload="waypoint-5b668759d5-vrnx8" dst.namespace="egress-gateway" dst.identity="spiffe://cluster.local/ns/egress-gateway/sa/waypoint" direction="outbound" bytes_sent=78 bytes_recv=540 duration="957ms"
3.5. Additional resources
Chapter 4. Configuring quantum secure gateways
Use the Kubernetes Gateway API with a post-quantum cryptographic algorithm to establish a secure ingress gateway.
4.1. Generating TLS certificates
Generate Transport Layer Security (TLS) certificates and create a secret to secure ingress traffic for a service mesh gateway.
Procedure
Create a directory for your certificates by running the following command:
$ mkdir certs
Generate the certificates for your gateway similar to the following examples:
Create the first certificate by running the following command:
$ openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 \ -subj '/O=example Inc./CN=example.com' \ -keyout certs/example.com.key \ -out certs/example.com.crt
Create the second certificate by running the following command:
$ openssl req -out certs/httpbin.example.com.csr -newkey rsa:2048 -nodes \ -keyout certs/httpbin.example.com.key \ -subj "/CN=httpbin.example.com/O=httpbin organization"
Create the third certificate by running the following command:
$ openssl x509 -req -sha256 -days 365 \ -CA certs/example.com.crt -CAkey certs/example.com.key \ -set_serial 0 -in certs/httpbin.example.com.csr \ -out certs/httpbin.example.com.crt
Create a secret containing the TLS certificate for your gateway by running the following command:
$ oc create -n istio-system secret tls httpbin-credential \ --key=certs/httpbin.example.com.key \ --cert=certs/httpbin.example.com.crt
4.2. Deploying quantum secure gateways
Configure and deploy a service mesh gateway by using the Kubernetes Gateway API to enable post-quantum cryptographic protection for ingress traffic.
Prerequisites
-
You have logged in to the OpenShift Container Platform web console 4.19+ as a user with the
cluster-adminrole. - You have installed the Red Hat OpenShift Service Mesh Operator 3.2.1+
-
You have created an
Istioresource with PQC enabled, and the Operator has deployed Istio. For more information, see "Installing service mesh with post-quantum cryptography (PQC)". You have installed the following CLI tools locally:
-
oc -
podman -
curl
-
Procedure
Deploy a gateway using the Kubernetes Gateway API by running the following command:
$ oc apply -f - <<EOF apiVersion: gateway.networking.k8s.io/v1beta1 kind: Gateway metadata: name: pqc-gateway namespace: istio-system spec: gatewayClassName: istio listeners: - name: https port: 443 protocol: HTTPS tls: mode: Terminate certificateRefs: - name: httpbin-credential namespace: istio-system allowedRoutes: namespaces: from: All --- apiVersion: gateway.networking.k8s.io/v1beta1 kind: HTTPRoute metadata: name: httpbin-route namespace: default spec: parentRefs: - name: pqc-gateway namespace: istio-system hostnames: - "httpbin.example.com" rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: httpbin port: 8000 EOFAdd the
istio-injection=enabledlabel to thedefaultnamespace by running the following command:$ oc label ns default istio-injection=enabled
Deploy the backend server by running the following command:
$ oc apply -n default -f \ https://raw.githubusercontent.com/openshift-service-mesh/istio/master/samples/httpbin/httpbin.yaml
4.3. Verifying quantum secure gateways
Verify the post-quantum gateway configuration by testing connections with both post-quantum cryptography (PQC)-enabled and standard clients to confirm that the gateway accepts only quantum-safe handshakes.
Procedure
Retrieve the external address based on the type of load balancer:
Retrieve the external address for your hostname-based load balancer by running the following command:
$ INGRESS_ADDR=$(oc get svc pqc-gateway-istio \ -n istio-system \ -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')Retrieve the external address for your IP-based load balancer by running the following command:
$ INGRESS_ADDR=$(oc get svc pqc-gateway-istio \ -n istio-system \ -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
Test the connection with the PQC-enabled client by running the following command:
$ podman run --rm -it \ -v ./certs/example.com.crt:/etc/certs/example.com.crt \ docker.io/openquantumsafe/curl \ curl -vk "https://$INGRESS_ADDR:443/headers" \ -H "Host: httpbin.example.com" \ --curves X25519MLKEM768 \ --cacert /etc/certs/example.com.crt
The request should succeed, and you should receive the
HTTPstatus as200.Verify that the connection fails with a standard
curlclient by running the following command:$ curl -vk "https://$INGRESS_ADDR:443/headers" \ -H "Host: httpbin.example.com" \ --cacert ./certs/example.com.crt
You will get errors similar to the following example:
* TLSv1.3 (OUT), TLS handshake, Client hello (1): * TLSv1.3 (IN), TLS alert, handshake failure (552): * TLS connect error: error:0A000410:SSL routines::ssl/tls alert handshake failure * closing connection #0 curl: (35) TLS connect error: error:0A000410:SSL routines::ssl/tls alert handshake failure