|
| 1 | +# Migrate Spring Cloud Gateway for Tanzu to self-hosted gateway application in Azure Container Apps |
| 2 | + |
| 3 | +[!INCLUDE [deprecation-note](../includes/deprecation-note.md)] |
| 4 | + |
| 5 | +**This article applies to:** ❎ Basic/Standard ✅ Enterprise |
| 6 | + |
| 7 | +This article shows you how to migrate Spring Cloud Gateway for Tanzu in Azure Spring Apps Enterprise plan to self-hosted Open Source Spring Cloud Gateway (OSS Gateway) running as an Azure Container Apps application. |
| 8 | + |
| 9 | +## Prerequisites |
| 10 | + |
| 11 | +- An Azure Spring Apps Enterprise plan instance with Spring Cloud Gateway enabled. |
| 12 | +- An Azure Container Apps. For more information, see [Quickstart: Deploy your first container app using the Azure portal](../../container-apps/quickstart-portal.md). |
| 13 | +- [Azure CLI](/cli/azure/install-azure-cli). |
| 14 | +- An Azure Container Registry with sufficient permissions to build and push Docker images, see [Create A Container Registry](../../container-registry/container-registry-get-started-azure-cli#create-a-container-registry) |
| 15 | + |
| 16 | +## Prepare the code of self-hosted OSS Gateway application |
| 17 | + |
| 18 | +To get the code of the OSS Gateway: |
| 19 | +1. Navigate to https://start.spring.io. |
| 20 | +1. Update the project metadata by setting the `Group` to your orgnization's name. Change the `Artifact` and `Name` to `gateway`. |
| 21 | +1. Add dependencies `Reactive Gateway` and `Spring Boot Actuator`. |
| 22 | +1. Leave the other properties at their default values. |
| 23 | +1. Click `Generate` to download the project. |
| 24 | + |
| 25 | +Extract the project when it's downloaded. |
| 26 | + |
| 27 | +## Configure the OSS Gateway |
| 28 | +Once the OSS Gateway code is ready, navigate to the `gateway/src/main/resources` directory of the project. Rename the `application.properties` file with `application.yml`. You can migrate from Spring Cloud Gateway for Tanzu by configuring the `application.yml`. |
| 29 | + |
| 30 | +The example of `application.yml` is like: |
| 31 | + |
| 32 | +```yaml |
| 33 | +spring: |
| 34 | + application: |
| 35 | + name: gateway |
| 36 | + cloud: |
| 37 | + gateway: |
| 38 | + globalcors: |
| 39 | + corsConfigurations: |
| 40 | + '[/**]': |
| 41 | + allowedOriginPatterns: "*" |
| 42 | + allowedMethods: |
| 43 | + - GET |
| 44 | + - POST |
| 45 | + - PUT |
| 46 | + - DELETE |
| 47 | + allowedHeaders: |
| 48 | + - "*" |
| 49 | + allowCredentials: true |
| 50 | + maxAge: 3600 |
| 51 | + routes: |
| 52 | + - id: front |
| 53 | + uri: http://front-app |
| 54 | + predicates: |
| 55 | + - Path=/** |
| 56 | + - Method=GET |
| 57 | + order: 1000 |
| 58 | + filters: |
| 59 | + - StripPrefix=0 |
| 60 | + tags: |
| 61 | + - front |
| 62 | +``` |
| 63 | +
|
| 64 | +### CORS configuration |
| 65 | +
|
| 66 | +To migrate the Cross-Origin Resource Sharing (CORS) configuration of Spring Cloud Gateway for Tanzu, you can refer to [CORS Configuration for OSS Gateway](https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#cors-configuration) for global CORS configuration and route CORS configuration. |
| 67 | +
|
| 68 | +### Scale |
| 69 | +When migrating to OSS Gateway application in Azure Container Apps, the scaling behavior should align with Azure Container Apps' model. The instance count from Spring Cloud Gateway for Tanzu maps to `min-replica` and `max-replica` in Azure Container Apps. You can configure automatic scaling for the gateway application by defining scaling rules. For more details, refer to [Set scaling rules in Azure Container Apps](../../container-apps/scale-app). |
| 70 | + |
| 71 | +The CPU and memory combinations available in Azure Spring Apps may differ from those in Azure Container Apps. When mapping resource allocations, ensure that the selected CPU and memory configurations in Azure Container Apps fit both performance needs and supported options. |
| 72 | + |
| 73 | +### Custom domain & certificates |
| 74 | +Azure Container Apps supports custom domains and certificates, you can refer to [Domains & certificates](../../container-apps/certificates-overview) to migrate custom domains configured on Spring Cloud Gateway for Tanzu. |
| 75 | + |
| 76 | +### Routes |
| 77 | + |
| 78 | +You can migrate the routes in Spring Cloud Gatewy for Tanzu to OSS Gateway as the example of `application.yml` shows. The following list describes the mapping relationship between routes of Spring Cloud Gateway for Tanzu and routes of OSS Gateway: |
| 79 | + |
| 80 | +- The `name` of the route is mapped to `id`. |
| 81 | +- The `appName` and `protocol` are mapped to the URI of the route, which should be the accessible URI for the Azure Container Apps instance, make sure that the Azure Container Apps applications enable the ingress. |
| 82 | +- Predicates and filters of Spring Cloud Gateway for Tanzu are mapped to that of OSS Gateway. Commercial predicates and filters are not supported, refer to [the document](https://techdocs.broadcom.com/us/en/vmware-tanzu/spring/spring-cloud-gateway-for-kubernetes/2-2/scg-k8s/developer-filters.html) for more details. |
| 83 | + |
| 84 | +For example, consider the following route config JSON file, `test-api.json`, which defines the `test-api` route in Spring Cloud Gateway for Tanzu for the `test` app: |
| 85 | + |
| 86 | +```json |
| 87 | +{ |
| 88 | + "protocol": "HTTP", |
| 89 | + "routes": [ |
| 90 | + { |
| 91 | + "title": "Test API", |
| 92 | + "predicates": [ |
| 93 | + "Path=/test/api/healthcheck", |
| 94 | + "Method=GET" |
| 95 | + ], |
| 96 | + "filters": [ |
| 97 | + "AddRequestHeader=X-Request-red, blue" |
| 98 | + ] |
| 99 | + } |
| 100 | + ] |
| 101 | +} |
| 102 | +``` |
| 103 | + |
| 104 | +Then, the following yaml shows the corresponding route configuration for OSS Gateway: |
| 105 | + |
| 106 | +```yaml |
| 107 | +spring: |
| 108 | + cloud: |
| 109 | + gateway: |
| 110 | + routes: |
| 111 | + - id: test-api |
| 112 | + uri: http://test |
| 113 | + predicates: |
| 114 | + - Path=/test/api/healthcheck |
| 115 | + - Method=GET |
| 116 | + filters: |
| 117 | + - AddRequestHeader=X-Request-red, blue |
| 118 | + - StripPrefix=1 |
| 119 | +``` |
| 120 | + |
| 121 | +Spring Cloud Gateway for Tanzu sets `StripPrefix=1` by default on every route. To migrate to OSS Gateway, you need to explicitly set `StripPrefix=1` in the filter configuration. |
| 122 | + |
| 123 | +To allow your OSS Gateway application to access other applications through the app name, you need to enable ingress for your Azure Container App applications. You can also use for the accessible FQDN of Azure Container Apps application as the uri of the route, following the format: `https://<app-name>.<container-app-env-name>.<region>.azurecontainerapps.io`. |
| 124 | + |
| 125 | +There are some [commercial predicates](https://docs.vmware.com/en/VMware-Spring-Cloud-Gateway-for-Kubernetes/2.2/scg-k8s/GUID-guides-predicates.html) and [commercial filters](https://docs.vmware.com/en/VMware-Spring-Cloud-Gateway-for-Kubernetes/2.2/scg-k8s/GUID-guides-filters.html) that aren't supported on OSS Gateway. |
| 126 | + |
| 127 | +### Response cache |
| 128 | + |
| 129 | +If you enable the response cache globally in Spring Cloud Gateway for Tanzu, use the following configuration in OSS Gateway and see [local cache response global filter](https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#local-cache-response-global-filter) for more details: |
| 130 | +```yaml |
| 131 | +spring: |
| 132 | + cloud: |
| 133 | + gateway: |
| 134 | + filter: |
| 135 | + local-response-cache: |
| 136 | + enabled: true |
| 137 | + time-to-live: <response-cache-ttl> |
| 138 | + size: <response-cache-size> |
| 139 | +``` |
| 140 | + |
| 141 | +If you enable the response cache for the route, you can use the [`LocalResponseCache`](https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#local-cache-response-filter) filter in the routing rule configuration of managed Gateway for Spring as the following YAML: |
| 142 | + |
| 143 | +```yaml |
| 144 | +spring: |
| 145 | + cloud: |
| 146 | + gateway: |
| 147 | + routes: |
| 148 | + - id: test-api |
| 149 | + uri: http://test |
| 150 | + predicates: |
| 151 | + - Path=/resource |
| 152 | + filters: |
| 153 | + - LocalResponseCache=30m,500MB |
| 154 | +``` |
| 155 | + |
| 156 | +### Integrate with APM |
| 157 | + |
| 158 | +To enable application performance monitoring (APM) for OSS Gateway application, refer to [Integrate application performance monitoring into container images](./migrate-to-azure-container-apps-build-application-performance-monitoring.md). |
| 159 | + |
| 160 | +## Deploy to Azure Continer Apps |
| 161 | + |
| 162 | +Once the OSS Gateway configuration is ready, build the image using Azure Container Registry and deploy it to Azure Container Apps. |
| 163 | + |
| 164 | +### Build and Push the Docker Image |
| 165 | + |
| 166 | +In the OSS Gateway project directory, create a `Dockerfile` with the following contents: |
| 167 | + |
| 168 | +```dockerfile |
| 169 | +FROM mcr.microsoft.com/openjdk/jdk:17-mariner as build |
| 170 | +WORKDIR /staging |
| 171 | +# Install gradle |
| 172 | +RUN tdnf install -y wget unzip |
| 173 | +
|
| 174 | +RUN wget https://services.gradle.org/distributions/gradle-8.8-bin.zip && \ |
| 175 | + unzip -d /opt/gradle gradle-8.8-bin.zip && \ |
| 176 | + chmod +x /opt/gradle/gradle-8.8/bin/gradle |
| 177 | +
|
| 178 | +ENV GRADLE_HOME=/opt/gradle/gradle-8.8 |
| 179 | +ENV PATH=$PATH:$GRADLE_HOME/bin |
| 180 | +
|
| 181 | +COPY . . |
| 182 | +
|
| 183 | +# Compile with gradle |
| 184 | +RUN gradle build -x test |
| 185 | +
|
| 186 | +FROM mcr.microsoft.com/openjdk/jdk:17-mariner as runtime |
| 187 | +
|
| 188 | +WORKDIR /app |
| 189 | +
|
| 190 | +COPY --from=build /staging/build/libs/gateway-0.0.1-SNAPSHOT.jar . |
| 191 | +
|
| 192 | +ENTRYPOINT ["java", "-jar", "gateway-0.0.1-SNAPSHOT.jar"] |
| 193 | +``` |
| 194 | + |
| 195 | +Alternatively, you can refer to the sample [Dockerfile](https://github.com/Azure-Samples/acme-fitness-store/blob/Azure/azure-kubernetes-service/resources/gateway/gateway/Dockerfile) for guidance. |
| 196 | + |
| 197 | +Run the following command to build the image of gateway using your Azure Container Registry: |
| 198 | + |
| 199 | +```azurecli |
| 200 | +az acr login --name <azure-container-registry-name> |
| 201 | +az acr build --image gateway:acrbuild-spring-cloud-gateway-0.0.1-SNAPSHOT --registry <azure-container-registry-name> --file Dockerfile . --resource-group <resource-group-name> |
| 202 | +``` |
| 203 | + |
| 204 | +Ensure the gateway image is created and get the image tag, which follows the format: `<azure-container-registry-name>.azurecr.io/gateway:acrbuild-spring-cloud-gateway-0.0.1-SNAPSHOT`. |
| 205 | + |
| 206 | +### Deploy the image in Azure Container Apps |
| 207 | + |
| 208 | +Once your gateway application image is ready, deploy it as an Azure Container Apps application `gateway`. Replace the <container-image-of-gateway> with the image tag retrieved in the previous step: |
| 209 | + |
| 210 | +```azurecli |
| 211 | +az containerapp up \ |
| 212 | + --name gateway \ |
| 213 | + --resource-group <resource-group-name> \ |
| 214 | + --environment <azure-container-app-environment-name> \ |
| 215 | + --image <container-image-of-gateway> \ |
| 216 | + --target-port 8080 \ |
| 217 | + --ingress external |
| 218 | +``` |
| 219 | + |
| 220 | +Access the FQDN of the OSS Gateway application to verify that it is running. |
| 221 | + |
| 222 | +## Troubleshooting |
| 223 | + |
| 224 | +If you encounter issues when running the OSS Gateway application, you can view real time and historical logs of the application `gateway` in Azure Container Apps following [Application Logging in Azure Container Apps](../../container-apps/logging). |
| 225 | + |
| 226 | +To monitor gateway application's metrics, refer to [Monitor Azure Container Apps metrics](../../container-apps/metrics) |
| 227 | + |
| 228 | +## Known limitation |
| 229 | +OSS Gateway does not support the following commercial features: |
| 230 | +- Metadata used to generate OpenAPI documentation |
| 231 | +- Single sign-on (SSO) functionality |
0 commit comments