{"id":283,"date":"2025-11-26T05:06:05","date_gmt":"2025-11-26T05:06:05","guid":{"rendered":"https:\/\/blog.ngocha.biz\/?p=283"},"modified":"2025-11-26T05:06:05","modified_gmt":"2025-11-26T05:06:05","slug":"istio-ingress-kubernetes-gateway-api","status":"publish","type":"post","link":"https:\/\/blog.ngocha.biz\/?p=283","title":{"rendered":"Setting up Istio Ingress With Kubernetes Gateway API"},"content":{"rendered":"<p>In this step by step blog, you will learn to set up and configure ingress for Istio mesh using Kubernetes Gateway API with examples.<\/p>\n<p>Here is what you will learn by the end of this blog.<\/p>\n<ol>\n<li>How to use the Kubernetes Gateway API with Istio<\/li>\n<li>How to expose services running inside an Istio service mesh using a Gateway.<\/li>\n<li>Configure canary traffic splitting using HTTPRoute weights.<\/li>\n<li>Add Istio traffic policies like circuit breaking using DestinationRule.<\/li>\n<li>Validate end-to-end traffic flow from an external client.<\/li>\n<li>How Gateway API and the GAMMA initiative extend the same model to internal (east-west) mesh traffic.<\/li>\n<\/ol>\n<h2 id=\"using-gateway-api-for-istio-ingress\">Using Gateway API for Istio Ingress<\/h2>\n<p><a href=\"https:\/\/devopscube.com\/istio-architecture\/\" rel=\"noreferrer\"><strong>Istio<\/strong><\/a> is a <a href=\"https:\/\/devopscube.com\/service-mesh-tools\/\" rel=\"noreferrer\"><strong>service mesh<\/strong><\/a> that primarily manages the internal traffic, meaning the service-to-service communication (<em>east-west traffic<\/em>).<\/p>\n<p>However, we also need to handle north-south traffic (<em>external to internal<\/em>). To do that, we need an ingress setup similar to native Kubernetes.<\/p>\n<p>For this, Istio provides its own <code>Gateway<\/code> + <code>VirtualService<\/code> API to handle ingress\/egress.<\/p>\n<p>However, Istio now supports the Kubernetes Gateway API for handling external traffic. Also it is <strong>intended to become the default API<\/strong> in the future for managing ingress\/egress traffic in Istio-enabled clusters. <\/p>\n<p>The image below shows the high-level architecture of what we are going to build. Once you finish the setup, come back to this diagram. It will make more sense then.<\/p>\n<figure class=\"kg-card kg-image-card kg-card-hascaption\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/11\/image-100.png\" class=\"kg-image\" alt=\"Gateway API and Istio Ingress architecture\" loading=\"lazy\" width=\"2000\" height=\"1962\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/11\/image-100.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1000\/2025\/11\/image-100.png 1000w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1600\/2025\/11\/image-100.png 1600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w2400\/2025\/11\/image-100.png 2400w\" sizes=\"auto, (min-width: 720px) 720px\"><figcaption><span style=\"white-space: pre-wrap;\">Using Gateway API for Istio Ingress<\/span><\/figcaption><\/figure>\n<p>Although there is support, here is what the official Istio documentation says about using the Gateway API for ingress:<\/p>\n<blockquote><p>While the Gateway APIs offer a lot of rich routing functionality, it does not yet cover 100% of Istio\u2019s feature set. (istio.io)<\/p><\/blockquote>\n<p>Now, lets understand the Gateway API integration practically.<\/p>\n<div class=\"kg-card kg-callout-card kg-callout-card-blue\">\n<div class=\"kg-callout-emoji\">\ud83d\udcda<\/div>\n<div class=\"kg-callout-text\">Understanding of Gateway API basics is very important for this implementation. If you are new to Gateway API, please refer to our <a href=\"https:\/\/devopscube.com\/kubernetes-gateway-api\/\" rel=\"noreferrer\">Kubernetes Gateway API tutorial<\/a><\/div>\n<\/div>\n<h2 id=\"setup-prerequisites\">Setup Prerequisites<\/h2>\n<p>To get started with this setup you need an Istio-enabled <a href=\"https:\/\/devopscube.com\/setup-kubernetes-cluster-kubeadm\/\" rel=\"noreferrer\">Kubernetes cluster.<\/a><\/p>\n<p>We have covered the full Istio setup using sidecar mode in a detailed blog. Please refer to the following guide for that setup. <\/p>\n<blockquote><p><a href=\"https:\/\/devopscube.com\/setup-istio-on-kubernetes\/\" rel=\"noreferrer\">Set up Istio on a Kubernetes Cluster<\/a><\/p><\/blockquote>\n<div class=\"kg-card kg-callout-card kg-callout-card-blue\">\n<div class=\"kg-callout-emoji\">\ud83d\udccc<\/div>\n<div class=\"kg-callout-text\">Since this is a continuation blog, we will <b><strong style=\"white-space: pre-wrap;\">use the same sample applications we deployed<\/strong><\/b> in the istio setup guide for testing ingress.<\/p>\n<p>So please make sure to deploy them as well.<\/p><\/div>\n<\/div>\n<h2 id=\"install-gateway-api-crds\">Install Gateway API CRD&#8217;s<\/h2>\n<p>The first step is to install the Kubernetes Gateway API CRDs. This way Kubernetes understands the Gateway API <a href=\"https:\/\/devopscube.com\/kubernetes-objects-resources\/\" rel=\"noreferrer\">custom objects<\/a> and Istio can watch for those Gateway API objects and act on them.<\/p>\n<p>To install the Gateway API CRDs, use the following command.<\/p>\n<pre><code class=\"language-bash\">kubectl apply -f https:\/\/github.com\/kubernetes-sigs\/gateway-api\/releases\/download\/v1.3.0\/standard-install.yaml\n<\/code><\/pre>\n<p>Once the installation is completed, we can list them to ensure the installation.<\/p>\n<pre><code class=\"language-bash\">$ kubectl get crds | grep gateway\n\ngatewayclasses.gateway.networking.k8s.io     2025-05-21T13:49:23Z\ngateways.gateway.networking.k8s.io           2025-05-21T13:49:29Z\ngrpcroutes.gateway.networking.k8s.io         2025-05-21T13:49:32Z\nhttproutes.gateway.networking.k8s.io         2025-05-21T13:49:35Z\nreferencegrants.gateway.networking.k8s.io    2025-05-21T13:49:36Z<\/code><\/pre>\n<p>The output confirms that the CRDs have been successfully installed and that they are used to define the routing rules.<\/p>\n<div class=\"kg-card kg-callout-card kg-callout-card-blue\">\n<div class=\"kg-callout-emoji\">\ud83d\udca1<\/div>\n<div class=\"kg-callout-text\">Apart from Gateway API CRDs, Kubernetes requires Controller to configure the underlying proxies and manage traffic (e.g., Nginx Gateway Fabric Controller)<\/p>\n<p>However, since we are using Istio, its <b><strong style=\"white-space: pre-wrap;\">built-in gateway controller<\/strong><\/b> acts as a <a href=\"https:\/\/devopscube.com\/setup-envoy-gateway-api\/\">Gateway API controller<\/a>. So we do not need to install a separate controller.<\/div>\n<\/div>\n<h2 id=\"default-istio-gatewayclass\">Default Istio GatewayClass<\/h2>\n<p>To use Gateway API, the first thing that we need is the <strong>GatewayClass<\/strong>. It tells Kubernetes <strong>which controller<\/strong> will implement the gateways. In our case its the istio <strong><code>gateway-controller<\/code>.<\/strong><\/p>\n<p>When we install Istio on a Kubernetes cluster, it automatically creates a <strong><code>GatewayClass<\/code><\/strong>.<\/p>\n<p>You can list the GatewayClasses using the following command.<\/p>\n<pre><code class=\"language-bash\">$ kubectl get gc\n\nNAME           CONTROLLER                    ACCEPTED   AGE\nistio          istio.io\/gateway-controller   True       3h43m\nistio-remote   istio.io\/unmanaged-gateway    True       3h43m\n<\/code><\/pre>\n<p>Here, you can see two Gateway Classes.<\/p>\n<ul>\n<li><code>istio<\/code> &#8211; This is Istio&#8217;s built-in controller that manages Gateway resources. It creates and manages actual gateway pods (like istio-ingressgateway) in your cluster.<\/li>\n<li><code>istio-remote<\/code> &#8211; It references gateways that exist in another. Meaning the controller is in another cluster and especially useful for the multi cluster mesh management.<\/li>\n<\/ul>\n<p>Next, let\u2019s deploy a demo application that we will use to test ingress connectivity using the Gateway API.<\/p>\n<h2 id=\"deploy-demo-application\">Deploy Demo Application<\/h2>\n<p>For this demo, we are using the same application <a href=\"https:\/\/devopscube.com\/kubernetes-deployment-tutorial\/\" rel=\"noreferrer\">deployment<\/a> from the Istio setup blog.<\/p>\n<p>If you are already following that blog and have the demo app running, you can skip this step. Otherwise, you can follow the deployment instructions here.<\/p>\n<p>Use the following manifest to deploy the demo apps and its related service endpoints (<strong><code>backend-v1<\/code><\/strong> &amp; <strong><code>backend-v2<\/code><\/strong>).<\/p>\n<pre><code class=\"language-yaml\">cat &lt;&lt;'EOF' | kubectl apply -f -\napiVersion: v1\nkind: Namespace\nmetadata:\n  labels:\n    istio-injection: enabled\n  name: istio-test\n---\napiVersion: apps\/v1\nkind: Deployment\nmetadata:\n  name: backend-v1\n  namespace: istio-test\nspec:\n  replicas: 3\n  selector:\n    matchLabels: { app: backend, version: v1 }\n  template:\n    metadata:\n      labels: { app: backend, version: v1 }\n    spec:\n      containers:\n      - name: echo\n        image: hashicorp\/http-echo\n        args: [\"-text=hello from backend v1\"]\n        ports:\n        - containerPort: 5678\n---\napiVersion: apps\/v1\nkind: Deployment\nmetadata:\n  name: backend-v2\n  namespace: istio-test\nspec:\n  replicas: 2\n  selector:\n    matchLabels: { app: backend, version: v2 }\n  template:\n    metadata:\n      labels: { app: backend, version: v2 }\n    spec:\n      containers:\n      - name: echo\n        image: hashicorp\/http-echo\n        args: [\"-text=hello from backend v2\"]\n        ports:\n        - containerPort: 5678\n---\napiVersion: v1\nkind: Service\nmetadata:\n  name: backend-v1\n  namespace: istio-test\nspec:\n  selector:\n    app: backend\n    version: v1\n  ports:\n  - name: http\n    port: 80\n    targetPort: 5678\n---\napiVersion: v1\nkind: Service\nmetadata:\n  name: backend-v2\n  namespace: istio-test\nspec:\n  selector:\n    app: backend\n    version: v2\n  ports:\n  - name: http\n    port: 80\n    targetPort: 5678\nEOF<\/code><\/pre>\n<p>Once the deployment is completed, ensure that the resources are running without any issues as given below.<\/p>\n<pre><code class=\"language-bash\">$ kubectl -n istio-test get po,svc\n\nNAME                              READY   STATUS    RESTARTS   AGE\npod\/backend-v1-7c88547fc6-9755x   2\/2     Running   0          10s\npod\/backend-v1-7c88547fc6-97hvg   2\/2     Running   0          10s\npod\/backend-v1-7c88547fc6-tdjb2   2\/2     Running   0          10s\npod\/backend-v2-86c767bf6b-9vplh   2\/2     Running   0          10s\npod\/backend-v2-86c767bf6b-bs2kg   2\/2     Running   0          10s\n\nNAME                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE\nservice\/backend-v1   ClusterIP   10.100.171.193   &lt;none&gt;        80\/TCP    10s\nservice\/backend-v2   ClusterIP   10.100.185.97    &lt;none&gt;        80\/TCP    9s<\/code><\/pre>\n<h2 id=\"creating-istio-ingress-with-gateway-api\">Creating Istio Ingress With Gateway API<\/h2>\n<p>Now that the required application and other basic setup is ready, we can start configuring ingress using Gateway API objects.<\/p>\n<p>Follow the steps given below.<\/p>\n<h3 id=\"step-1-create-a-gateway\">Step 1: Create a Gateway <\/h3>\n<p><strong>Gateway<\/strong> is a Custom Resource of Gateway API where we define what type of traffic the Controller should handle.<\/p>\n<p>For this demo, we will use the following.<\/p>\n<ul>\n<li>Traffic type &#8211; <strong>HTTP<\/strong><\/li>\n<li>Protocol &#8211; <strong>80<\/strong><\/li>\n<li>Gateway Class &#8211; <strong>istio<\/strong><\/li>\n<\/ul>\n<p>When we deploy a Gateway object, the Gateway controller (Istio controller) <strong>creates an Envoy proxy pod<\/strong> to route traffic to your backend pods. It also <strong>creates an external load balancer<\/strong> (on the cloud) so that external traffic can reach the proxy.<\/p>\n<p>Copy the following code on your terminal to create a Gateway YAML configuration file.<\/p>\n<div class=\"kg-card kg-callout-card kg-callout-card-yellow\">\n<div class=\"kg-callout-emoji\">\u26a0\ufe0f<\/div>\n<div class=\"kg-callout-text\">We are tested this setup on <a href=\"https:\/\/devopscube.com\/create-aws-eks-cluster-eksctl\/\" rel=\"noreferrer\">AWS EKS<\/a>. Thats why we are using AWS-specific annotations for the load balancer.<\/p>\n<p>Please update these annotations based on the cloud provider you are using. The rest of the configuration remains the same.<\/p><\/div>\n<\/div>\n<pre><code class=\"language-bash\">cat &lt;&lt; EOF &gt; istio-gateway.yaml\napiVersion: gateway.networking.k8s.io\/v1\nkind: Gateway\nmetadata:\n  name: istio-gateway\n  namespace: istio-test\n  annotations:\n    service.beta.kubernetes.io\/aws-load-balancer-type: \"nlb\"\nspec:\n  gatewayClassName: istio\n  listeners:\n  - name: http\n    protocol: HTTP\n    port: 80\n    allowedRoutes:\n      namespaces:\n        from: Same\nEOF<\/code><\/pre>\n<p>To apply this configuration, use the following command.<\/p>\n<pre><code class=\"language-bash\">kubectl apply -f istio-gateway.yaml<\/code><\/pre>\n<p>It will deploy a proxy pod (Data plane controller) and service type <strong><code>LoadBalancer<\/code><\/strong> in the <strong><code>istio-test<\/code><\/strong> namespace.<\/p>\n<p>Use the following command to validate that the proxy pod and service are deployed.<\/p>\n<pre><code class=\"language-bash\">$ kubectl get po,svc -n istio-test -l gateway.networking.k8s.io\/gateway-name=istio-gateway\n\n\nNAME                                       READY   STATUS    RESTARTS   AGE\npod\/istio-gateway-istio-67584dc449-qmkpx   1\/1     Running   0          4m31s\n\nNAME                          TYPE           CLUSTER-IP     EXTERNAL-IP                                                                     PORT(S)                        AGE\nservice\/istio-gateway-istio   LoadBalancer   10.100.77.16   ad8805f370c854e749a18ed03f2bb2e0-4940c029a9c83906.elb.us-west-2.amazonaws.com   15021:31161\/TCP,80:31432\/TCP   4m31s<\/code><\/pre>\n<p>If you describe the Proxy pod, you will see <strong><code>istio\/proxyv2<\/code> <\/strong>image being used. It is a envoy based proxy.<\/p>\n<p>Now use the following command list the Gateway object and see its created and valid.<\/p>\n<pre><code class=\"language-bash\">$ kubectl -n istio-test get gateway\n\nNAME            CLASS   ADDRESS                                                                         PROGRAMMED   AGE\nistio-gateway   istio   ad8805f370c854e749a18ed03f2bb2e0-4940c029a9c83906.elb.us-west-2.amazonaws.com   True         17s<\/code><\/pre>\n<p>In the above output, <strong><code>...9a9c83906.elb.us-west-2.amazonaws.com<\/code><\/strong> is the DNS name of the created <a href=\"https:\/\/devopscube.com\/aws-load-balancers\/\" rel=\"noreferrer\">Network Load Balancer<\/a>. If you are using Google Cloud or Azure, you will see the respective load balancer endpoint instead.<\/p>\n<p>Now our gateway is ready. This means <strong>traffic from external sources<\/strong> can reach the cluster through the Gateway load balancer that was created.<\/p>\n<p>Next, we need to configure routes so that the gateway proxy pod inside the cluster knows <strong>which pods<\/strong> to send the traffic to and <strong>how<\/strong> it should route that traffic.<\/p>\n<h3 id=\"step-2-create-an-httproute\">Step 2: Create an HTTPRoute<\/h3>\n<p><strong><code>HTTPRoute<\/code><\/strong> is another Gateway API Custom Resource to defines the routing rules (where to send the traffic internally).<\/p>\n<p>In the <strong><code>HTTPRoute<\/code><\/strong> configuration, we will primarily define the following.<\/p>\n<ul>\n<li>The Gateway that we created in previous step. <\/li>\n<li>A hostname<\/li>\n<li>The backend services (Demo app services <strong><code>backend-v1<\/code><\/strong> &amp; <strong><code>backend-v1<\/code><\/strong>)<\/li>\n<li>Define weights (50 &#8211; 50) to split the traffic between two services (canary based)<\/li>\n<\/ul>\n<div class=\"kg-card kg-callout-card kg-callout-card-blue\">\n<div class=\"kg-callout-emoji\">\ud83d\udca1<\/div>\n<div class=\"kg-callout-text\">If you have a valid domain (for example, managed in Route53), you can use it for this testing. <\/p>\n<p>Even if you do not have one <b><strong style=\"white-space: pre-wrap;\">continue with the following hostname configurations<\/strong><\/b>. We will cover local DNS resolution in the next steps.<\/div>\n<\/div>\n<p>To create a <strong><code>HTTPRoute<\/code><\/strong> manifest, copy the following in the terminal.<\/p>\n<pre><code class=\"language-bash\">cat &lt;&lt; EOF &gt; istio-httproute.yaml\napiVersion: gateway.networking.k8s.io\/v1\nkind: HTTPRoute\nmetadata:\n  name: backend-route\n  namespace: istio-test\nspec:\n  parentRefs:\n  - name: istio-gateway\n    namespace: istio-test\n  hostnames:\n  - \"test.devopscube.com\"\n  rules:\n  - matches:\n    - path:\n        type: PathPrefix\n        value: \/\n    backendRefs:\n    - name: backend-v1\n      port: 80\n      weight: 50\n    - name: backend-v2\n      port: 80\n      weight: 50\nEOF<\/code><\/pre>\n<p>To apply this, use the following command. It will create a HttpRoute in the <strong><code>istio-test<\/code><\/strong> namespace.<\/p>\n<pre><code class=\"language-bash\">kubectl apply -f istio-httproute.yaml<\/code><\/pre>\n<p>Now, validate the <strong><code>HttpRoute<\/code><\/strong> resource using the following command.<\/p>\n<pre><code class=\"language-bash\">$ kubectl -n istio-test get httproutes\n\nNAME            HOSTNAMES                 AGE\nbackend-route   [\"test.devopscube.com\"]   85s<\/code><\/pre>\n<p>Now that we have defined the routing rules, the gateway proxy pod knows which Kubernetes service endpoint to send the traffic to and how to split it in a canary style.<\/p>\n<h3 id=\"step-4-create-a-destination-rule\">Step 4: Create a Destination Rule<\/h3>\n<p>The Gateway API standard doesn&#8217;t yet have mature features for circuit breaking or connection pooling.<\/p>\n<p>So, if you want to use Istio <strong>features like circuit breaking, custom load-balancing algorithms, mTLS or rate limiting<\/strong> at the application service level, you need to add Istio <strong><code>DestinationRule<\/code><\/strong> resources for those services.<\/p>\n<p>Istio <strong><code>DestinationRule<\/code><\/strong> defines policies that apply to traffic intended for a service <strong>after<\/strong> routing has occurred.<\/p>\n<p>For example, in our <strong><code>DestinationRule<\/code><\/strong> we are going to define <strong><code>ROUND_ROBIN<\/code> <\/strong>algorithm, <strong><code>maxConnections<\/code><\/strong> and Outlier Detection.<\/p>\n<p>Copy the following to the terminal to create the <code>DestinationRule<\/code> <\/p>\n<pre><code class=\"language-bash\">cat &lt;&lt; EOF &gt; istio-destinationrule.yaml\napiVersion: networking.istio.io\/v1beta1\nkind: DestinationRule\nmetadata:\n  name: backend-destination-rule\n  namespace: istio-test\nspec:\n  host: backend-v1.istio-test.svc.cluster.local\n  trafficPolicy:\n    loadBalancer:\n      simple: ROUND_ROBIN\n    connectionPool:\n      tcp:\n        maxConnections: 100\n      http:\n        http1MaxPendingRequests: 50\n        http2MaxRequests: 100\n        maxRequestsPerConnection: 2\n    outlierDetection:\n      consecutive5xxErrors: 5\n      interval: 30s\n      baseEjectionTime: 30s\n      maxEjectionPercent: 50\n---\napiVersion: networking.istio.io\/v1beta1\nkind: DestinationRule\nmetadata:\n  name: backend-v2-destination-rule\n  namespace: istio-test\nspec:\n  host: backend-v2.istio-test.svc.cluster.local\n  trafficPolicy:\n    loadBalancer:\n      simple: ROUND_ROBIN\n    connectionPool:\n      tcp:\n        maxConnections: 100\n      http:\n        http1MaxPendingRequests: 50\n        http2MaxRequests: 100\n        maxRequestsPerConnection: 2\n    outlierDetection:\n      consecutive5xxErrors: 5\n      interval: 30s\n      baseEjectionTime: 30s\n      maxEjectionPercent: 50\nEOF<\/code><\/pre>\n<p>To apply, use the following command.<\/p>\n<pre><code class=\"language-bash\">kubectl apply -f istio-destinationrule.yaml<\/code><\/pre>\n<p>It creates two destination rules for each backend services. Both uses the same traffic policy configurations.<\/p>\n<p>Now list the <strong><code>DestinationRule<\/code><\/strong> resources and validate it.<\/p>\n<pre><code class=\"language-bash\">$ kubectl -n istio-test get destinationrules\n\nNAME                          HOST                                      AGE\nbackend-destination-rule      backend-v1.istio-test.svc.cluster.local   106m\nbackend-v2-destination-rule   backend-v2.istio-test.svc.cluster.local   106m<\/code><\/pre>\n<h3 id=\"step-5-configure-local-dns-resolution-optional\">Step 5: Configure Local DNS Resolution (Optional)<\/h3>\n<div class=\"kg-card kg-callout-card kg-callout-card-blue\">\n<div class=\"kg-callout-emoji\">\u26a0\ufe0f<\/div>\n<div class=\"kg-callout-text\">In production, use a DNS provider like Route53 with a valid domain name.<\/div>\n<\/div>\n<p>Now, we are going to create a temporary DNS entry on our local machine so that we can test the traffic with the <code>test.devopscube.com<\/code> hostname we used in the HttpRoute.<\/p>\n<p>If your load balancer endpoint is a DNS name, get the public IP of the load balancer using the following command.<\/p>\n<div class=\"kg-card kg-callout-card kg-callout-card-blue\">\n<div class=\"kg-callout-emoji\">\ud83d\udccc<\/div>\n<div class=\"kg-callout-text\">Ignore this step if your cloud load balancer already provides a direct IP address.<\/div>\n<\/div>\n<pre><code class=\"language-bash\">dig +short &lt;Load Balancer DNS Name&gt;<\/code><\/pre>\n<p>You will get a similar like output.<\/p>\n<pre><code class=\"language-bash\">$ dig +short ad8805f370c854e749a18ed03f2bb2e0-4940c029a9c83906.elb.us-west-2.amazonaws.com\n\n35.95.166.48<\/code><\/pre>\n<p>Now, open the <code>\/etc\/hosts<\/code> on your local machine and paste IP and the hostname name you have given in the <strong>HTTPRoute<\/strong> config.<\/p>\n<p>For example,<\/p>\n<pre><code>35.95.166.48 test.devopscube.com<\/code><\/pre>\n<p>Here is how it looks<\/p>\n<pre><code class=\"language-bash\">$ sudo vim \/etc\/hosts\nPassword:\n\n$ cat \/etc\/hosts\n\n##\n# Host Database\n#\n# localhost is used to configure the loopback interface\n# when the system is booting.  Do not change this entry.\n##\n127.0.0.1       localhost\n255.255.255.255 broadcasthost\n::1             localhost\n\n35.95.166.48 test.devopscube.com<\/code><\/pre>\n<p>Once the IP is mapped with the hostname, save the file and exit.<\/p>\n<p>Now our entire ingress configuration is ready. The next step is to validate the end-to-end traffic flow.<\/p>\n<h3 id=\"step-4-validate-the-ingress-traffic-flow\">Step 4: Validate the Ingress Traffic Flow <\/h3>\n<p>Now lets test the complete ingress traffic flow.<\/p>\n<p>The following linux script runs the <code>curl test.devopscube.com<\/code> command 10 times in a row. This helps us validate whether the canary traffic split is happening between the v1 and v2 services as configured in the <code>HttpRoute<\/code><\/p>\n<pre><code class=\"language-bash\">for i in {1..10}; do curl test.devopscube.com; done<\/code><\/pre>\n<p>The following output shows that the external traffic is properly routed to both backend services.<\/p>\n<pre><code class=\"language-bash\">$ for i in {1..10}; do curl test.devopscube.com; done\n\nhello from backend v1\nhello from backend v2\nhello from backend v2\nhello from backend v1\nhello from backend v2\nhello from backend v2\nhello from backend v1\nhello from backend v1\nhello from backend v2\nhello from backend v1<\/code><\/pre>\n<h2 id=\"conclusion\">Conclusion<\/h2>\n<p>In this blog we have covered how to configure Istio + Kubernetes Gateway API to manage ingress (north-south) traffic in a Kubernetes cluster. We practically walked through how a Gateway + HTTPRoute can <strong>expose Istio mesh services externally.<\/strong><\/p>\n<p>With the <a href=\"https:\/\/istio.io\/latest\/blog\/2024\/gateway-mesh-ga\/?ref=devopscube.com\" rel=\"noreferrer\">graduation of mesh support in Gateway <\/a>API, Gateway API supports internal (east-west) traffic routing inside a service mesh via the <a href=\"https:\/\/gateway-api.sigs.k8s.io\/mesh\/gamma\/?ref=devopscube.com\" rel=\"noreferrer\">GAMMA Initiative <\/a>(Gateway API for Mesh Management and Administration).<\/p>\n<p>That means Gateway API is no longer limited just to ingress\/egress. <\/p>\n<p>You can use HTTPRoute, GRPCRoute, etc..to declare how services talk to each other inside the Istio service mesh. This actually brings <strong>consistency to both external and internal<\/strong> traffic management.<\/p>\n<p>Refer the<a href=\"https:\/\/devopscube.com\/gateway-api-for-service-mesh\/\" rel=\"noreferrer\"> Managing East-West Traffic with Gateway API<\/a> blog to see it in action.<\/p>\n<p>If you want a real world example, you can look at Careem use case. They recently migrated to Istio with Gateway API + GAMMA to enable a \u201cdefine-once, route-everywhere\u201d model.<\/p>\n<p>Also, in <a href=\"https:\/\/devopscube.com\/setup-istio-ambient-mode\/\" rel=\"noreferrer\">Istio ambient mesh mode<\/a>, the Waypoint porxy for L7 traffic managment is managed through Gateway API.<\/p>\n<\/p>\n<hr>\n<p><strong>Ngu\u1ed3n:<\/strong> <a href=\"https:\/\/devopscube.com\/istio-ingress-kubernetes-gateway-api\/\" target=\"_blank\" rel=\"noopener noreferrer\">Setting up Istio Ingress With Kubernetes Gateway API \u2014 DevOpsCube<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Source: https:\/\/devopscube.com\/istio-ingress-kubernetes-gateway-api\/<\/p>\n","protected":false},"author":1,"featured_media":284,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-283","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-devops"],"_links":{"self":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/posts\/283","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=283"}],"version-history":[{"count":0,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/posts\/283\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/media\/284"}],"wp:attachment":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=283"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=283"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=283"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}