Potřebný hardware
U velkých systémů se chceme soustředit především na spolehlivost. A o čím větší systém se jedná, tím spíše chceme, aby vše běželo hladce. Tomuto cíli můžeme dopomoci už výběrem spolehlivého hardwaru. I když se dá cluster vyrobit z komponent ve stylu „co dům dá“, pro produkční prostředí nemohu tento princip doporučit.
Pro začátek je dobré identifikovat všechna případná slabá místa, zhodnotit riziko a následky jejich selhání a rozhodnout se, zda se s tím rozhodneme něco dělat. Má současná představa stroje vhodného na produkční nasazení obsahuje přinejmenším redundantní zdroj napájení a zrcadlené disky (ano staromódní mdadm a RAID1).
A jelikož mám velké plány, budu takovéto stroje potřebovat nejméně dva. Tolik k hardwarové části našeho budoucího malého privátního cloudu.
Instalace
Potřeba více stejných strojů přímo volá po automatizaci už samotného instalačního procesu. Čím více takových strojů plánujeme instalovat, tím spíše u některého můžeme zapomenout na jeden z kroků a dostaneme nesourodé prostředí, které nás v tu nejnevhodnější chvíli dokáže vypéct. Nemusíme vymýšlet žádné extra složité řešení. Na našem budoucím hypervisoru bude použit Debian a instalátor má možnost využít tzv. preseed souboru. V kombinaci se síťově bootovatelným instalátorem tak máme celkem jednoduché a elegantní řešení. Stačí jen server přípojit k elektrické a datové síti a spustit. Návodů na toto téma lze jistě nalézt dost (v mém případě se jedná o nastavení nástrojů dnsmasq, tftp, pxelinux).
# pxelinux.cfg -- klíčová položka z boot menu label debian_preseed menu label ^Install Debian kernel debian-installer/amd64/linux append initrd=debian-installer/amd64/initrd.gz vga=788 \ auto=true hostname=server domain=example.net \ url=tftp://192.168.0.1/debian-installer/debian-preseed.txt \ preseed-md5=0bc87e175086c246fd8135157b8387a0 -- quiet
# debian-preseed.txt -- ukázka některých nastavení instalátoru # Locale d-i localechooser/supported-locales multiselect en_US.UTF-8, cs_CZ.UTF-8 # Datum a čas d-i time/zone string Europe/Prague # Volba sítě d-i netcfg/choose_interface select auto # Partitioning ## Chceme GPT d-i partman-basicfilesystems/choose_label string gpt d-i partman-basicfilesystems/default_label string gpt d-i partman-partitioning/choose_label string gpt d-i partman-partitioning/default_label string gpt d-i partman/choose_label string gpt d-i partman/default_label string gpt ## Chceme LVM d-i partman-lvm/confirm boolean true d-i partman-auto-lvm/new_vg_name string vg0 d-i partman-auto-lvm/guided_size string 100G ## Chceme RAID1 d-i partman-auto/method string raid d-i partman-auto/disk string /dev/sda /dev/sdb d-i partman-auto-raid/recipe string \ 1 2 0 lvm - \ /dev/sda2#/dev/sdb2 \ . d-i partman-md/confirm boolean true d-i partman/confirm boolean true # Instalace dalších balíčků a upgrade d-i pkgsel/include string openssh-server python-apt vim d-i pkgsel/upgrade select full-upgrade # Po instalaci vypnout d-i debian-installer/exit/poweroff boolean true
Souborový systém
Pokud bych měl dělat žebříček položek, nad kterými přemýšlím nejdéle, je vytváření oddílů a volba souborového systému na stupni vítězů (ve skutečnosti je na druhém místě, první místo je obsazeno položkou hostname).
Na základě zkušeností jsem nakonec zakotvil u následujícího schématu. Mám dva pevné disky, na kterých jsou pomocí nástroje gdisk vytvořeny dva oddíly (BIOS partition pro Grub2 a samotný datový oddíl).
Number Start (sector) End (sector) Size Code Name 1 2048 63487 30.0 MiB EF02 2 63488 5860532223 2.7 TiB FD00
Datový oddíl je použit jako zařízení pro md-raid1, které pak slouží jako physical volume pro LVM. To mi nabízí jednak flexibilitu ve vytváření oddílů (a experimentování se souborovými systémy dle konkrétního nasazení – např. btrfs pro LXC, ext4 pro ElasticSearch), ale také jednoduchost a transparentnost při správě samotných pevných disků (při poruše se prostě vymění kus za kus).
Šifrování
Jedním ze základních požadavků na bezpečnost je ukládání dat v zašifrované podobě. Pokud chceme, flexibilita řešení s LVM nám umožňuje mít šifrované i nešifrované oddíly a definovat tak, která data mají být chráněna a která ne. Pro výrobu šifrovaných oddílů použijeme LUKS (a tedy nástroj cryptsetup).
V dnešní době je již možné mít šifrovaný celý filesystém včetně bootovacího oddílu (a tedy kernelu i init-ramdisku) a využít pro odemknutí možnosti Grubu. Vzhledem k tomu, že ale nechceme k našemu serveru chodit, kdykoli je potřeba provést jeho restart (a protože se nechceme spoléhat na přeposílání konzole po síti například skrze IPMI modul), uděláme to trochu jinak.
Pokud jsme tak již neučinili při instalaci a systém máme zatím nešifrovaný, nic není ztraceno. Vyrobíme si v LVM dva oddíly. Jeden bude sloužit jako kořenový svazek a bude šifrovaný, druhý necháme v nešifrované podobě pro /boot. Získáme tak trochu pohodlí za cenu menší bezpečnosti – útočník nám může teoreticky podstrčit vlastní initrd a například odposlechnout heslo k systémovému oddílu.
# Vytvoříme logický svazek root-crypt o velikosti 20 GB lvcreate --name root-crypt --size 20g vg0 # Zinicializujeme šifrování a nastavíme heslo cryptsetup luksformat /dev/vg0/root-crypt # Odemkneme svazek cryptsetup luksOpen /dev/vg0/root-crypt root # Vyrobíme souborový systém mkfs.ext4 /dev/mapper/root # Vytvoříme svazek pro /boot lvcreate --name boot --size 1g vg0 # Vyrobíme souborový systém mkfs.ext4 /dev/vg0/boot
Oddíly postupně připojíme a nakopírujeme na ně patřičná data ze současného (nešifrovaného) kořenového svazku (rsync -axv nebo cp -axv jsou dostačující).
Pokud budeme chtít přidat nějaké další svazky (například úložiště pro NFS server, btrfs svazek pro LXC kontejnery, swap, …), zopakujeme stejný postup. Pro větší pohodlnost můžeme další svazky odemykat také pomocí klíče uloženého někde na šifrovaném hlavním svazku.
# Ukázka z /etc/crypttab root /dev/vg0/root-crypt none luks lxc /dev/vg0/lxc-crypt /root/.crypt/lxc luks
# Ukázka z /etc/fstab /dev/mapper/root / ext4 errors=remount-ro 0 0 /dev/vg0/boot /boot ext4 defaults 0 0 /dev/mapper/lxc /var/lib/lxc btrfs space_cache,compress=lzo 0 0
Boot
Když jsou všechny úpravy hotovy, zbývá ještě doladit boot. Z důvodu pohodlí jsme zvolili nešifrovaný bootovací svazek, takže můžeme do našeho init-ramdisku přidat spoustu zajímavých funkcí. Jednou z nich je možnost odemknout systémový svazek za pomoci SSH. V novém Debianu (stretch) je pro tyto účely již balíček dropbear-initramfs, který zvládne zařídit vše podstatné.
V jiném (nebo starším) systému si můžeme případně pomoci sami vhodným skriptem (návodů je opět hojnost). Já mám navíc podporu pro notifikaci do Rocket.Chatu v případě, že server čeká na zadání hesla. Součástí notifikace je i jeho současná IP adresa, takže se stačí připojit, zkontrolovat integritu init-ramdisku a zadat heslo.