VDDK m’as tué

Symantec s’est mangé une bonne déculottée public par Veeam après avoir FUDé via twitter au sujet d’un potentiel bug dans l’API de backup de vSphere 5.1 :

Any vendor claiming support for #vStorage 5.1 API, CANNOT perform consistent backups

Réponse bien précise de veeam :

Our development team wasn’t able to fix these issues but they did realize that separating the VDDK calls into a separate process monitored by a watchdog process will help to dramatically increase overall reliability. In case this process hangs, we simply kill the process without affecting the job. With an alternative architecture not featuring such isolation, VDDK code hang will cause they whole backup and restore “job” to hang just as the VMware KB article explains.

Additionally, Veeam sets extra timeouts on some critical VDDK calls to avoid possible deadlocks.

Conclusion :

In short, Veeam customers are immune to VDDK issues while Symantec customers need to go back and verify the recoverability all of their VMware VM backups, as per Symantec’s own tweet.

Ça fait mal.

Tags: , , ,

FC to iSCSI failover : MRU ranking

Au détour de l’excellent Storage Implementation in vSphere 5.0 de Mostafa “VCDX #2″ Khalil,  nous avons découvert le Path Ranking. Détaillé dans une kb vmware (et dans un post de Cormac Hogan), le path raking permet de pondérer un ou plusieurs chemins lorsque le plugin VMW_PSP_MRU est utilisé.

In ESXi 5.0, VMW_PSP_MRU has path ranking capabilities that allows you to assign ranks to individual paths. VMW_PSP_MRU goes through the path group states in the following order: Active, Active_UO and Standby, and picks a path that has the highest rank for I/O.

Evidemment, le scénario dans le quel le path ranking nous intéresse le plus est le fameux FC to iSCSI failover dans le quel nous étions particulièrement gêné par le fait que les chemins en FC n’étaient pas prioritaires sur les chemins iSCSI et pouvant mener à des situations où un chemin iSCSI serait utilisé alors qu’un chemin FC serait disponible :

On passe le PSP du datastore en MRU et un coup de PowerCLI pour monter le ranking des chemins FC :

(Get-VMHost esx.vmware.com|Get-EsxCli).storage.nmp.path.list("naa.0123456789")|sort RuntimeName|select RuntimeName, @{n="rank";e={(Get-VMHost esx.vmware.com|Get-EsxCli).storage.nmp.psp.generic.pathconfig.get($_.RuntimeName)}}|ft -AutoSize
(Get-VMHost vmvisor01.vmwa.re|Get-EsxCli).storage.nmp.psp.generic.pathconfig.set("rank=1","vmhba0:C0:T0:L0")

Le (bon) résultat est immédiat :

Tags: , , , , , , , ,

ESXi>Graylog2 – Quickstart – MAJ

MAJ 31.10.2012 : Pour ceux qui veulent profiter rapidement des alarmes, allez modifier le fichier /usr/share/graylog2-web/config/email.yml et rajoutez ces 2 lignes dans votre crontab :

su - -c 'cd /usr/share/graylog2-web;rake RAILS_ENV=production streamalarms:send>>/var/log/graylog.log'
su - -c 'cd /usr/share/graylog2-web;rake RAILS_ENV=production subscriptions:send>>/var/log/graylog.log'

Ceux qui connaissent Graylog2 savent à quel point c’est un serveur syslog surpuissant mais pas vraiment simple à installer. De plus, ceux qui s’en servent pour des ESXi ont eu la douloureuse surprise de constater que graylog2 ne supportait pas le format syslog d’ESXi 5.x alors que celui de 4.x était parfaitement géré. Nous allons donc faire d’une pierre deux coups.

En ce qui concerne la simplicité, Mick Pollard a posté cet été comment utiliser ses packages sur un Ubuntu 12.04, ce à quoi nous ajouterons des morceaux d’un autre how-to pour faire tourner l’interface web de graylog2 sous apache.

Et pour la compatibilité, nous configurerons graylog2 pour écouter sur un port “alternatif” (10514 dans notre exemple) car le port 514 sera pour rsyslog qui réécrira tout ce qui passe au bon format et le forwardera (non, ce mot n’existe pas) à graylog2. Attention ca va aller très vite :

echo 'deb http://ppa.lunix.com.au/ubuntu/ precise main' | sudo tee /etc/apt/sources.list.d/aussielunix.list
apt-key adv --keyserver keyserver.ubuntu.com --recv D77A4DCC
apt-get update
apt-get install mongodb elasticsearch graylog2-server graylog2-web apache2 libapache2-mod-passenger

Vous pouvez aller boire un café, ya ~500Mo à downloader/installer. Ensuite il faut configurer quelques trucs :

/etc/graylog2.conf
syslog_listen_port = 10514

/etc/rsyslog.conf
$ModLoad immark
$ModLoad imudp
$UDPServerRun 514
$ModLoad imtcp
$InputTCPServerRun 514

/etc/rsyslog.d/50-default.conf
#*.*;auth,authpriv.none -/var/log/syslog

/etc/apache2/sites-available/default

<VirtualHost *:80>
    DocumentRoot /usr/share/graylog2-web/public/
        RailsEnv 'production'
    <Directory /usr/share/graylog2-web/public/>
        Allow from all
        Options -MultiViews
    </Directory>

    ErrorLog /var/log/apache2/error.log
    LogLevel warn
    CustomLog /var/log/apache2/access.log combined
</VirtualHost>

/etc/rsyslog.d/32-graylog2.conf

$template GRAYLOG2,"<%PRI%>1 %timegenerated:::date-rfc3339% %HOSTNAME% %syslogtag% - %APP-NAME%: %msg:::drop-last-lf%\n"
$ActionForwardDefaultTemplate GRAYLOG2
$PreserveFQDN on
*.*     @localhost:10514

/etc/security/limits.conf
root – nofile 64000
root – memlock unlimited

/etc/pam.d/su
session required pam_limits.so

Après, on secoue bien :

service elasticsearch start
service mongodb restart
service graylog2-server start
service rsyslog restart
service apache2 restart

Selon le formatage des messages, il est parfois nécessaire d’avoir un reverse DNS pour que le hostname remonte bien (au lieu de l’ip). Sur le screenshot suivant vous pourrez constater la présence de log provenant d’ESXi 5, de pfSense et d’Astaro/UTM mais nous avons pu également valider que cette solution était fonctionnelle pour ESXi 4, FreeNAS, NTsyslog, Snare/Epilog et nxlog.

On vous laisse découvrir les joyeusetés des streams et des analytics de Graylog2 ;)

Tags: ,

Nexenta 3.1.3.5 paravirtualisé

C’est à l’occasion du VMworld 2012 EMEA que nous avons pu en savoir un peu plus sur la roadmap de l’appliance ZFS et sur la fameuse version 3.1.3.5 (oui c’est n’importe quoi mais il paraîtrai qu’il fallait rapidement sortir une version et que la 3.1.4 n’était pas prête…) qui a fait son apparition cette semaine.

A la lecture du release notes, on remarque tout de suite qu’il est globalement question de nouveaux drivers dont vmxnet3 (très attendu) et pvscsi, derniers maillons manquant à Nexenta pour être une pure appliance de stockage VMware.

Pour ceux qui passeraient par le processus d’upgrade, il est fort probable que vous ayez à lancer les commandes suivantes (suivit d’un reboot) pour installer les 2 packages contenant les pilotes :

apt-get install nexenta-vmxnet3
apt-get install nexenta-pvscsi

Pendant notre échange avec les gens de chez Nexenta (qui nous ont confirmé la sortie de Nexenta 4.0 basé sur illumos d’ici la fin de l’année), nous avons pu apercevoir la nouvelle version de NexentaVSA for View (une appliance dédié au VDI)  mais surtout l’intégration d’une version++ d’Aura, l’interface de monitoring révolutionnaire développé à l’arrache pendant le VMworld 2011 :

D’après le sales manager présent lors de notre discussion, l’intégration d’Aura serait prévue dans la version 4.0 de Nexenta et le support de VAAI NFS sera pour la suivante mais surtout inclut dans la version Community Edition comme pour le VAAI en mode block depuis la 3.1.3. D’ici la, nous aurons tout de même droit à la version 3.1.4 :)

Tags:

[PSH] HA AutoSlotSize – MAJ

MAJ 21.02.2013 : Ajout de filtres pour les hosts vide afin d’éviter les divisions par 0.

MAJ 06.02.2013 : Debug des scripts.

MAJ 22.11.2012 : Nous avons oublié de préciser que pour que le script fonctionne correctement, le “statistic level” pour l’intervale de 5 minutes doit être à 2 minimum :

MAJ 23.10.2012 : Ajout d’un filtre dans les scripts pour ne modifier le(s) cluster que si nécéssaire.

Suite au post de Frank “distributed” Denneman traitant du sujet délicat des HA slot size “HA admission control is not a capacity management tool“, nous avons dépoussiéré une vieille idée de script de configuration automatique des “slot size” (mémoire et cpu) d’un cluster HA pour en faire un bon petit oneliner. L’idée est forcer le “slot size” à une valeur reflétant une vm moyenne du cluster afin de savoir approximativement la “place” restante dans le cluster et surtout pouvoir vraiment tirer parti de l’alarme “insufficient resources to satisfy HA failover level“

Nous avons fais nos tests sur un cluster de 6 ESXi 4.1 (4×4 cores 2.3Ghz & 64Go de RAM) contenant environ 150 VM sans réservations. Par défaut, voici ce qu’HA remonte comme information dans le vCenter :

Ces informations sont totalement erronés étant donné que le cluster est presque plein (en tenant compte du N-1 pour HA) mais c’est le comportement attendu d’HA lorsque les VM n’ont pas de réservations (l’overhead est pris en compte). On notera que le nombre de vcpu correspond à la plus grosse vm.

Voici ce qu’HA remonte après avoir passé notre script :

On est nettement plus proche de la vérité. Le calcul pour le cpu est la moyenne d’utilisation journalière par vm démarrée, idem pour les vcpu mais pour la ram nous avons du faire un choix pas trop optimiste (active memory) ni trop optimiste (consumed memory). Nous avons donc choisi de prendre la valeur médiane entre active et consumed (moyene journalière). Voici le résultat sur une journée de stat sur notre cluster de test :

Idéalement, ce script est donc à lancée une fois par jour. Voici la version pour vSphere 4.x (filtré par cluster où HA est activé) :

foreach ($cluster in (get-view -viewtype ClusterComputeResource -property Host,ConfigurationEx|?{$_.ConfigurationEx.DasConfig.Enabled})) {,($cluster.host|%{get-view $_ -property runtime,vm}|?{$_.Runtime.ConnectionState -match "^connected$"}|?{($_.vm|%{get-view $_ -property Runtime}|?{$_.Runtime.PowerState -eq "poweredon"})}|select @{n="mem";e={(($_|%{((get-view (Get-View ServiceInstance).content.PerfManager).QueryPerf((New-Object VMware.Vim.PerfQuerySpec -property @{entity = $_.moref;format = "normal";IntervalId = "300";MetricId = (New-Object VMware.Vim.PerfMetricId -property @{instance = "";counterId = (((Get-View (Get-View ServiceINstance).Content.PerfManager).PerfCounter|?{$_.groupinfo.key -match "mem"}|?{$_.nameinfo.key -match "active$"}|?{$_.RollupType -match "average"}).key)})}))|%{$_.value}|%{$_.value}|measure -Average).average/(($_.vm|%{get-view $_ -property Runtime}|?{$_.Runtime.PowerState -eq "poweredon"})|measure).count/1kb}) + ($_|%{((get-view (Get-View ServiceInstance).content.PerfManager).QueryPerf((New-Object VMware.Vim.PerfQuerySpec -property @{entity = $_.moref;format = "normal";IntervalId = "300";MetricId = (New-Object VMware.Vim.PerfMetricId -property @{instance = "";counterId = (((Get-View (Get-View ServiceINstance).Content.PerfManager).PerfCounter|?{$_.groupinfo.key -match "mem"}|?{$_.nameinfo.key -match "consumed$"}|?{$_.RollupType -match "average"}).key)})}))|%{$_.value}|%{$_.value}|measure -Average).average/(($_.vm|%{get-view $_ -property Runtime}|?{$_.Runtime.PowerState -eq "poweredon"})|measure).count/1kb}))/2}}, @{n="cpu";e={($_|%{((get-view (Get-View ServiceInstance).content.PerfManager).QueryPerf((New-Object VMware.Vim.PerfQuerySpec -property @{entity = $_.moref;format = "normal";IntervalId = "300";MetricId = (New-Object VMware.Vim.PerfMetricId -property @{instance = "";counterId = (((Get-View (Get-View ServiceINstance).Content.PerfManager).PerfCounter|?{$_.groupinfo.key -match "cpu"}|?{$_.nameinfo.key -match "usagemhz"}|?{$_.RollupType -match "average"}).key)})}))|%{$_.value}|%{$_.value}|measure -Average).average/(($_.vm|%{get-view $_ -property Runtime}|?{$_.Runtime.PowerState -eq "poweredon"})|measure).count})}}, @{n="vcpu";e={(($_.vm|%{get-view $_ -property Runtime,Config}|?{$_.Runtime.PowerState -eq "poweredon"})|%{$_.Config.Hardware.NumCpu}|measure -average).average}}|measure -average -property mem,cpu,vcpu|%{[math]::round($_.average,0)})|%{if (($_|measure -Sum).sum -ne ($cluster.ConfigurationEx.DasConfig.Option|?{$_.key -match "das.slotCpuInMhz|das.slotMemInMB"}|measure -Sum -Property value).sum) {$cluster.ReconfigureComputeResource((New-Object VMware.Vim.ClusterConfigSpecEx -property @{dasConfig=(New-Object VMware.Vim.ClusterDasConfigInfo -property @{option=@((New-Object VMware.Vim.OptionValue -property @{key="das.vmMemoryMinMB";value=$_[0].tostring()});(New-Object VMware.Vim.OptionValue -property @{key="das.vmCpuMinMHz";value=$_[1].tostring()});(New-Object VMware.Vim.OptionValue -property @{key="das.slotMemInMB";value=$_[0].tostring()});(New-Object VMware.Vim.OptionValue -property @{key="das.slotCpuInMhz";value=$_[1].tostring()});(New-Object VMware.Vim.OptionValue -property @{key="das.SlotNumVCpus";value=$_[2].tostring()}))})}),$true)}}}

Pour vSphere 5.0, le nombre de vcpu ne rentre plus en comptre pour le calcul du slot size, nous avons donc adapté le script en conséquence :

foreach ($cluster in (get-view -viewtype ClusterComputeResource -property Host,ConfigurationEx|?{$_.ConfigurationEx.DasConfig.Enabled})) {,($cluster.host|%{get-view $_ -property runtime,vm}|?{$_.Runtime.ConnectionState -match "^connected$"}|?{($_.vm|%{get-view $_ -property Runtime}|?{$_.Runtime.PowerState -eq "poweredon"})}|select @{n="mem";e={(($_|%{((get-view (Get-View ServiceInstance).content.PerfManager).QueryPerf((New-Object VMware.Vim.PerfQuerySpec -property @{entity = $_.moref;format = "normal";IntervalId = "300";MetricId = (New-Object VMware.Vim.PerfMetricId -property @{instance = "";counterId = (((Get-View (Get-View ServiceINstance).Content.PerfManager).PerfCounter|?{$_.groupinfo.key -match "mem"}|?{$_.nameinfo.key -match "active$"}|?{$_.RollupType -match "average"}).key)})}))|%{$_.value}|%{$_.value}|measure -Average).average/(($_.vm|%{get-view $_ -property Runtime}|?{$_.Runtime.PowerState -eq "poweredon"})|measure).count/1kb}) + ($_|%{((get-view (Get-View ServiceInstance).content.PerfManager).QueryPerf((New-Object VMware.Vim.PerfQuerySpec -property @{entity = $_.moref;format = "normal";IntervalId = "300";MetricId = (New-Object VMware.Vim.PerfMetricId -property @{instance = "";counterId = (((Get-View (Get-View ServiceINstance).Content.PerfManager).PerfCounter|?{$_.groupinfo.key -match "mem"}|?{$_.nameinfo.key -match "consumed$"}|?{$_.RollupType -match "average"}).key)})}))|%{$_.value}|%{$_.value}|measure -Average).average/(($_.vm|%{get-view $_ -property Runtime}|?{$_.Runtime.PowerState -eq "poweredon"})|measure).count/1kb}))/2}}, @{n="cpu";e={($_|%{((get-view (Get-View ServiceInstance).content.PerfManager).QueryPerf((New-Object VMware.Vim.PerfQuerySpec -property @{entity = $_.moref;format = "normal";IntervalId = "300";MetricId = (New-Object VMware.Vim.PerfMetricId -property @{instance = "";counterId = (((Get-View (Get-View ServiceINstance).Content.PerfManager).PerfCounter|?{$_.groupinfo.key -match "cpu"}|?{$_.nameinfo.key -match "usagemhz"}|?{$_.RollupType -match "average"}).key)})}))|%{$_.value}|%{$_.value}|measure -Average).average/(($_.vm|%{get-view $_ -property Runtime}|?{$_.Runtime.PowerState -eq "poweredon"})|measure).count})}}|measure -average -property mem,cpu|%{[math]::round($_.average,0)})|%{if (($_|measure -Sum).sum -ne ($cluster.ConfigurationEx.DasConfig.Option|?{$_.key -match "das.slotCpuInMhz|das.slotMemInMB"}|measure -Sum -Property value).sum) {$cluster.ReconfigureComputeResource((New-Object VMware.Vim.ClusterConfigSpecEx -property @{dasConfig=(New-Object VMware.Vim.ClusterDasConfigInfo -property @{option=@((New-Object VMware.Vim.OptionValue -property @{key="das.vmMemoryMinMB";value=$_[0].tostring()});(New-Object VMware.Vim.OptionValue -property @{key="das.vmCpuMinMHz";value=$_[1].tostring()});(New-Object VMware.Vim.OptionValue -property @{key="das.slotMemInMB";value=$_[0].tostring()});(New-Object VMware.Vim.OptionValue -property @{key="das.slotCpuInMhz";value=$_[1].tostring()}))})}),$true)}}}

As of vSphere API 5.0, the number of vcpus is no longer used for slot calculations

Pour vSphere 5.1, le slot size est maintenant configurable dans via la GUI du web client (et donc de nouvelles propriétés sont disponibles) mais on va le faire en PowerCLI quand même :)

foreach ($cluster in (get-view -viewtype ClusterComputeResource -property Host,ConfigurationEx|?{$_.ConfigurationEx.DasConfig.Enabled})) {,($cluster.host|%{get-view $_ -property runtime,vm}|?{$_.Runtime.ConnectionState -match "^connected$"}|?{($_.vm|%{get-view $_ -property Runtime}|?{$_.Runtime.PowerState -eq "poweredon"})}|select @{n="mem";e={(($_|%{((get-view (Get-View ServiceInstance).content.PerfManager).QueryPerf((New-Object VMware.Vim.PerfQuerySpec -property @{entity = $_.moref;format = "normal";IntervalId = "300";MetricId = (New-Object VMware.Vim.PerfMetricId -property @{instance = "";counterId = (((Get-View (Get-View ServiceINstance).Content.PerfManager).PerfCounter|?{$_.groupinfo.key -match "mem"}|?{$_.nameinfo.key -match "active$"}|?{$_.RollupType -match "average"}).key)})}))|%{$_.value}|%{$_.value}|measure -Average).average/(($_.vm|%{get-view $_ -property Runtime}|?{$_.Runtime.PowerState -eq "poweredon"})|measure).count/1kb}) + ($_|%{((get-view (Get-View ServiceInstance).content.PerfManager).QueryPerf((New-Object VMware.Vim.PerfQuerySpec -property @{entity = $_.moref;format = "normal";IntervalId = "300";MetricId = (New-Object VMware.Vim.PerfMetricId -property @{instance = "";counterId = (((Get-View (Get-View ServiceINstance).Content.PerfManager).PerfCounter|?{$_.groupinfo.key -match "mem"}|?{$_.nameinfo.key -match "consumed$"}|?{$_.RollupType -match "average"}).key)})}))|%{$_.value}|%{$_.value}|measure -Average).average/(($_.vm|%{get-view $_ -property Runtime}|?{$_.Runtime.PowerState -eq "poweredon"})|measure).count/1kb}))/2}}, @{n="cpu";e={($_|%{((get-view (Get-View ServiceInstance).content.PerfManager).QueryPerf((New-Object VMware.Vim.PerfQuerySpec -property @{entity = $_.moref;format = "normal";IntervalId = "300";MetricId = (New-Object VMware.Vim.PerfMetricId -property @{instance = "";counterId = (((Get-View (Get-View ServiceINstance).Content.PerfManager).PerfCounter|?{$_.groupinfo.key -match "cpu"}|?{$_.nameinfo.key -match "usagemhz"}|?{$_.RollupType -match "average"}).key)})}))|%{$_.value}|%{$_.value}|measure -Average).average/(($_.vm|%{get-view $_ -property Runtime}|?{$_.Runtime.PowerState -eq "poweredon"})|measure).count})}}|measure -average -property mem,cpu|%{[math]::round($_.average,0)})|%{if (($_|measure -Sum).sum -ne (@($cluster.ConfigurationEx.DasConfig.AdmissionControlPolicy.SlotPolicy.Memory, $cluster.ConfigurationEx.DasConfig.AdmissionControlPolicy.SlotPolicy.Cpu)|measure -Sum).sum) {$cluster.ReconfigureComputeResource((New-Object VMware.Vim.ClusterConfigSpecEx -property @{dasConfig=((New-Object VMware.Vim.ClusterDasConfigInfo -property @{admissionControlPolicy=((New-Object VMware.Vim.ClusterFailoverLevelAdmissionControlPolicy -property @{slotPolicy=(New-Object VMware.Vim.ClusterFixedSizeSlotPolicy -property @{cpu = $_[1];memory = $_[0]});FailoverLevel = $cluster.ConfigurationEx.DasConfig.AdmissionControlPolicy.FailoverLevel}))}))}),$true)}}}

Ceux qui ont l’oeil auront certainement remarqué l’usage d’une “multidimensional array” (aka nested array) dans nos oneliner pour faire passer des tableaux au travers d’un pipe sans en changer le type.

Pour plus d’information sur HA, nous vous conseillons vivement la lecture de la série “Clustering Deepdive” de Duncan et Frank.

Tags: , , , ,