Description
/kind feature
What happened:
When multiple Ingress resources are created in the Kubernetes cluster, each with the kubernetes.io/ingress.class: "openstack" annotation (or the corresponding ingressClassName), the octavia-ingress-controller creates a separate Octavia LoadBalancer for each Ingress resource. This results in multiple public IP addresses being allocated, with each IP corresponding to a single Ingress definition.
What you expected to happen:
I expected the octavia-ingress-controller to follow the "Single Entry Point" model, which is the standard behavior for most major ingress controllers (like NGINX).
The expected behavior is that the controller should manage a single Octavia LoadBalancer and a single public IP address. When new Ingress resources are created, the controller should read their rules and dynamically update the configuration of this single, existing LoadBalancer (by adding new listeners, pools, or rules) instead of creating a new one. This allows multiple applications and services to be exposed through one centralized ingress point, which is more cost-effective and easier to manage.
How to reproduce it:
Just apply this yaml file:
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-app-deployment
spec:
replicas: 1
selector:
matchLabels:
app: sample-app
template:
metadata:
labels:
app: sample-app
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
name: http-port
- containerPort: 8080
name: grpc-port
---
apiVersion: v1
kind: Service
metadata:
name: sample-app-service
spec:
type: NodePort
selector:
app: sample-app
ports:
- name: http
protocol: TCP
port: 80
targetPort: http-port
- name: grpc
protocol: TCP
port: 8080
targetPort: grpc-port
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: http-ingress
annotations:
octavia.ingress.kubernetes.io/backend-protocol: "HTTP"
kubernetes.io/ingress.class: "openstack"
octavia.ingress.kubernetes.io/internal: "false"
spec:
rules:
- host: "your.example.com"
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: sample-app-service
port:
name: http
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: grpc-ingress
annotations:
octavia.ingress.kubernetes.io/backend-protocol: "GRPC"
kubernetes.io/ingress.class: "openstack"
octavia.ingress.kubernetes.io/internal: "false"
spec:
rules:
- host: "your.example.com"
http:
paths:
- path: /grpc
pathType: Prefix
backend:
service:
name: sample-app-service
port:
name: grpc
My expectation here is that it is managed through a single loadbalancer, because the same domain name is just ingress rules that address different endpoints and protocols. However, for this scenario, 2 separate loadbalancers are created and I encounter 2 different floating IP addresses.
Anything else we need to know?:
The current behavior significantly increases the cost and complexity of using the controller. Exposing multiple services requires allocating multiple Floating IPs and managing multiple DNS records.
Environment:
- octavia-ingress-controller version: [v1.32.0]
- Kubernetes version: [v1.32.5+rke2r1]