Proxmox VE
Pourquoi faire compliquer ?
Comme d’habitude, j’allais prendre par facilité une debian et tout réinstaller as usual (faut pas changer les petites habitudes).
Mais en voyant le travail nécessaire pour la migration, reconfiguration & co … (c’est un serveur qui a 2ans 1/2 et qui a servi pour pas mal de projet perso ou non).
Je me suis dit qu’il serait bien de réfléchir à une solution de facilité pour les prochaines fois et accélérer les migrations et l’organisation du serveur.
Je me suis donc renseigné et j’ai fini par arriver sur la virtualisation et le cloud.
Des mots qui auraient tendance à me faire un peu peur dernièrement vu l’utilisation abusive qui en est faite par les marketeux de tout poile.
Sur le papier, faire de la virtualisation sur un serveur, ça permet :
- d’isoler les VM les unes des autres
- la création/suppression de VM en moins de 5 minutes
- mieux gérer les ressources et éviter qu’un process/système défaillant impacte toute la machine
- pouvoir démarrer/arrêter ses VM selon ses besoins
- pouvoir backuper/migrer des VM entières et les redémarrer en quelques secondes
Autant dire que ça parait plutôt pas mal sur le papier.
Après avoir lus de nombreux test/review je me suis finalement tourné vers Proxmox (open-source, gratuit et basé sur débian).
Jusque-là, mes principaux contacts avec la virtualisation étaient soit sous desktop (vmware, virtual box, wine), soit sous forme de VPS déjà préconfiguré.
Autant dire que je partais au combat équipé comme un touriste ?
La virtualisation, comment ça marche ?
Alors pour faire simple il y a deux formes de virtualisation couramment utilisées sur serveur.
- La virtualisation hard (l’hypervision)
C’est souvent le type de virtualisation auquel on pense en premier. Cela consiste à émuler entièrement une machine et tout son hardware et à y installer un os.
L’avantage : on peut émuler quasiment n’importe quel hardware, et on peut y installer quasiment n’importe quel os. Les VM sont totalement indépendantes les unes des autres.
L’inconvénient : c’est lourd et ça coute cher.
Soft connus : VMware, Xen, KVM, Hyper-v - La virtualisation soft (l’isolation ou virtualisation par container)
Très utilisé pour de l’hosting (vps, vks) car peu chère et facile à mettre en œuvre. Cela revient plus ou moins à lancer des OS sous forme de process de la machine Hôte. Toutes les VM partage donc le kernel de la machine hôte mais chaque OS a sa propre instance et vis sa propre vie.
L’avantage : quasiment par d’overhead et de pertes de performances.
Inconvénient : ne peut être utiliser que pour des systèmes linux/unix (comme la machine hôte). Les environnements ne sont pas complètement isolés, et on peut par exemple tuer un processus d’une VM depuis la machine hôte.
Soft connu :LXC, OpenVZ, Chroot
Bien entendu, aucun système n’est parfait et les deux ont leurs avantages. Personnellement, j’étais surtout intéressé par l’isolation ne souhaitant installé que des systèmes unix.
Proxmox, kézako?
Proxmox c’est un hyperviseur graphique (en version web) qui permet de gérer ses machines virtuel.
Il est proposé gratuitement et on peut le trouver en version préinstallé chez de nombreux fournisseurs de serveur dédié.
Sinon il s’installe sans mal sur une debian et peut même se tester dans une VM (c’est cocasse, mais ça marche).
Un des points qui m’a le plus intéressé, c’est qu’il propose à la fois l’utilisation de OpenVZ que de KVM. Donc on peut faire de l’isolation comme de la virtualisation en fonction de ses besoins, voir même mélanger les deux.
En gros si je veux avoir une infra avec 2 debian, 3 ubuntu et 2 windows. C’est possible!
Ça s’utilise comment?
Voici le type d’affichage que l’on obtient lorsque l’on se connecte à l’interface proxmox
Pour faire simple, on a :
- a gauche : la liste des machines rangé par datacenter
- au centre : un récapitulatif de la machine et si on scroll un peu, de nombreux graphiques (cpu, ram, network, io).
- en haut à droite : la possibilité de créé des VM
Et si on clique sur une VM, on gardera un affichage similaire mais avec les infos relatives à la machine (graphique dédié & co).
Voilà donc gros truc de faignant, plus besoin de rrd, munin & co. L’hyperviseur s’occupe de grapher automatiquement chaque VM. C’est plutôt pratique et ça assure des graphes cohérents, peu importe les systèmes utilisés sur les VM.
Et voilà ce qui est appelé des templates.
Pour ceux qui n’ont jamais fait de virtualisation, ce sont des systèmes préinstallés qui peuvent se lancer en quelques minutes.
Ici proxmox par défaut en fourni plus de 300 avec tout et n’importe quoi :
- des os nues : debian, ubuntu, centos,
- des cms : wordpress, joomla, drupal, mediawiki
- et de nombreux soft: gitlab, trac, tomcat, symfony, mongodb, mysql, django …
En double cliquant on peut récupérer le tar.gz du système voulu, et par la suite il pourra être utilisé pour créer plein de vm.
Donc pas de procédure d’install relou, il suffit de cliquer dans l’interface pour télécharger un template, créer une vm avec et la lancer.
Les seules infos à saisir à la création son un nom, un password root, la configuration réseau, les ressources ram/cpu/disk et basta.
Bon je vous rassure, vous pouvez créé vos templates, et sinon installer vos vm depuis une ISO tout ce qu’il y a de plus standard, c’est juste plus long.
Si vous êtes arrivé jusque là, voici quelques liens qui pourraient vous intéresser :
- http://fr.wikipedia.org/wiki/Virtualisation
- http://www.proxmox.com/
Allez on a fini la présentation, la prochaine fois on pourra enfin ouvrir la console et taper des commandes ^^
Voilà la suite du post d’hier sur proxmox et la virtualisation. Après la présentation, je vais rapidement présenter l’infra et les grandes lignes concernant la configuration.
L’infrastructure
J’étais pour le coup soumis à quelques contraintes externes, par exemple Kimsufi sur l’offre 2013 ne permet plus la prise en charge des IP-failover.
Cela aurait permis de faire pointer plusieurs IP sur un même serveur et ainsi de pouvoir attribuer une IP à certaines VM.
J’étais donc contraint d’avoir l’ip sur mon host et de devoir gérer moi-même le trafic entrant.
J’ai donc décidé assez simplement :
- De mettre toutes mes VM en venet (donc sur un VLAN interne) et donc sans accès au net.
- Ajouter une interface sur la machine Hote pour qu’elle puisse accéder au venet
- Configurer la machine hôte pour autoriser le forwarding VLan<->Internet
- Et finalement gérer les connections externe via du Nat et Iptables.
Donc depuis le réseau interne, les VM ont accès à internet sans problèmes.
Depuis internet, une IP (celle de la machine hôte) et en fonction des requêtes et du port utilisé on arrivera sur la VM adéquate.
Cela permet également de cacher son infra à des bots/robots qui tenterait de scanner les machines pour y trouver des failles.
Je vais donc vous décrire dans la suite de l’article, les différentes étapes permettant d’arriver à ce résultat.
La gestion des VM
Une fois installés, les VM sont des machines à part entière et les règles usuelles d’administration s’y appliquent.
- généré des mots de passe aléatoire
- penser à update régulièrement (voir l’automatiser)
- éviter de laisser trop de ports ouverts, voir n’en laisser aucun (si vous n’utiliser par ssh par exemple).
Enfin je vais pas vous apprendre les bases communes à l’administration de tout serveur, il y a déjà de nombreux tuto sur le sujet.
Par contre petite subtilité fournie par proxmox, la possibilité depuis la machine hôte de se logger dans une VM.
C’est très rapide et ça évite d’avoir une connexion ssh par vm.
1
2
3
4
5
6
7
8
9
|
root@host> # Pour vous logger sur la VM avec l'id 100 (ici network) vzctl enter 100 root@network> # On ressort de la VM et on récupère son prompt exit root@host> |
C’est hyper pratique et on prend vite le coup de changer de VM à tout vas.
Attention à ne pas refaire exit, sinon vous allez killer votre console ssh ?
La gestion du Nat
De ce coté là pas grand-chose de révolutionnaire. Pour faire simple, j’ai 2 interfaces vmbr0 (interface net) et vmbr0:0 (interface venet)
Premièrement, on active le forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward
Deuxièmement, on devrait taper des règles IPTable mais comme je suis faignant, je vais vous filer un script qui fait ça à votre place.
Créé un premier fichier qui va servir à stocker votre configuration : /etc/nat.conf
01
02
03
04
05
06
07
08
09
10
|
#=================================================# # Usage : # # ip_outside:port ip_inside:port # # # # Exemple : # # 200.200.200.200:533 10.0.0.1:53 # #=================================================# [votre ip publique]:80 192.168.0.10:80 [votre ip publique]:8080 192.168.0.12:80 |
Puis enregistrer le script suivant : run-nat.sh (vous pouvez le mettre où vous voulez, votre home est un bon endroit).
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
#!/bin/bash iptables -t nat -F iptables -t nat -X iptables -t nat -Z iptables -t nat -A POSTROUTING -s 192.168.0.0 /24 -o vmbr0 -j SNAT --to 200.200.200.200 function addNat { iptables -t nat -A PREROUTING -p tcp -d $1 --dport $2 -i vmbr0 -j DNAT --to-destination $3:$4 } if [ -f /etc/nat .conf ] then # Nettoyage du fichier de configuration cat /etc/nat .conf | grep - v "^\s*#" | grep - v "^\s*$" | sed -e 's/^\s*//g' > /tmp/nat .$$.txt while IFS=:- read ipout portout ipin portin do addNat $ipout $portout $ipin $portin done < /tmp/nat .$$.txt rm /tmp/nat .$$.txt fi |
Et voilà vous avez juste à mettre vos valeurs à la place des différentes adresses IP :
- 192.168.0.0/24 (l’ip du réseau venet)
- 200.200.200.200 (l’ip public du serveur)
- /etc/nat.conf (le path où vous avez enregistré votre fichier de config)
Il ne reste plus qu’à
1
2
|
chmod +x run-nat.sh . /run-nat .sh |
Et il va automatiquement nettoyer et réécrire vos règles iptables.
Attention quand même, les règles iptables ne sont pas persistantes, si le serveur reboot elles seront vidés, il faudra donc penser à lancer ce script au démarrage.
Et pour le web, un reverse proxy
Pour ceux qui ont déjà fait du nat, c’est pratique, mais cela représente un gros inconvénient. On redirige un port vers une ip et donc une machine unique.
Or on a de fortes chances d’avoir plusieurs serveurs web sur son réseau (prod, dev, tools, …).
L’idée va donc être d’installer sur une VM ou l’hôte, un soft pour accepter les requêtes http et choisir automatiquement et de façon transparente quelle VM il faut utiliser.
C’est ce qu’on appelle un reverse proxy.
Il en existe de nombreux spécialisé dans leurs domaines : pound, haproxy, nginx, apache, …
J’ai choisi d’utiliser nginx car il est performant, permet de faire du cache et les fichiers de configurations reste facilement compréhensibles.
pour l’installation :
1
|
apt-get install nginx |
Alors, pour le soft il y a assez peu de fichiers à connaître :
- /etc/nginx/nginx.conf (le fichier de configuration par défaut)
- /etc/nginx/sites-enabled/* (le dossier où vous enregistrez vos différents sites)
Et c’est presque tout, quand je vous avais dit que c’était facilement compréhensible.
Allez c’est parti pour la configuration custom.
Alors pour le fichier /etc/nginx/nginx.conf
01
02
03
04
05
06
07
08
09
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
|
# Two processes work well for a single CPU user www-data; worker_processes 2; error_log /var/log/nginx/error .log; pid /var/run/nginx .pid; events { worker_connections 1024; use epoll; } http { include /etc/nginx/mime .types; # Nginx does the logging access_log /var/log/nginx/access .log; # TCP sendfile on; keepalive_timeout 65; tcp_nodelay on; server_names_hash_bucket_size 64; server_tokens off; # Have nginx do the compression, turn off Apache's mod_deflate gzip on; gzip_vary on; gzip_http_version 1.1; gzip_disable "MSIE [1-6]\.(?!.*SV1)" ; gzip_comp_level 6; gzip_min_length 1400; gzip_proxied any; # text/html mime type is automatically included for gzip, have to add the rest gzip_types text /plain text /css application /x-javascript text /xml application /xml application /rss +xml text /javascript ; # Definir une zone de cache appeller "STATIC de 1Go Max" proxy_cache_path /var/cache/nginx levels=2:2:2 keys_zone=STATIC:1000m inactive=24h max_size=1g; proxy_temp_path /var/lib/nginx/proxy ; include /etc/nginx/conf .d/*.conf; include /etc/nginx/sites-enabled/ *; } |
Et pendant qu’on y est, je vais, vous conseiller, de créer 2 fichiers supplémentaires (c’est facultatif, mais pratique pour la suite).
Ça permettra de séparer les données que l’on peut mettre en cache (js, img, css) des données qui doivent être accédées directement.
Fichier pour le proxy simple : /etc/nginx/proxy.conf
1
2
3
4
5
6
7
|
proxy_redirect off; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_hide_header X-Powered-By; proxy_set_header Server "" ; |
Fichier pour le proxy avec cache : /etc/nginx/proxy-cache.conf
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
proxy_redirect off; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_hide_header X-Powered-By; # Clear a few headers we might not want to pass on proxy_set_header Accept "" ; proxy_set_header Connection "" ; proxy_set_header Server "" ; # Enable caching for the proxied requests using the STATIC storage # Cache 200 (OK), as well as 301 and 302 (redirect) responses for 30m proxy_cache STATIC; proxy_cache_valid 200 301 302 30m; proxy_connect_timeout 90; proxy_send_timeout 90; proxy_read_timeout 90; # Allow using stale data (cached data that has expired) in the following cases: # - an error has occurred while connecting to the server, sending a request to it, or reading its response # - timeout occurred during the connection with the server, transfer the request or while reading response from the server # - server returned a empty or incorrect answer # - server returned an error status (500, 502-504) proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504; |
Donc pour résumer ce que font ces 3 fichiers de configuration :
- ils permettent de camoufler les infos sur les serveurs web utilisés
- ils permettent l’utilisation de cache
- ils permettent le gzip automatique du contenu http
Voilà on est enfin parer pour définir tous ces domaines/serveurs internes dans /etc/nginx/sites-enabled/
Prenons le cas du /etc/nginx/sites-enabled/default (mais vous pouvez en créer plein d’autres dans ce dossier).
01
02
03
04
05
06
07
08
09
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
|
# # Blog perso # server { server_name blog.ganbaranai.fr blog.remilia.fr; access_log /var/log/nginx/perso .access.log; error_log /var/log/nginx/perso .error.log; # On cache les fichiers statics 24h (css/js) location ~*^.+(css|js)$ { include proxy-cache.conf; proxy_pass http: //192 .168.0.11:8080; expires 24h; } # On cache les fichiers statics 1semaine (img/archives/doc) location ~*^.+(swf|jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt| tar |mid|midi|wav|bmp|rtf|js)$ { include proxy-cache.conf; proxy_pass http: //192 .168.0.11:8080; expires 168h; } # On rend le reste directement location / { include proxy.conf; proxy_pass http: //192 .168.0.11:8080; } } # # Default (port 80 sur perso) # server { listen 80; server_name ganbaranai.fr; access_log /var/log/nginx/access .log; error_log /var/log/nginx/error .log; location / { include proxy.conf; proxy_pass http: //192 .168.0.11:80/; } } |
Et comme ça vous pouvez définir des centaines de règles différentes pour gérer la façon dont on accède en http à vos services.
Les infos les plus utiles à comprendre sont :
listen 80; (on écoute toujours sur le port 80 de toute façon dans cet exemple).
server_name: test.domain.fr kikoo.domain.fr *.domain.fr; (nom de domaine qui va être concerné par cette règle).
access_log & error_log : ça parait évident, mais ça permet de séparer les logs par service, ce qui est assez pratique.
un ou plusieurs bloc ‘location’ : C’est un filtre qui match sur l’url « location / » est celui par défaut et sinon vous avez un peu plus haut celui pour matcher sur les extensions.
‘include proxy.conf’ ou ‘include proxy-cache.conf’ : voilà donc là vous devez enfin comprendre ce qu’on a fait juste avant. En fonction de la règle location, on va activer ou non le cache des fichiers.
expire : permet de définir un Expire HTTP pour forcer le cache par le browser du client.
proxy_pass : le champs le plus utile puisqu’il va vous permettre de choisir sur quelle IP/Port envoyer la requête.
Une fois que c’est fait, un petit
1
|
/etc/nginx/reload |
Et il va recharger les fichiers de config et vous prévenir en cas de problèmes.
Et normalement c’est tout bon, il reste plus qu’à vérifier tout ça.
Mais c’est pas trop lourd comme système pour du web ?
Et bah … effectivement, ça peut paraître compliqué, mais niveau performance, elles sont bien meilleures qu’un simple serveur web type apache.
Le Nginx ne fait rien d’autre que proxy et cache et il est très rapide pour ça (pas de php & co).
Et lorsqu’il a les fichiers en cache, il les sert directement au client sans recontacter le serveur web de la VM.
On a donc un serveur léger qui sert des fichiers static, et le serveur lourd derrière (apache la plupart du temps) qui ne va plus faire que générer les pages web.
Le serveur apache ne faisant presque plus rien, il rend les pages bien plus rapidement sans la moindre optimisation.
Voici d’ailleurs un exemple avec le blog et sa homepage :
- Sans le cache, j’en suis à 49 requêtes HTTP sur le serveur apache (surtout des images)
- Avec le cache, plus qu’une requête celle de la page php, tout le reste a été pris en charge par le cache de nginx.
J’en ai rapidement parlé plus tôt, mais un des autres avantages et le fait de cacher la signature des serveurs web utilisés.
De nombreux bots parcourent le web à la recherche de serveurs avec des versions bien précises sur lequel des failles ont été découvertes.
Le fait d’obfusquer ces informations et ne pas indiquer quel serveur, quel langage, quelle version sont utilisés rend plus difficiles les attaques automatisées.
Ça permet aussi de pouvoir faire cohabiter dans un même website des technos très différentes.
Sur mon domaine, j’ai actuellement du python, du ruby on rail, du lighttpd/nginx/apache suivant les services, mais le passage de l’un à l’autre est totalement transparent.
Moins de galères que reconfigurer pour chaque serveur expire, gzip, header http. Ici ce n’est géré que sur un seul point d’entrée, ce qui facilite la gestion.
Mais qui dit point d’entrée unique, dit aussi point sensible du réseau, il faudra donc penser à le dédoubler dès que possible.
Et voilà 3eme partie, qui celle-là sera bien plus courte que les deux autres, mais sûrement la plus fun.
Ça va consister à vérifier si ce qu’on a fait jusque-là roox du poney ou non, et voir quel est le point de faiblesse de cette infra.
Comment on test chef ?
Il existe plein de moyen compliqué pour faire de vrai stresstests, mais vu qu’on est faignant et qu’on va juste faire un ou deux tests, osef.
Allez, pour ça je vais vous présenter un site loadimpact.com qui va s’occuper de ça pour nous.
C’est un site payant, mais qui propose des comptes gratuits avec lesquels on peut déjà faire quelques tests sympathiques.
Pour schématiser, ce service utilise plein de VM situé chez amazon, et fait des requêtes sur votre siteweb pour en vérifier le comportement.
Il compile les résultats et vous fourni des graphiques clef en main, pas besoin de se faire chier.
Allez, c’est parti on va lancer un premier test, voyons ce que ça donne :
Voici le détail : http://loadimpact.com/load-test/blog.ganbaranai.fr-1fdd577124e8d3878896760c9059e236
Alors, essayons de décrypter un peu tout ça, voici les infos les plus importantes :
- SBU :Nombre de visiteurs simulé (ça reste des scripts, il ne font qu’imiter le comportement d’un visiteur).
- Requete par Seconde
- Tcp Connexion
- Et le plus important de tous, « User load Time », le temps de réponse du serveur.
Si vous avez un système parfait, l’ « User load Time » doit être plat, du début à la fin du test peut importe l’augmentation du nombre de requêtes et de SBU.
Ça veut simplement dire que le temps de réponse du serveur reste stable et que celui-ci n’est pas submergé par la charge.
Comme on peut le voir plus haut, l’infra a l’air de tenir, et effectivement les serveurs ont l’air de se toucher la nouille coté graph proxmox.
Donc je pourrais me satisfaire de ça et me dire que mon blog à l’air de tenir facile pour 50 visiteurs simultanés (je ne les aurais sûrement jamais sur ce blog de toute façon :D)
Mais c’est tout chef ?
Bien sûr que non, c’est pas fini, si je fais ça c’est pour testé et voir où ça coincera en premiers.
Ni une ni deux, je claque mes quelques crédits pour un test un peu plus sympa.
Avec une augmentation progressive de 0 à 200 users simultanées depuis 2 sites différents Dublin/Londres sur 10 minutes.
Et c’est parti …
50 visiteurs ça va easy
100 visiteurs ça va eaxy
150 visiteurs … hum … ça fluctue un peu
200 visiteurs … padaboum les temps de réponses s’envole passant de ~1s à 6s
Voici le détail : http://loadimpact.com/load-test/blog.ganbaranai.fr-e095b362ec675dda79202bb2d8c709aa
Bon ok, ce sont quand même 200 visiteurs soit + de 250r/s et un peu plus de 1000 connexions TCP/IP, mais quand même.
Le site était toujours accessible, j’ai fait quelques accès pendant le test pour vérifier et j’ai toujours pu y accéder.
Mais le fait que les délais augmentent montre que ça coince quelques parts et que ça va s’aggraver très rapidement (l’exponentiel inverse, ça vous parle?)
Où est-ce que ça a coincé ?
En regardant les graph des différents serveurs, le coupable a été vite trouvé. C’est le serveur apache qui héberge le blog.
Malgré le fait que nginx encaisse toutes les requêtes de fichiers static, il n’a jamais passé les 5% CPU. Là où le serveur apache qui ne faisait que du PHP s’est retrouvé à 90~95% (20~25% cpu pour l’intégralité du serveur).
C’est là que je me suis rappelé que je n’avais autorisé sur cette VM qu’un seul des 4 core CPU /o\
Donc concrètement ça marche ou pas ?
Bah bien sûr que ça marche et surtout ce test m’a permis de vérifier quel est le point le plus problématique de mon système.
Un peu de CPU en plus sur cette VM, quelques optimisations Apache/Php/Wordpres (là c’est quasiment un apt-get install apache2 php5 sur cette VM), et je devrais pouvoir passer les ~500 visiteurs simultanés sans trop de problèmes.
Il était une fois, de rapides optimisations web
Dans cette partie, on va laisser proxmox et le réseau de coté pour se concentrer sur la VM qui fait office de serveur web.
On va s’attaquer à un peu tous les éléments d’un serveur qui impacte le temps de rendu d’un site : Mysql/Apache2/PHP/Wordpress
Bon pour premièrement, on va utiliser une commande assez simple permettant de vérifier nos optimisations.
ab -t30 -c5 //blog.mondomaine.com/
C’est un tools de Apache nommé ApacheBench et qui permet de faire plein de requêtes sur une url unique.
C’est beaucoup moins réaliste et complet que le test précédent, mais ça peut se faire en local et c’est simple à lancer.
Vous pouvez le relancer en boucle à différents point du tuto pour suivre l’évolution de perf.
Ajoutons quelques tools
Installation de Memcache & Xcode :
aptitude install libcache-memcached-perl php5-memcache memcached aptitude install php5-xcache
Et modifier /etc/php5/conf.d/xcache.ini
xcache.size = 64M
Pour Mysql
Hum … j’ai la flemme donc ca sera mysqltuner
aptitude install mysqltuner mysqltuner
C’est un script bien connu qui va s’occuper de vous suggérer des optimisations en fonction de votre utilisation.
Il est vivement conseillé de l’exécuter après des heures/jours d’usage de votre site.
Voici le type d’informations qu’il fournit :
General recommendations: Run OPTIMIZE TABLE to defragment tables for better performance MySQL started within last 24 hours - recommendations may be inaccurate Enable the slow query log to troubleshoot bad queries When making adjustments, make tmp_table_size/max_heap_table_size equal Reduce your SELECT DISTINCT queries without LIMIT clauses Variables to adjust: tmp_table_size (> 50M) max_heap_table_size (> 50M)
Passons à Apache
Donc toujours dans /etc/apache2/apache2.conf
StartServers 4 MinSpareServers 4 MaxSpareServers 12 MaxClients 200 MaxRequestsPerChild 10000 KeepAlive On MaxKeepAliveRequests 200 KeepAliveTimeout 5 Timeout 50
/etc/init.d/apache2 restart
Passons à WordPress
Pour wordpress c’est assez simple, il faut installer le plugin suivant : W3 Total Cache
C’est un plugin qui va vous permettre de configurer l’utilisation automatique de cache par wordpress.
Donc une fois l’installation terminée, se rendre dans Performance > General Settings :
- Page Cache ( Enabled + Memcached )
- Database Cache ( Enabled + Memcached )
Et là normalement, en quelques minutes, on a un blog qui va vraiment bien mieux répondre.
Finissons par un retour à Nginx
Ce n’est pas vraiment une optimisation, plus par sécurité qu’autre chose.
Mais on va rajouter quelques règles à notre nginx (donc toujours /etc/nginx/nginx.conf)
# Limit Connexion limit_conn_zone $binary_remote_addr zone=perip:10m; limit_conn_zone $server_name zone=perserver:10m; limit_conn perip 50; limit_conn perserver 800; # Limit Request (50r/s avec des burst 200r lors des chargements de pages) limit_req_zone $binary_remote_addr zone=req_perip:10m rate=50r/s; limit_req zone=req_perip burst=200;
Ça semble assez clair, ça permet de limiter le nombre de connexions/requêtes par ip.
Ces règles sont vraiment permissives, c’est plus pour éviter des emmerdes qu’autre chose.
Un utilisateur qui fait plus de 50requetes seconde ou plus de 50 connexions a un gros problème ou cherche à faire une connerie.
Et voilà
P.S. j’ajoute un bonus finalement. Un élément encore un peu plus tricky et donc totalement à vos risques et périles ?
Bonus track : Passer à Apache 2 Worker et PHP FastCGI (totalement optionnel)
La procédure est assez simple, mais permet de gagner en perf/stabilité. Par contre cette solution n’est pas threadsafe toussa toussa.
Pour l’install :
apt-get install apache2-mpm-worker libapache2-mod-fcgid php5-cgi
On active le module apache
a2enmod fcgid
Et après le plus chiant, c’est qu’il va falloir aller modifier ses host présents dans /etc/apache2/sites-enabled/
Pour remplacer tous les
<Directory /> Options FollowSymLinks AllowOverride All </Directory>
par des
<Directory /> <strong>AddHandler fcgid-script .php FCGIWrapper /usr/lib/cgi-bin/php5 .php</strong> Options <strong>ExecCGI</strong> FollowSymLinks #Options FollowSymLinks AllowOverride All </Directory>
Sans ça, vous n’aurez tout simplement plus de php, quand je vous avez dit que c’était un peu tricky ?
P.S. pour vous donner un ordre d’idée, sur le blog avec le même outil que celui de départ, voilà le type d’info que j’obtiens :
Total transferred: 346811329 bytes HTML transferred: 344570593 bytes Requests per second: 274.49 [#/sec] (mean) Time per request: 36.431 [ms] (mean) Time per request: 3.643 [ms] (mean, across all concurrent requests) Transfer rate: 11289.00 [Kbytes/sec] received
J’étais au départ aux alentours de ~10 Requests per Second, ce qui fait grosso modo x20 sans avoir passé trop de temps, ni changé de serveur.
Pour rappel ce nombre ne prend en compte que la page php, par les fichiers static eux géré par le nginx en frontend.
Je referai un jolie graph de benchmark à l’occasion.
Il était une fois, l’activation du HTTPS et de l’IPV6
On a un blog qui tourne, un serveur qui va bien. On va pouvoir commencer à ajouter quelques feature avancées.
Comme le nom de l’article l’annonce, on va pouvoir dans cette 5e partie, s’attaquer au HTTPS et à l’IPV6.
Le HTTPS
Le https, suffit pas de rajouter un s à l’url ?
Pour faire fonctionner le https et donc utiliser ssl, il va falloir plusieurs points :
- Pouvoir accéder aux sites web sur le port 443
- Avoir un ou plusieurs certificats
- Modifier les vhost des sites pour prendre ça en compte
Et ce pour chaque serveur qui a besoin de https.
Autant dire que ça devient vite chiant à gérer dès qu’on a plus de 2~3 sites web où l’on veut activer le https.
Et la solution ?
La solution est assez simple, on va configurer le reverse proxy pour qu’il s’occupe du ssl.
Ainsi, on centralise les certificats et les configurations sur le proxy et on n’a plus besoin de toucher aux différents serveurs web.
L’utilisateur se connecte en https jusqu’à notre reverse proxy, qui lui établit une connexion en http sur notre venet.
C’est compliqué de faire ça ?
Non pas tellement, allez c’est parti.
Donc on se dirige vers notre fameux nginx, sur lequel on va créer les certificats dont on a besoin.
N’ayant pas plusieurs centaines d’euros à balancer à la poubelle, je vais faire des certificats autosignés.
mkdir /etc/nginx/ssl cd /etc/nginx/ssl
# Autority openssl genrsa -des3 -out ca.key 2048 openssl req -new -x509 -days 3650 -key ca.key -out ca.crt # on peut la vérifier avec openssl x509 -in elao-ca.crt -text -noout
Voilà donc ce petit bout de code va nous permettre de générer un premier certificat, qui va servir à signer tous ceux qu’on fera ensuite.
Lors de la 2nd commande, il devrait vous être demandé quelques informations.
Seul le champ « Common Name » est utile :
#Voici quelques-unes des questions Country Name (2 letter code) [AU]:FR State or Province Name (full name) [Some-State]:Rhone-alpes Locality Name (eg, city) []:Annecy Organization Name (eg, company) [Internet Widgits Pty Ltd]:Kef Network Organizational Unit Name (eg, section) []:IT Common Name (e.g. server FQDN or YOUR name) []:*.ganbaranai.fr Email Address []:webmaster@ganbaranai.fr
Voilà, donc on a notre certificat d’origine ca.crt, maintenant on va pouvoir en générer pour tous nos noms de domaines.
Et oui pas possible d’utiliser un certificat pour plusieurs domaines différents.
Voici le code à réitérer pour chaque serveur :
# Server openssl genrsa -des3 -out ganbaranai-server.key 1024 openssl req -new -key ganbaranai-server.key -out ganbaranai-server.csr openssl x509 -req -in ganbaranai-server.csr -out ganbaranai-server.crt -sha1 -CA ca.crt -CAkey ca.key -CAcreateserial -days 3650 # on test openssl x509 -in ganbaranai-server.crt -text -noout # on genere un .key sans passphrase openssl rsa -in ganbaranai-server.key -out ganbaranai-server.nopass.key
Et voilà donc pour ce serveur, on obtient un fichier ganbaranai-server.nopass.key, c’est celui qui sera utilisé par nginx.
C’est déjà bien compliqué non ?
Bah vous avez déjà fait le plus dur coté proxy.
Maintenant il ne reste plus qu’à mettre à jour la config de vos sites nginx pour lesquels vous souhaitez activer https.
Allez, je vais reprendre l’exemple du blog, donc dans /etc/nginx/sites-enabled/blog
J’avais déjà :
server { server_name blog.ganbaranai.fr; access_log /var/log/nginx/perso.access.log; ... }
on va rajouter un second bloc serveur pour le https (avec quasiment les mêmes règles)
server { listen 443; server_name blog.ganbaranai.fr blog.remilia.fr; ssl on; ssl_certificate /etc/nginx/ssl/ganbaranai-server.crt; ssl_certificate_key /etc/nginx/ssl/ganbaranai-server.nopass.key; access_log /var/log/nginx/perso.access.log; ... location / { ... proxy_set_header X-Forwarded-Proto $scheme; add_header Front-End-Https on; } }
Et voilà, la config https est bonne, il ne reste plus qu’à faire un /etc/init.d/nginx reload
C’est enfin fini pour le https ?
Oui et non, coté config réseau oui c’est bon. Normalement votre site répond aussi bien en http qu’en https.
Par contre, il est fort probable que votre site soit pas mal broken en https.
La raison est simple, une page en https ne doit charger que des fichiers en https.
Hors souvent les css, js, img présent dans les pages ont été intégrés avec des « http:// »
Il faut donc modifier un peu le code du site pour qu’il prenne ça en compte.
Si vous utilisez un CMS ça a surement été prévu, il suffit de lui indiquer qu’on fait du https.
Pour wordpress, dans wp-config.php, j’ai ajouté :
/** Mise en place du HTTPS derrière un proxy **/ if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https'){ $_SERVER['HTTPS'] = 'on'; }
Il reste ensuite à fixer quelques css, js présent dans le thème du blog et voilà.
Vous pouvez tester, le blog fonctionne maintenant https
L’IPV6
Bah il suffit de faire apt-get install ipv6 non?
Dans la plupart des cas, votre serveur aura déjà une plage d’ipv6 fourni (et configuré) par votre hébergeur.
Dans le cas d’ovh, j’ai sur mes deux serveurs une /64 et une /128 (avec le temps, ils sont moins généreux).
Le problème de l’ipv6 est jusque là, l’impossibilité de faire du nat (c’est dispo depuis le kernel linux 3.7, mais faut tout upgrade).
On ne peut donc pas se contenter de faire un copier/coller de notre infra ipv4 pour que ça tourne.
L’idée et de seulement permettre l’accès aux sites web en ipv6, et pour ça comme on l’a vu pour l’https précédemment c’est assez simple.
On ne va pas mettre une ipv6 à chaque VM, mais à une seul, le reverse-proxy.
J’ai lu que c’était compliqué ?
Oui ça peut-être vite compliqué comme super simple.
Je vais vous présenter une méthode très simple et très courte.
Alors pour éviter de vous embrouillez par la suite, il va vous falloir 3 IPv6 :
* l’ip de votre serveur physique
* l’ip qui vous souhaitez attribuer à votre vm
* l’ip de gateway
Dans mon cas, la seule info que j’ai d’ovh est dans leur manager est 2001:41d0:1:bdc2::1/64, c’est l’ipv6 du serveur physique.
* l’ip que je souhaite attribuer à ma VM 2001:41d0:1:bdc2::2
* l’ip de gateway 2001:41D0:1:BDff:ff:ff:ff:ff (c’est comme en ipv4 avec 255.255.255, ici ce sont des FF:FF:FF)
Une fois que vous avez ces infos, ça va être assez rapide.
Tout d’abord, il va falloir activer sur votre hôte, le forwarding pour l’ipv6.
C’est l’heure de bosser
Donc ouvrez /etc/sysctl.conf et ajoutez :
# Activate Forwarding net.ipv4.ip_forward=1 net.ipv6.conf.all.forwarding=1 net.ipv6.conf.all.proxy_ndp = 1
Maintenant le trafic ipv6 va pouvoir transiter entre internet et le venet.
Mais encore faut-il qu’il soit routable, et pour ça j’ai fait un script très simple (set-ipv6.sh)
ip -6 ro add @IP_DU_NETWORK dev vmbr0 ip -6 ro add default via @IP_DE_LA_GATEWAY dev vmbr0 vzctl set @IP_DE_LA_VM --ipadd --save ip -6 neigh add proxy @IP_DE_LA_VM dev vmbr0
pour moi, voici les info qu’il prend
ip -6 ro add 2001:41D0:1:BDff::/64 dev vmbr0 ip -6 ro add default via 2001:41D0:1:BDff:ff:ff:ff:ff dev vmbr0 vzctl set 100 --ipadd 2001:41D0:1:BDc2::2 --save ip -6 neigh add proxy 2001:41D0:1:BDc2::2 dev vmbr0
Il ne reste plus qu’à faire un coup de
chmod +x set-ipv6.sh ./set-ipv6.sh
Et Bam, votre VM va se trouver avec une IPV6 (il est parfois nécessaire de faire un restart de la VM).
Si vous avez un autre serveur, vous pouvez tester la connectivité via ping6 qui fonctionne comme la commande ping mais en ipv6.
Exemple : ping6 google.fr ou ping6 2001:41D0:1:BDc2::2
P.S. Il va falloir bien entendu lancer automatiquement ce script au démarrage du serveur.
Et c’est bon là ?
Non pas encore, il va falloir allez changer les règles DNS. Et oui, tous les sous-domaines sont saisies via des entrées A.
C’est un entrée uniquement IPV4, il va falloir rajouter des entrées AAAA et saisir l’ip de notre vm si dessus.
Après quelques minutes ping6 blog.ganbarai.fr répond correctement.
Mais il reste un tout petit détail à régler. Nginx n’est pas encore au courant de nos changements et il n’écoute pas forcément sur le port 80 de l’ipv6.
Il va falloir modifier les vhost encore une fois. On retourne donc dans notre /etc/nginx/sites-enabled/blog
Et ajouter ces paramètres :
server { listen 80 default_server; listen [::]:80 ipv6only=on default_server; server_name blog.ganbaranai.fr; ... } server { listen 443 ssl default_server; listen [::]:443 ipv6only=on ssl default_server; server_name blog.ganbaranai.fr; ... }
Encore une fois, un petit /etc/init.d/nginx reload et normalement cette fois-ci c’est bon.
Voici un site qui vous permet de tester que ça fonctionne : http://ipv6-test.com/
Il était une fois … le monitoring de nos services
Ça ne suffit pas les graph de proxmox ou d’ovh ?
C’est bien d’avoir des graphes, mais ce n’est pas ça qui va nous sauver lorsqu’il y aura un problème avec un des softs que l’on utilise.
Aucun logiciel n’est parfait et il arrive assez couramment qu’ils crashs (aucun logiciel n’est épargné).
Qui n’a pas déjà vu un serveur apache en rade où une db qui timeout.
L’idée va donc être de mettre sous surveillance nos différentes machines et leurs processus.
Et lorsqu’un problème est détecté, soit essayer de le corriger (via des restart, reset de config, …), soit envoyer des mails d’alertes pour nous prévenir (attention toutefois à ne pas se spammer).
C’est quand même nettement plus efficace que d’attendre de se rendre compte que ça ne fonctionne plus.
A faire sur tous les serveurs
Pour ca, on va utiliser un soft qui s’appelle monit et qui est fait pour ça :
1
|
apt-get install monit |
Et on va editer son fichier de config /etc/monit/monitrc
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
################################# ## Fichier Monit Ganbaranai.fr ## ################################# # Periode de controle (toutes les minutes avec un start delay de 2 minutes) set daemon 60 with start delay 120 # Logging (ici on log dans le syslog) set logfile syslog facility log_daemon # Configuration des mailing d'alertes set mailserver smtp.gmail.com port 587 username "[un compte login@gmail.com]" password "[le password du compte]" using tlsv1 with timeout timeout 30 seconds set mail- format { from: webmaster@ganbaranai.fr subject: [monit] $SERVICE: $EVENT } set alert [votre adresse mail qui recevra les alertes] # Gestion des queues d'evenements set eventqueue basedir /var/lib/monit/events # set the base directory where events will be stored slots 100 # optionally limit the queue size # Start Interface Web set httpd port 2812 and use address localhost # only accept connection from localhost allow localhost # Chargement automatique des check include /etc/monit/conf .d/* |
et un ptit restart
1
|
/etc/init .d /monit force-reload |
Pour résumer vite fait la configuration que l’on vient de saisir, votre monit va vérifier toutes les 2 minutes que vos différents processus fonctionnent.
Et en cas d’anomalie, il va vous envoyer un mail de notification via Gmail.
Autant dire que vous allez pouvoir déployer ça sur tous vos serveurs.
Mais là il ne surveille rien ?
C’est exactement ça, il va falloir définir pour chaque machine quels processus sont à surveiller et comment.
Pour ça, il suffit de créer un nouveau fichier dans /etc/monit/conf.d/
Voici quelques exemples de scripts à ajouter en fonction des process qui tourne sur la machine :
Vérifier le système
Pour vérifier le système ( /etc/monit/conf.d/system )
1
2
3
4
5
6
7
|
check system local if loadavg (1min) > 4 then alert if loadavg (5min) > 2 then alert if memory usage > 75% then alert if cpu usage (user) > 70% then alert if cpu usage (system) > 30% then alert if cpu usage (wait) > 20% then alert |
Les Process unix/reseau
Pour Cron ( /etc/monit/conf.d/cron )
1
2
3
4
5
|
check process cron with pidfile /var/run/crond .pid group system start program = "/etc/init.d/cron start" stop program = "/etc/init.d/cron stop" if 5 restarts within 5 cycles then timeout |
Pour SSH ( /etc/monit/conf.d/ssh )
1
2
3
4
5
|
check process sshd with pidfile /var/run/sshd .pid start program "/etc/init.d/ssh start" stop program "/etc/init.d/ssh stop" if failed port 22 protocol ssh then restart if 5 restarts within 5 cycles then timeout |
Pour Fail2Ban ( /etc/monit/conf.d/fail2ban )
1
2
3
4
5
|
check process fail2ban with pidfile /var/run/fail2ban/fail2ban .pid start program = "/etc/init.d/fail2ban start" stop program = "/etc/init.d/fail2ban stop" if failed unixsocket /var/run/fail2ban/fail2ban .sock then restart if 5 restarts within 5 cycles then timeout |
Les Serveurs Web
Pour Nginx ( /etc/monit/conf.d/nginx )
01
02
03
04
05
06
07
08
09
10
11
|
check process nginx with pidfile /var/run/nginx .pid group www start program = "/etc/init.d/nginx start" stop program = "/etc/init.d/nginx stop" if failed host 127.0.0.1 port 80 protocol http and request "/nginx_status" then restart if cpu > 60% for 2 cycles then alert if cpu > 90% for 5 cycles then restart if totalmem > 50% for 5 cycles then restart if children > 250 then restart if loadavg(5min) greater than 10 for 8 cycles then stop if 3 restarts within 5 cycles then timeout |
Pour Apache ( /etc/monit/conf.d/apache2 )
01
02
03
04
05
06
07
08
09
10
11
|
check process apache with pidfile /var/run/apache2 .pid group www start program = "/etc/init.d/apache2 start" stop program = "/etc/init.d/apache2 stop" if failed host 127.0.0.1 port 80 protocol http and request "/monit/token" then restart if cpu is greater than 60% for 2 cycles then alert if cpu > 80% for 5 cycles then restart if totalmem > 500 MB for 5 cycles then restart if children > 250 then restart if loadavg(5min) greater than 10 for 8 cycles then stop if 3 restarts within 5 cycles then timeout |
Pour Lighttpd ( /etc/monit/conf.d/lighttpd )
1
2
3
4
5
6
|
check process lighttpd with pidfile /var/run/lighttpd .pid group www start program = "/etc/init.d/lighttpd start" stop program = "/etc/init.d/lighttpd stop" if failed host 127.0.0.1 port 80 protocol http then restart if 5 restarts within 5 cycles then timeout |
Pour Tomcat ( /etc/monit/conf.d/tomcat )
1
2
3
4
5
|
check process tomcat with pidfile /var/run/tomcat/tomcat .pid group www start program = "/etc/init.d/tomcat start" stop program = "/etc/init.d/tomcat stop" if failed host 127.0.0.1 port 80 then alert if failed host 127.0.0.1 port 80 for 5 cycles then restart |
Les Bases de données / Cache
Pour Mysql ( /etc/monit/conf.d/mysql )
1
2
3
4
5
6
|
check process mysql with pidfile /var/run/mysqld/mysqld .pid group database start program = "/etc/init.d/mysql start" stop program = "/etc/init.d/mysql stop" if failed unix "/var/run/mysqld/mysqld.sock" then restart if failed host 127.0.0.1 port 3306 then restart if 5 restarts within 5 cycles then timeout |
Pour Memcached ( /etc/monit/conf.d/memcached )
1
2
3
4
5
6
7
|
check process memcached with pidfile /var/run/memcached/memcached .pid group memcached start program = "/etc/init.d/memcached start" stop program = "/etc/init.d/memcached stop" if failed host 127.0.0.1 port 11211 protocol MEMCACHE then restart if cpu > 70% for 2 cycles then alert if cpu > 90% for 5 cycles then restart if 2 restarts within 3 cycles then timeout |
Pour Redis ( /etc/monit/conf.d/redis )
1
2
3
4
5
|
check process redis with pidfile /var/run/redis .pid group redis start program = "/etc/init.d/redis-server start" stop program = "/etc/init.d/redis-server stop" check file dump.rdb with path /var/lib/redis/dump .rdb if size > 100 MB then alert |
Et voilà, il ne vous reste plus qu’à piocher là dedans en fonctions des process que vous utilisez.
Veuillez quand même à faire attention aux group/uid/path déjà utiliser et que ne correspondent pas forcement à la configuration que vous utilisez.
Une fois en place c’est vraiment facile et puissant à utiliser.
La syntaxe est assez simple et il est facile de monitorer ses propres scripts/application de la même façon.
Il est quand même conseillé de tester le fonctionnement en stoppant les process monitorés.
Vous verrez alors assez vite si le process restart et si vous recevez des mails ?
Il était une fois, les backup/migration de VM sous Proxmox
Et voilà dernier article de cette série, cette fois-ci dédié au backup de ses différents services.
De quoi pouvoir récupérer d’une grosse défaillance software ou hardware sans rien perdre.
Qu’est-ce que ça change proxmox pour les backup ?
Jusque-là, pour les backup, il fallait préparer des procédures de backup service par service (mysql avec des dump régulier, apache avec de l’archivage journalier, logs, memcache, …)
On finissait avec de très nombreux backup pour finalement se rendre compte le jour où l’on en a besoin qu’on a pas le bon backup où qu’il ne fonctionne plus depuis 6 mois :'(
Ou alors par exemple que le dump sql ne correspond pas aux dumps des fichiers.
L’idée ici va être plus simple, on backup les VM entièrement avec leurs contenus.
Le serveur SQL est mort, pas grave je te remonte un backup de tout le serveur en moins de 5 minutes (ça n’empêche par de faire des dumps régulièrs).
Dans cet article, on va voir dans un premier temps comment faire des backup et restaurer ses machines virtuelles.
Et dans un second temps comment faire des migrations ou des copies de VM d’un serveur à un autre.
On utilise l’interface web ?
Au début j’étais assez intéressé par l’interface et l’onglet backup.
Malheureusement, je trouve celui-ci un peu trop contraignant, j’ai donc décidé d’utiliser les utilitaires en lignes de commandes et de faire comme bon me semble.
Ce tuto ne vous présentera donc que des lignes de commandes, désolé pour ceux qui voulait du user friendly ?
Quel type de backup va t’on faire ?
Sous OpenVZ, il y a 3 techniques de backup pour vos VM :
snapshot : cela fait un snapshot live de votre VM (ram + disk) et il est capable de la relancer dans le même état
suspend : cela met la VM en veille, copie tous les fichiers et la sort de veille (indispo de la VM <5s).
stop : cela arrête complètement la VM, copie tous les fichiers et la redémarre (indispo de la VM ~1min).
Ayant eu des problèmes avec le mode snapshot et un serveur SQL qui ne voulait plus repartir (une jolie corruption de table), j’ai arrêté d’utiliser ce type de backup.
J’utilise désormais quasi systématiquement le mode suspend qui lui provoque une légère indisponibilité, mais qui fourni des backups plus fiables.
Alors comment on sauvegarde ?
La commande est assez simple
vzdump <id de la vm>
Mais bon, on peut rajouter un certain nombre de paramètres, voici un exemple légèrement plus complet
1
|
vzdump 105 --dumpdir /var/lib/vz/dump/ --bwlimit /80000 --maxfiles 2 --mode suspend --compress gzip --exclude-path /home/static/content |
Voilà, donc là voici un vrai commande de backup que j’utilise sur l’une de mes vm :
dumpdir : dossier dans lequel les backup seront enregistré
bwlimit : vitesse d’écriture max (pour éviter de pourrir tous les IO disque du serveur)
maxfiles : nombre de backup à conserver pour cette vm
mode (snapshot/suspend/stop) : donc le mode de backup
compress (0/lzo/gzip) : type de compression qu’on va utiliser pour gagner de la place
exclude-path : permet d’extraire certains dossier pour gagner de la place et du temps sur les copies de backup
C’est pas dangereux de backup en local?
Si totalement.
Si on les conserve en local, c’est surtout pour pouvoir facilement et rapidement revert un gros crash, un hack ou une corruption de données.
Mais en cas de défaillance du raid, du disk ou de la machine, on risque de tout perdre et les backups avec.
C’est pourquoi on va simplement rajouter une règle à la fin de notre script pour synchroniser ça ailleurs (sur un autre serveur, un ftp, une machine chez vous …).
Dans mon infra mon serv1 va copier ses backup sur serv2.
et inversement, serv2 va copier ses backup sur serv1.
Le jour où je perds l’un de ces deux serveurs, je ne perdrais aucune VM.
J’aurai la possibilité de remonter un proxmox tout neuf assez rapidement et le relancer comme si de rien était.
Et voilà le script
Et voilà donc le petit script python que j’ai fait pour gérer mes backup :
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
import sys, os, commands; # # Configuration des Backup # path_log = "/var/log/auto-vzdump.log" ; path_vzdump = "vzdump" ; path_dump = "/var/lib/vz/dump/" ; dump_bw_limit = 50000 ; # Configuration remote (SSH / SCP) enable_remote_backup = True ; remote_host = "[adresse d'un serveur distant]" remote_login = "backup" remote_folder = "/var/lib/vz/dump/" # Configuration des backup par VM config_vm = { '101' :{ 'mode' : 'suspend' , 'compress' : True , 'exclude-tmp' : True , 'exclude-path' : [ '/home/deluge' , '/home/deluge-tmp' ], 'max_backup_local' : 2 }, '104' :{ 'mode' : 'suspend' , 'compress' : True , 'exclude-tmp' : True , 'max_backup_local' : 5 } }; # # Fin de la configuration # # Functions def build_cli_dump( vm_id, vm_options ): cli = path_vzdump + " " + vm_id; # On set le dossier de backup if path_dump : cli + = " --dumpdir " + path_dump; # On set la vitesse de backup if dump_bw_limit : cli + = " --bwlimit " + str (dump_bw_limit); # On set le nombre de backup conserver if 'max_backup_local' in vm_options.keys() : cli + = " --maxfiles " + str (vm_options[ 'max_backup_local' ]); # On set le mode de backup utiliser if 'mode' in vm_options.keys() : cli + = " --mode " + vm_options[ 'mode' ]; else : cli + = " --mode suspend" ; # On active ou non la compression if 'compress' in vm_options.keys() : if vm_options[ 'compress' ] : cli + = " --compress gzip" ; else : cli + = " --compress 0" ; # On ajoute l'option pour clean les dossiers temporaires (/var/log, /tmp, /var/tmp, ...) if 'exclude-tmp' in vm_options.keys() : if vm_options[ 'exclude-tmp' ] : cli + = " --stdexcludes 1" ; else : cli + = " --stdexcludes 0" ; # On ajoute ou non des excludes path custom if 'exclude-path' in vm_options.keys() : for path in vm_options[ 'exclude-path' ]: cli + = " --exclude-path " + path; return cli def get_last_backup( vm_id ): lastFile = False ; for files in os.listdir( path_dump ): if files.endswith( ".tar.gz" ) or files.endswith( ".tgz" ) or files.endswith( ".lzo" ) : if "vzdump-openvz-" + vm_id in files : lastFile = files return lastFile; def remote_backup( vm_id ): backup = get_last_backup( vm_id ); if backup : hostname = commands.getoutput( "hostname" ); folder = remote_folder + hostname + "/" ; # Creation du folder distant cmdSsh = "ssh " + remote_login + "@" + remote_host + " \"mkdir -p " + folder + "\"" ; log( ">> " + cmdSsh ); log( commands.getoutput(cmdSsh) ); # Copie du backup dans le folder distant filename, extension = os.path.splitext( backup ); cmdScp = "scp " + path_dump + backup + " " + remote_login + "@" + remote_host + ":" + folder + "vzdump-openvz-" + str (vm_id) + "-last.tar" + extension; log( ">> " + cmdScp ); log( commands.getoutput(cmdScp) ); def log( txt ): print txt; with open (path_log, "a" ) as logfile: logfile.write( txt + "\n" ); # Processing for vm_id, vm_options in config_vm.items() : log( "Backup of VM " + vm_id + " : Started" ); log( " * Nettoyage des connexions de cette VM" ); cmdClean = "kill `ps -e | grep 'vzctl enter " + str (vm_id) + "' | awk '{print $1}'`" log( ">> " + cmdClean ); log( " * Commande de Backup" ); cmd = build_cli_dump( vm_id, vm_options ); log( ">> " + cmd ); log( commands.getoutput(cmd) ); if enable_remote_backup : log( " * Copie du backup sur un serveur distant : " + remote_host ); remote_backup( vm_id ); log( "Backup of VM " + vm_id + " : Finished" ); |
C’est donc un exemple qui va backup deux VM ( 101 et 104 ) et qui va les copier sur un autre serveur.
Il ne reste plus qu’à rajouter un petit crontab -e
1
|
0 4 * * 2,6 /usr/bin/python /root/backup-vm .py |
Et voilà, tous les mardi et samedi à 4h du mat, ce script de backup sera exécuté.
Bien entendu, pour les connexions scp/ssh, pas question de rentrer un mot de passe à chaque backup.
Il faut donc avoir mis en place des authorized keys ssh pour pouvoir se logger directement.
Et comment on restaure une VM le jour où on en a besoin ?
assez simple :
1
|
vzrestore [fichier] [ id de la vm] |
C’est bien les commandes comme ça où il n’y a pas besoin de longues descriptions.
Et donc une migration/copie de VM?
Ça parait compliqué sur le papier de migré une machine, et pourtant.
Il suffit de faire un vzrestore d’une VM d’un autre serveur en précisant un ID de VM qui n’existe pas en local.
Exemple, sur mon serv2 :
1
|
vzrestore /var/lib/vz/dump/ks203802/vzdump-openvz-105-last . tar .gz 105 |
et voila je me retrouve avec la VM 105 installée sur ce proxmox et visible dans l’interface.
Et c’est une copie exacte de la première VM qui tournait sur l’autre serveur (attention si les deux serveurs sont en vpn, il risque d’y avoir des problèmes de configuration réseau, les 2 VM ayant la même).
Il ne reste plus qu’à changer cette config réseau et on peut la start comme d’habitude.
Et voilà c’est tout, le plus long c’est au final le scp/rsync entre les serveurs.
Bon, cet article se termine là, à la prochaine ++
Merci pour ton site très ludique et attractif sur le contenu avec ses mises en scène !!! Que du plaisir à te lire !!!