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:
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).
Set the following in your helm values:
ingressController:
enabled: false
Apply the changes with:
helm upgrade -n ${NAMESPACE} ${RELEASE_NAME} kong/kong
Set the following in your helm values:
controller:
enabled: false
Apply the changes with:
helm upgrade -n ${NAMESPACE} ${RELEASE_NAME} kong/ingress
At this point you have the KIC uninstalled and Kong Gateway still serving traffic with the existing configuration.
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
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
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.
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"
},
...
}
]
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.
If everything is working as expected, you can proceed to uninstall the remaining Kong Gateway deployment.
helm uninstall -n ${NAMESPACE} ${RELEASE_NAME}