gateway-api
gateway-api copied to clipboard
BackendObjectReference's Port field is underspecified
What happened:
Currently, the Port field of BackendObjectReference has the following godoc:
// Port specifies the destination port number to use for this resource.
// Port is required when the referent is a Kubernetes Service.
// For other resources, destination port might be derived from the referent
// resource or this field.
This godoc is ambiguous because a service's port specification includes two port numbers: the service port and the target port. For example, an annoying person could define the following service:
apiVersion: v1
kind: Service
metadata:
name: some-service
namespace: some-namespace
spec:
selector:
app: some-app
ports:
- name: port-1
protocol: TCP
port: 8080
targetPort: 8888
- name: port-2
protocol: TCP
port: 8888
targetPort: 8080
Then it is ambiguous which port the following httproute uses:
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: some-route
namespace: some-namespace
spec:
parentRefs:
- name: some-gateway
namespace: some-namespace
rules:
- backendRefs:
- name: some-service
port: 8080
A reasonable person could assume that BackendObjectReference's Port field specified the target port since the typical implementation forwards traffic to the target port (i.e., directly to the pod), not to the service port (i.e., through kube-proxy). (For what it's worth, with the OpenShift Route API, the user is expected to specify the target port, and this is explicit in that API's godoc: https://github.com/openshift/api/blob/475c352b5b246a58e756e06205847f5515b7e9a9/route/v1/types.go#L167-L173.)
From reviewing the conformance tests and https://github.com/kubernetes-sigs/gateway-api/pull/581, it seems that the decision has been made that BackendObjectReference's Port field specifies the service port number, not the target port number.
What you expected to happen:
I propose documenting the expected behavior as follows:
// Port is required when the referent is a Kubernetes Service. In this
// case, the port number is the service port number, not the target port.
How to reproduce it (as minimally and precisely as possible):
% kubectl explain httproutes.spec.rules.backendRefs.port
KIND: HTTPRoute
VERSION: gateway.networking.k8s.io/v1beta1
FIELD: port <integer>
DESCRIPTION:
Port specifies the destination port number to use for this resource. Port
is required when the referent is a Kubernetes Service. For other resources,
destination port might be derived from the referent resource or this field.
%
Anything else we need to know?:
I don't believe so.