Nouvelles Chroniques d'Amethyste

Penser au Sens, pas au Verbe

Point de terminaison, équilibrage de charge et ACL sous Azure

Poster un commentaire

En première lecture on a l’impression qu’un point de terminaison (endpoint) fait redondance avec le pare feu. En réalité il s’agit de deux choses qui n’ont rien à voir et se paramètrent de façon indépendante.

Un point de terminaison est une règle qui remplit 4 fonctions:

  1. Définition d’un accès public (depuis Internet) à un service
  2. Redirection de port (port forwarding)
  3.  Equilibrage de charge et la mise en place facultative d’une sonde
  4.  Support pour les ACL

La redirection de port est un moyen qui permet de s’adresser à une VM individuelle alors qu’il n’y a qu’une adresse IP publique pour l’ensemble du service cloud.

2015-04-17_22-30-21

Deux VM dans un service exposent le port 3889 qui permet d’y accéder en RDP. Dans ce scénario il est évidemment essentiel de pouvoir accéder à une machine particulière. Pour y parvenir on va créer deux points de terminaisons, un sur chaque VM avec le mapping suivant:

VM 1  : 5000 <==> 3389
VM 2 : 5001 <==> 3389

Dans ce schéma, le point de terminaison n’est pas load balancé. On dit qu’il est autonome (stand alone).
Ce n’est pas forcément le scénario voulu. Si les VM hébergent un site web accessible sur le port 80 par exemple, on a besoin de mettre en place un équilibrage de charge avec la prise en charge d’une sonde pour tester la disponibilité des VM.

Placer une ACL est un moyen de filtrer l’accessibilité d’un point de terminaison. L’ACL par défaut est Permit sur le sous réseau 0.0.0.0/0. Cela signifie que le port est accessible par tout le monde. Il est possible bien entendu de placer des filtres plus spécifiques.
Pour toute la suite je vais réutiliser les variables définies dans cet article:
https://amethyste16.wordpress.com/2015/04/13/pilotez-vos-vm-azure-avec-powershell/

Création d’un point de terminaison autonome

Créer un point de terminaison avec le portail n’est pas très difficile, voyons plutôt comment faire avec PowerShell.
On déclare un point de terminaison lors de la création de la VM à l’aide de Add-AzureEndPoint:

 


New-AzureService -ServiceName $serviceName -Location $location

$Config = New-AzureVMConfig -Name $vmname -InstanceSize $size -ImageName $imageName
$Config | Add-AzureProvisioningConfig -Windows -AdminUsername $user -Password $pwd
$config | Add-AzureEndpoint -Name "MonEndPoint" -Protocol tcp -LocalPort 80 -PublicPort 80
$config | New-AzureVM -ServiceName $serviceName -WaitForBoot

On dispose d’un point sur le port public (et privé) 80. Si on se rend dans l’onglet ENDPOINTS de la VM:

2015-04-16_18-44-12

Avec cette syntaxe, le trafic vers le point de terminaison ne sera pas équilibré, mais redirigé vers la VM individuelle.
On peut ajouter un autre point sur une VM qui existe déjà avec la même cmdlet:

 

$Config = get-azurevm -ServiceName $serviceName -Name $vmName

$config | Add-AzureEndpoint -Name "MonNouvelEndPoint" -Protocol tcp -LocalPort 8001 -PublicPort 8002 | Update-azureVM

 

2015-04-16_18-55-28

Il est possible de retrouver les points d’une VM avec Get-AzureEndpoint:

$config | Get-AzureEndpoint

On enlève un point de terminaison facilement:

$config | Remove-AzureEndpoint -Name « MonNouvelEndPoint »
La dernière étape sera peut-être de paramétrer correctement le pare-feu du serveur pour accepter les appels en provenance du port privé.

Equilibrage de charge

L’équilibrage de charge n’est pas un mécanisme si différent que ça de la redirection de port. C’est d’ailleurs également avec Add-AzureEndpoint qu’on le met en place.  La différence est que l’on déclare un point de terminaison supplémentaire qui correspond à l’équilibreur de charge. C’est le LBSet dont la présence indique à Azure que le port privé est partagé par toutes les VM du  groupe. Il est également possible de déclarer une sonde qui va tester si les VM du LBSet répondent et éventuellement la sortir du carrousel.

Autre point, Azure propose deux scénarios d’équilibrage de charge:

  1. Equilibrage de charge sur des adresses publiques
  2.  Equilibrage de charge sur des adresses internes (ILB)

Il est en outre possible d’ajouter une sonde que l’équilibreur de charge va consulter régulièrement pour savoir si telle VM peut encore faire partie du carrousel de VM. On a deux types de sonde: TCP ou HTTP.

La sonde TCP est la plus simple à mettre en place. L’équilibreur teste la VM et attend un ACK. La sonde HTTP émet une requête HTTP et attend un code retour 200 en cas de succès.

Equilibrage de charge public

Pour créer un point de terminaison avec équilibrage de charge on utilise la cmdlet Add-AzureEndPoint à nouveau, mais avec d’autres paramètres qui dépendent du scénario que l’on souhaite mettre en place.

Pour juste mettre en place un équilibrage de charge sans sonde, on peut utiliser le script suivant:

 

New-AzureService -ServiceName $serviceName -Location $location

$configs = @()
for($i=1; $i -le 2; $i++)
{
    $CurrentName = $vmName + $i
    $Config = New-AzureVMConfig -Name $CurrentName -InstanceSize $size -ImageName $imageName
    $Config | Add-AzureProvisioningConfig -Windows -AdminUsername $user -Password $pwd
    $config | Add-AzureEndpoint -Name "NoProbe" -Protocol tcp -LocalPort 80  -LBSetName "NoProbeSet" -NoProbe
    $Configs += $Config
}
New-AzureVM -ServiceName $serviceName -VMs $configs -WaitForBoot

Le script construit 2  VM dans le même service avec activation de l’équilibrage de charge sur le port 80.

  • LBSetName: nom du LBSet
    Ce sont les machines appartenant au même LBSet qui seront équilibrées sur leur adresse VIP. Les autres VM du service ne seront pas concernées.
  • NoProbe: pas de sonde
  • LocalPort: port privé. Si PublicPort n’est pas spécifié, Azure en choisira un pour nous. Ce sera bien sûr le même port public pour chaque VM du LBSet

2015-04-17_23-31-08

On remarque une alerte pour rappeler qu’il n’y a pas de sonde. Ce n’est jamais une bonne idée. Pour mettre en place une sonde on a le choix entre une sonde par défaut qui suffit dans la plupart des cas et une sonde personnalisée.

Avec la sonde par défaut:

 

$configs = @()
for($i=1; $i -le 2; $i++)
{
    $CurrentName = $vmName + $i
    $Config = New-AzureVMConfig -Name $CurrentName -InstanceSize $size -ImageName $imageName
    $Config | Add-AzureProvisioningConfig -Windows -AdminUsername $user -Password $pwd
    $config | Add-AzureEndpoint -Name "DefaultProbe" -Protocol tcp -LocalPort 80  -LBSetName "DefaultProbeSet" -DefaultProbe
    $Configs += $Config
}
New-AzureVM -ServiceName $serviceName -VMs $configs -WaitForBoot

La sonde par défaut est une sonde TCP. Les VMs sont testées toutes les 15 secondes sur le port local et l’IP interne.

Mais on peut souhaiter gérer soi-même les paramètres de la sonde. Le plus souvent ce sera pour utiliser un port (ProbePort) ou chemin personnalisés (ProbePath).
Il est par contre impossible de gérer l’authentification. La sonde doit donc répondre correctement aux requêtes anonymes.

New-AzureService -ServiceName $serviceName -Location $location
$configs = @()
for($i=1; $i -le 2; $i++)
{
    $CurrentName = $vmName + $i
    $Config = New-AzureVMConfig -Name $CurrentName -InstanceSize $size -ImageName $imageName 
    $Config | Add-AzureProvisioningConfig -Windows -AdminUsername $user -Password $pwd
    $config | Add-AzureEndpoint -Name "Probe" -Protocol tcp -LocalPort 80 -PublicPort 80 -LBSetName "ProbeSet" -ProbeProtocol http -ProbePath "/" -ProbePort 80
    $Configs += $Config
}
New-AzureVM -ServiceName $serviceName -VMs $configs -WaitForBoot

La sonde écoute sur le port désigné par ProbePort (80 dans notre exemple). Il  est également possible de personnaliser le protocole de la sonde avec ProbeProtocol ainsi que l’url où aura lieu l’écoute avec ProbePath.

2015-04-16_15-41-26

Côté serveur il faudra bien entendu déployer un site qui réponde sur le port 80. La sonde attend un HTTP 200. Il est conseillé, mais pas obligatoire, de placer les VM dans un groupe de disponibilité.

On peut aussi modifier une sonde existante avec Set-AzureLoadBalancedEndpoint:

Set-AzureLoadBalancedEndpoint -LocalPort 8005 -PublicPort 8005 -LBSetName « ProbeSet » -ServiceName $serviceName

Renumérote les ports.

Si l’on a besoin d’en savoir plus sur l’algorithme d’équilibrage de charge utilisé par Azure:

http://azure.microsoft.com/blog/2014/04/08/microsoft-azure-load-balancing-services

Equilibrage de charge interne (ILB)

Azure ILB équilibre des serveurs situés dans un même réseau régional (pas de support pour les groupes d’affinité) ou dans un même service cloud. Ce scénario ne peut être mis en place qu’avec PowerShell.

On ne peut ajouter qu’un seul ILB par service cloud, mais il est possible de le faire soit à la création, soit sur une configuration existante. On va tester les deux scénarios.

Création sur une configuration existante

Voici notre configuration

2015-05-01_21-08-06

Deux VMs situées sur le sous-réseau MainNetwork du réseau networkamethyste.

 

On commence par créer l’instance de l’ILB, c’est à dire le point de terminaison du trafic entrant dont la charge sera équilibrée.

$serviceName="serviceAmethyste"
 $subnetName = "MainNetwork"
 $ilb="IlbAmethyste"
Add-AzureInternalLoadBalancer -ServiceName $serviceName `
 -InternalLoadBalancerName $ilb `
 -SubnetName $subnetName

Plusieurs scénarios sont en fait supportés, on verra les détails dans la documentation.  Une adresse IP sera automatiquement affectée, mais on peut la choisir une valeur à l’aide du paramètre StaticVNetIPAddress.

On ajoute ensuite les points de terminaisons ILB aux VM:

 

$vms = get-azurevm -ServiceName $serviceName
foreach($vm in $vms)
{
    $vm |
    Add-AzureEndpoint -Name "web" -LocalPort 80 -PublicPort 80 -Protocol tcp -LBSetName "ProbeSet" -InternalLoadBalancerName $ilb -DefaultProbe |
    update-AzureVM -ServiceName $serviceName 
}

Comme toujours on teste. Tout d’abord on lance Get-AzureInternalLoadBalancer:

Get-AzureInternalLoadBalancer -ServiceName $serviceName

2015-05-01_21-39-24

On découvre ainsi l’IP équilibrée dans l’espace d’adresses du sous réseau (10.0.1.6). Côté portail on ne voit rien de particulier apparaître à ma connaissance.

On peut tester que l’équilibrage fonctionne. Pour cela on se connecte à chaque VM. On installe le rôle IIS et on modifie la page du site par défaut pour afficher le nom du serveur.

On est sur une IP interne. On ne peut donc pas tester depuis l’extérieur. On doit se connecte en VPN au réseau ou bien depuis une autre VM dans le réseau et on lance la requête:

http://10.0.1.6/

On fait plusieurs fois F5 et on devrait basculer d’une machine à l’autre grâce à la magie de l’équilibrage de charge. S’il est un peu dur d’oreille on peut arrêter une des VMs et la sonde fera son travail.

Montage de l’ILB au moment de la création des VM

Commençons par le script:

 

$familyName= "Windows Server 2012 R2 Datacenter"
$size= "Small"
$vmName= "AmethysteVM"
$serviceName="serviceAmethyste"
$location = "West Europe"
$user= "admin489"
$pwd= "azerty@12345"

$imageName = get-azurevmimage | where {$_.ImageFamily -eq $familyName}| sort PublishedDate -Descending|select -ExpandProperty ImageName -First 1

New-AzureService -ServiceName $serviceName -Location $location
$configs = @()

$ilb="IlbAmethyste"

for($i=1; $i -le 2; $i++)
{
    $CurrentName = $vmName + $i
    $Config = New-AzureVMConfig -Name $CurrentName -InstanceSize $size -ImageName $imageName 
    $Config | Add-AzureProvisioningConfig -Windows -AdminUsername $user -Password $pwd 
    $Config | Set-AzureSubnet 'MainNetwork' |
    Add-AzureEndpoint -Name "web" -LocalPort 80 -PublicPort 80 -Protocol tcp -LBSetName "ProbeSet" -InternalLoadBalancerName $ilb -DefaultProbe

    $Configs += $Config
}

$subnetName = "MainNetwork"
$ilbConfig = New-AzureInternalLoadBalancerConfig -InternalLoadBalancerName $ilb -SubnetName $subnetName
New-AzureVM -ServiceName $serviceName -VMs $configs -VNetName 'NetworkAmethyste' -InternalLoadBalancerConfig $ilbConfig  -WaitForBoot

 

Tout d’abord on créée une configuration avec New-AzureInternalLoadBalancerConfig . Cette configuration est passé en paramètre à New-AzureVM. On renseigne Add-AzureEndpoint de la même façon qu’au chapitre précédent pour créer le point de terminaison sur chaque VM.

 

On trouvera plusieurs exemples ici:

https://msdn.microsoft.com/fr-fr/library/azure/dn690125.aspx

http://michaelwasham.com/windows-azure-powershell-reference-guide/using-the-internal-load-balancer-with-azure-virtual-machines/

Les ACL

Les ACL (Access Control List) concernent tous les points de terminaisons, qu’ils soient équilibrés ou pas. Il est possible de placer jusqu’à 50 règle par ACL.

Voyons tout d’abord le cas du portail. On se rend dans l’onglet ENDPOINTS:

2015-04-17_22-47-09

On sélectionne le point que l’on va gérer, ici HTTP et on clique sur le menu MANAGE ACL:

2015-04-17_22-48-22

Le formulaire suivant s’ouvre:

2015-04-17_22-49-34

Une règle est déclarée et interdit l’accès au port 80 depuis ma machine. Ce n’est pas une IP que l’on ajoute, mais une plage d’adresses en notation CIDR.
Les règles sont exécutées dans l’ordre où elles apparaissent.
On constate qu’avec cette règle le port 80 n’est pas accessible, mais le redevient si on passe la règle à Permit.

Essayons avec PowerShell.

On construit un ACL avec cette ligne de commande:

$acl=New-AzureAclConfig

Qui remonte un NetworkAclObject qu’il ne nous reste plus qu’à configurer à l’aide de Set-AzureAclConfig:

$acl=New-AzureAclConfig |
 Set-AzureAclConfig -AddRule -Order 50 -Action Deny -RemoteSubnet "172.16.102.141/32" -Description "ACL From PowerShell"

Le sens des paramètre est évident je pense. La dernière étape est d’affecter l’ACL à un point de terminaison. Le script complet est celui-là:

$acl=New-AzureAclConfig |
 Set-AzureAclConfig -AddRule -Order 50 -Action Deny -RemoteSubnet "172.16.102.141/32" -Description "ACL From PowerShell"

 $config = Get-AzureVM -ServiceName $serviceName -Name $vmName
 $config | Set-AzureEndpoint -Name "HTTP" -ACL $acl |
 Update-AzureVM

Une fois exécuté le script reconstitue l’état que nous avions obtenu depuis le portail:

2015-04-17_22-52-25

On peut lister les ACL d’un point:

$config | Get-AzureAclConfig -EndpointName « HTTP »

2015-04-17_22-53-54

Set-AzureAclConfig admet deux autres paramètres:

  1. SetRule: Modifie une règle qui existe
  2. RemoveRule: Supprime une règle

Bibliographie

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Publicités

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s