Migrating Ingress NGINX Go Code to Gateway API with Konveyor and KAI

Author: Savitha Raghunathan

Ingress NGINX has been a cornerstone of Kubernetes networking for years, powering traffic routing for countless production workloads. As the ecosystem evolves, the project has announced its retirement, passing the torch to the Gateway API — a more expressive, role-oriented successor. Tools like ingress2gateway make it straightforward to convert Ingress YAML manifests into Gateway and HTTPRoute resources.

But what about the Go programs that build Ingress objects in code?

Many platform teams have operators and CLI tools written in Go that programmatically create and manage Ingress resources using k8s.io/api/networking/v1 and client-go. ingress2gateway can convert the deployed Ingress resources, but it doesn’t modify the Go source code that creates and manages them. You’d still need to update every networkingv1 type reference, every client-go API call, and every nginx annotation string in your codebase. Konveyor addresses this source code side of the migration.

Migrating Ingress NGINX Go code to Gateway API with Konveyor and KAI Image generated with Gemini Nano Banana Pro.

How Konveyor Fills the Gap

Konveyor with KAI addresses code-level migration through three capabilities:

  • Discovery — the Konveyor Go extension scans Go source to find every reference to Ingress types, client-go API calls, and nginx annotation strings
  • Migration guidance — each rule produces a violation with concrete steps showing the Gateway API equivalent
  • KAI fixes — KAI uses the rule messages as LLM context to generate context-aware Gateway API code, understanding the surrounding Go source

The Konveyor Go extension uses the vscode go extension to detect type references — so it knows the difference between networkingv1.Ingress (the Kubernetes type) and a random variable named ingress. This gives you precise, low-noise results.

The Migration Scenario

I built a sample migration scenario to demonstrate this workflow. The sample app is a Go CLI tool that a platform team uses to provision standardized Ingress resources for tenant applications. It uses the full spread of Ingress-NGINX patterns:

Ingress Concept Gateway API Equivalent
Ingress HTTPRoute + Gateway
IngressClass GatewayClass
kubernetes.io/ingress.class annotation HTTPRoute.spec.parentRefs
TLS via spec.tls TLS on Gateway.spec.listeners
nginx annotations (ssl-redirect, HSTS, timeouts) Native HTTPRoute filters

I wrote custom rules to detect these patterns — 8 rules use the go.referenced provider for type-level detection, and the rest use builtin.filecontent for string patterns like client-go API calls and annotation keys. When Konveyor analyzes the sample app, it finds 16 issues with 38 total incidents.

From Violations to Fixes

The violations fall into three categories:

Type references — flags every usage of networkingv1 types and shows the Gateway API equivalent (HTTPRoute, GatewayClass, HTTPRouteRule):

networkingv1.Ingress      →  gatewayv1.HTTPRoute
networkingv1.IngressClass →  gatewayv1.GatewayClass
networkingv1.IngressRule  →  gatewayv1.HTTPRouteRule
networkingv1.IngressTLS   →  Gateway.spec.listeners[].tls

Client-go API calls — flags the Kubernetes API calls that need to change. The Gateway API uses a separate clientset (not the core client-go); use GatewayV1().HTTPRoutes(namespace) and GatewayV1().GatewayClasses() on that client:

.NetworkingV1().Ingresses(namespace)  →  .GatewayV1().HTTPRoutes(namespace)
.NetworkingV1().IngressClasses()      →  .GatewayV1().GatewayClasses()

Annotation patterns — flags nginx annotation strings and maps them to native Gateway API filters and timeouts:

ssl-redirect            →  TLS on Gateway listener + RequestRedirect filter
configuration-snippet   →  ResponseHeaderModifier filter
proxy-read/send-timeout →  HTTPRouteTimeouts (native on HTTPRouteRule)
HSTS annotations        →  ResponseHeaderModifier with Strict-Transport-Security header

With KAI’s GenAI configured, click the wrench icon on a violation to request a fix. KAI uses the incident details to generate a targeted fix. The changes can be reviewed before applying.

Writing Custom Rules

The rules use two providers (go and builtin), and the message field is what KAI feeds to the LLM as migration context:

go.referenced — detects type-level references via gopls:

- ruleID: ingress-nginx-go-ref-00001
  category: mandatory
  effort: 3
  when:
    go.referenced:
      pattern: '\bIngress\b'
  message: |
    This code references `networkingv1.Ingress`. Migrate to
    `gatewayv1.HTTPRoute`.

builtin.filecontent — matches string patterns in Go files:

- ruleID: ingress-nginx-go-ref-00028
  category: mandatory
  effort: 1
  when:
    builtin.filecontent:
      pattern: 'nginx\.ingress\.kubernetes\.io/proxy-(read|send|connect)-timeout'
      filePattern: "*.go"
  message: |
    Replace proxy timeout annotations with HTTPRouteTimeouts.

A well-crafted message with concrete before/after code examples leads to better-generated fixes. You can follow the same approach to write custom rules for other migration scenarios.

Demo

Migrating Go source code from Ingress-NGINX to Gateway API using Konveyor

Try It Out

This scenario demonstrates Konveyor’s capabilities with Go, but Konveyor supports multiple languages. The Konveyor extension pack bundles providers for Java, JavaScript, Go, and C# — install once and the right provider activates when it detects a matching project. Whether you’re migrating Java EE to Quarkus, upgrading Spring Boot, or modernizing Go infrastructure tooling like this scenario, Konveyor and KAI can help discover what needs to change and generate the fixes.

Check out the step-by-step tutorial, and join us on the Konveyor community. We look forward to your feedback, ideas, and collaboration as we grow Konveyor and KAI together.