Skip to content

Commit 05fa152

Browse files
loehdeKasper Løhde
authored andcommitted
fix container publish args duplicates - container fails to deploy
1 parent 2068c18 commit 05fa152

4 files changed

Lines changed: 125 additions & 4 deletions

File tree

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
apiVersion: gateway.networking.k8s.io/v1
2+
kind: Gateway
3+
metadata:
4+
name: multi-listener-gateway
5+
spec:
6+
gatewayClassName: cloud-provider-kind
7+
listeners:
8+
- protocol: HTTP
9+
port: 80
10+
hostname: "*.multi-listener.test"
11+
name: wildcard
12+
allowedRoutes:
13+
namespaces:
14+
from: All
15+
- protocol: HTTP
16+
port: 80
17+
hostname: multi-listener.test
18+
name: root
19+
allowedRoutes:
20+
namespaces:
21+
from: All
22+
---
23+
apiVersion: gateway.networking.k8s.io/v1
24+
kind: HTTPRoute
25+
metadata:
26+
name: multi-listener-route
27+
spec:
28+
parentRefs:
29+
- name: multi-listener-gateway
30+
hostnames:
31+
- route.multi-listener.test
32+
rules:
33+
- backendRefs:
34+
- name: multi-listener-app-svc
35+
port: 8080
36+
---
37+
apiVersion: apps/v1
38+
kind: Deployment
39+
metadata:
40+
name: multi-listener-app
41+
spec:
42+
selector:
43+
matchLabels:
44+
app: MultiListenerApp
45+
replicas: 1
46+
template:
47+
metadata:
48+
labels:
49+
app: MultiListenerApp
50+
spec:
51+
containers:
52+
- name: multi-listener-app
53+
image: registry.k8s.io/e2e-test-images/agnhost:2.63.0
54+
args:
55+
- netexec
56+
- --http-port=80
57+
- --delay-shutdown=30
58+
ports:
59+
- name: httpd
60+
containerPort: 80
61+
---
62+
apiVersion: v1
63+
kind: Service
64+
metadata:
65+
name: multi-listener-app-svc
66+
spec:
67+
type: ClusterIP
68+
selector:
69+
app: MultiListenerApp
70+
ports:
71+
- name: httpd
72+
port: 8080
73+
targetPort: 80

pkg/gateway/envoy.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,17 +214,27 @@ func createGateway(clusterName string, nameserver string, localAddress string, l
214214
// advertised but not functional end-to-end (e.g. some GitHub Actions runners).
215215
// For dual-stack or unspecified gateways, publish without an explicit address.
216216
// See https://github.com/kubernetes-sigs/cloud-provider-kind/issues/387
217+
seen := make(map[string]struct{})
217218
for _, listener := range gateway.Spec.Listeners {
218219
proto := "tcp"
219220
if listener.Protocol == gatewayv1.UDPProtocolType {
220221
proto = "udp"
221222
}
223+
224+
var publishArg string
222225
if listenAddress != "" {
223226
hostPortBinding := net.JoinHostPort(listenAddress, fmt.Sprintf("%d", listener.Port))
224-
args = append(args, fmt.Sprintf("--publish=%s:%d/%s", hostPortBinding, listener.Port, proto))
227+
publishArg = fmt.Sprintf("--publish=%s:%d/%s", hostPortBinding, listener.Port, proto)
225228
} else {
226-
args = append(args, fmt.Sprintf("--publish=%d/%s", listener.Port, proto))
229+
publishArg = fmt.Sprintf("--publish=%d/%s", listener.Port, proto)
230+
}
231+
232+
if _, exists := seen[publishArg]; exists {
233+
continue
227234
}
235+
236+
seen[publishArg] = struct{}{}
237+
args = append(args, publishArg)
228238
}
229239
}
230240
args = append(args, "--publish-all")

tests/setup_suite.bash

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ function setup_suite {
1515
kind create cluster --name $CLUSTER_NAME -v7 --wait 1m --retain --config="$BATS_TEST_DIRNAME/kind.yaml"
1616

1717
cd "$BATS_TEST_DIRNAME"/.. && make
18-
nohup "$BATS_TEST_DIRNAME"/../bin/cloud-provider-kind -v 2 --gateway-channel=standard --enable-log-dumping --logs-dir "$ARTIFACTS_DIR" > "$ARTIFACTS_DIR"/ccm-kind.log 2>&1 &
18+
nohup "$BATS_TEST_DIRNAME"/../bin/cloud-provider-kind -v 2 --gateway-channel=standard --enable-lb-port-mapping --enable-log-dumping --logs-dir "$ARTIFACTS_DIR" > "$ARTIFACTS_DIR"/ccm-kind.log 2>&1 &
1919
export CCM_PID=$!
2020

2121
# test depend on external connectivity that can be very flaky

tests/tests.bats

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,44 @@
119119
kubectl delete --ignore-not-found -f "$BATS_TEST_DIRNAME"/../examples/gateway_httproute_simple.yaml
120120
}
121121

122+
@test "Gateway: Multiple HTTP Listeners on Same Port with enable-lb-port-mapping" {
123+
# Apply a Gateway with two HTTP listeners on the same port (443) with different
124+
# hostnames. This reproduces the bug where duplicate --publish=443/tcp args
125+
# caused Docker to fail with exit status 125.
126+
kubectl apply -f "$BATS_TEST_DIRNAME"/../examples/gateway_https_multi_listener.yaml
127+
128+
# Wait for the backend application pod to be ready
129+
kubectl wait --for=condition=ready pods -l app=MultiListenerApp --timeout=60s
130+
131+
# Retry loop to get the Gateway's external IP address
132+
for i in {1..10}
133+
do
134+
IP=$(kubectl get gateway multi-listener-gateway --output jsonpath='{.status.addresses[0].value}' 2>/dev/null)
135+
[[ ! -z "$IP" ]] && break || sleep 1
136+
done
137+
if [[ -z "$IP" ]]; then
138+
echo "Failed to get Gateway IP address"
139+
return 1
140+
fi
141+
echo "Gateway IP: $IP"
142+
143+
# Verify the gateway container is reachable (if duplicates existed, container creation would have failed)
144+
for i in {1..10}
145+
do
146+
HOSTNAME=$(curl -s --connect-timeout 5 http://${IP}/hostname -H "Host: route.multi-listener.test" || true)
147+
[[ ! -z "$HOSTNAME" ]] && break || sleep 1
148+
done
149+
if [[ -z "$HOSTNAME" ]]; then
150+
echo "Failed to get hostname via Gateway"
151+
return 1
152+
fi
153+
echo "Hostname via Gateway: $HOSTNAME"
154+
155+
# Cleanup
156+
kubectl delete --ignore-not-found -f "$BATS_TEST_DIRNAME"/../examples/gateway_https_multi_listener.yaml
157+
}
158+
159+
122160

123161
@test "Ingress to Gateway Migration and X-Forwarded-For Header" {
124162
# Apply the Gateway and HTTPRoute manifests
@@ -258,4 +296,4 @@ EOF
258296
kubectl delete deployment ws-echo
259297
kubectl delete service ws-service
260298
kubectl delete ingress ws-ingress
261-
}
299+
}

0 commit comments

Comments
 (0)