Skip to content

Commit ae44676

Browse files
authored
Merge pull request #292992 from JackStromberg/patch-92415
AGC - WebSockets
2 parents cee3ee7 + ebac968 commit ae44676

File tree

5 files changed

+437
-0
lines changed

5 files changed

+437
-0
lines changed
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
apiVersion: v1
2+
kind: Namespace
3+
metadata:
4+
name: test-infra
5+
---
6+
apiVersion: apps/v1
7+
kind: Deployment
8+
metadata:
9+
name: websocket-backend
10+
namespace: test-infra
11+
spec:
12+
replicas: 1
13+
selector:
14+
matchLabels:
15+
app: websocket-backend
16+
template:
17+
metadata:
18+
labels:
19+
app: websocket-backend
20+
spec:
21+
containers:
22+
- name: websocket-backend
23+
image: trafficcontrollertestimages.azurecr.io/images/websockets-test-backend:latest
24+
imagePullPolicy: Always
25+
ports:
26+
- name: http
27+
containerPort: 8080
28+
protocol: TCP
29+
resources:
30+
requests:
31+
cpu: 10m
32+
---
33+
apiVersion: v1
34+
kind: Service
35+
metadata:
36+
name: websocket-backend
37+
namespace: test-infra
38+
spec:
39+
type: ClusterIP
40+
ports:
41+
- port: 8080
42+
targetPort: http
43+
protocol: TCP
44+
name: http-back
45+
selector:
46+
app: websocket-backend
Lines changed: 296 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,296 @@
1+
---
2+
title: WebSocket protocol and Azure Application Gateway for Containers - Gateway API
3+
description: Learn how to send a WebSocket request to a backend target with Application Gateway for Containers.
4+
services: application gateway
5+
author: greg-lindsay
6+
ms.service: azure-appgw-for-containers
7+
ms.topic: conceptual
8+
ms.date: 1/13/2025
9+
ms.author: greglin
10+
---
11+
12+
# WebSocket request for Azure Application Gateway for Containers - Gateway API
13+
14+
Application Gateway for Containers allows you to leverage WebSocket protocol to connect to backend targets with Application Gateway for Containers.
15+
16+
## Usage details
17+
18+
WebSocket protocol has no specific implementation with Gateway API for configuration or enablement. However, you can use this how-to guide to understand the end-to-end configuration and proper health probe configuration. This ensures WebSocket requests are properly handled by a backend service.
19+
20+
## Prerequisites
21+
22+
1. If following the BYO deployment strategy, ensure you set up your Application Gateway for Containers resources and [ALB Controller](quickstart-deploy-application-gateway-for-containers-alb-controller.md).
23+
2. If following the ALB managed deployment strategy, ensure you provision your [ALB Controller](quickstart-deploy-application-gateway-for-containers-alb-controller.md) and provision the Application Gateway for Containers resources via the [ApplicationLoadBalancer custom resource](quickstart-create-application-gateway-for-containers-managed-by-alb-controller.md).
24+
3. Deploy sample HTTP and WebSocket application:
25+
26+
Apply the following deployment.yaml file on your cluster to create a sample web application to demonstrate WebSocket support.
27+
28+
```bash
29+
kubectl apply -f https://learn.microsoft.com/azure/application-gateway/for-containers/examples/websocket-scenario/deployment.yaml
30+
```
31+
32+
This command creates the following on your cluster:
33+
34+
- A namespace called `test-infra`
35+
- One service called `websocket-backend` in the `test-infra` namespace
36+
- One deployment called `websocket-backend` in the `test-infra` namespace
37+
38+
## Deploy the required Gateway API resources
39+
40+
# [ALB managed deployment](#tab/alb-managed)
41+
42+
1. Create a Gateway
43+
44+
```bash
45+
kubectl apply -f - <<EOF
46+
apiVersion: gateway.networking.k8s.io/v1
47+
kind: Gateway
48+
metadata:
49+
name: gateway-01
50+
namespace: test-infra
51+
annotations:
52+
alb.networking.azure.io/alb-namespace: alb-test-infra
53+
alb.networking.azure.io/alb-name: alb-test
54+
spec:
55+
gatewayClassName: azure-alb-external
56+
listeners:
57+
- name: http-listener
58+
port: 80
59+
protocol: HTTP
60+
allowedRoutes:
61+
namespaces:
62+
from: Same
63+
EOF
64+
```
65+
66+
[!INCLUDE [application-gateway-for-containers-frontend-naming](../../../includes/application-gateway-for-containers-frontend-naming.md)]
67+
68+
# [Bring your own (BYO) deployment](#tab/byo)
69+
70+
1. Set the following environment variables
71+
72+
```bash
73+
RESOURCE_GROUP='<resource group name of the Application Gateway For Containers resource>'
74+
RESOURCE_NAME='alb-test'
75+
76+
RESOURCE_ID=$(az network alb show --resource-group $RESOURCE_GROUP --name $RESOURCE_NAME --query id -o tsv)
77+
FRONTEND_NAME='frontend'
78+
```
79+
80+
2. Create a Gateway
81+
82+
```bash
83+
kubectl apply -f - <<EOF
84+
apiVersion: gateway.networking.k8s.io/v1
85+
kind: Gateway
86+
metadata:
87+
name: gateway-01
88+
namespace: test-infra
89+
annotations:
90+
alb.networking.azure.io/alb-id: $RESOURCE_ID
91+
spec:
92+
gatewayClassName: azure-alb-external
93+
listeners:
94+
- name: http-listener
95+
port: 80
96+
protocol: HTTP
97+
allowedRoutes:
98+
namespaces:
99+
from: Same
100+
addresses:
101+
- type: alb.networking.azure.io/alb-frontend
102+
value: $FRONTEND_NAME
103+
EOF
104+
```
105+
106+
---
107+
108+
Once the gateway resource is created, ensure the status is valid, the listener is _Programmed_, and an address is assigned to the gateway.
109+
110+
```bash
111+
kubectl get gateway gateway-01 -n test-infra -o yaml
112+
```
113+
114+
Example output of successful gateway creation.
115+
116+
```yaml
117+
status:
118+
addresses:
119+
- type: Hostname
120+
value: xxxx.yyyy.alb.azure.com
121+
conditions:
122+
- lastTransitionTime: "2023-06-19T21:04:55Z"
123+
message: Valid Gateway
124+
observedGeneration: 1
125+
reason: Accepted
126+
status: "True"
127+
type: Accepted
128+
- lastTransitionTime: "2023-06-19T21:04:55Z"
129+
message: Application Gateway For Containers resource has been successfully updated.
130+
observedGeneration: 1
131+
reason: Programmed
132+
status: "True"
133+
type: Programmed
134+
listeners:
135+
- attachedRoutes: 0
136+
conditions:
137+
- lastTransitionTime: "2023-06-19T21:04:55Z"
138+
message: ""
139+
observedGeneration: 1
140+
reason: ResolvedRefs
141+
status: "True"
142+
type: ResolvedRefs
143+
- lastTransitionTime: "2023-06-19T21:04:55Z"
144+
message: Listener is accepted
145+
observedGeneration: 1
146+
reason: Accepted
147+
status: "True"
148+
type: Accepted
149+
- lastTransitionTime: "2023-06-19T21:04:55Z"
150+
message: Application Gateway For Containers resource has been successfully updated.
151+
observedGeneration: 1
152+
reason: Programmed
153+
status: "True"
154+
type: Programmed
155+
name: https-listener
156+
supportedKinds:
157+
- group: gateway.networking.k8s.io
158+
kind: HTTPRoute
159+
```
160+
161+
Once the gateway is created, create an HTTPRoute resource for `contoso.com`.
162+
163+
```bash
164+
kubectl apply -f - <<EOF
165+
apiVersion: gateway.networking.k8s.io/v1
166+
kind: HTTPRoute
167+
metadata:
168+
name: websocket-example
169+
namespace: test-infra
170+
spec:
171+
parentRefs:
172+
- name: gateway-01
173+
hostnames:
174+
- "contoso.com"
175+
rules:
176+
- backendRefs:
177+
- name: websocket-backend
178+
port: 8080
179+
EOF
180+
```
181+
182+
When the HTTPRoute resource is created, ensure the HTTPRoute resource shows _Accepted_ and the Application Gateway for Containers resource is _Programmed_.
183+
184+
```bash
185+
kubectl get httproute websocket-example -n test-infra -o yaml
186+
```
187+
188+
Verify the Application Gateway for Containers resource is successfully updated for the HTTPRoute.
189+
190+
```yaml
191+
status:
192+
parents:
193+
- conditions:
194+
- lastTransitionTime: "2023-06-19T22:18:23Z"
195+
message: ""
196+
observedGeneration: 1
197+
reason: ResolvedRefs
198+
status: "True"
199+
type: ResolvedRefs
200+
- lastTransitionTime: "2023-06-19T22:18:23Z"
201+
message: Route is Accepted
202+
observedGeneration: 1
203+
reason: Accepted
204+
status: "True"
205+
type: Accepted
206+
- lastTransitionTime: "2023-06-19T22:18:23Z"
207+
message: Application Gateway For Containers resource has been successfully updated.
208+
observedGeneration: 1
209+
reason: Programmed
210+
status: "True"
211+
type: Programmed
212+
controllerName: alb.networking.azure.io/alb-controller
213+
parentRef:
214+
group: gateway.networking.k8s.io
215+
kind: Gateway
216+
name: gateway-01
217+
namespace: test-infra
218+
```
219+
220+
For this example, health checks are exposed on the path `/health`. To ensure Application Gateway for Containers can validate the health of this application, define a HealthCheckPolicy resource for the HTTP path of `/health`.
221+
222+
```bash
223+
kubectl apply -f - <<EOF
224+
apiVersion: alb.networking.azure.io/v1
225+
kind: HealthCheckPolicy
226+
metadata:
227+
name: websockets-backend-health-check-policy
228+
namespace: test-infra
229+
spec:
230+
targetRef:
231+
group: ""
232+
kind: Service
233+
name: websocket-backend
234+
namespace: test-infra
235+
default:
236+
interval: 5s
237+
timeout: 3s
238+
healthyThreshold: 1
239+
unhealthyThreshold: 1
240+
http:
241+
path: /health
242+
EOF
243+
```
244+
245+
When the HealthCheckPolicy resource is created, ensure the HealthCheckPolicy resource shows _Accepted_ and the Application Gateway for Containers resource is _Programmed_.
246+
247+
```bash
248+
kubectl get httproute websocket-example -n test-infra -o yaml
249+
```
250+
251+
Verify the Application Gateway for Containers HealthCheckPolicy is successfully updated.
252+
253+
```yaml
254+
status:
255+
conditions:
256+
- lastTransitionTime: "2024-10-29T16:40:34Z"
257+
message: Valid HealthCheckPolicy
258+
observedGeneration: 1
259+
reason: Accepted
260+
status: "True"
261+
type: Accepted
262+
```
263+
264+
## Test access to the application
265+
266+
Now we're ready to send some traffic to our sample application, via the FQDN assigned to the frontend. Use the following command to get the FQDN and resolve its IP address.
267+
268+
```bash
269+
fqdn=$(kubectl get gateway gateway-01 -n test-infra -o jsonpath='{.status.addresses[0].value}')
270+
fqdnIp=$(dig +short $fqdn)
271+
```
272+
273+
Obtain the websocket utility to make a websocket request. For example purposes, the latest version of the utility is downloaded and marked as executable in a linux home directory instead of installed locally on the machine. This enables you to use the utility via Cloud Shell.
274+
275+
```bash
276+
wget -O ~/websocat https://github.com/vi/websocat/releases/latest/download/websocat.x86_64-unknown-linux-musl
277+
chmod a+x ~/websocat
278+
```
279+
280+
Call the websocket utility to make a websocket request. In this example, a chat application is exposed on the path `/chat`, where the application responds back with the text sent.
281+
282+
```bash
283+
./websocat -t - --ws-c-uri=ws://contoso.com/chat ws-c:tcp:$fqdnIp:80
284+
```
285+
286+
Once connected, type `Hello world!!!`
287+
288+
Via the response we should see the same response:
289+
290+
```
291+
Hello world!!!
292+
```
293+
294+
Use the keystroke combination Control + C to break out of the websocat utility.
295+
296+
Congratulations, you have installed ALB Controller, deployed a backend application and used the WebSocket protocol to establish a connection to a backend target on Application Gateway for Containers.

0 commit comments

Comments
 (0)