oracle / oracle/oci-cloud-controller-manager
[Bug] NLB ignores different NodePorts when multiple protocols share the same external port
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 158
- Forks
- 108
- PR merge metrics
- No merged PRs in 30d
Description
Description
When a Kubernetes Service of type LoadBalancer (using OCI NLB) is configured with multiple protocols (TCP and UDP) on the same external port but with different NodePorts, the OCI Cloud Controller Manager (CCM) incorrectly merges them into a single TCP_AND_UDP listener.
During this process, the CCM only picks the NodePort of the first protocol defined in the service spec and ignores the NodePort of the second protocol. As a result, traffic for the second protocol is routed to the wrong internal port on the worker nodes.
To Reproduce
Create a service with the following port configuration:
apiVersion: v1
kind: Service
metadata:
name: mixed-protocol-service
annotations:
oci.oraclecloud.com/load-balancer-type: "nlb"
spec:
type: LoadBalancer
selector:
app: my-app
ports:
- name: tcp
protocol: TCP
port: 80
targetPort: 8080
nodePort: 30001
- name: udp
protocol: UDP
port: 80
targetPort: 8080
nodePort: 30002
Observed Behavior
- A single NLB Listener TCP_AND_UDP-80 is created.
- The BackendSet points to only one NodePort (e.g., 30001).
- UDP traffic arriving at port 80 is incorrectly routed to port 30001 instead of 30002.
Expected Behavior
If the NodePorts for TCP and UDP are different, the CCM should create separate listeners (e.g., TCP-80 and UDP-80) and separate BackendSets to correctly route traffic to their respective target ports.
Aditional Context
This issue stems from getBackendSetNamePortMap and getListenersNetworkLoadBalancer in pkg/cloudprovider/providers/oci/load_balancer_spec.go, which unconditionally groups protocols by the external port number without checking if the underlying NodePorts are identical.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in pkg/cloudprovider/providers/oci/load_balancer_spec.go by reading getBackendSetNamePortMap and getListenersNetworkLoadBalancer. Trace how protocols sharing an external port are grouped and compare their NodePorts. Done means TCP and UDP with different NodePorts produce separate listeners and BackendSets, while the reported routing mismatch is avoided.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- cloud, infrastructure
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 75/100