Configurar un ILB con PowerShell en Azure Resource Manager
De acuerdo con la documentación de azure, tenemos no una ni dos, sino cuatro formas distintas de definir un balanceador interno de carga en Azure Resource Manager desde cero. Ahora bien, ¿qué sucede cuando ya se tiene infraestructura desplegada y se desea balancear?
Antes de nada… ¿qué es un balanceador interno?
Un ILB (siglas en inglés) proporciona balanceo de carga de red entre máquinas virtuales que residan en la misma red virtual de Azure. Este servicio permite la creación de servicios configurados en alta disponibilidad, de forma que, ante picos elevados de carga, el trabajo se distribuye equitativamente entre los miembros del grupo balanceado. Igualmente, en caso de que alguna máquina del grupo balanceado deje de funcionar, ya sea por tareas de mantenimiento, error de configuración, o fallo de la máquina virtual, el balanceador detecta que la máquina afectada ya no está disponible, y de forma dinámica redistribuye la carga entre el resto de máquinas virtuales del grupo balanceado.
Un escenario básico se correspondería con el siguiente diagrama:
Se tienen dos máquinas que actúan como servidor Web, dos interfaces de red, el balanceador de carga, y una IP privada que es donde se van a recibir todas las peticiones de servicio.
Descripción del escenario propuesto:
Se tiene un servidor web linux, que está proporcionando un servicio, pero se desea cambiar la configuración “servidor único” por una configuración balanceada, para obtener los beneficios de reducir la carga del servicio en la máquina original, así como conseguir tener una infraestructura más resistente a fallos.
En este caso, una opción sencilla es desplegar una máquina idéntica a la máquina original, y configurar el balanceo de carga a posteriori.
Para asegurarse de que la segunda máquina es una copia idéntica de la primera, es posible utilizar un software como rsync.
Así pues, en este escenario tenemos ya dos máquinas virtuales, con sus correspondientes interfaces de red, y todo está ya funcionando. Sólo falta balancear el sistema.
Paso a paso
En primer lugar, toca iniciar sesión en Azure. En el ejemplo, mi cuenta sólo está adscrita a una suscripción de Azure. En caso de que estuviese dado de alta en más de una, habría que usar los cmdlets “Get-Azure-RmSubscription” y“Select-AzureRmSubscription” para determinar el ID de la subscripción que se desea utilizar, y así poder seleccionarla.
Como las máquinas virtuales ya existen, pertenecen a una red virtual de Azure. En este caso, tendremos que averiguar en qué red están con el cmdlet “get-AzureRmVirtualNetwork”. Este cmdlet nos permite seleccionar la red virtual en la que están las máquinas virtuales, y así poder trabajar con sus subredes.
De esta forma, se puede crear la IP de frontend que va a definir el punto de entrada de las solicitudes del servicio balanceado. A continuación, se crea el backend que recibe el tráfico del frontend.
1 2 3 |
$vnet=Get-AzureRmVirtualNetwork -ResourceGroupName amarquez-ILB-blogpost-marzo -Name amarquez-ILB-blogpost-marzo $frontendIP= New-AzureRmLoadBalancerFrontendIpConfig -Name amarquezILB -PrivateIpAddress 10.1.100.1 -SubnetId $vnet.subnets[0].id $backendpool=New-AzureRmLoadBalancerBackendAddressPoolConfig -name "amarquezILB-backend" |
Una vez se ha creado todo lo necesario, se puede proceder a crear el balanceador de carga:
Ahora es cuando empieza lo interesante: Se tienen las máquinas virtuales, las interfaces de red, y el balanceador de carga. Toca ir juntando las piezas para formar el puzzle.
Se obtiene la configuración de cada interfaz de red de las VM, y se le asigna el backend del balanceador de carga. A continuación, se guarda la configuración de la interfaz de red, y con esto se asigna dicha interfaz al balanceador de carga interno:
Una vez asignadas ambas interfaces, el balanceador de carga interno estará listo para su uso.
Desde el portal de Azure se puede examinar la configuración del balanceador.
Y finalmente llega la prueba de fuego: testear el servicio balanceado. Como las máquinas son servidores linux, la forma más sencilla de hacerlo es editar la página de inicio de Apache con versiones diferentes de la web, de forma que la respuesta que devuelve cada servidor sea diferente. En este caso, se ha optado por hacer que cada máquina devuelva “server1” o “server2” dependiendo de cuál de ellos está sirviendo la respuesta.
En esta prueba, primero se hace una conexión en local al servidor, a ver de qué máquina se trata, y a continuación se hace una petición al ILB, para ver qué máquina nos está respondiendo. Se puede ver que, en cada caso, la respuesta la devuelve una máquina distinta, así que el balanceador funciona correctamente.
Al ser un servicio balanceado, en caso de que uno de los servidores deje de funcionar, la sonda se encargará de determinar en un intervalo máximo de 45 segundos que la máquina afectada no debe de seguir dando servicio (en el caso de que la máquina falle justo después de una sonda, ésta ha de fallar dos veces consecutivas para que el ILB deje de usarla para servir respuestas, en un intervalo de 15 segundos entre cada sondeo).
Conclusiones
De esta forma, se puede configurar un servicio balanceado usando PowerShell. Hay documentación que automatiza el proceso incluyendo la creación de servidores e interfaces de red. Actualmente, ése es un proceso muy interesante si tenemos en cuenta que actualmente hay una limitación muy importante en la configuración de los balanceadores de carga, y que se describe en la siguiente sección.
A continuación, se adjunta un script que resume los pasos llevados a cabo para montar el servicio.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
#parámetros $rgname="amarquez-ILB-blogpost-marzo" $vnetName="amarquez-ILB-blogpost-marzo" $FrontEndName="amarquezILB" $BackEndName="amarquezILB-backend" $ILBIP="10.1.0.200" $sondaName="Sonda" $rbName="HTTP" $balancerName="amarquez-ILB" $location="North Europe" $NICnames=@("amarquez-ILB1493", "amarquez-ILB252") ############ $totalsteps=5+$NICnames.Count #obtener red virtual y generar el FrontEnd y BackEnd write-progress -id 1 -activity "Configurando ILB" -status "Obtener red virtual y generar el FrontEnd y BackEnd" -percentcomplete ((1/$totalsteps)*100) -currentOperation "..." $vnet=Get-AzureRmVirtualNetwork -ResourceGroupName $rgname -Name $vnetName $frontendIP= New-AzureRmLoadBalancerFrontendIpConfig -Name $FrontEndName -PrivateIpAddress $ILBIP -SubnetId $vnet.subnets[0].id $backendpool=New-AzureRmLoadBalancerBackendAddressPoolConfig -name $BackEndName #Generar la sonda y la regla de balanceo HTTP write-progress -id 1 -activity "Configurando ILB" -status "Generar la sonda y la regla de balanceo HTTP" -percentcomplete ((2/$totalsteps)*100) -currentOperation "..." $Sonda = New-AzureRmLoadBalancerProbeConfig -Name $SondaName -Protocol tcp -Port 80 -IntervalInSeconds 15 -ProbeCount 2 $reglaBalanceo = New-AzureRmLoadBalancerRuleConfig -Name $rbName -FrontendIpConfiguration $frontendIP -BackendAddressPool $backendpool -Probe $Sonda -Protocol Tcp -FrontendPort 80 -BackendPort 80 #Creación del balanceador write-progress -id 1 -activity "Configurando ILB" -status "Creacion del balanceador" -percentcomplete ((3/$totalsteps)*100) -currentOperation "..." $ilb=New-AzureRmLoadBalancer -ResourceGroupName $rgname -Name $balancerName -Location $location -FrontendIpConfiguration $frontendIP -LoadBalancingRule $reglaBalanceo -BackendAddressPool $backendpool -Probe $Sonda #Obtener configuración del balanceador write-progress -id 1 -activity "Configurando ILB" -status "Obtener configuracion del balanceador" -percentcomplete ((3/$totalsteps)*100) -currentOperation "..." $lb=Get-AzureRmLoadBalancer -name $balancerName -resourcegroupname $rgname $backend=Get-AzureRmLoadBalancerBackendAddressPoolConfig -name $BackEndName -LoadBalancer $lb #Asignar las interfaces de red al balanceador write-progress -id 1 -activity "Configurando ILB" -status "Asignar las interfaces de red al balanceador" -percentcomplete ((5/$totalsteps)*100) -currentOperation "..." $count=0 $NICnames | foreach { write-progress -id 1 -activity "Configurando ILB" -status "Asignar las interfaces de red al balanceador" -percentcomplete (((5+$count)/$totalsteps*100)) -currentOperation $_ $nic=Get-AzureRmNetworkInterface -name $_ -resourcegroupname $rgname $nic.IpConfigurations[0].LoadBalancerBackendAddressPools=$backend $int=Set-AzureRmNetworkInterface -NetworkInterface $nic $count+=1 } Write-host "Configuración de ILB Terminada" |
Limitaciones actuales
Ambas máquinas deben estar en el mismo grupo de disponibilidad. En el modo clásico, se pueden añadir o quitar libremente máquinas virtuales de un grupo, pero en modo Resource Manager, aún no hay soporte para ello. En caso de que ambas máquinas no estén en el mismo grupo de disponibilidad (Availability Set), aparecerá un mensaje de error similar a este:
En el modo Service Manager de Azure, sí que es posible asignar una VM a un Availability Set sin ningún tipo de problema. Cabe esperar que en un futuro próximo esta funcionalidad también esté disponible en el modo Resource Manager.