Migrating from Kong Ingress Controller to Kong Operator 2.0.0

Kong Operator (KO) is next generation Kubernetes-native operator that simplifies the management of ingress controllers and Kong data planes.

In this guide, we will walk you through the steps to migrate from Kong Ingress Controller (KIC) to Kong Operator (KO) 2.0.0.

Prerequisites

Before starting the migration, ensure you:

  1. Backup your current configuration

  2. Verify the current Kong Ingress Controller version:

    # Depending on the release name the deployment name and chart used (kong/ingress) might have a different name
    kubectl get deploy -n ${NAMESPACE} kong-controller -o jsonpath="{.spec.template.spec.containers[?(@.name=='ingress-controller')].image}"
    kong/kubernetes-ingress-controller:3.5.0
    

    This guide assumes that you’re running the latest version of Kong Ingress Controller (3.5).

    If you’re not running 3.5, please upgrade before proceeding.

  3. Can Access the Kubernetes cluster with admin privileges

  4. Verify cert-manager is installed (recommended for webhooks certificate management):

    Note: Kong Operator 2.0.0 uses webhooks that require TLS certificates managed by cert-manager. If cert-manager is not installed, follow the cert-manager installation guide before proceeding. If you do not use cert-manager, the Helm chart will install certificates for you and you will be responsible for managing their lifecycle.

Migrate to Kong Operator 2.0.0

Important: This process involves down time. Plan your migration accordingly.

The migration process requires several manual steps due to breaking changes in certificate management and CRD structure. We recommend a blue / green cut-over of your Gateways, which are detailed in the following steps:

Step 1: Uninstall existing KIC deployment

First step is to uninstall the existing KIC deployment to stop it from reconciling the cluster objects. This will prevent both KIC and the new KO from reconciling the same resources and fighting over the status updates of your configuration. Your existing Gateway (blue) will continue to serve traffic during this time, but any new changes to configuration will only apply to the new Gateway instance (green).

At this point you have the KIC uninstalled and Kong Gateway still serving traffic with the existing configuration.

Step 2: Install KO

Install the new Kong Operator using Helm:

helm repo update kong
helm upgrade --install kong-operator kong/kong-operator \
  -n kong-system \
  --create-namespace \
  --take-ownership \
  --set env.ENABLE_CONTROLLER_KONNECT=true \
  --set ko-crds.enabled=true \
  --set global.conversionWebhook.enabled=true \
  --set global.conversionWebhook.certManager.enabled=true 

Step 3: Verify the Installation

Verify that Kong Operator 2.0.0 is running correctly:

Check the operator deployment:

kubectl get pod -n kong-system

Check operator logs:

kubectl logs -n kong-system -l app=kong-operator-kong-operator

Step 4: Prepare the Gateway manifest to replace Kong Gateway and KIC

KO uses CRDs to manage among other things: Kong Gateway and the ingress controller.

What used to be a pair of Kong Gateway and KIC deployed via helm is now modelled through Gateway API’s Gateway only, greatly simplifying the configuration.

You can learn more about it on Gateway API website.

To customize the Gateway manifest for your environment, you can use Kong’s GatewayConfiguration CRD.

If you have an existing GatewayClass defined in your KIC installation, you will need to delete this before creating the new GatewayConfiguration and Gateway:

kubectl delete GatewayClass kong

Please refer to the following example which can serve as a base for your configuration:

echo '
kind: GatewayConfiguration
apiVersion: gateway-operator.konghq.com/v2beta1
metadata:
  name: kong
  namespace: default
spec:
  dataPlaneOptions:
    deployment:
      podTemplateSpec:
        spec:
          containers:
          - name: proxy
            image: kong/kong-gateway:3.11
  controlPlaneOptions:
    featureGates:
    - name: GatewayAlpha
      state: enabled
    controllers:
    - name: GWAPI_GATEWAY
      state: enabled
    - name: GWAPI_HTTPROUTE
      state: enabled
---
kind: GatewayClass
apiVersion: gateway.networking.k8s.io/v1
metadata:
  name: kong
spec:
  controllerName: konghq.com/gateway-operator
  parametersRef:
    group: gateway-operator.konghq.com
    kind: GatewayConfiguration
    name: kong
    namespace: default
---
kind: Gateway
apiVersion: gateway.networking.k8s.io/v1
metadata:
  name: kong
  namespace: default
spec:
  gatewayClassName: kong
  listeners:
  - name: http
    protocol: HTTP
    port: 80
' | kubectl apply -f -

For more information on the GatewayConfiguration parameters review the reference page.

Step 5: Validate Gateway status

At this point the Gateway should be marked as Programmed in its status:

kubectl get gateway -n default kong -o jsonpath-as-json='{.status}'
[
    {
        "addresses": [
            {
                "type": "IPAddress",
                "value": "172.18.128.1"
            }
        ],
        "conditions": [
            {
                "lastTransitionTime": "2025-08-09T18:17:00Z",
                "message": "",
                "observedGeneration": 1,
                "reason": "Programmed",
                "status": "True",
                "type": "Programmed"
            },
            ...
    }
]

Step 6: Validate generated configuration

Validate configuration generated by Kong Operator by accessing the Kong Gateway.

From the above Gateway status, you can see the address is 172.18.128.1. You can test the configuration by sending requests against this address.

Step 7: Uninstall remaining Kong Gateway deployment

If everything is working as expected, you can proceed to uninstall the remaining Kong Gateway deployment.

helm uninstall -n ${NAMESPACE} ${RELEASE_NAME}
Something wrong?

Help us make these docs great!

Kong Developer docs are open source. If you find these useful and want to make them better, contribute today!