microsoft / azure-container-apps

Roadmap and issues for Azure Container Apps
MIT License
356 stars 27 forks source link

Roadmap: URL Based Routing #591

Open SophCarp opened 1 year ago

SophCarp commented 1 year ago

ETA: Public Preview Q4 2023 - Q1 2024

LynnAU commented 11 months ago

Is there any update on this?

Also how is this url based routing proposed to work? Would I be able to use a single entrypoint/domain and route the incoming requests to other container apps similar to application gateway/front door?

goldsam commented 11 months ago

It's now August. Can you please provide an update on this?

waynebrantley commented 11 months ago

When thinking about URL based routing - the destination needs to be a container OR the DAPR sidecar.

For example - if I have a few dapr services that live in the application environment, I would be able to communicate to them (from inside the environment) with /v1.0/invoke/theappid/method/ping.

If I wanted to be able to also map /api2/ to these dapr services from the outside, what I would currently have to do is create YARP container that simply proxies from /api2/ to http://localhost:3500//invoke/theappid/method/*

This would end up with the built in Envoy proxy doing a proxy to my container proxy that just sends to the DAPR sidecar.

So it would be nice when create url based routing that not only can I map URLs to different containers, I would be able to map URLs to the 'sidecar'. That avoids having an additional proxy and the management of that.

Any thoughts?

mortenf1984 commented 10 months ago

Any new information on this? It states end of June but now it is start of September

cachai2 commented 10 months ago

Hi folks, apologies for the delay on updating this, and thank you for your patience. The feature has been delayed on our side. We are targeting later this calendar year. In the meantime, if you have specific scenarios and requirements for the feature that you can share, that would be great so we can take them into consideration. How are you handling path-based routing today? Do you need rewrite rules? Would you prefer to have a centralized hub to configure routing or handle routing at an individual app level?

In the meantime, there are several alternative options: 1) Integrate with Application Gateway or Azure Front Door for routing 2) Configure a container app within your environment with a nginx image. This container app can then route the traffic to the appropriate destinations within your environment. A bicep example of how to do this is here: https://github.com/ahmelsayed/bicep-templates/tree/main/apps/routers/nginx

hoijnet commented 9 months ago

Unsure if this will help with having a route preference to specific containers based on paths, and was thinking of a workaround meanwhile.

So I made a write-up with a workaround until released, by using the cookie-based session affinity as a somewhat clunky but hopefully working workaround, with a reverse proxy in front and using session-based affinity in a custom way. The full write-up is here: https://hoijnet.medium.com/routing-based-load-balancing-key-with-azure-container-apps-cookie-based-session-affinity-f977d34ead6a

It seems to do what I want and I'm building a solution on my own based on the described findings. Unsure if this is a stable way of using the cookie, but hope it works long enough until the URL based routing is released.

Hope it helps someone! And, looking forward to the release of this feature!

cachai2 commented 3 months ago

Hi folks, we've recently released a blog post on how path-based routing can be achieved in Azure Container Apps today by using an nginx container as a reverse proxy. Would love to hear your feedback if this covers your scenarios and if not what is missing from the experience and what you would like to see.

Blog post: Path and hostname-based routing in Azure Container Apps with NGINX

raix commented 3 months ago

@SophCarp is the ETA still on track? - looking forwards to more insights / preview 🥹

goldsam commented 3 months ago

@cachai2 I commented on the blog post as well, but the proposed solution fails to address scaling or resiliency. The proposed solution in the blog post is useless in a production environment.

tjementum commented 3 months ago

@cachai2 I fear this comment is a sign that you are considering not doing this 😱

I agree with @goldsam. This is not the solution for this problem we need. ACA is supposed to be simple, and this should be configurable in the Portal and Bicep.

I just want to take my Docker images and deploy them. I don't want to learn about anything with Linux like NGINX and nginx.conf, let alone have an extra storage account to store configuration. This is way too complex. And I fear I have to learn NGINX to troubleshoot how to e.g. make sure the correct HTTP headers are forwarded (e.g., the location of the browser), or something completely different.

Not to mention that I now have another container that I need to scale as a host. This needs to be always on, and in our case, it will double the price of ACA, as this needs to be always on (currently we have only one Container App that is always on for fast replies, and the rest scale to 0).

Here is one big vote for you to build this in natively to the ACA, with configuration directly in the Portal.

mortenf1984 commented 3 months ago

I also agree with @tjementum and @goldsam, being able to do this through portal or BICEP is really important, as each container in our environment is responsible for its own routing, so being able to do this via deployment is crucial for us.

For how the deployment will work, I would think in similar ways as routes in Azure FrontDoor, where you can deploy each routing by it self, not like ApplicationGateway where you need to redeploy the whole AppGW for any changes.

As a workaround, we have created a .Net YARP container, that is retrieving the configuration from Azure App Configuration, so we can dynamically update the configuration, but as Tjementum said, this requires a special knowledge and development to get to work, and not a long term viable solution.

nikneem commented 3 months ago

For how the deployment will work, I would think in similar ways as routes in Azure FrontDoor, where you can deploy each routing by it self, not like ApplicationGateway where you need to redeploy the whole AppGW for any changes.

I completely second this, the suggestion to move to App Gateway only works in a dynamic was (properly) when you route that traffic to API Management and do the reverse proxy job from there on.

So for now you should stick with either (costly) API Management or create a proxy youself with NGINX like Cary mentioned above, or with YARP, I have written a blog about this here: https://hexmaster.nl/posts/proxying-azure-container-apps-with-yarp/

raix commented 3 months ago

@cachai2 regarding using nginx - Would it be registered as ingress controller or would that require AKS/k8s? (Also seems like a blob storage is required instead of using config maps?)

@SophCarp Is container apps only ment for BFF/proxy architectures or will it have more configuration of ingress?

nikneem commented 3 months ago

@raix Container apps runs k8s under the hood. It is designed to run microservices architectures and event-driven systems without having to have the in-depth knowledge of k8s. So ACA is an abstraction layer on top of k8s, to make it easier to get up and running with the orchestration of containers.

About the nginx solution, there are multiple ways to control ingress into your ACA containers. For convenience, you generally want one container to be in control of incoming traffic, and route that traffic to the appropriate service. This is sometimes referred to as a gateway proxy, or reverse proxy. Both nginx and yarp are reverse proxy solutions that will help you simplify calling services from the outside world. Both solutions will run as a separate container (App) in your ACA environment.

raix commented 3 months ago

@nikneem The suggested nginx solution is clearly a workaround, not something I would recommend using in production. Last time I checked there was already an ingress controller "AppVeyor" under the hood, will be awaiting an official direction on this.

alanta commented 3 months ago

@raix I think you mean Envoy not "AppVeyor"? Envoy is a very capable reverse proxy so it's totally possible to have that handle url based routing, but we can't get to it (yet).

@cachai2 I would like to see configuration on the app environment level, where I can add a domain name and TLS cert and then declare rules for what path is directed to what backend container (or DAPR sidecar). Rewriting would be nice to have, but not essential imo.

cachai2 commented 3 months ago

Hi folks, thank you for all the feedback. Currently, this feature has been deprioritized as there are alternative solutions through NGINX or using another reverse proxy such as App Gateway. I'd love to discuss more and understand your scenarios/concerns though to see if we need to reprioritize. I'm also happy to discuss in-depth if anyone wants to hop on a call, feel free to reach out to me on linkedin or at cachai [at] microsoft [dot] com. Addressing comments below.

@cachai2 I commented on the blog post as well, but the proposed solution fails to address scaling or resiliency. The proposed solution in the blog post is useless in a production environment.

@goldsam can you specify in which ways it fails to address scaling and resiliency? The container that is running NGINX will still support the feature set of ACA such as serverless scaling.

@cachai2 I fear this comment is a sign that you are considering not doing this 😱

I agree with @goldsam. This is not the solution for this problem we need. ACA is supposed to be simple, and this should be configurable in the Portal and Bicep.

I just want to take my Docker images and deploy them. I don't want to learn about anything with Linux like NGINX and nginx.conf, let alone have an extra storage account to store configuration. This is way too complex. And I fear I have to learn NGINX to troubleshoot how to e.g. make sure the correct HTTP headers are forwarded (e.g., the location of the browser), or something completely different.

Not to mention that I now have another container that I need to scale as a host. This needs to be always on, and in our case, it will double the price of ACA, as this needs to be always on (currently we have only one Container App that is always on for fast replies, and the rest scale to 0).

Here is one big vote for you to build this in natively to the ACA, with configuration directly in the Portal.

@tjementum I agree with your viewpoint that ACA should be simple and understand the tradeoffs you outlined for using NGINX as a solution. However, aside from NGINX, there are also additional ways to do routing in Azure today. Are Azure Application Gateway, Azure Front Door, or APIM viable solutions for path/header based routing for you today, or do you see gaps in the experience that make integrating with these other reverse proxies a blocker? Is it largely a question of cost? I am curious, how are you handling your routing currently?

I also agree with @tjementum and @goldsam, being able to do this through portal or BICEP is really important, as each container in our environment is responsible for its own routing, so being able to do this via deployment is crucial for us.

For how the deployment will work, I would think in similar ways as routes in Azure FrontDoor, where you can deploy each routing by it self, not like ApplicationGateway where you need to redeploy the whole AppGW for any changes.

As a workaround, we have created a .Net YARP container, that is retrieving the configuration from Azure App Configuration, so we can dynamically update the configuration, but as Tjementum said, this requires a special knowledge and development to get to work, and not a long term viable solution.

@mortenf1984 When using another reverse proxy service like App Gateway, you can configure routing through portal or BICEP. Is there a reason App Gateway and Azure FrontDoor I understand the extra special knowledge and development to get the .NET YARP container working, but can you help me understand why it's not a long-term viable solution?

@nikneem The suggested nginx solution is clearly a workaround, not something I would recommend using in production. Last time I checked there was already an ingress controller "AppVeyor" under the hood, will be awaiting an official direction on this.

@raix We do have multiple large enterprise customers following the NGINX pattern to route their ingress traffic in production which is why we put together the blog post on how to implement it as an alternative to other reverse proxies to handle routing. Azure Container Apps runs Envoy not AppVeyor under the hood.

@cachai2 I would like to see configuration on the app environment level, where I can add a domain name and TLS cert and then declare rules for what path is directed to what backend container (or DAPR sidecar). Rewriting would be nice to have, but not essential imo.

@alanta Thank you for the feedback. Will definitely take this as feedback for feature designs if we're able to get the feature prioritized.

Thank you @nikneem for providing some additional context in the thread.

raix commented 3 months ago

We do have multiple large enterprise customers following the NGINX pattern to route their ingress traffic in production which is why we put together the blog post on how to implement it as an alternative to other reverse proxies to handle routing. Azure Container Apps runs Envoy not AppVeyor under the hood.

@cachai2 Mobile spelling is not ideal - same goes for the suggested solution by not leveraging Envoy. I'm surprised to hear that any enterprise customer are doing this - tbh. that should be enough for the Microsoft team to prioritize this?

Adding extra redundant infrastructure instead of leveraging the one already there. There's additional cost/waste both money wise / complexity and environmental / CO2 etc. Having to maintain and scale nginx and a blob storage for configuration seems to be somewhat of a workaround - it feels like going against the promise of have an easy way to work with containers vs. using k8s.

That said, it's nice to finally know the direction container apps are moving ❤️ it makes decision making much easier.

mortenf1984 commented 3 months ago

@cachai2 I see your response and see you mention Frontdoor, but that is not a option as #867 is still not fixed and no date on when it will be available. Also in large environments with a lot of containers and routes, the limitations of FrontDoor can easily be reached, making it a less than ideal solution anyway for URL based routing.

As for Application Gateway, it does not support update of a single route, but only the whole AppGW meaning that we need to stagger all the deployments to be able to use AppGW in this way, and that is not possible for us, which is also the reason I stated that we need to be able to update in the same way as we can with FrontDoor where all portions can be deployed separately.

Above mentioned reason is also the reason we cannot use NGINX and created our own YARP, the dynamic update is crucial and option to update routes and endpoints parallel

For us, this is important that we get.

tjementum commented 3 months ago

I am curious, how are you handling your routing currently?

We have been waiting for you to deliver on the mentioned ETA of this feature, so currently, we are running a monolith (one primary container without routing). We want to split our monolith into 2 self-contained systems (aka. microservices).

Are Azure Application Gateway, Azure Front Door, or APIM viable solutions for path/header based routing for you today, or do you see gaps in the experience that make integrating with these other reverse proxies a blocker?

My main problem is complexity. I don't want to take upon a new technology just to do routing, if this can be avoided. As a .NET developer with no experience with Linux, I don't like the proposed solution. Hosting NGINX is not trivial, and having an extra storage account just to store a configuration file feels hacky. ACA is about getting the power of AKS and the simplicity of Web Apps/PaaS. Looking at your Roadmap this feature seems to be the only one that everyone would need and benefit from. And I would say this is a core feature of any orchestration offering like ACA.

Is it largely a question of cost?

As far as I can tell Application Gateway is ~$6 per day! I don't know if you realize, but ACA is likely the cheapest way to host an application in Azure with a domain. We host an always-on solution with ACA (0.25 CPU scale to 1), KeyVault, Service Bus, SQL Database, Blob Storage, Azure Communication Service (Email), Container Registry, and Application Insights for less than $1 per day!!! This makes it possible for us to have a feature environment per pull-request, staging, a developer environment per developer. For a pricing point of view Application Gateway and Front Door are not good alternatives.

This is our spending for the staging environment last month (the first 180,000 vCPU seconds/8.33 days are free).

CleanShot 2024-03-21 at 12 50 44@2x

quality-leftovers commented 2 months ago

@cachai2

The nice thing about ACA is the low management overhead and not having to manage the ingress reverse proxy.

If one needs to set up a complex system to get path based routing I wonder what's the point of using ACA over kubernetes when one needs URL based routing.

In Kubernetes I can define the path based routing in my application spec / helm charts, I can also run my applications locally or move services with few dependencies easily to other cloud providers if needed.

I was pretty sure we'd be getting this feature since the issue here was created by Microsoft and even mentions an ETA.

m-soltani commented 1 week ago

I'd like to share my experience dealing with this issue. Working with NGINX has been extremely challenging for someone with little to no knowledge of its internals or reverse proxy configuration. While setting up my ACA infrastructure took only two hours, I spent two days troubleshooting various NGINX routing issues, including headers, proxy versions, routing rules, and proxy buffers. After two days of frustration, I ultimately gave up and decided to write my own YARP proxy server.

Throughout this process, I kept questioning why I was dealing with these complications. Application Gateways and similar tools add unnecessary management overheads, which ideally should be avoided.

Please consider adding native routing solution to ACA.

tjementum commented 1 week ago

I also ended up using YARP as a reverse proxy, and I must say I’m extremely happy.

My setup is available as an open-source template called PlatformPlatform which you should be able to check out and run in a few minutes and get up and running in production by running one CLI command. It showcases how to use Azure Container Apps and other Azure Services together with a full GitHub SDLC, multi environment (staging, production), multi-language, and 2 self-contained systems (big microservices with API and background workers) with a React frontend.

Using YARP as a reverse proxy, I’m able to get my local infrastructure running (using .NET Aspire) with the exact same configuration as in production. And YARP is just extremely powerful, as I’m able to rewrite incoming and outgoing headers/cookies with plain .NET.

As I wrote above, I was very disappointed that the Azure Container Apps team did not prioritize path-based routes, but now I’m very happy that I was forced to look into this.

CleanShot 2024-06-24 at 15 08 14 CleanShot 2024-06-24 at 15 10 38

m-soltani commented 1 week ago

I also ended up using YARP as a reverse proxy, and I must say I’m extremely happy.

My setup is available as an open-source template called PlatformPlatform which you should be able to check out and run in a few minutes and get up and running in production by running one CLI command. It showcases how to use Azure Container Apps and other Azure Services together with a full GitHub SDLC, multi environment (staging, production), multi-language, and 2 self-contained systems (big microservices with API and background workers) with a React frontend.

Using YARP as a reverse proxy, I’m able to get my local infrastructure running (using .NET Aspire) with the exact same configuration as in production. And YARP is just extremely powerful, as I’m able to rewrite incoming and outgoing headers/cookies with plain .NET.

As I wrote above, I was very disappointed that the Azure Container Apps team did not prioritize path-based routes, but now I’m very happy that I was forced to look into this.

CleanShot 2024-06-24 at 15 08 14 CleanShot 2024-06-24 at 15 10 38

Happy to hear that YARP is working well in this setup. I am a new user of YARP and with feedbacks that I see, we are not going to be disappointed using this as our API gateway. I am going to open source our solutions as well (It's fully Bicep - SQL, Redis, ACA, KeyVault, ACR).

I am assuming something like ALB Controller in Application Gateway for Containers can be implemented for ACA as well. The ALB controller might help ACA internals to create and update Routing rules automatically. Anyways we are fine at this stage. I know YARP is being used in Azure App Services and this gives us confidence about our decision as well.