We've got an API micro-services infrastructure hosted on Azure VMs. Each VM will host several APIs which are separate sites running on Kestrel. All external traffic comes in through an RP (running on IIS).
We have some API's that are designed to accept external requests and some that are internal APIs only.
The internal APIs are hosted on scalesets with each scaleset VM being a replica that hosts all of the internal APIs. There is an internal load balancer(ILB)/vip in front of the scaleset. The root issue is that we have internal APIs that call other internal APIs that are hosted on the same scaleset. Ideally these calls would go to the VIP (using internal DNS) and the VIP would route to one of the machines in the scaleset. But it looks like Azure doesn't allow this...per the documentation:
You cannot access the ILB VIP from the same Virtual Machines that are being load-balanced
So how do people set this up with micro-services? I can see three ways, none of which are ideal:
Separate out the APIs to different scalesets. Not ideal as the
services are very lightweight and I don't want to triple my Azure VM
expenses.
Convert the internal LB to an external LB (add a public
IP address). Then put that LB in it's own network security
group/subnet to only allow calls from our Azure IP range. I would
expect more latency here and exposing the endpoints externally in
any way creates more attack surface area as well as more
configuration complexity.
Set up the VM to loopback if it needs a call to the ILB...meaning any requests originating from a VM will be
handled by the same VM. This defeats the purpose of micro-services
behind a VIP. An internal micro-service may be down on the same
machine for some reason and available on another...thats' the reason
we set up health probes on the ILB for each service separately. If
it just goes back to the same machine, you lose resiliency.
Any pointers on how others have approached this would be appreciated.
Thanks!
I think your problem is related to service discovery.
Load balancers are not designed for that obviously. You should consider dedicated softwares such as Eureka (which can work outside of AWS).
Service discovery makes your microservices call directly each others after being discovered.
Also take a look at client-side load balancing tools such as Ribbon.
#Cdelmas answer is awesome on Service Discovery. Please allow me to add my thoughts:
For services such as yours, you can also look into Netflix's ZUUL proxy for Server and Client side load balancing. You could even Use Histrix on top of Eureka for latency and Fault tolerance. Netflix is way ahead of the game on this.
You may also look into Consul.io product for your cause if you want to use GO language. It has a scriptable configuration for better managing your services, allows advanced security configurations and usage of non-rest endpoints. Eureka also does these but requires you add a configuration Server (Netflix Archaius, Apache Zookeeper, Spring Cloud Config), coded security and support accesses using ZUUL/Sidecar.
Related
In Azure, I have 3 Web Apps (for simplicity):
Frontend website
Endpoint 1
Endpoint 2
The frontend website requests data from an endpoint.
Both endpoints are synchronized all the time (outside the scope of this question), but sometimes I need to do some maintenance on them, which gives me some downtime.
Can I somehow setup a loadbalancer only my frontend website can see, and get any of the online endpoints - like this:
The last line of this article says Internal Load Balancers might be the fit:
Can I use ILB on PaaS services (Web/Worker roles)?
ILB is designed to work with web/worker roles as well, and it is available from SDK 2.4 onwards.
Does anyone know of a guide, or have tried making this with Web Apps?
I dont think this is something you can achieve "natively" with load balancers. App Services are not actually bound to the VNet. Previously you could only use point-to-site vpn to connect them to vnet, right now there is a new vnet integration feature in preview which might allow you to use internal load balancers, but I doubt that, because they (load balancers) only allow to use virtual machines\scale sets\availability sets as backend pools.
Application gateways can be bound to the App Services. And they can be internal as well. You'd also need to restrict App Service(s) to receive traffic from anything that is not you Application gateway.
You can use traffic manager\front door for this sort of load balancing, but the endpoints won't be private
I have a use case where my cluster has 3 VMs working as head node in HPC Pack and a bunch of other VMs working as compute nodes.
So basically, after creating this cluster, i must install a special HCP client, from this client, i type the DNS name of each of VMs to access the HPC management interface.
For example: https://head-node-1.azure.com
Of course, if i access this DNS from Chrome, i only see IIS page.
I wants to create a load balancer with its DNS name. Let's say https://load-balancer.azure.com
So from my client, every time i access load balancer DNS name, i can see the management interface, not IIS page.
How can i do that?
Not sure I'm understanding you correctly. Basically, Azure Application Gateway supports URL path-based routing rules.
Actually, Application Gateway supports web-based traffic load balancing. [Azure load balancer][2] supports stream-based traffic. If you want to listen to the protocol HTTP or HTTPS, you can use Application Gateway. Per your description, you could not access HPC management interface from web explorer, you could use a 4 layer load balancing based on TCP/UDP.
So you could create a public-facing load balancing and add the head node VMs as the backend pools. Create a health probe and load balancing rules to specify the ports you want to listen for your HPC management interface on the each of VMs.
Hope this helps, let me know if you have any concerns.
We have a cisco load balancer on-premise which routes traffic to our DMZ Servers on-premise
We want to use Azure Load Balancer or Azure Solutions (AG) which can balance traffic to our DMZ Servers on-premise, basically replace the CISCO with Azure
Is it possible? we have SFT/HTTPS sites currently hosted on our DMZ Environment.
TIA
What you're proposing isn't the use-case for Application Gateways. Application Gateways are Layer 7 load balancers / reverse proxies. What you want to do is almost treat them as a one-site forward proxy. It's not a good architecture and even if it were possible would ultimately be more costly in the long-run since you would pay for data egress as your App Gateway accepts requests and then forwards on to your web servers via an outbound connection over the Internet. They then receive the response headers/body from your web servers and again send that result on to the original caller.
In that scenario, you are forced to have to use end-to-end SSL for your applications, removing any possibility of using the App Gateway for SSL offload in the future. If your traffic isn't encrypted or doesn't need to be, the predictability of the source and destination of your traffic increases the security risk to your website's users and your company.
You also have the possible security implications of this type of architecture. Your web servers still need to be accessible at the very least by your Application Gateway, which means they are either freely available on the Internet anyway (in which case why bother with an App Gateways at all) or they're firewalled at a single layer and permit only traffic from the source IP address of your Application Gateway.
The bad news with the firewall approach is that you cannot assign a static public IP address to an Application Gateway, it is forced as Dynamic. Realistically the public IP won't change until the App Gateways are rebooted but you should know that when, not if, they do, your firewall rules will be wrong and your App Gateways won't be able to get to your DMZ servers any more, which means an outage. The only true solution for that is a firewall that can do URI based firewall rules...the impact there is cost (time and CPU) to perform a DNS lookup, see if the traffic is from the App Gateway by its DNS address - something like bd8f86bb-5d5a-4498-bc0c-e1a48b3873bf.cloudapp.net and then either permit or deny the request.
As discussed above, a further security consideration is that your traffic will be fairly consistently originating from one location (the App Gateways) and arriving at your DMZ. If there's a well defined source of traffic, that fact could be used in an attack against your servers/DMZ. While I'm sure attacking this is non-trivial, you damage your security posture by making source and destination traffic predictable across the Internet.
I've configured a good number of Application Gateways now for Enterprise applications and out of morbid curiosity I had a go at configuring a very basic one using HTTP to do what you're attempting - fortunately (yes, fortunately) I received an HTTP 502 so I'm going say that this isn't possible. I'll add that I'm glad it isn't possible because it's a Bad Idea (TM).
My suggestion is that you either migrate your DMZ servers to Azure (for the best performance/network latency) or implement a VPN or (preferably) ExpressRoute. You'll then be able to deploy an Application Gateway using the correct architecture where you terminate your users' connections at the App Gateway and that re-transmits the request within your RFC1918 network to your DMZ servers which respond within the network back to the App Gateway and ultimately back to the requestor.
Sorry it's not what you wanted to hear. If you're determined to do this, perhaps nginx could be made to?
I am evaluating the convenience of moving to azure. Currently, I am trying to figure out how to balance the load and make routing for different websites on the same machine. I saw tutorials where a user created a separate LB on a different VM. I also found many articles about the possibility to balance the load using Azure load balancing.
So I assume both are possible, is that correct?
I would like to know how to connect between machines on azure. Would it be possible to do so using a local ip, machinename, or dns?
I also need to figure out how to forward traffic to different ports based on http header, is that possible without a seperate machine as load balancer? I see the endpoint config in my azure dashboard and found the official documentation, but unfortunately it's not enough for my understanding.
Currently, I am trying to figure out how to balance the load and make
routing for different websites on the same machine.
You can have different web sites on the same machine by configuring virtual hosting on IIS. This is accomplished using host header. VM, Cloud Service or even Websites supports this functionality. VMs and Cloud Services should be pretty straight forward. Example using websites:
Hosting multiple domains under one Azure Website
http://blogs.msdn.com/b/cschotte/archive/2013/05/30/hosting-multiple-domains-under-one-azure.aspx
I also found many articles about the possibility to balance the load
using Azure load balancing.
LB for VMs are as easy as creating a load balance set inside endpoint configuration wizard. Once you create a balance set, for example, enpoint HTTP port 80, you can assign this balance set to any VM on the same cloud service. All requests to port 80 would be automatically balanced across all VMs in the set.
So I assume both are possible, is that correct?
Yes.
I would like to know how to connect between machines on azure. Would
it be possible to do so using a local ip, machinename, or dns?
You just have to create a virtual network and deploy the VMs to it. Websites (through preview portal only), Cloud Services and VMs supports VNet.
Virtual Network Overview
https://msdn.microsoft.com/library/azure/jj156007.aspx/
I also need to figure out how to forward traffic to different ports
based on http header, is that possible without a seperate machine as
load balancer?
Not at this moment. Best you can have with native Azure Services is a 3-tuple (Source IP, Destination IP, Protocol) load balance configuration.
Azure Load Balancer new distribution mode
http://azure.microsoft.com/blog/2014/10/30/azure-load-balancer-new-distribution-mode/
depending on how you're deploying there's a couple of options:
first of all: LB sets in VM's in a cloud service. For this the Cloud service acts as the LB. this can only be achieved when using a standard sku VM.
second of all in Azure WebApps : load balancing is achieved automagically when deploying through standard means, since scaling is foreseen here.
Third of all there's Cloud Services with roles, who also do this "automagically".
Now none of that seem to apply to your needs. you can also start thinking about using traffic manager, something with a little more bite :-)
have you read this article by any chance? http://azure.microsoft.com/en-us/documentation/articles/virtual-machines-load-balance/
I'd like to advise you to add different endpoints to your VM's work with traffic manager and ake sure you IIS has all the headers on the correct ports (cause i'm assuming that's what you're doing already)
I have a Cloud Service that is connected to a LAN through a virtual network. I have a web role that machines on the LAN will be hitting for tasks like telling the cloud service that data needs to be refreshed. It it possible to have and endpoint that's load-balanced, but that only accepts traffic through the virtual network?
Well... you have a few things to think about.
You could set up your own load balancer in a separate role, which then does the load balancing. You'd probably want two instances to deal with high availability, and if there was any stateful/sticky-session data you'd need to sync it between your two load balancers. OR...
Now: If your code needing load-balancing lived in a Virtual Machine, rather than in a web/worker role, you could take advantage of the brand-new IP-level endpoint ACL feature introduced at TechEd. With this feature, you can have an endpoint that allows/blocks traffic based on source IP address. So you could have a load-balanced endpoint balancing traffic between a few virtual machines, and you could then limit access to, say, your LAN machines, and even add your existing Cloud Service (web/worker) VIP so that your web and worker role instances could access the service, all through the endpoint without going through the VPN. This way, you'd get to take advantage of Azure's built-in load balancer, while at the same time providing secure access for your app's services.
You can see more details of endpoint ACLs here.
No. The load balancer for a cloud service is public only. You can't predict the ip addresses of the individual instances on the virtual network, so you can't even hook them into your own load balancer. Yes, you can do it with VMs (as David recommends) — but then you're doing old-school IIS, not a cloud service. I went through this in November 2012, and was unable to find a decent solution.