KlientWundermanProduction
Obecně
Wunderman Production je menší organizace, která je součástí nadnárodní korporace Wunderman (a ta je snad součástí portfolia YR). Wunderman Production se zabývá tvorbou reklamních webů pro různé zákazníky. Má k dispozici mladý a poměrně nezkušený tým vývojářů. Projekty, na kterých pracují, se značně liší požadavky i velikostí, nicméně jde převážně o LAMP stack projekty.
Kontaktní osoba
| Martin Tomáš (nár. SK) | senior developer architect | martin.tomas@wunderman.com | +420 601 082 674 | martin.tomas@jabber.cz |
| Stephen Bornholtz (nár. USA) | senior manager | stephen.bornholtz@wunderman.com | +420 601 393 922 |
Kancelář
Office Building
Nádražní 762/32
155 00, Praha
vjezd na parkoviště z ulice Rozkošného
Lístek za parkování si nechat před odjezdem z parkoviště vynulovat v recepci (stačí zmínit, že se jedná o návštěvu Stephena Bornholtze z Wundermanu).
Spolupráce
Wunderman Production nás požádal o vybudování prostředí pro jejich webové vývojáře. Dříve vše dělali na desktopech a každý vývojář si udržoval svůj vlastní LAMP stack, což bylo neúnosné. Základní požadavky zněly:
- vývojové prostředí centrálně spravované UVTem
- očekává se, že různé projekty budou používat dosti rozdílná linuxová prostředí (OS, verze SW)
- vývojáři chtějí používat své nástroje jako doposud
- vývojáři by měli být schopni sdílet prostředí, aby si mohli efektivně předávat práci
- prostředí musí být propojené s firemním bitbucket serverem (git) mimo naši správu
- zákazníci musí mít k dispozici náhled předprodukčního webu
- vývojáři by neměli ukládat svá doménová hesla (např do gitu) mimo Wunderman
Vývojové prostředí
Základní myšlenkou vytvořeného prostředí je z pohledu vývojáře práce přes OpenVPN a namapování síťového disku na každý vývojářský stroj. Na síťovém disku vývojář vidí všechny své projekty v několika instancích. K dispozici je vývojářský phpmyadmin a logy z apache pro každý projekt. Vývojář pracuje se vzdáleným diskem, jako by byl lokální, používá tedy všechny své dřívější nástroje (git klient, IDE, atd.). Zároveň heslo ke gitu zůstává neustále v síti Wunderman, neboť gitové operace provádí vývojář lokálně a pouze data přesouvá na vzdálený disk.
Z pohledu serveru je důležité omezit množství spravovaných virtuálů na snesitelné množství. Proto projektové docrooty nejsou přímo spojeny s konkrétním LAMP stackem, ale jsou to samostatné disky, které se do toho konkrétního virtuálu připojují. Tak je možné třeba i během vývoje projektu převést projekt na kompletně jiné běhové prostředí.
- Celé řešení se v současné době skládá z několika OVZ virtuálů a běží toho času na serveru lh1.casa.cldn.eu
- Pro serverové řešení byla společností Wunderman zakoupena doména ppewun.eu (PreProductionEnvironmentWunderman)
- Většina sdíleného nastavení je uložena v centrálním LDAPu v podstromu dc=wunderman
Následuje popis jednotlivých klíčových serverů:
ovz_wunderman_vpn
Jde o CentOS 7 virtuál, který slouží jako centrální přístupový bod pro vývojáře.
OpenVPN
- na serveru běží OpenVPN server v UDP režimu (kvůli výkonu)
- VPN server je napojen na zákaznický LDAP a používá pythoní skripty pro nastavování firewallu
- VPN server přiděluje IP adresy z poolu 172.20.12.0/24
- VPN používá nadstandardní šifry kvůli bezpečnosti
- součástí klientské VPN konfigurace je Powershell skript, který mapuje projektový adresář na disk I: (viz níže)
Nginx
- na serveru běží servisní nginx, který obsluhuje stránku https://ppewun.eu
- návod na připojení do VPN běží na https://ppewun.eu/vpn a je chráněn HTTP autentifikací (keepass)
- klientská konfigurace OpenVPN se stahuje ze stránky s návodem jako .zip archív
PDNS
- na serveru běží autoritativní DNS pro doménu ppewun.eu
- doménové záznamy jsou uloženy v centrálním LDAPu
- DNS je zvláštní v tom, že překládá jak veřejné záznamy (VPN server, UAT instance, ...), tak lokální záznamy dostupné pouze z VPN
- interní VPN záznamy jsou vždy čtvrté úrovně a mají v poddoméně třetí úrovně uvedeno vpn (např. grolsch-devel.vpn.ppewun.eu)
- interní VPN záznamy jsou v LDAPu uloženy v samostatném podstromu
ovz_wunderman_samba
Jde o CentOS 7 virtuál, na kterém běží samba 4. Jediným účelem tohoto serveru je poskytovat síťový disk pro vývojáře.
SMBD
- na serveru běží samba napojená na centrální LDAP.
- samba poskytuje jediný share pro projekty, který využívá vlastnosti samby mapovat různé adresáře podle loginu (homes)
- mapují se adresáře z cesty /data/devel_home
- mapování je povoleno pouze z VPN adres
Organizace disků
Aby bylo možné projekty jednoduše sdílet mezi vývojáři a zároveň je přiřazovat k serverovým instancím, je každý projekt reprezentován jako samostatný disk s EXT4 FS. Tyto disky se připojují do VM do adresáře /projects/<jméno projketu>. Každý projekt má jednoznačné pojmenování, které by mělo vystihovat, kterého klienta se projekt týká. Jméno je nutné zvolit při zakládání projektu.
Protože na jednom projektu pracuje více vývojářů zároveň, existuje pro každý projekt několik instancí (reprezentovaných jako adresáře na disku). Jejich počet a jména jsou uvedena v LDAPu. Nicméně je dobré se držet pojmenování instance<číslo>. Není-li specifikováno jinak, měl by mít projekt při založení dvě instance.
Každá instance projektu by měla na úvod obsahovat jistý pevný počet adresářů s domluveným jménem a významem. V současné době jsou to adresáře:
| db | adresář, do kterého vývojáři ukládají číslované .sql soubory se strukturou databáze a jejími změnami | |||
| secrets | adresář, do kterého se ukládají hesla a další citlivé údaje spojené s projektem | |||
| logs | adresář s Apache logy pro danou instanci, vývojáři smějí pouze číst | |||
| www | docroot instance, Apache má zde právo zápisu | |||
| doc | různé dokumentace k projektu | |||
CRON skript a oprávnění k projektům
Ne každý vývojář má právo přistupovat ke všem projektům. Systém oprávnění k projektům je vybudován na úrovni skupin a mapování je plně uložené v LDAPu v podstromu dc=projects. V LDAPu je u každého projektu (jméno musí souhlasit s přípojným bodem projektu, viz výše) uvedeno, které skupiny (atribut member) jsou součástí projektu a dále, kolik instancí a s jakým jménem bude každý projekt mít.
Informace z LDAPu jsou převedeny na řetězec bind mountů pomocí CRON úlohy create_project_dirs, která se spouští každých pět minut. Pythonovský skript provede mapování příslušných projektů do adresářů /data/devel_home/<uid>, vytvoří adresáře instancí a nastaví práva. Uživatelé ve skupině sysadmins mají implicitně přístup do všech projektů.
ovz_wunderman_*_devel
Jde o sdílené vývojářské HTTP servery. Na těchto serverech se zobrazují vývojářské instance projektů. Jelikož projekty mohou mít stejné požadavky na OS a/nebo verzi balíků, jsou servery pojmenované podle OS, který na nich běží, a nikoliv podle projektu. Projekty jsou opět připojeny do /projects/<jméno projketu>. Apache konfigurace je nastavena tak, aby docroot směroval na /projects/<jméno projketu>/instanceX/www a logy se ukladaly do ''/projects/<jméno projketu>/instanceX/logs'. Pro každou instanci projektu musí existovat samostatná Apache konfigurace.
ovz_wunderman_devel_dbs
Jde o databázový stroj pro vývojářské instance. Běží na něm jedna MariaDB 10.1. Na serveru běží též PHPMyAdmin dostupný z VPN na http://devel-dbs.vpn.ppewun.eu. Pro každou instanci projektu je nutné vytvořit samostatnou databázi. Přístupové údaje se vývojářům předávají nakopírováním na projektový disk, do /projects/<jméno projektu>/instanceX/secrets. Root heslo je uvedené v keepassu.
ovz_wunderman_build
Jde o stroj, který je určen pro kompilaci a nasazovaní vyvíjených projektů z gitu. Na stroji se používá uživatel git.importer, pod kterým běží jednak USWGI aplikace zpracovávající git webhooky z bitbucketu, druhak zde běží kompilační skripty.
UWSGI aplikace je jednoduchý pythonovský web používající flask. Aplikaci tvoří jediný soubor www/www/build.py.
Když na bitbucketu dojde ke změně, zavolá se webhook, který je obsloužen flask aplikací. Ta dále spustí sktript scripts/deploy_php_project.sh. Tento skript stáhne příslušnou větev projektu z bitbucketu do adresáře ''build/<projekt>-<větev>. Zde se zkompilují statické js a css soubory, dojde k minifikaci a dalším úkonům (řízené přes gulpfile.js), a nakonec se výsledný web (podadresář www) přesune na příslušný web server.
Logy z flask aplikace a celého procesu nasazování lze nalézt v souboru www/logs/webhook.log.
Speciální projekt Internal
V rámci infrastruktury existuje jeden speciální projekt pojmenovaný internal. Tento projekt je určen pro sdílení hesel a dokumentů mezi ÚVT a vedoucími Wunderman Production. Nejdůležitější je adresář secrets, který obsahuje soubory s různými hesly.
Založení nového uživatele
Nový uživatel se zakládá skriptem add-user popsaným v centrálním LDAPu. Do skriptu je vždy nutné uvést jméno, příjmení a email uživatele (bude vždy dodán s žádostí o nový účet nebo na vyžádání). Pokud bude k uživateli dodán i telefonní kontakt, je dobré ho uvést (ručně v LDAPu) do atributu telephoneNumber. Uživatelské jméno má vždy podobu <příjmení><první písmeno jména> s výjimkou uživatele uvt.
Při založení uživatele skript vypíše jeho nové heslo. Toto heslo je nutné uložit do atributu sambaNTPassword. Uděláme to zavoláním příkazu smbpasswd -a ve virtuálu ovz_wunderman_samba.
Heslo se předává nakopírováním výstupu ze zakládacího skriptu do /projects/internal/instance1/secrets/developers_login.txt. Kvůli lepší čitelnosti ve Windows je dobré soubor po změně prohnat přes nástroj todos.
Založení nového projektu
Nejprve je vždy nutné zjistit, kterého webu/zákazníka se bude projekt týkat. Z této znalosti je nutné odvodit unikátní jednoslovné a popisné jméno projektu. Toto jméno se bude používat na množství různých míst, proto musí být zvoleno dobře. Od teď budeme předpokládat, že jako jméno projektu jsme zvolili test.
- v centrálním LDAPu založíme skupinu projektu
./add-group.pl -c wunderman -g test
. - přidáme do skupiny vývojáře, kteří budou na projektu pracovat, např.
./add-user-to-group.pl -c wunderman -g test -u krejcit
. Členové skupiny sysadmins mají implicitně přístup do všech projektů a není je tak nutné explicitně uvádět. - přímo v LDAP prohlížeči je nutné pod DN dc=projects,dc=wunderman,dc=customers,dc=cldn,dc=eu vytvořit hierarchii pro nový projekt. Zde je nutné hlavně vyplnit správně atribut member a spojit tak projekt s příslušnou skupinou. Na pomoc nám může přijít definice projektu internal. Projekt by měl v základu mít dvě instance.
- vytvoříme nový projektový disk
lvcreate -V10G -T vg_lh1_0/lh1_pool -n /dev/vg_lh1_0/ovz_wunderman_test_shared
. Název projektu se vždy promítne v názvu LV mezi slovy wunderman a shared. - vytvoříme FS
mkfs.ext4 -v -E lazy_itable_init=1 /dev/vg_lh1_0/ovz_wunderman_test_shared tune2fs -c -1 -i 0 /dev/vg_lh1_0/ovz_wunderman_test_shared
- upravíme fstab a připojíme disk
echo "/dev/vg_lh1_0/ovz_wunderman_test_shared /vz/libvirt/mounts/ovz_wunderman_test_shared ext4 defaults,noatime,acl,user_xattr,_netdev 0 0" >> /etc/fstab mkdir -p /vz/libvirt/mounts/ovz_wunderman_test_shared mount /vz/libvirt/mounts/ovz_wunderman_test_shared
- připojíme projektový disk do virtuálu ovz_wunderman_samba (disk musí být připojen do adresáře, který se jmenuje stejně jako projekt)
cat > /root/test.xml << EOF <filesystem type='mount'> <source dir='/vz/libvirt/mounts/ovz_wunderman_test_shared' fs='auto'/> <target dir='/projects/test'/> </filesystem> EOF virshvz attach-device ve2006 test.xml --live --config # a ještě upravit doménu (přidat mount) v /etc/libvirt/domains/wunderman/bossonvz/ovz_wunderman_samba.xml vim /etc/libvirt/domains/wunderman/bossonvz/ovz_wunderman_samba.xml - v tuto chvíli by měl CRON skript na sambě dovytvořit potřebné adresáře a propojit projekt se sdílenými adresáři vývojářů. Vývojáři by tak měli mít přístup na sdílený projektový disk.
- pokud projekt vyžaduje vývojové prostředí (OS, verze balíků), které se výrazně liší od již existujících prostředí, je nutné založit nový virtuál po vzoru již existujících a projekt v něm rozjet tak, jak bude popsáno v dalších bodech. Vývojový virtuál by měl být pojmenován podle běžícího OS. DB server by měl stačit jen jeden již existující. Nezapomeneme přidat IP nového stroje do správných skupin v LDAPu kvůli VPN firewallu.
- projekt se do vývojového stroje přidá tak, že se připojí projektový disk do adresáře /projects stejně jako v bodu 7.
- vytvoříme konfigurační soubor v adresáři Apache po vzoru již existujících. Je důležité, aby logy i docroot směrovaly do sdíleného adresáře.
- vytvoříme DNS záznamy <název projektu>-instance<X>.vpn.ppewun.eu pro každou instanci pomocí LDAP prohlížeče pod DN dc=vpn,dc=ppewun.eu,dc=dns,dc=wunderman,dc=customers,dc=cldn,dc=eu. Uvedeme IP adresu námi zvoleného vývojového stroje.
- vytvoříme DB pro každou instanci projektu na stroji ovz_wunderman_devel_dbs. Databáze by měla sledovat jmennou konvenci db_<jméno projektu>_instance<X>, uživatelské jméno by pak mělo být společné pro všechny instance <jméno projektu>_dbuser, heslo by mělo být náhodné, deset znaků dlouhé.
mysql create database db_test_instance1 default character set utf8 default collate utf8_general_ci; grant all privileges on `db_test_instance1`.* to 'test_dbuser'@'localhost' identified by '<heslo>; grant all privileges on `db_test_instance1`.* to 'test_dbuser'@'192.168.56.%' identified by <heslo>'; flush privileges;
- databázové údaje uvedeme do souboru devel_db_passwords.txt a uložíme do adresáře secrets v každé instanci
# voláme na ovz_wunderman_samba cat > /projects/test/instance1/secrets/devel_db_passwords.txt << EOF instance1: db: db_test_instance1 user: test_dbuser pass: <heslo> host: devel-dbs.vpn.ppewun.eu EOF todos /projects/test/instance1/secrets/devel_db_passwords.txt # opakujeme pro každou instanci
Grolsch live
Projekt Grolsch Beer (http://grolsch.com/) je webová prezentace v Drupalu běžící na produkčním stroji v Rackspace (OS Ubuntu 14.04). Pro produkční web děláme monitoring a řešíme problémy v rámci VM samotného (spadlý Apache, apod.). Problémy s externí infrastrukturou (síť, spadlý virtuál, ...) řešíme s administrátory infrastruktury Grolsch. Přístup do VM je omezen na IP domečku. Uživatel grwebuser má právo sudo.
| ssh grwebuser v(e) 162.13.245.135 | keepass | |||
Pro web je vyčleněna samostatně běžící MySQL databáze, do které máme jen uživatelský přístup. Údaje v keepassu.
Nasazení produkční verze webu
Nová verze webu je vždy uložená ve větvi master a označena verzí (např v3.8) - tato verze bude specifikovaná při požadavku o nasazení. V současné době neexistuje automatizovaný skript pro nasazení produkčního grolsche. Vše je nutné dělat ručně. Následuje popis kroků:
- Připojit se na stroj ovz_wunderman_build na LH1.
- Přepnout se na uživatele git.importer a přejít do build/grolsch-release.
- Spustit
git reset --hard
. - Zavolat
git status
a smazat pomocí rm všechny soubory označené jako modified. - Zavolat
git pull origin <verze>
. - Zavolat
git status
a pokud jsou nektere soubory ve stavu deleted je treba na ne zavolat "git checkout" - Zavolat
npm install
. - Zavolat
gulp --production
. Lze volat pouze jednou. Při opakovaném pokusu o zavolání selže. - Zazipovat adresář www a db a přenést na produkční stroj (nejlépe přes SSH).
- Připojit se na produkční stroj (viz keepass).
- Rozbalit zip archiv.
- Udělat zálohu adresáře /var/www/www.grolsch.com/www.
- Udělat dump databáze
mysqldump --routines --triggers --events gr_db > ~/dbback/grolsh_<datum>.sql
. - Nakopírovat rozbalený adresář www do /var/www/www.grolsch.com/www a přepsat všechny existující soubory (nemazat nekonfliktní soubory!).
- Upravit práva
chown -R root:www-data /var/www/www.grolsch.com/www chmod -R u=rwX,g=rX,o=rX /var/www/www.grolsch.com/www chmod -R u=rwX,g=rwX,o=rX /var/www/www.grolsch.com/www/sites/default/files
- Nahrát rozdílové dumpy z rozbaleného adresáře db v pořadí. Je nutné začít od souboru neuvedeném v ~/fixtures a zaznamenat jméno každého aplikovaného dumpu do tohoto adresáře.
- Smazat cache zavoláním skriptu
clear_cache.sh