Skip to content

Commit 9951abe

Browse files
committed
ASA migration batch 5
1 parent ec4423a commit 9951abe

5 files changed

+795
-0
lines changed
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
---
2+
title: The Experience of Blue-Green Deployment in Azure Container Apps
3+
description: Describes the experience of blue-green deployment in Azure Container Apps.
4+
author: KarlErickson
5+
ms.author: dixue
6+
ms.service: azure-spring-apps
7+
ms.topic: upgrade-and-migration-article
8+
ms.date: 01/29/2025
9+
ms.custom: devx-track-java, devx-track-extended-java
10+
---
11+
12+
# The experience of blue-green deployment in Azure Container Apps
13+
14+
[!INCLUDE [deprecation-note](../includes/deprecation-note.md)]
15+
16+
**This article applies to:** ✅ Basic/Standard ✅ Enterprise
17+
18+
This article describes blue-green deployment with Azure Container Apps.
19+
20+
In Azure Container Apps, you can enable blue-green deployment by combining [container apps revisions](../../container-apps/revisions.md), [traffic weights](../../container-apps/traffic-splitting.md), and [revision labels](../../container-apps/revisions.md#labels).
21+
22+
## Create or update a container app with multiple active revisions enabled
23+
24+
To create a new container app with multiple active revisions enabled, use the following command:
25+
26+
```azurecli
27+
az containerapp create \
28+
--resource-group <RESOURCE_GROUP> \
29+
--name <APP_NAME> \
30+
--environment <APP_ENVIRONMENT_NAME> \
31+
--image mcr.microsoft.com/k8se/samples/test-app:<BLUE_COMMIT_ID> \
32+
--revision-suffix <BLUE_SUFFIX> \
33+
--ingress external \
34+
--target-port 80 \
35+
--revisions-mode multiple
36+
```
37+
38+
Alternatively, you can use the following command to update an existing app to enable multiple revisions:
39+
40+
```azurecli
41+
az containerapp revision set-mode \
42+
--resource-group <RESOURCE_GROUP> \
43+
--name <APP_NAME> \
44+
--mode multiple
45+
```
46+
47+
## Deploy a new revision and assign labels
48+
49+
To deploy a new revision, use the following command:
50+
51+
```azurecli
52+
az containerapp update \
53+
--resource-group <RESOURCE_GROUP> \
54+
--name <APP_NAME> \
55+
--image mcr.microsoft.com/k8se/samples/test-app:<GREEN_COMMIT_ID> \
56+
--revision-suffix <GREEN_SUFFIX>
57+
```
58+
59+
You can add labels to specific revisions as shown in the following example:
60+
61+
```azurecli
62+
az containerapp revision label add \
63+
--resource-group <RESOURCE_GROUP> \
64+
--name <APP_NAME> \
65+
--label blue \
66+
--revision <APP_NAME>--<BLUE_SUFFIX>
67+
68+
az containerapp revision label add \
69+
--resource-group <RESOURCE_GROUP> \
70+
--name <APP_NAME> \
71+
--label green \
72+
--revision <APP_NAME>--<GREEN_SUFFIX>
73+
```
74+
75+
Initially, the revision with the *blue* `commitId` takes 100% of production traffic, while the newly deployed revision with the *green* `commitId` doesn't take any production traffic.
76+
77+
In Azure Spring Apps, you can deploy at most two revisions of one app: one set as Production and the other as Staging. However, Azure Container Apps supports deploying multiple revisions for a single app.
78+
79+
## Test a new revision
80+
81+
Each revision in Azure Container Apps has its own URL, enabling you to test and verify your deployment against the specific URL. Use the following commands to test the green revision with a specific domain, even though all production traffic is directed to the blue revision:
82+
83+
```azurecli
84+
export GREEN_DOMAIN=$(az containerapp revision show \
85+
--resource-group <RESOURCE_GROUP> \
86+
--name <APP_NAME> \
87+
--revision <GREEN_REVISION_NAME> \
88+
--query "properties.fqdn" \
89+
--output tsv \
90+
| tr -d '\r\n')
91+
92+
curl -s http://$GREEN_DOMAIN
93+
```
94+
95+
Use the following commands to test with the label-specific fully qualified domain name (FQDN):
96+
97+
```azurecli
98+
# Get the containerapp environment default domain
99+
export APP_DOMAIN=$(az containerapp env show \
100+
--resource-group <RESOURCE_GROUP> \
101+
--name <APP_ENVIRONMENT_NAME> \
102+
--query "properties.defaultDomain" \
103+
--output tsv \
104+
| tr -d '\r\n')
105+
106+
# Test the production FQDN
107+
curl -s https://$APP_NAME.$APP_DOMAIN
108+
109+
# Test the blue label FQDN
110+
curl -s https://$APP_NAME---blue.$APP_DOMAIN
111+
112+
# Test the green label FQDN
113+
curl -s https://$APP_NAME---green.$APP_DOMAIN
114+
```
115+
116+
## Send production traffic to the green revision
117+
118+
To switch production traffic to the green revision, use the following commands:
119+
120+
```azurecli
121+
# switch based on revision name
122+
az containerapp ingress traffic set \
123+
--resource-group <RESOURCE_GROUP> \
124+
--name <APP_NAME> \
125+
--revision-weight <BLUE_REVISION_NAME>=0 <GREEN_REVISION_NAME>=100
126+
127+
# switch based on label
128+
az containerapp ingress traffic set \
129+
--resource-group <RESOURCE_GROUP> \
130+
--name <APP_NAME> \
131+
--label-weight blue=0 green=100
132+
```
133+
134+
Ensure that the total label weight doesn't exceed 100.
135+
136+
Azure Container Apps not only enables you to switch traffic between blue-green deployments but also between multiple revisions. You can also redirect a specific amount of production traffic to the green deployment.
137+
138+
For more information about blue-green deployment in Azure Container Apps, see [Blue-Green Deployment in Azure Container Apps](../../container-apps/blue-green-deployment.md).
139+
140+
## Limitation
141+
142+
The Eureka Server isn't suitable for blue-green deployment because all revisions of the app are registered with the Eureka Server, preventing effective traffic splitting.
143+
144+
To enable traffic splitting when using Spring Cloud Gateway, you need to set the application URL in the URI field of your gateway configuration. You can obtain the application URL by using the following command:
145+
146+
```azurecli
147+
az containerapp show \
148+
--resource-group <RESOURCE_GROUP> \
149+
--name <APP_NAME> \
150+
--query "properties.configuration.ingress.fqdn" \
151+
--output tsv \
152+
| tr -d '\r\n'
153+
```
Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
---
2+
title: Integrate Application Performance Monitoring into Container Images
3+
description: Describes how to integrate application performance monitoring into container images.
4+
author: KarlErickson
5+
ms.author: dixue
6+
ms.service: azure-spring-apps
7+
ms.topic: upgrade-and-migration-article
8+
ms.date: 01/29/2025
9+
ms.custom: devx-track-java, devx-track-extended-java
10+
---
11+
12+
# Integrate application performance monitoring into container images
13+
14+
[!INCLUDE [deprecation-note](../includes/deprecation-note.md)]
15+
16+
**This article applies to:** ✅ Basic/Standard ✅ Enterprise
17+
18+
This article explains how to integrate the Application Insights Java agent into your container image. In a similar way, you can also integrate other application performance monitoring (APM) agents into your container image, including AppDynamics, New Relic, and Dynatrace.
19+
20+
Azure Spring Apps integrates smoothly with APM agents. When migrating applications to Azure Container Apps or Azure Kubernetes Service (AKS), you need to integrate with APM while building the image. The process is similar to the approach used by Azure Spring Apps. You can also add an APM agent in a separate init-container and inject it into a container app during its initialization.
21+
22+
## Prerequisites
23+
24+
- [Docker](https://docs.docker.com/get-docker/)
25+
- [Pack CLI](https://buildpacks.io/docs/for-platform-operators/how-to/integrate-ci/pack/)
26+
27+
## Choose the Application Insights Java agent
28+
29+
Azure Spring Apps currently uses Application Insights Java agent 3.5.2. You can choose another version depending on your needs. You can find all versions on the [Application Insights Java releases page](https://github.com/microsoft/ApplicationInsights-Java/releases).
30+
31+
You can find the Application Insights connection string in the Azure portal on the **Overview** pane of your Application Insights instance. This string is required for the instructions in this article.
32+
33+
There are some configuration options for Application Insights Java agent, such as sampling percentage and cloud role name. For more information, see [Configuration options of Application Insights for Java](/azure/azure-monitor/app/java-standalone-config).
34+
35+
If you're using a Dockerfile to build a container image, see the [Use Dockerfile](#use-dockerfile) section. If you're using Paketo Buildpacks to build a container image, see the [Use Paketo Buildpacks](#use-paketo-buildpacks) section.
36+
37+
## Use Dockerfile
38+
39+
Use the following steps to modify your Dockerfile:
40+
41+
1. Download the Application Insights Java agent and create a configuration file for it, called **applicationinsights.json**.
42+
1. Add the `-javaagent` option to the entry point of the container image.
43+
44+
To learn more about building JAR file or WAR file with a Dockerfile, see [Build a container image from a JAR or WAR](./migrate-to-azure-container-apps-build-artifacts.md).
45+
46+
### Build a JAR file
47+
48+
The following example Dockerfile builds a JAR file with the previous changes:
49+
50+
```dockerfile
51+
FROM mcr.microsoft.com/openjdk/jdk:17-mariner
52+
53+
ARG APP_INSIGHTS_VERSION
54+
ARG APP_INSIGHTS_CONNECTION_STRING
55+
ARG JAR_FILENAME
56+
57+
# Set up Application Insights agent
58+
ADD https://github.com/microsoft/ApplicationInsights-Java/releases/download/${APP_INSIGHTS_VERSION}/applicationinsights-agent-${APP_INSIGHTS_VERSION}.jar \
59+
/java-agent/applicationinsights-agent.jar
60+
RUN echo "{\"connectionString\": \"${APP_INSIGHTS_CONNECTION_STRING}\"}" > applicationinsights.json \
61+
&& mv applicationinsights.json /java-agent/applicationinsights.json
62+
63+
COPY $JAR_FILENAME /opt/app/app.jar
64+
65+
# Add -javaagent option
66+
ENTRYPOINT ["java", "-javaagent:/java-agent/applicationinsights-agent.jar", "-jar", "/opt/app/app.jar"]
67+
```
68+
69+
When you build a container image with this Dockerfile, you need to add build arguments using `--build-arg`, as shown in the following example:
70+
71+
```bash
72+
docker build -t <image-name>:<image-tag> \
73+
-f JAR.dockerfile \
74+
--build-arg APP_INSIGHTS_VERSION=3.5.2 \
75+
--build-arg APP_INSIGHTS_CONNECTION_STRING="<connection-string>" \
76+
--build-arg JAR_FILENAME=<path-to-jar> \
77+
.
78+
```
79+
80+
### Build a WAR file
81+
82+
The following example Dockerfile builds a WAR file with the previous changes:
83+
84+
```dockerfile
85+
FROM mcr.microsoft.com/openjdk/jdk:17-mariner
86+
87+
ARG TOMCAT_VERSION
88+
ARG TOMCAT_MAJOR_VERSION
89+
ARG APP_INSIGHTS_VERSION
90+
ARG APP_INSIGHTS_CONNECTION_STRING
91+
ARG WAR_FILENAME
92+
ARG TOMCAT_HOME=/opt/tomcat
93+
94+
# Set up Application Insights agent
95+
ADD https://github.com/microsoft/ApplicationInsights-Java/releases/download/${APP_INSIGHTS_VERSION}/applicationinsights-agent-${APP_INSIGHTS_VERSION}.jar \
96+
/java-agent/applicationinsights-agent.jar
97+
RUN echo "{\"connectionString\": \"${APP_INSIGHTS_CONNECTION_STRING}\"}" > applicationinsights.json \
98+
&& mv applicationinsights.json /java-agent/applicationinsights.json
99+
100+
# Set up Tomcat
101+
ADD https://archive.apache.org/dist/tomcat/tomcat-$TOMCAT_MAJOR_VERSION/v$TOMCAT_VERSION/bin/apache-tomcat-$TOMCAT_VERSION.tar.gz \
102+
$TOMCAT_HOME/apache-tomcat-$TOMCAT_VERSION.tar.gz
103+
RUN tdnf update -y \
104+
&& tdnf install -y tar \
105+
&& tar -zxf $TOMCAT_HOME/apache-tomcat-$TOMCAT_VERSION.tar.gz -C $TOMCAT_HOME --strip-components 1 \
106+
&& rm $TOMCAT_HOME/apache-tomcat-$TOMCAT_VERSION.tar.gz \
107+
&& rm -r $TOMCAT_HOME/webapps/*
108+
109+
COPY $WAR_FILENAME $TOMCAT_HOME/webapps/app.war
110+
111+
# Add the -javaagent option
112+
ENTRYPOINT ["/bin/sh", "-c" , "export CATALINA_OPTS=-javaagent:/java-agent/applicationinsights-agent.jar && /opt/tomcat/bin/catalina.sh run"]
113+
```
114+
115+
When you build a container image with this Dockerfile, you need to add build arguments using `--build-arg`, as shown in the following example:
116+
117+
```bash
118+
docker build -t <image-name>:<image-tag> \
119+
-f WAR.dockerfile \
120+
--build-arg APP_INSIGHTS_VERSION=3.5.2 \
121+
--build-arg APP_INSIGHTS_CONNECTION_STRING="<connection-string>" \
122+
--build-arg WAR_FILENAME=<path-to-war> \
123+
--build-arg TOMCAT_VERSION=<version> \
124+
--build-arg TOMCAT_MAJOR_VERSION=<major-version> \
125+
.
126+
```
127+
128+
### Integrate other application performance monitoring agents using Dockerfile
129+
130+
You can integrate other application performance monitoring (APM) agents in a similar way. The following list shows a few other APM agents, along with a brief description on how to integrate them. For download instructions, see the APM official documentation.
131+
132+
- Dynatrace
133+
- Download the Dynatrace agent in the Dockerfile.
134+
- Set the following environment variables at runtime:
135+
- `LD_PRELOAD=<path-to-agent>`
136+
- `DT_TENANT=<tenant>`
137+
- `DT_TENANTTOKEN=<token>`
138+
- `DT_CONNECTION_POINT=<connection-point>`
139+
- `DT_LOGLEVELCON=info`
140+
For more information, see [Set up OneAgent on containers for application-only monitoring](https://docs.dynatrace.com/docs/ingest-from/setup-on-container-platforms/docker/set-up-oneagent-on-containers-for-application-only-monitoring).
141+
- AppDynamics
142+
- Download the AppDynamics agent in the Dockerfile.
143+
- Add `-javaagent:<path-to-agent>` to the JVM options.
144+
- Set the required environment variables, including `APPDYNAMICS_AGENT_ACCOUNT_NAME`, `APPDYNAMICS_AGENT_ACCOUNT_ACCESS_KEY`, and so on, at runtime. For a complete list of configuration properties, see [AppDynamics Java Agent Configuration Properties](https://docs.appdynamics.com/appd/23.x/latest/en/application-monitoring/install-app-server-agents/java-agent/administer-the-java-agent/java-agent-configuration-properties).
145+
- New Relic
146+
- Download the New Relic agent in the Dockerfile. If you have a New Relic Java agent config file, copy it from local machine to your container. For more information about config files, see [Java agent configuration: Config file](https://docs.newrelic.com/docs/apm/agents/java-agent/configuration/java-agent-configuration-config-file/).
147+
- Add `-javaagent:<path-to-agent>` to the JVM options.
148+
- Set the environment variables `NEW_RELIC_LICENSE_KEY=<license-key>` and `NEW_RELIC_APP_NAME=<app-name>` at runtime, if you haven't set them in a config file or you want to override the values in a config file.
149+
150+
There's another approach to integrate an APM agent, which is to prebuild a container image for the APM agent and run it as an init container. For more information about this approach, see [Tutorial: Configure the Application Performance Management (APM) Java agent with init containers in Azure Container Apps](../../container-apps/java-application-performance-management-config.md).
151+
152+
## Use Paketo Buildpacks
153+
154+
To integrate the Application Insights agent in your container image, you need a binding. For more information about bindings, see [Bindings](https://paketo.io/docs/howto/configuration/#bindings) in the Paketo documentation.
155+
156+
First, use the following commands to create a binding named **application-insights** in the **bindings** directory on your local machine. The binding consists of only one file, named **type**. The content of the **type** file is the text `ApplicationInsights`, indicating an Application Insights binding.
157+
158+
```bash
159+
mkdir -p bindings/application-insights
160+
echo "ApplicationInsights" > bindings/application-insights/type
161+
```
162+
163+
The following diagram shows the directory structure:
164+
165+
```
166+
bindings
167+
└── application-insights
168+
└── type
169+
```
170+
171+
Then, use the following command to build the image. Provide the binding to your build by using the `--volume` option. The pack CLI mounts the binding directory into the build container. Then, the Application Insights buildpack detects it and participates in the build process.
172+
173+
```bash
174+
pack build <image-name>:<image-tag> \
175+
--volume $(pwd)/bindings/application-insights:/platform/bindings/application-insights" \
176+
--path <path-to-source-root> \
177+
--builder <builder-name>
178+
```
179+
180+
To deploy the container image in an Azure Container Apps environment, you can use the Azure CLI. For more information, see [Deploy Azure Container Apps with the az containerapp up command](../../container-apps/containerapp-up.md). There are two approaches to pass the Application Insights connection string to the Application Insights agent at runtime. One approach is to pass the connection string as an environment variable. For more information, see the [Configure with environment variables](#configure-with-environment-variables) section. The other approach is to pass the connection string via bindings. For more information, see the [Configure with Bindings](#configure-with-bindings) section.
181+
182+
### Configure with environment variables
183+
184+
To pass a connection string to Application Insights, specify `APPLICATIONINSIGHTS_CONNECTION_STRING` in the `--env-vars` option, as shown in the following example. You can specify other environment variables if you want to pass more configuration options to the agent.
185+
186+
```azurecli
187+
az containerapp up \
188+
--name <container-app-name> \
189+
--image <image-name>:<image-tag> \
190+
--resource-group <resource-group> \
191+
--environment <environment-name> \
192+
--location <location> \
193+
--env-vars "APPLICATIONINSIGHTS_CONNECTION_STRING=<connection-string>"
194+
```
195+
196+
### Configure with bindings
197+
198+
To configure the Application Insights agent with bindings, you can store the Application Insights connection string, binding type, and any other configurations as secrets in your container app. Mount the secrets in a volume so that the Application Insights buildpack can read them at runtime.
199+
200+
With the following command, you declare two secrets at the application level: `type` and `connection-string`. They're mounted to **/bindings/application-insights** in the container. The buildpack searches for bindings in the **/bindings** directory because the `SERVICE_BINDING_ROOT` environment variable is set.
201+
202+
```azurecli
203+
az containerapp create \
204+
--name <container-app-name> \
205+
--image <image-name>:<image-tag> \
206+
--resource-group <resource-group> \
207+
--environment <environment-name> \
208+
--secrets "type=ApplicationInsights" "connection-string=<connection-string>" \
209+
--secret-volume-mount "/bindings/application-insights" \
210+
--env-vars "SERVICE_BINDING_ROOT=/bindings"
211+
```
212+
213+
Alternatively, you can store the connection string in Azure Key Vault and reference it in secrets. For more information, see [Manage secrets in Azure Container Apps](../../container-apps/manage-secrets.md).
214+
215+
To deploy the container image to Azure Kubernetes Service, see [How to use buildpacks in Kubernetes for Java](https://github.com/paketo-buildpacks/azure-application-insights/blob/main/docs/how-to-use-buildpacks-in-kubernetes-for-java.md#runtime-phase).
216+
217+
### Integrate other application performance monitoring agents using Paketo Buildpacks
218+
219+
There are buildpacks for various APM agents, including the following agents. For more information about binding setup and configurations, see the documentation for each agent.
220+
221+
- [Dynatrace](https://github.com/paketo-buildpacks/dynatrace)
222+
- [AppDynamics](https://github.com/paketo-buildpacks/appdynamics)
223+
- [New Relic](https://github.com/paketo-buildpacks/new-relic)

0 commit comments

Comments
 (0)