Un petit article pour vous présenter Syncthing.
J’ai découvert ce logiciel il y a quelques années, mais je n’avais jamais eu l’occasion de m’en servir, c’est chose faite, donc j’en parle un peu ici. Continuer la lecture
Un petit article pour vous présenter Syncthing.
J’ai découvert ce logiciel il y a quelques années, mais je n’avais jamais eu l’occasion de m’en servir, c’est chose faite, donc j’en parle un peu ici. Continuer la lecture
Juste une petite description de l’architecture de ce site.
Pas de détails, rien de très compliqué non plus.
Ce site est installé comme suit :
Sa base de données est :
Le tout est sur une petite Dedibox qui fait plein d’autres trucs.
Un petit article pour décrire le fonctionnement de LXC (LinuX Containers) et son utilisation sur une Debian Wheezy.
J’avais commencé ce blog en parlant de Linux Vserver, un système de « virtualisations au niveau du système d’exploitation ».
Ça m’a bien rendu service, mais vserver n’est plus intégré à la Debian Wheezy, il a été remplacé par LXC, hors il fallait bien que je fasse la mise à jour de mes Squeeze.
Je vais faire court car il existe de nombreuses docs sur LXC.
On commence par mettre à jour la Debian (sauf exceptions, il vaut mieux utiliser aptitude que apt-get) :
aptitude update && aptitude full-upgrade
On installe le paquet LXC :
aptitude install lxc
Je rajoute aussi le paquet bridge-utils, mais il n’est pas obligatoire.
Dans /etc/fstab, on ajoute un point de montage pour gérer les ressources :
cgroup /sys/fs/cgroup cgroup defaults 0 0
Attention, il y a un bug dans le script de création des premières Wheezy (corrigé en 7.4 de mémoire).
Le plus simple est de créer un nouveau fichier de modèle, je me suis librement inspiré de celui proposé ici.
Voici mon template /usr/share/lxc/templates/lxc-debian-wheezy :
#!/bin/bash #Debian Wheezy LXC template configure_debian() { rootfs=$1 hostname=$2 # squeeze only has /dev/tty and /dev/tty0 by default, # therefore creating missing device nodes for tty1-4. for tty in $(seq 1 4); do if [ ! -e $rootfs/dev/tty$tty ]; then mknod $rootfs/dev/tty$tty c 4 $tty fi done # configure the inittab cat <<EOF > $rootfs/etc/inittab id:3:initdefault: si::sysinit:/etc/init.d/rcS l0:0:wait:/etc/init.d/rc 0 l1:1:wait:/etc/init.d/rc 1 l2:2:wait:/etc/init.d/rc 2 l3:3:wait:/etc/init.d/rc 3 l4:4:wait:/etc/init.d/rc 4 l5:5:wait:/etc/init.d/rc 5 l6:6:wait:/etc/init.d/rc 6 # Normally not reached, but fallthrough in case of emergency. z6:6:respawn:/sbin/sulogin 1:2345:respawn:/sbin/getty 38400 console c1:12345:respawn:/sbin/getty 38400 tty1 linux c2:12345:respawn:/sbin/getty 38400 tty2 linux c3:12345:respawn:/sbin/getty 38400 tty3 linux c4:12345:respawn:/sbin/getty 38400 tty4 linux EOF # disable selinux in debian mkdir -p $rootfs/selinux echo 0 > $rootfs/selinux/enforce # configure the network cat <<EOF > $rootfs/etc/network/interfaces auto lo iface lo inet loopback EOF # set the hostname cat <<EOF > $rootfs/etc/hostname $hostname EOF # reconfigure timezone echo "Europe/Paris" > $rootfs/etc/timezone chroot $rootfs dpkg-reconfigure -f noninteractive tzdata # reconfigure language sed -i "s/^# en_US.UTF-8/en_US.UTF-8/" $rootfs/etc/locale.gen chroot $rootfs locale-gen # remove pointless services in a container chroot $rootfs /usr/sbin/update-rc.d -f umountfs remove chroot $rootfs /usr/sbin/update-rc.d -f hwclock.sh remove chroot $rootfs /usr/sbin/update-rc.d -f hwclockfirst.sh remove echo "root:root" | chroot $rootfs chpasswd echo "Root password is 'root', please change !" return 0 } download_debian() { packages= ifupdown, locales, libui-dialog-perl, dialog, netbase, net-tools, iproute, vim, bash-completion, locales, iputils-ping, aptitude cache=$1 arch=$2 # check the mini debian was not already downloaded mkdir -p "$cache/partial-$arch" if [ $? -ne 0 ]; then echo "Failed to create '$cache/partial-$arch' directory" return 1 fi # download a mini debian into a cache echo "Downloading debian minimal ..." debootstrap --verbose --variant=minbase --arch=$arch --include $packages wheezy $cache/partial-$arch http://ftp.debian.org/debian if [ $? -ne 0 ]; then echo "Failed to download the rootfs, aborting." return 1 fi mv "$1/partial-$arch" "$1/rootfs-$arch" echo "Download complete." return 0 } copy_debian() { cache=$1 arch=$2 rootfs=$3 # make a local copy of the minidebian echo -n "Copying rootfs to $rootfs..." cp -a $cache/rootfs-$arch $rootfs || return 1 return 0 } install_debian() { cache="/var/cache/lxc/debian-wheezy" rootfs=$1 mkdir -p /var/lock/subsys/ ( flock -n -x 200 if [ $? -ne 0 ]; then echo "Cache repository is busy." return 1 fi arch=$(arch) if [ "$arch" == "x86_64" ]; then arch=amd64 fi if [ "$arch" == "i686" ]; then arch=i386 fi if [ "$arch" == "armv5tel" ]; then arch=armel fi echo "Checking cache download in $cache/rootfs-$arch ... " if [ ! -e "$cache/rootfs-$arch" ]; then download_debian $cache $arch if [ $? -ne 0 ]; then echo "Failed to download 'debian base'" return 1 fi fi copy_debian $cache $arch $rootfs if [ $? -ne 0 ]; then echo "Failed to copy rootfs" return 1 fi return 0 ) 200>/var/lock/subsys/lxc return $? } copy_configuration() { path=$1 rootfs=$2 name=$3 cat <<EOF >> $path/config lxc.tty = 4 lxc.pts = 1024 lxc.rootfs = $rootfs lxc.cgroup.devices.deny = a # /dev/null and zero lxc.cgroup.devices.allow = c 1:3 rwm lxc.cgroup.devices.allow = c 1:5 rwm # consoles lxc.cgroup.devices.allow = c 5:1 rwm lxc.cgroup.devices.allow = c 5:0 rwm lxc.cgroup.devices.allow = c 4:0 rwm lxc.cgroup.devices.allow = c 4:1 rwm # /dev/{,u}random lxc.cgroup.devices.allow = c 1:9 rwm lxc.cgroup.devices.allow = c 1:8 rwm lxc.cgroup.devices.allow = c 136:* rwm lxc.cgroup.devices.allow = c 5:2 rwm # rtc lxc.cgroup.devices.allow = c 254:0 rwm # mounts point lxc.mount.entry=proc $rootfs/proc proc nodev,noexec,nosuid 0 0 lxc.mount.entry=devpts $rootfs/dev/pts devpts defaults 0 0 lxc.mount.entry=sysfs $rootfs/sys sysfs defaults 0 0 # networking lxc.utsname = $name lxc.network.type = veth lxc.network.flags = up lxc.network.link = br0 lxc.network.ipv4 = 10.1.1.2/24 lxc.network.ipv4.gateway = 10.1.1.1 lxc.network.hwaddr = 00:1E:$(hex):$(hex):$(hex):$(hex) EOF if [ $? -ne 0 ]; then echo "Failed to add configuration" return 1 fi return 0 } # nice trick from: http://mindref.blogspot.com/2011/01/debian-lxc-create.html hex() { echo "`tr -dc A-F0-9 < /dev/urandom | head -c 2 | xargs`" } clean() { cache="/var/cache/lxc/debian-wheezy" if [ ! -e $cache ]; then exit 0 fi # lock, so we won't purge while someone is creating a repository ( flock -n -x 200 if [ $? != 0 ]; then echo "Cache repository is busy." exit 1 fi echo -n "Purging the download cache..." rm --preserve-root --one-file-system -rf $cache && echo "Done." || exit 1 exit 0 ) 200>/var/lock/subsys/lxc } usage() { cat <<EOF $1 -h|--help -p|--path=<path> --clean EOF return 0 } options=$(getopt -o hp:n:c -l help,path:,name:,clean -- "$@") if [ $? -ne 0 ]; then usage $(basename $0) exit 1 fi eval set -- "$options" while true do case "$1" in -h|--help) usage $0 && exit 0;; -p|--path) path=$2; shift 2;; -n|--name) name=$2; shift 2;; -c|--clean) clean=$2; shift 2;; --) shift 1; break ;; *) break ;; esac done if [ ! -z "$clean" -a -z "$path" ]; then clean || exit 1 exit 0 fi type debootstrap if [ $? -ne 0 ]; then echo "'debootstrap' command is missing" exit 1 fi if [ -z "$path" ]; then echo "'path' parameter is required" exit 1 fi if [ "$(id -u)" != "0" ]; then echo "This script should be run as 'root'" exit 1 fi rootfs=$path/rootfs install_debian $rootfs if [ $? -ne 0 ]; then echo "failed to install debian" exit 1 fi configure_debian $rootfs $name if [ $? -ne 0 ]; then echo "failed to configure debian for a container" exit 1 fi copy_configuration $path $rootfs $name if [ $? -ne 0 ]; then echo "failed write configuration file" exit 1 fi if [ ! -z $clean ]; then clean || exit 1 exit 0 fi
Attention à la ligne 65, il faut bien évidemment changer le mot de passe, soit dans le template lui-même, soit dans le conteneur une fois déployé.
Pour le reste, libre à vous d’adapter le script, en particulier les lignes 74 à 85 (paquets installés par défaut) et les lignes 179 à 212 qui contiennent le paramétrage du conteneur, en particulier la configuration réseau :
lxc.network.type = veth #type réseau pour le conteneur (empty/veth/vlan/macvlan/phys) lxc.network.flags = up #la carte monte au démarrage lxc.network.link = br0 #elle est attachée à l'interface br0 de l'hôte lxc.network.ipv4 = 10.1.1.2/24 #son IP/masque lxc.network.ipv4.gateway = 10.1.1.1 #le routeur par défaut lxc.network.hwaddr = 00:1E:$(hex):$(hex):$(hex):$(hex) #une adresse physique aléatoire
Le paquet LXC vient avec toute une panoplie d’outils de gestion des conteneurs, entre autre :
lxc-create -n mon.premier.conteneur -t debian-wheezy
/var/lib/lxc/mon.premier.conteneur/config
lxc-start -n mon.premier.conteneur
lxc-console mon.premier.conteneur
Pour quitter la console il faut faire CTRL+a, q
lxc-stop -n mon.premier.conteneur
lxc-destroy -n mon.premier.conteneur
ln -s /var/lib/lxc/mon.premier.conteneur/config /etc/lxc/auto/mon.premier.conteneur
Quelques recommandations pour terminer :
Comme je ne sais pas par où commencer dans mon rangement, je vais donc noter ici ce sur quoi je travaille en ce moment : vserver
Dans le cadre de mon travail, on m’a demandé d’étudier les différentes solutions d’hébergement « vite fait et pas cher ». L’objectif est d’offrir à certains utilisateurs la possibilité, d’avoir leur propre espace Web perso, accessible de partout et surtout sans que ça nécessite des ressources de support, en gros du clefs en main.
La suite est une petite histoire qui n’intéressera probablement que ceux qui travaillent dans un métier d’administration système ou de support IT.
Quelques points de détails font qu’on ne peut pas décemment leur dire d’aller chez le premier hébergeur venu :
Actuellement, quand l’un des ces utilisateurs veut un tel espace, il y a en gros 3 cas de figure, qui s’enchainent (de 1 vers 3 et de 3 vers 1) :
Dans tous les cas ça nous (service info) pose des problèmes de sécurité et/ou de ressources en support à plus ou moins court terme : l’utilisateur demande une intégration de son site aux sites internes, il souhaite avoir une URL @corp, il n’arrive pas à déménager son site chez un autre hébergeur, on ne peut pas lui laisser toute la latitude qu’il souhaite sur nos serveurs (question de sécurité), nous sommes des incompétents …
J’ai donc fait une étude rapide sur les offres d’hébergement du marché (OVH, 1&1, Online, Amen …).
Sur beaucoup de points ces offres semblaient répondre aux besoins, mais elles avaient toutes le même talon d’Achille, elles nous auraient couté très chez en temps de support (gestion des comptes, création des bases SQL, configuration DNS, sauvegardes, …). Il aurait donc fallut acheter un hébergement par utilisateur (et là c’est le cout administratif qui aurait explosé).
En gros les offres d’hébergement mutualisé c’est bien quand ce n’est pas mutualisé.
J’ai donc regardé la possibilité de le faire en interne. La problématique est la suivante :
Indépendamment les uns des autres, ces points sont simples à respecter, mais les mettre tous ensemble relève du casse tête.
Pour le 1, pas de problèmes pour le serveur Web (il suffit de l’installer) ni pour le FTP (on peut facilement chrooter les utilisateurs), mais PHP pose un sérieux problème de sécurité en environnement mutualisé. En quelques lignes, on accède (au moins) à tout ce qui est accessible par le serveur Web, à commencer par les données des autres utilisateurs, ce qui entre en conflit avec le point 6. Si on sécurise d’avantage PHP (open_basedir, disable_functions, …), le point 5 ne peut pas être respecté.
J’ai donc cherché une autre approche, virtualiser tout ça, sur un seul serveur avec un reverse proxy et un peu de SNAT.
Il existe plusieurs types de virtualisation, on dispose d’ailleurs d’une ferme ESX, mais le point 8 en réduit l’utilité.Je suis donc partie sur une solution indépendante, autonome et bien plus efficace en terme de ressource : le VPS.
J’ai évalué 3 techno de VPS :
J’ai donc opté pour Linux-VServer dans l’architecture suivante :
La mise en place de l’architecture (installation, configuration, backup, logs, template, scripts de déploiement, …) peut se faire en 2 heures, plus environ autant pour la documentation d’exploitation.
Il me reste encore à peaufiner quelques points pour l’automatisation totale du déploiement, notamment mettre une interface devant mon script de déploiement et ajouter un petit module de stats propre à chaque utilisateur, mais je pense que c’est une technologie que je vais faire rentrer de plus en plus dans notre DataCenter.
Pour le détail de l’installation, c’est un autre article.