Skip to content

Commit 8e8e751

Browse files
authored
Merge pull request #297347 from craigshoemaker/aca/jason/scaling-cpu-memory
[Container Apps] Update: Scaling CPU and memory tutorials
2 parents a5689fb + bcb3c72 commit 8e8e751

File tree

1 file changed

+227
-54
lines changed

1 file changed

+227
-54
lines changed

articles/container-apps/tutorial-scaling.md

Lines changed: 227 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ services: container-apps
55
author: craigshoemaker
66
ms.service: azure-container-apps
77
ms.topic: tutorial
8-
ms.date: 02/03/2025
8+
ms.date: 03/26/2025
99
ms.author: cshoe
1010
ms.custom: devx-track-azurecli
1111
ms.devlang: azurecli
@@ -37,7 +37,7 @@ Create and deploy your container app with the `containerapp up` command. This co
3737

3838
If any of these resources already exist, the command uses the existing resources rather than creating new ones.
3939

40-
Lastly, the command creates and deploys the container app using a public container image.
40+
Lastly, the command creates and deploys the container app using a public container image, `mcr.microsoft.com/dotnet/samples:aspnetapp`. This image is used to trigger the scale rules you create in this article. You don't need to know or use .NET to complete this procedure.
4141

4242
# [Bash](#tab/bash)
4343

@@ -47,7 +47,7 @@ az containerapp up \
4747
--resource-group my-container-apps \
4848
--location centralus \
4949
--environment 'my-container-apps' \
50-
--image mcr.microsoft.com/k8se/quickstart:latest \
50+
--image mcr.microsoft.com/dotnet/samples:aspnetapp \
5151
--target-port 8080 \
5252
--ingress external \
5353
--query properties.configuration.ingress.fqdn \
@@ -61,7 +61,7 @@ az containerapp up `
6161
--resource-group my-container-apps `
6262
--location centralus `
6363
--environment my-container-apps `
64-
--image mcr.microsoft.com/k8se/quickstart:latest `
64+
--image mcr.microsoft.com/dotnet/samples:aspnetapp `
6565
--target-port 8080 `
6666
--ingress external `
6767
--query properties.configuration.ingress.fqdn `
@@ -74,7 +74,7 @@ az containerapp up `
7474
7575
By setting `--ingress` to `external`, you make the container app available to public requests.
7676

77-
The `up` command returns the fully qualified domain name (FQDN) for the container app. Copy this FQDN to a text file. You'll use it in the [Send requests](#send-requests) section. Your FQDN looks like the following example:
77+
The `up` command returns the fully qualified domain name (FQDN) for the container app. Copy this FQDN to a text file. You use it in the [Send requests](#send-requests) section. Your FQDN looks like the following example:
7878

7979
```text
8080
https://my-container-app.icydune-96848328.centralus.azurecontainerapps.io
@@ -88,8 +88,10 @@ Add an HTTP scale rule to your container app by running the `az containerapp upd
8888

8989
```azurecli
9090
az containerapp update \
91-
--name my-container-app \
92-
--resource-group my-container-apps \
91+
--name my-container-app \
92+
--resource-group my-container-apps \
93+
--min-replicas 1 \
94+
--max-replicas 10 \
9395
--scale-rule-name my-http-scale-rule \
9496
--scale-rule-http-concurrency 1
9597
```
@@ -98,8 +100,10 @@ az containerapp update \
98100

99101
```powershell
100102
az containerapp update `
101-
--name my-container-app `
102-
--resource-group my-container-apps `
103+
--name my-container-app `
104+
--resource-group my-container-apps `
105+
--min-replicas 1 `
106+
--max-replicas 10 `
103107
--scale-rule-name my-http-scale-rule `
104108
--scale-rule-http-concurrency 1
105109
```
@@ -118,20 +122,20 @@ You can observe the effects of your application scaling by viewing the logs gene
118122

119123
```azurecli
120124
az containerapp logs show \
121-
--name my-container-app \
122-
--resource-group my-container-apps \
123-
--type=system \
124-
--follow=true
125+
--name my-container-app \
126+
--resource-group my-container-apps \
127+
--type=system \
128+
--follow=true
125129
```
126130

127131
# [PowerShell](#tab/powershell)
128132

129133
```powershell
130134
az containerapp logs show `
131-
--name my-container-app `
132-
--resource-group my-container-apps `
133-
--type=system `
134-
--follow=true
135+
--name my-container-app `
136+
--resource-group my-container-apps `
137+
--type=system `
138+
--follow=true
135139
```
136140

137141
---
@@ -140,46 +144,46 @@ The `show` command returns entries from the system logs for your container app i
140144

141145
```json
142146
{
143-
"TimeStamp":"2023-08-01T16:49:03.02752",
144-
"Log":"Connecting to the container 'my-container-app'..."
147+
"TimeStamp":"2023-08-01T16:49:03.02752",
148+
"Log":"Connecting to the container 'my-container-app'..."
145149
}
146150
{
147-
"TimeStamp":"2023-08-01T16:49:03.04437",
148-
"Log":"Successfully Connected to container:
149-
'my-container-app' [Revision: 'my-container-app--9uj51l6',
150-
Replica: 'my-container-app--9uj51l6-5f96557ffb-5khg9']"
151+
"TimeStamp":"2023-08-01T16:49:03.04437",
152+
"Log":"Successfully Connected to container:
153+
'my-container-app' [Revision: 'my-container-app--9uj51l6',
154+
Replica: 'my-container-app--9uj51l6-5f96557ffb-5khg9']"
151155
}
152156
{
153-
"TimeStamp":"2023-08-01T16:47:31.9480811+00:00",
154-
"Log":"Microsoft.Hosting.Lifetime[14]"
157+
"TimeStamp":"2023-08-01T16:47:31.9480811+00:00",
158+
"Log":"Microsoft.Hosting.Lifetime[14]"
155159
}
156160
{
157-
"TimeStamp":"2023-08-01T16:47:31.9481264+00:00",
158-
"Log":"Now listening on: http://[::]:8080"
161+
"TimeStamp":"2023-08-01T16:47:31.9481264+00:00",
162+
"Log":"Now listening on: http://[::]:80"
159163
}
160164
{
161-
"TimeStamp":"2023-08-01T16:47:31.9490917+00:00",
162-
"Log":"Microsoft.Hosting.Lifetime[0]"
165+
"TimeStamp":"2023-08-01T16:47:31.9490917+00:00",
166+
"Log":"Microsoft.Hosting.Lifetime[0]"
163167
}
164168
{
165-
"TimeStamp":"2023-08-01T16:47:31.9491036+00:00",
166-
"Log":"Application started. Press Ctrl+C to shut down."
169+
"TimeStamp":"2023-08-01T16:47:31.9491036+00:00",
170+
"Log":"Application started. Press Ctrl+C to shut down."
167171
}
168172
{
169-
"TimeStamp":"2023-08-01T16:47:31.949723+00:00",
170-
"Log":"Microsoft.Hosting.Lifetime[0]"
173+
"TimeStamp":"2023-08-01T16:47:31.949723+00:00",
174+
"Log":"Microsoft.Hosting.Lifetime[0]"
171175
}
172176
{
173-
"TimeStamp":"2023-08-01T16:47:31.9497292+00:00",
174-
"Log":"Hosting environment: Production"
177+
"TimeStamp":"2023-08-01T16:47:31.9497292+00:00",
178+
"Log":"Hosting environment: Production"
175179
}
176180
{
177-
"TimeStamp":"2023-08-01T16:47:31.9497325+00:00",
178-
"Log":"Microsoft.Hosting.Lifetime[0]"
181+
"TimeStamp":"2023-08-01T16:47:31.9497325+00:00",
182+
"Log":"Microsoft.Hosting.Lifetime[0]"
179183
}
180184
{
181-
"TimeStamp":"2023-08-01T16:47:31.9497367+00:00",
182-
"Log":"Content root path: /app/"
185+
"TimeStamp":"2023-08-01T16:47:31.9497367+00:00",
186+
"Log":"Content root path: /app/"
183187
}
184188
```
185189

@@ -248,15 +252,15 @@ In the first shell, where you ran the `az containerapp logs show` command, the o
248252

249253
```json
250254
{
251-
"TimeStamp":"2023-08-01 18:09:52 +0000 UTC",
252-
"Type":"Normal",
253-
"ContainerAppName":"my-container-app",
254-
"RevisionName":"my-container-app--9uj51l6",
255-
"ReplicaName":"my-container-app--9uj51l6-5f96557ffb-f795d",
256-
"Msg":"Replica 'my-container-app--9uj51l6-5f96557ffb-f795d' has been scheduled to run on a node.",
257-
"Reason":"AssigningReplica",
258-
"EventSource":"ContainerAppController",
259-
"Count":0
255+
"TimeStamp":"2023-08-01 18:09:52 +0000 UTC",
256+
"Type":"Normal",
257+
"ContainerAppName":"my-container-app",
258+
"RevisionName":"my-container-app--00001111",
259+
"ReplicaName":"my-container-app--00001111-aaaaa22222-bbbb",
260+
"Msg":"Replica 'my-container-app--00001111-aaaaa22222-bbbb' has been scheduled to run on a node.",
261+
"Reason":"AssigningReplica",
262+
"EventSource":"ContainerAppController",
263+
"Count":0
260264
}
261265
```
262266

@@ -269,9 +273,9 @@ In the first shell, where you ran the `az containerapp logs show` command, the o
269273
1. In the *Scale and Replicas* page, select **Replicas**.
270274
1. Your container app now has more than one replica running.
271275

272-
:::image type="content" source="media/scale-app/azure-container-apps-scale-replicas.png" alt-text="Screenshot of container app replicas.":::
276+
:::image type="content" source="media/scale-app/azure-container-apps-scale-replicas.png" alt-text="Screenshot of container app replicas.":::
273277

274-
You may need to select **Refresh** to see the new replicas.
278+
You might need to select **Refresh** to see the new replicas.
275279

276280
1. In the navigation bar at the left, expand **Monitoring** and select **Metrics**.
277281
1. In the *Metrics* page, set **Metric** to **Requests**.
@@ -283,20 +287,189 @@ You may need to select **Refresh** to see the new replicas.
283287
:::image type="content" source="media/scale-app/azure-container-apps-scale-replicas-metrics-1.png" alt-text="Container app metrics graph, showing requests split by replica.":::
284288

285289
1. By default, the graph scale is set to last 24 hours, with a time granularity of 15 minutes. Select the scale and change it to the last 30 minutes, with a time granularity of one minute. Select the **Apply** button.
290+
286291
1. Select on the graph and drag to highlight the recent increase in requests received by your container app.
287292

288-
:::image type="content" source="media/scale-app/azure-container-apps-scale-replicas-metrics-2.png" alt-text="Screenshot of container app metrics graph, showing requests split by replica, with a scale of 30 minutes and time granularity of one minute.":::
293+
:::image type="content" source="media/scale-app/azure-container-apps-scale-replicas-metrics-2.png" alt-text="Screenshot of container app metrics graph, showing requests split by replica, with a scale of 30 minutes and time granularity of one minute.":::
294+
295+
The following screenshot shows a zoomed view of how the requests received by your container app are divided among replicas.
296+
297+
:::image type="content" source="media/scale-app/azure-container-apps-scale-replicas-metrics-3.png" alt-text="Screenshot of container app metrics graph, showing requests split by replica, in a zoomed view.":::
298+
299+
## CPU and memory scaling
300+
301+
You should prefer [HTTP scale rules](/azure/container-apps/scale-app#http) to CPU or memory scale rules when possible. CPU and memory scaling don't allow your container app to scale to zero.
302+
303+
After you add a CPU or memory scale rule, you can test it by [sending requests to your container app](#send-requests) and [viewing the scaling in Azure portal](#view-scaling-in-azure-portal-optional).
304+
305+
After you send requests to your scale app, it might take a minute before the scale rule is triggered and the new replicas are created.
306+
307+
### CPU scaling
308+
309+
CPU scaling allows your app to scale in or out depending on how much the CPU is being used.
310+
311+
For example, if you create a CPU scale rule with a utilization value of `50`, Azure Container Apps creates more replicas of your container app when the average CPU utilization for all replicas reaches 50%.
312+
313+
CPU scaling doesn't allow your container app to scale to zero. For more information about this trigger, see [KEDA CPU scale trigger](https://keda.sh/docs/scalers/cpu/).
314+
315+
Add a CPU scale rule to your container app by running the `az containerapp update` command.
316+
317+
> [!NOTE]
318+
> When you use the Azure CLI to add a scale rule to a container app that already has a scale rule, the new scale rule replaces the old scale rule. To see how to add multiple scale rules, see [Multiple scale rules](#multiple-scale-rules).
319+
320+
Before running the following command, replace the `<PLACEHOLDERS>` with your values. For this tutorial, replace `<UTILIZATION>` with `1`. This causes your container app to scale when the average CPU utilization for all replicas reaches 1%. This value is for demonstration only. The number of replicas is limited to 10 by the `--max-replicas 10` you specified when running `az containerapp update`.
321+
322+
# [Bash](#tab/bash)
323+
324+
```azurecli
325+
az containerapp update \
326+
--name my-container-app \
327+
--resource-group my-container-apps \
328+
--min-replicas 1 \
329+
--max-replicas 10 \
330+
--scale-rule-name my-cpu-scale-rule \
331+
--scale-rule-type cpu \
332+
--scale-rule-metadata type=Utilization value=<UTILIZATION>
333+
```
334+
335+
# [PowerShell](#tab/powershell)
336+
337+
```powershell
338+
az containerapp update `
339+
--name my-container-app `
340+
--resource-group my-container-apps `
341+
--min-replicas 1 `
342+
--max-replicas 10 `
343+
--scale-rule-name my-cpu-scale-rule `
344+
--scale-rule-type cpu `
345+
--scale-rule-metadata type=Utilization value=<UTILIZATION>
346+
```
347+
348+
---
349+
350+
### Memory scaling
351+
352+
Memory scaling allows your app to scale in or out depending on how much memory is being used.
353+
354+
For example, if you create a memory scale rule with a utilization value of `50`, Azure Container Apps creates more replicas of your container app when the average memory utilization for all replicas reaches 50%.
289355

290-
The following screenshot shows a zoomed view of how the requests received by your container app are divided among replicas.
356+
Memory scaling doesn't allow your container app to scale to zero. For more information about this trigger, see [KEDA memory scale trigger](https://keda.sh/docs/scalers/memory/).
357+
358+
Add a memory scale rule to your container app by running the `az containerapp update` command.
359+
360+
> [!NOTE]
361+
> When you use the Azure CLI to add a scale rule to a container app that already has a scale rule, the new scale rule replaces the old scale rule. To see how to add multiple scale rules, see [Multiple scale rules](#multiple-scale-rules).
362+
363+
Before running the following command, replace the `<PLACEHOLDERS>` with your values. For this tutorial, replace `<UTILIZATION>` with `1`. This causes your container app to scale when the average memory utilization for all replicas reaches 1%. This value is for demonstration only. The number of replicas is limited to 10 by the `--max-replicas 10` you specified when running `az containerapp update`.
364+
365+
# [Bash](#tab/bash)
366+
367+
```azurecli
368+
az containerapp update \
369+
--name my-container-app \
370+
--resource-group my-container-apps \
371+
--min-replicas 1 \
372+
--max-replicas 10 \
373+
--scale-rule-name my-memory-scale-rule \
374+
--scale-rule-type memory \
375+
--scale-rule-metadata type=Utilization value=<UTILIZATION>
376+
```
377+
378+
# [PowerShell](#tab/powershell)
379+
380+
```powershell
381+
az containerapp update `
382+
--name my-container-app `
383+
--resource-group my-container-apps `
384+
--min-replicas 1 `
385+
--max-replicas 10 `
386+
--scale-rule-name my-memory-scale-rule `
387+
--scale-rule-type memory `
388+
--scale-rule-metadata type=Utilization value=<UTILIZATION>
389+
```
390+
391+
---
291392

292-
:::image type="content" source="media/scale-app/azure-container-apps-scale-replicas-metrics-3.png" alt-text="Screenshot of container app metrics graph, showing requests split by replica, in a zoomed view.":::
393+
## Multiple scale rules
394+
395+
To add multiple scale rules to your container app using the Azure CLI, you must use YAML.
396+
397+
1. Export your container app configuration to YAML with the `az containerapp show` command.
398+
399+
# [Bash](#tab/bash)
400+
401+
```azurecli
402+
az containerapp show \
403+
--name my-container-app \
404+
--resource-group my-container-apps \
405+
--output yaml > app.yaml
406+
```
407+
408+
# [PowerShell](#tab/powershell)
409+
410+
```powershell
411+
az containerapp show `
412+
--name my-container-app `
413+
--resource-group my-container-apps `
414+
--output yaml > app.yaml
415+
```
416+
417+
---
418+
419+
1. In the `properties` > `template` > `scale` > `rules` section of `app.yaml`, add the following properties. Replace the `<PLACEHOLDERS>` with your values.
420+
421+
```yaml
422+
...
423+
properties:
424+
...
425+
template:
426+
...
427+
scale:
428+
...
429+
rules:
430+
- name: cpu-scaling-rule
431+
custom:
432+
type: cpu
433+
metadata:
434+
type: "Utilization"
435+
value: "<CPU_UTILIZATION>"
436+
- name: memory-scaling-rule
437+
custom:
438+
type: memory
439+
metadata:
440+
type: "Utilization"
441+
value: "<MEMORY_UTILIZATION>"
442+
...
443+
```
444+
445+
1. Import your container app configuration from `app.yaml` with the `az containerapp update` command.
446+
447+
# [Bash](#tab/bash)
448+
449+
```azurecli
450+
az containerapp update \
451+
--name my-container-app \
452+
--resource-group my-container-apps \
453+
--yaml app.yaml
454+
```
455+
456+
# [PowerShell](#tab/powershell)
457+
458+
```powershell
459+
az containerapp update `
460+
--name my-container-app `
461+
--resource-group my-container-apps `
462+
--yaml app.yaml
463+
```
464+
465+
---
293466
294467
## Clean up resources
295468
296469
If you're not going to continue to use this application, run the following command to delete the resource group along with all the resources created in this tutorial.
297470
298471
>[!CAUTION]
299-
> The following command deletes the specified resource group and all resources contained within it. If resources outside the scope of this tutorial exist in the specified resource group, they will also be deleted.
472+
> The following command deletes the specified resource group and all resources contained within it. If resources outside the scope of this tutorial exist in the specified resource group, they'll also be deleted.
300473
301474
```azurecli
302475
az group delete --name my-container-apps

0 commit comments

Comments
 (0)