HTTPRoute status is reconciled regardless of `Gateway`'s `AllowedRoutes` and/or `--gateway-to-reconcile` flag
Closed this issue · 0 comments
Is there an existing issue for this?
- I have searched the existing issues
Current Behavior
When more than 1 KIC is deployed (e.g. using KGO and Gateway
resources) then HTTPRoutes that are to be reconciled have their status filled in regardless of the listeners' AllowedRoutes
and/or --gateway-to-reconcile
flag.
This issue has 2 aspects:
-
Not filtering routes per their
Gateway
attachment (consulted with--gateway-to-reconcile
flag) does make sense to to properly react to situations where an attachment of a route changes (a route was attached to a gateway marked with the flag but now it's not), this could be narrowed down to filtering update events when the route:- was created attached to a Gateway that is being reconciled
- becomes attached to a Gateway that is being reconciled
- becomes detached from a Gateway that is being reconciled: this should cause the removal of the route from dataplane's configuration
-
Because of the above lack of filtering and KIC clearing the route status only matching on controller name (and not taking into account listeners
AllowedRoutes
) this results in perpetual loop of2024-05-22T12:26:12Z error controllers.HTTPRoute Reconciler error {"reconcileID": "9418485c-120c-4c51-a2ba-e8a13f648289", "error": "Operation cannot be fulfilled on httproutes.gateway.networking.k8s.io \"httproute-echo\": the object has been modified; please apply your changes to the latest version and try again"} 2024-05-22T12:26:12Z debug controllers.HTTPRoute Processing httproute {"GatewayV1HTTPRoute": {"name":"httproute-echo","namespace":"default"}, "v": 1, "namespace": "default", "name": "httproute-echo"} 2024-05-22T12:26:12Z debug controllers.HTTPRoute Checking deletion timestamp {"GatewayV1HTTPRoute": {"name":"httproute-echo","namespace":"default"}, "v": 1, "namespace": "default", "name": "httproute-echo"} 2024-05-22T12:26:12Z debug controllers.HTTPRoute Retrieving GatewayClass and Gateway for route {"GatewayV1HTTPRoute": {"name":"httproute-echo","namespace":"default"}, "v": 1, "namespace": "default", "name": "httproute-echo"} 2024-05-22T12:26:12Z debug controllers.HTTPRoute Unsupported route found, processing to verify whether it was ever supported {"GatewayV1HTTPRoute": {"name":"httproute-echo","namespace":"default"}, "v": 1, "namespace": "default", "name": "httproute-echo"} 2024-05-22T12:26:12Z debug controllers.HTTPRoute Unsupported route was previously supported, status was updated {"GatewayV1HTTPRoute": {"name":"httproute-echo","namespace":"default"}, "v": 1, "namespace": "default", "name": "httproute-echo"} 2024-05-22T12:26:12Z debug controllers.Gateway The request does not match the specified Gateway and will be skipped. {"v": 1, "gateway": "default/kong2"} 2024-05-22T12:26:12Z debug controllers.HTTPRoute Processing httproute {"GatewayV1HTTPRoute": {"name":"httproute-echo","namespace":"default"}, "v": 1, "namespace": "default", "name": "httproute-echo"} 2024-05-22T12:26:12Z debug controllers.HTTPRoute Checking deletion timestamp {"GatewayV1HTTPRoute": {"name":"httproute-echo","namespace":"default"}, "v": 1, "namespace": "default", "name": "httproute-echo"} 2024-05-22T12:26:12Z debug controllers.HTTPRoute Retrieving GatewayClass and Gateway for route {"GatewayV1HTTPRoute": {"name":"httproute-echo","namespace":"default"}, "v": 1, "namespace": "default", "name": "httproute-echo"} 2024-05-22T12:26:12Z debug controllers.HTTPRoute Unsupported route found, processing to verify whether it was ever supported {"GatewayV1HTTPRoute": {"name":"httproute-echo","namespace":"default"}, "v": 1, "namespace": "default", "name": "httproute-echo"} 2024-05-22T12:26:12Z debug controllers.HTTPRoute Ensuring that dataplane is updated to remove unsupported route (if applicable) {"GatewayV1HTTPRoute": {"name":"httproute-echo","namespace":"default"}, "v": 1, "namespace": "default", "name": "httproute-echo"} 2024-05-22T12:26:12Z debug controllers.HTTPRoute Processing httproute {"GatewayV1HTTPRoute": {"name":"httproute-echo","namespace":"default"}, "v": 1, "namespace": "default", "name": "httproute-echo"} 2024-05-22T12:26:12Z debug controllers.HTTPRoute Checking deletion timestamp {"GatewayV1HTTPRoute": {"name":"httproute-echo","namespace":"default"}, "v": 1, "namespace": "default", "name": "httproute-echo"} 2024-05-22T12:26:12Z debug controllers.HTTPRoute Retrieving GatewayClass and Gateway for route {"GatewayV1HTTPRoute": {"name":"httproute-echo","namespace":"default"}, "v": 1, "namespace": "default", "name": "httproute-echo"} 2024-05-22T12:26:12Z debug controllers.HTTPRoute Unsupported route found, processing to verify whether it was ever supported {"GatewayV1HTTPRoute": {"name":"httproute-echo","namespace":"default"}, "v": 1, "namespace": "default", "name": "httproute-echo"} 2024-05-22T12:26:12Z debug controllers.HTTPRoute Ensuring that dataplane is updated to remove unsupported route (if applicable) {"GatewayV1HTTPRoute": {"name":"httproute-echo","namespace":"default"}, "v": 1, "namespace": "default", "name": "httproute-echo"}
This also comes up when running KGO Gateway API conformance tests because that deploys multiple Gateway
s (and thus KIC instances).
Expected Behavior
When more than 1 KIC is deployed with --gateway-to-reconcile
, and that Gateway
has allowedRoutes
set, then that is taken into account when setting/clearing routes' statuses.
Steps To Reproduce
Using KGO:
1. Deploy KGO
1. Deploy the following manifests:
apiVersion: v1
kind: Service
metadata:
name: echo
spec:
ports:
- protocol: TCP
name: http
port: 80
targetPort: http
selector:
app: echo
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: echo
name: echo
spec:
replicas: 1
selector:
matchLabels:
app: echo
template:
metadata:
labels:
app: echo
spec:
containers:
- name: echo
image: registry.k8s.io/e2e-test-images/agnhost:2.40
command:
- /agnhost
- netexec
- --http-port=8080
ports:
- containerPort: 8080
name: http
env:
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
resources:
requests:
cpu: 10m
---
kind: GatewayConfiguration
apiVersion: gateway-operator.konghq.com/v1beta1
metadata:
name: kong
namespace: default
spec:
dataPlaneOptions:
deployment:
podTemplateSpec:
spec:
containers:
- name: proxy
# renovate: datasource=docker versioning=docker
image: kong/kong-gateway:3.6
readinessProbe:
initialDelaySeconds: 1
periodSeconds: 1
controlPlaneOptions:
deployment:
podTemplateSpec:
spec:
containers:
- name: controller
# renovate: datasource=docker versioning=docker
image: kong/kubernetes-ingress-controller:3.1.5
readinessProbe:
initialDelaySeconds: 1
periodSeconds: 1
env:
- name: CONTROLLER_LOG_LEVEL
value: debug
---
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: kong
spec:
controllerName: konghq.com/gateway-operator
parametersRef:
group: gateway-operator.konghq.com
kind: GatewayConfiguration
name: kong
namespace: default
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: kong
namespace: default
spec:
gatewayClassName: kong
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
kinds:
- kind: HTTPRoute
namespaces:
from: Selector
selector:
matchLabels:
# This label is added automatically as of K8s 1.22 to all namespaces
kubernetes.io/metadata.name: default
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: httproute-echo
namespace: default
annotations:
konghq.com/strip-path: "true"
spec:
parentRefs:
- name: kong
rules:
- matches:
- path:
type: PathPrefix
value: /echo
backendRefs:
- name: echo
kind: Service
port: 80
---
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: kong2
spec:
controllerName: konghq.com/gateway-operator
parametersRef:
group: gateway-operator.konghq.com
kind: GatewayConfiguration
name: kong
namespace: default
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: kong2
namespace: default
spec:
gatewayClassName: kong
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
kinds:
- kind: HTTPRoute
namespaces:
from: Selector
selector:
matchLabels:
kubernetes.io/metadata.name: kong-system # this should match 0 routes as the only one deployed here is in 'default' namespace
Kong Ingress Controller version
3.1.5
Kubernetes version
No response
Proposed solution
- take listeners
allowedRoutes
into account when clearing the HTTPRoute status - add filtering for HTTPRoutes in HTTPRoute controller so that on updates, HTTPRoute is reconciled when
- it was created attached to a Gateway that is being reconciled
- it becomes attached to a Gateway that is being reconciled
- it becomes detached from a Gateway that is being reconciled: this should cause the removal of the route from dataplane's configuration