1"use strict";(globalThis.webpackChunkhome=globalThis.webpackChunkhome||[]).push([[2111],{2810(e,n,a){a.r(n),a.d(n,{assets:()=>l,contentTitle:()=>c,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>d});const i=JSON.parse('{"id":"xks/operator-guide/ingress-nginx deprecation/gateway-api","title":"Gateway API","description":"Overview","source":"@site/docs/xks/operator-guide/ingress-nginx deprecation/gateway-api.md","sourceDirName":"xks/operator-guide/ingress-nginx deprecation","slug":"/xks/operator-guide/ingress-nginx deprecation/gateway-api","permalink":"/docs/xks/operator-guide/ingress-nginx deprecation/gateway-api","draft":false,"unlisted":false,"editUrl":"https://github.com/xenitab/xenitab.github.io/edit/main/docs/xks/operator-guide/ingress-nginx deprecation/gateway-api.md","tags":[],"version":"current","frontMatter":{"id":"gateway-api","title":"Gateway API"},"sidebar":"docs","previous":{"title":"Ingress Nginx Retiring","permalink":"/docs/xks/operator-guide/ingress-nginx deprecation/ingress-nginx-retiring"},"next":{"title":"Envoy Gateway","permalink":"/docs/xks/operator-guide/ingress-nginx deprecation/envoy-gateway"}}');var t=a(4848),s=a(8453),r=a(8180);const o={id:"gateway-api",title:"Gateway API"},c=void 0,l={},d=[{value:"Overview",id:"overview",level:2},{value:"Why Gateway API?",id:"why-gateway-api",level:2},{value:"Key Concepts",id:"key-concepts",level:2},{value:"Role-Oriented Design",id:"role-oriented-design",level:3},{value:"Core Resources",id:"core-resources",level:3},{value:"Getting Started",id:"getting-started",level:2},{value:"Prerequisites",id:"prerequisites",level:3},{value:"Basic HTTP Route",id:"basic-http-route",level:3},{value:"TLS Configuration",id:"tls-configuration",level:3},{value:"Path-Based Routing",id:"path-based-routing",level:3},{value:"Header-Based Routing",id:"header-based-routing",level:3},{value:"Traffic Splitting and Canary Deployments",id:"traffic-splitting-and-canary-deployments",level:3},{value:"Request Mirroring",id:"request-mirroring",level:3},{value:"URL Rewriting",id:"url-rewriting",level:3},{value:"Request Header Modification",id:"request-header-modification",level:3},{value:"Cross-Namespace Routing",id:"cross-namespace-routing",level:3},{value:"Public and Private Gateways",id:"public-and-private-gateways",level:2},{value:"Policies and Advanced Features",id:"policies-and-advanced-features",level:2},{value:"Network Policy Configuration",id:"network-policy-configuration",level:2},{value:"Migration from Ingress",id:"migration-from-ingress",level:2},{value:"Ingress Example",id:"ingress-example",level:3},{value:"Equivalent HTTPRoute",id:"equivalent-httproute",level:3},{value:"Key Differences",id:"key-differences",level:3},{value:"Debugging",id:"debugging",level:2},{value:"Check HTTPRoute Status",id:"check-httproute-status",level:3},{value:"View Gateway Status",id:"view-gateway-status",level:3},{value:"Common Issues",id:"common-issues",level:3},{value:"Further Reading",id:"further-reading",level:2}];function p(e){const n={a:"a",blockquote:"blockquote",code:"code",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h2,{id:"overview",children:"Overview"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"https://gateway-api.sigs.k8s.io/",children:"Kubernetes Gateway API"})," is the next-generation networking standard for Kubernetes, designed to replace the traditional Ingress API. XKS uses Gateway API as the core ingress solution, providing a more powerful, flexible, and future-proof way to manage traffic entering your cluster."]}),"\n",(0,t.jsx)(n.p,{children:"Gateway API represents a significant evolution in Kubernetes networking, offering role-oriented design, enhanced expressiveness, and extensive extensibility that addresses the limitations of the original Ingress API."}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Note"}),": XKS uses ",(0,t.jsx)(n.a,{href:"/docs/xks/operator-guide/ingress-nginx%20deprecation/envoy-gateway",children:"Envoy Gateway"})," as the implementation of Gateway API. For Envoy-specific features like policies, observability, and performance tuning, see the ",(0,t.jsx)(n.a,{href:"/docs/xks/operator-guide/ingress-nginx%20deprecation/envoy-gateway",children:"Envoy Gateway documentation"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Migrating from Ingress?"})," See the ",(0,t.jsx)(n.a,{href:"/docs/xks/operator-guide/ingress-nginx%20deprecation/ingress-nginx-retiring",children:"Ingress Nginx Migration Guide"})," for deprecation information, timelines, and step-by-step migration instructions."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"why-gateway-api",children:"Why Gateway API?"}),"\n",(0,t.jsxs)(n.p,{children:["Gateway API brings several significant improvements over the traditional Ingress API. For a detailed comparison and migration information, see the ",(0,t.jsx)(n.a,{href:"/docs/xks/operator-guide/ingress-nginx%20deprecation/ingress-nginx-retiring#why-migrate",children:"Ingress Nginx Migration Guide"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"key-concepts",children:"Key Concepts"}),"\n",(0,t.jsx)(n.h3,{id:"role-oriented-design",children:"Role-Oriented Design"}),"\n",(0,t.jsx)(n.p,{children:"Gateway API introduces a clear separation of concerns between different organizational roles:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Infrastru
1cture Provider"}),": Manages the ",(0,t.jsx)(n.code,{children:"GatewayClass"})," resource, which defines the type of load balancer and its configuration"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Cluster Operator"}),": Manages ",(0,t.jsx)(n.code,{children:"Gateway"})," resources, which instantiate load balancers and define listeners"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Application Developer"}),": Manages ",(0,t.jsx)(n.code,{children:"HTTPRoute"})," and other route resources, which define how traffic is routed to applications"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"This separation allows teams to work independently while maintaining security boundaries and operational clarity."}),"\n",(0,t.jsx)("img",{alt:"Gateway API Roles",src:(0,r.Ay)("img/assets/xks/operator-guide/gateway-route-binding.png")}),"\n",(0,t.jsx)(n.h3,{id:"core-resources",children:"Core Resources"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"GatewayClass"}),": Defines a class of Gateways (similar to IngressClass). In XKS, this is pre-configured by the platform team."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Gateway"}),": Instantiates a load balancer. Managed by cluster operators, it defines listeners (ports, protocols, hostnames) and TLS configuration."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"HTTPRoute"}),": Defines how HTTP traffic should be routed. This is what application developers work with most often."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"ReferenceGrant"}),": Allows routes to reference resources in other namespaces, enabling secure cross-namespace routing."]}),"\n",(0,t.jsxs)(n.p,{children:["For comprehensive documentation of all Gateway API concepts, see the ",(0,t.jsx)(n.a,{href:"https://gateway-api.sigs.k8s.io/concepts/api-overview/",children:"official Gateway API documentation"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"getting-started",children:"Getting Started"}),"\n",(0,t.jsx)(n.h3,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(n.p,{children:["Ensure your namespace has appropriate Network Policies configured to allow traffic from the Gateway. See the ",(0,t.jsx)(n.a,{href:"#network-policy-configuration",children:"Network Policies"})," section below."]}),"\n",(0,t.jsx)(n.h3,{id:"basic-http-route",children:"Basic HTTP Route"}),"\n",(0,t.jsxs)(n.p,{children:["The simplest way to expose an application is to create an ",(0,t.jsx)(n.code,{children:"HTTPRoute"})," resource. HTTPRoutes define how HTTP traffic should be routed to your services."]}),"\n",(0,t.jsx)(n.p,{children:"First, ensure you have a Service running:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"apiVersion: v1\nkind: Service\nmetadata:\n name: example-app\n namespace: tenant\nspec:\n selector:\n app: example-app\n ports:\n - name: http\n port: 80\n targetPort: 8080\n"})}),"\n",(0,t.jsx)(n.p,{children:"Create an HTTPRoute to expose this service:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'apiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n name: example-app\n namespace: tenant\nspec:\n parentRefs:\n - name: default-gateway\n namespace: gateway-system\n hostnames:\n - "example-app.example.com"\n rules:\n - matches:\n - path:\n type: PathPrefix\n value: /\n backendRefs:\n - name: example-app\n port: 80\n'})}),"\n",(0,t.jsx)(n.p,{children:"Key points:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"parentRefs"})," references the Gateway that will handle this route (typically managed by the cluster operator)"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"hostnames"})," defines which domain names this route responds to"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"rules"})," define matching criteria and backend services"]}),"\n",(0,t.jsx)(n.li,{children:"External DNS will automatically create the DNS record"}),"\n",(0,t.jsx)(n.li,{children:"Certificate management will automatically provision TLS certificates"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"tls-configuration",children:"TLS Configuration"}),"\n",(0,t.jsx)(n.p,{children:"Unlike Ingress, TLS is configured at the Gateway level rather than per-route. The cluster operator will have configured the Gateway with TLS listeners. Your HTTPRoute will automatically use TLS when matching traffic arrives on a TLS-enabled listener."}),"\n",(0,t.jsx)(n.p,{children:"For most use cases, you simply need to ensure your hostname is included in the Gateway's certificate. In XKS, certificates are automatically managed via Cert Manager with Let's Encrypt."}),"\n",(0,t.jsx)(n.p,{children:"If you need a custom certificate, you can create a Certificate resource:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"apiVersion: cert-manager.io/v1\nkind: Certificate\nmetadata:\n name: example-app-cert\n namespace: gateway-system\nspec:\n issuerRef:\n group: cert-manager.io\n kind: ClusterIssuer\n name: letsencrypt\n dnsNames:\n - example-app.example.com\n - api.example-app.example.com\n secretName: example-app-cert\n"})}),"\n",(0,t.jsx)(n.p,{children:"The cluster operator can then reference this certificate in the Gateway configuration."}),"\n",(0,t.jsx)(n.h3,{id:"path-based-routing",children:"Path-Based Routing"}),"\n",(0,t.jsx)(n.p,{children:"HTTPRoute supports sophisticated path matching beyond simple prefixes:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'apiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n name: example-app-paths\n namespace: tenant\nspec:\n parentRefs:\n - name: default-gateway\n namespace: gateway-system\n hostnames:\n - "example-app.example.com"\n rules:\n # Exact path match\n - matches:\n - path:\n type: Exact\n value: /api/v1/health\n backendRefs:\n - name: health-service\n port: 80\n # Prefix match for API endpoints\n - matches:\n - path:\n type: PathPrefix\n value: /api/v1\n backendRefs:\n - name: api-service\n port: 80\n # RegularExpression match (if supported by implementation)\n - matches:\n - path:\n type: RegularExpression\n value: "^/v[0-9]+/.*"\n backendRefs:\n - name: versioned-api\n port: 80\n # Default - catch all other traffic\n - matches:\n - path:\n type: PathPrefix\n value: /\n backendRefs:\n - name: frontend-service\n port: 80\n'})}),"\n",(0,t.jsx)(n.h3,{id:"header-based-routing",children:"Header-Based Routing"}),"\n",(0,t.jsx)(n.p,{children:"Route traffic based on HTTP headers:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'apiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n name: example-header-routing\n namespace: tenant\nspec:\n parentRefs:\n - name: default-gateway\n namespace: gateway-system\n hostnames:\n - "api.example.com"\n rules:\n # Route mobile traffic\n - matches:\n - headers:\n - type: Exact\n name: User-Agent\n value: "MobileApp/1.0"\n backendRefs:\n - name: mobile-api\n port: 80\n # Route beta users\n - matches:\n - headers:\n - type: Exact\n name: X-Beta-User\n value: "true"\n backendRefs:\n - name: beta-api\n port: 80\n # Default backend\n - backendRefs:\n - name: standard-api\n port: 80\n'})}),"\n",(0,t.jsx)(n.h3,{id:"traffic-splitting-and-canary-deployments",children:"Traffic Splitting and Canary Deployments"}),"\n",(0,t.jsx)(n.p,{children:"Gateway API natively supports weighted traffic distribution:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'apiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n name: canary-deployment\n namespace: tenant\nspec:\n parentRefs:\n - name: default-gateway\n namespace: gateway-system\n hostnames:\n - "app.example.com"\n rules:\n - backendRefs:\n # 90% of traffic goes to stable version\n - name: app-stable\n port: 80\n weight: 90\n # 10% of traffic goes to canary version\n - name: app-canary\n port: 80\n weight: 10\n'})}),"\n",(0,t.jsx)(n.p,{children:"As confidence in the canary version grows, you can gradually increase the weight:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"# Update to 50/50\n- name: app-stable\n port: 80\n weight: 50\n- name: app-canary\n port: 80\n weight: 50\n"})}),"\n",(0,t.jsx)(n.h3,{id:"request-mirroring",children:"Request Mirroring"}),"\n",(0,t.jsx)(n.p,{children:"Duplicate traffic to a test environment without affecting production responses:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'apiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n name: traffic-mirroring\n namespace: tenant\nspec:\n parentRefs:\n - name: default-gateway\n namespace: gateway-system\n hostnames:\n - "app.example.com"\n rules:\n - matches:\n - path:\n type: PathPrefix\n value: /\n backendRefs:\n # Primary backend - responses returned to client\n - name: production-app\n port: 80\n filters:\n # Mirror traffic to test backend - responses discarded\n - type: RequestMirror\n requestMirror:\n backendRef:\n name: test-app\n port: 80\n'})}),"\n",(0,t.jsx)(n.h3,{id:"url-rewriting",children:"URL Rewriting"}),"\n",(0,t.jsx)(n.p,{children:"Modify requests before they reach the backend:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'apiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n name: url-rewrite\n namespace: tenant\nspec:\n parentRefs:\n - name: default-gateway\n namespace: gateway-system\n hostnames:\n - "app.example.com"\n rules:\n - matches:\n - path:\n type: PathPrefix\n value: /api/v1\n filters:\n # Remove /api/v1 prefix before forwarding\n - type: URLRewrite\n urlRewrite:\n path:\n type: ReplacePrefixMatch\n replacePrefixMatch: /\n backendRefs:\n - name: api-service\n port: 80\n'})}),"\n",(0,t.jsx)(n.h3,{id:"request-header-modification",children:"Request Header Modification"}),"\n",(0,t.jsx)(n.p,{children:"Add, set, or remove headers:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'apiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n name: header-modification\n namespace: tenant\nspec:\n parentRefs:\n - name: default-gateway\n namespace: gateway-system\n hostnames:\n - "app.example.com"\n rules:\n - filters:\n - type: RequestHeaderModifier\n requestHeaderModifier:\n # Add new headers\n add:\n - name: X-
1Forwarded-Client\n value: gateway\n # Set headers (replace if exists)\n set:\n - name: X-Custom-Header\n value: custom-value\n # Remove headers\n remove:\n - X-Internal-Header\n backendRefs:\n - name: app-service\n port: 80\n'})}),"\n",(0,t.jsx)(n.h3,{id:"cross-namespace-routing",children:"Cross-Namespace Routing"}),"\n",(0,t.jsx)(n.p,{children:"HTTPRoute can reference services in different namespaces with explicit permission:"}),"\n",(0,t.jsx)(n.p,{children:"First, the service namespace grants access:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'apiVersion: gateway.networking.k8s.io/v1beta1\nkind: ReferenceGrant\nmetadata:\n name: allow-tenant-routes\n namespace: shared-services\nspec:\n from:\n - group: gateway.networking.k8s.io\n kind: HTTPRoute\n namespace: tenant\n to:\n - group: ""\n kind: Service\n'})}),"\n",(0,t.jsx)(n.p,{children:"Then the HTTPRoute can reference the service:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'apiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n name: cross-namespace-route\n namespace: tenant\nspec:\n parentRefs:\n - name: default-gateway\n namespace: gateway-system\n hostnames:\n - "app.example.com"\n rules:\n - backendRefs:\n - name: shared-api\n namespace: shared-services\n port: 80\n'})}),"\n",(0,t.jsx)(n.h2,{id:"public-and-private-gateways",children:"Public and Private Gateways"}),"\n",(0,t.jsx)(n.p,{children:"Similar to the Ingress setup, XKS can provide both public and private Gateways. The default Gateway is public and exposed to the Internet. For internal-only applications, you can create a private Gateway and reference that in the HTTPRoute:"}),"\n",(0,t.jsx)(n.p,{children:"Gateway:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'apiVersion: gateway.networking.k8s.io/v1\nkind: Gateway\nmetadata:\n name: private-gateway\n namespace: gateway-system\nspec:\n gatewayClassName: envoy\n infrastructure:\n annotations:\n service.beta.kubernetes.io/azure-load-balancer-internal: "true"\n listeners:\n - name: https\n port: 443\n protocol: HTTPS\n'})}),"\n",(0,t.jsx)(n.p,{children:"HTTPRoute:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'apiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n name: internal-app\n namespace: tenant\nspec:\n parentRefs:\n - name: private-gateway\n namespace: gateway-system\n hostnames:\n - "internal-app.example.com"\n rules:\n - backendRefs:\n - name: internal-service\n port: 80\n'})}),"\n",(0,t.jsx)(n.p,{children:"The private Gateway is only accessible from within the virtual network, not from the public Internet."}),"\n",(0,t.jsx)(n.h2,{id:"policies-and-advanced-features",children:"Policies and Advanced Features"}),"\n",(0,t.jsxs)(n.p,{children:["For advanced traffic management features including rate limiting, circuit breaking, timeouts, retries, health checks, load balancing, and observability configuration, see the ",(0,t.jsx)(n.a,{href:"/docs/xks/operator-guide/ingress-nginx%20deprecation/envoy-gateway",children:"Envoy Gateway documentation"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"These features are configured using Envoy Gateway-specific policy resources:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:(0,t.jsx)(n.a,{href:"/docs/xks/operator-guide/ingress-nginx%20deprecation/envoy-gateway#backendtrafficpolicy",children:"BackendTrafficPolicy"})}),": Configure backend behavior (rate limiting, circuit breaking, timeouts, retries, health checks, load balancing)"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:(0,t.jsx)(n.a,{href:"/docs/xks/operator-guide/ingress-nginx%20deprecation/envoy-gateway#clienttrafficpolicy",children:"ClientTrafficPolicy"})}),": Configure client-facing behavior (timeouts, HTTP/2, client IP detection)"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:(0,t.jsx)(n.a,{href:"/docs/xks/operator-guide/ingress-nginx%20deprecation/envoy-gateway#securitypolicy",children:"SecurityPolicy"})}),": Configure security features (CORS, authentication, JWT validation)"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"network-policy-configuration",children:"Network Policy Configuration"}),"\n",(0,t.jsx)(n.p,{children:"Gateway traffic must be explicitly allowed by Network Policies. Update your namespace's Network Policy to allow ingress from the Gateway:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"apiVersion: networking.k8s.io/v1\nkind: NetworkPolicy\nmetadata:\n name: allow-gateway\n namespace: tenant\nspec:\n ingress:\n - from:\n - namespaceSelector:\n matchLabels:\n name: gateway-system\n podSelector:\n matchLabels:\n app: example-app\n policyTypes:\n - Ingress\n"})}),"\n",(0,t.jsx)(n.h2,{id:"migration-from-ingress",children:"Migration from Ingress"}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Complete Migration Guide"}),": For comprehensive migration information including deprecation timelines, official documentation links, and detailed step-by-step instructions, see the ",(0,t.jsx)(n.a,{href:"/docs/xks/operator-guide/ingress-nginx%20deprecation/ingress-nginx-retiring",children:"Ingress Nginx Migration Guide"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Migrating from Ingress to HTTPRoute is straightforward. Here's a quick comparison:"}),"\n",(0,t.jsx)(n.h3,{id:"ingress-example",children:"Ingress Example"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"apiVersion: networking.k8s.io/v1\nkind: Ingress\nmetadata:\n name: example-app\n namespace: tenant\n annotations:\n nginx.ingress.kubernetes.io/rewrite-target: /\nspec:\n ingressClassName: nginx\n rules:\n - host: example-app.example.com\n http:\n paths:\n - path: /api\n pathType: Prefix\n backend:\n service:\n name: example-app\n port:\n number: 80\n tls:\n - hosts:\n - example-app.example.com\n secretName: example-app-cert\n"})}),"\n",(0,t.jsx)(n.h3,{id:"equivalent-httproute",children:"Equivalent HTTPRoute"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'apiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n name: example-app\n namespace: tenant\nspec:\n parentRefs:\n - name: default-gateway\n namespace: gateway-system\n hostnames:\n - "example-app.example.com"\n rules:\n - matches:\n - path:\n type: PathPrefix\n value: /api\n filters:\n - type: URLRewrite\n urlRewrite:\n path:\n type: ReplacePrefixMatch\n replacePrefixMatch: /\n backendRefs:\n - name: example-app\n port: 80\n'})}),"\n",(0,t.jsx)(n.h3,{id:"key-differences",children:"Key Differences"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"No IngressClass"}),": Instead, you reference a ",(0,t.jsx)(n.code,{children:"Gateway"})," via ",(0,t.jsx)(n.code,{children:"parentRefs"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"No TLS section"}),": TLS is configured on the Gateway, not the route"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Typed filters"}),": Instead of annotations, use typed filter resources"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Explicit backend references"}),": Use ",(0,t.jsx)(n.code,{children:"backendRefs"})," instead of ",(0,t.jsx)(n.code,{children:"backend"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Path matching"}),": More explicit with ",(0,t.jsx)(n.code,{children:"type"})," field (",(0,t.jsx)(n.code,{children:"PathPrefix"}),", ",(0,t.jsx)(n.code,{children:"Exact"}),", etc.)"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["For detailed migration steps, annotation mapping, and support resources, see the ",(0,t.jsx)(n.a,{href:"/docs/xks/operator-guide/ingress-nginx%20deprecation/ingress-nginx-retiring",children:"Ingress Nginx Migration Guide"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"debugging",children:"Debugging"}),"\n",(0,t.jsx)(n.h3,{id:"check-httproute-status",children:"Check HTTPRoute Status"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-shell",children:"kubectl get httproute example-app -n tenant -o yaml\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Look at the ",(0,t.jsx)(n.code,{children:"status"})," section for information about whether the route was accepted by the Gateway and any error messages."]}),"\n",(0,t.jsx)(n.h3,{id:"view-gateway-status",children:"View Gateway Status"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-shell",children:"kubectl get gateway default-gateway -n gateway-system -o yaml\n"})}),"\n",(0,t.jsx)(n.p,{children:"Check if the Gateway is ready and which routes are attached."}),"\n",(0,t.jsxs)(n.p,{children:["For advanced Envoy-specific debugging including configuration inspection, statistics, and logging, see the ",(0,t.jsx)(n.a,{href:"/docs/xks/operator-guide/ingress-nginx%20deprecation/envoy-gateway#debugging",children:"Envoy Gateway Debugging Guide"}),"."]}),"\n",(0,t.jsx)(n.h3,{id:"common-issues",children:"Common Issues"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"HTTPRoute not working"}),":"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Verify the Gateway reference in ",(0,t.jsx)(n.code,{children:"parentRefs"})," is correct"]}),"\n",(0,t.jsx)(n.li,{children:"Check Network Policies allow traffic from gateway-system namespace"}),"\n",(0,t.jsx)(n.li,{children:"Ensure the Service exists and has healthy endpoints"}),"\n",(0,t.jsx)(n.li,{children:"Check HTTPRoute status for acceptance conditions"}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"TLS not working"}),":"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Verify the Gateway has a TLS listener configured"}),"\n",(0,t.jsx)(n.li,{children:"Check Certificate resource status"}),"\n",(0,t.jsx)(n.li,{children:"Ensure DNS record points to Gateway IP address"}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"No traffic reaching backend"}),":"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Check Service selector matches Pod labels"}),"\n",(0,t.jsx)(n.li,{children:"Verify Pod is running and healthy"}),"\n",(0,t.jsx)(n.li,{children:"Check Network Policies allow traffic within namespace"}),"\n",(0,t.jsxs)(n.li,{children:["Review backend Service port matches HTTPRoute ",(0,t.jsx)(n.code,{children:"backendRefs"})," port"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"further-reading",children:"Further Reading"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"https://gateway-api.sigs.k8s.io/",children:"Gateway API Official Documentation"})," - Complete specification and concepts"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"https://gateway-api.sigs.k8s.io/guides/",children:"Gateway API User Guides"})," - Official tutorials and guides"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"https://gateway-api.sigs.k8s.io/guides/",children:"Gateway API Best Practices"})," - Recommended patterns"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"https://gateway-api.sigs.k8s.io/guides/migrating-from-ingress/",children:"Official Migration Guide"})," - Kubernetes SIG Network migration documentation"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/docs/xks/operator-guide/ingress-nginx%20deprecation/envoy-gateway",children:"Envoy Gateway Guide"})," - XKS Envoy Gateway documentation"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/docs/xks/operator-guide/ingress-nginx%20deprecation/ingress-nginx-retiring",children:"Ingress Migration Guide"})," - XKS migration guide and timelines"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},8453(e,n,a){a.d(n,{R:()=>r,x:()=>o});var i=a(6540);const t={},s=i.createContext(t);function r(e){const n=i.useContext(s);return i.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:r(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.