Perinteisen virtuaalikoneen vaihto Dockeriin - osa 1

Kysyin, ja Internet vastasi. Olen jo jonkun aikaa yrittänyt löytää keinoja pienentää perinteisen virtuaalikoneen jalanjälkeä lokaalissa kehitysympäristössä. Tunkkasin tätä projektia varten ihan puhtaalta pöydältä uuden koneen, jolla sain imagen koon 60 gigasta 25 gigaan, mutta tuo 25 gigaa on edelleen aika tuhti paketti erityisesti varmuuskopiointia ajatellen. Lisäksi VMware-koneiden jakaminen on käytännössä mahdotonta, joten lokaali kehitys on väkisin sidottu yhteen fyysiseen koneeseen ja SSH:n yli räpeltämiseen. Kymmenen vuotta sitten tämä oli state-of-the-art ja viisi vuotta sitten vielä ihan kohtuullinen ratkaisu, mutta nykyään, Raymond Hettingerin sanoin, there must be a better way!

Docker on ollut hyperlimpparia jo niin monta vuotta, että kun vouhotus ei vaan ole tuntunut lakkaavan niin nyt oli korkea aika ottaa härkää sarvista. Olen muutaman projektin, erityisesti Discoursen, kautta Dockerin kanssa joutunut tekemisiin, mutta se on lukuisista blogipostauksista ja introvideoista huolimatta tuntunut liikaa magialta.

Itse konsepti on simppeli; (tavalla jonka toteutusta en edes uneksi osaavani ymmärtää) virtuaalikone kootaan keveistä komponenteista, joita löytyy apt/PyPI/NPM -tyylisestä hubista kymmeniä tuhansia sekä virallisia että yhteisön ja yksilöiden itse väkertämiä. Komponentteja löytyy käyttöjärjestelmistä yksittäisiin sovelluksiin (tyyliin ). Debian Jessie painaa ~180 Mt, erityisesti Dockeria varten höylätty Alpine-distro 5 (!!) – viisi – megatavua. Ollaan siis vahvasti eri pallokentällä kuin VMwaren 25 Gt.

Docker-imaget rakennetaan Vagrant-tyyppisesti yml-fileellä, johon on todella helppo kliksutella kaikki mahdollinen Python-asennuksista Redikseen ja Celeryyn. (Yllättäen olen tässä nyt vähän Django-asetelmissa.) Olemassa olleen Ubuntu + MySQL + Redis + Elasticsearch + Python 3 + PIP + yarn -paketit sisältäneen prokkiksen kokoaminen kokonaiseksi ajokelpoiseksi Docker-imageksi vaati kaksi tiedostoa: Dockerfile (16 riviä) + docker-compose.yml (36 riviä). En omaa aiempaa kokemusta vastaavantyyppisistä asetelmista kuin Vagrantista (ja hajun Puppetista), mutta muutaman tunnin detaljien kanssa tappelun päätteeksi tämä tuntui toimivalta ja loogiselta.

Perstuntumalta ensimmäinen build otti aikaa muutaman minuutin, eli samaa luokkaa kuin Vagrantilla. Huikea ero tulee kuitenkin siinä, että jokun asetuksen muuttuessa koko härdelliä ei tarvitse kääntää alusta asti uusiksi vaan suurin osa tulee suoraan välimuistista ja tyypillinen ”lisätään tämä apt-paketti” tai ”ainiin, RabbitMQ vielä” oli vain kymmeniä sekunteja, ja mikä tärkeintä, yhden paketin tuunaus (tyyliin ”näytä portti 8000 ulospäin porttina 80”) vie alle kymmenen sekuntia. Riippuen CI-asetelmasta, testausprosessi täydellisine buildeineen voi lyhentyä merkittävästi.

Viiden megatavun imageen en kuitenkaan ihan päässyt. Ensinnäkään, vaikka kuinka olisi Dockerin virallinen ja tukema distro, en ole vaihtamassa tuotantokäyttistä pois Debian/Ubuntu-maailmasta vain sadan megatavun takia. Toisekseen, en vaan halua lähteä metsästämään uusia paketin nimiä ja ties kenen väsäämiä ihmepaketteja vain sen vuoksi että se on Dockerin mielestä cool, joten käyttis pysyi Ubuntuna (joka on identtinen olemassaolevan tuotantosetupin kanssa). Lähes jokaisesta Docker-imagesta on olemassa ”slim”-versio ja useita muita vastaavia riisuttuja vaihtoehtoja jotka pienentävät imagen kokoa merkittävästi (jopa sinne kymmenen megan luokkaan), mutta alkuun pääseminen on aika paljon helpompaa kun vaan asentaa sen perushärdellin jossa tulee mukana ne kaikki paketit joiden dependencyt pitäisi riisutuissa versioissa keksiä manuaalisesti. Premature optimization jne… Lopullisesta 16+36 rivin build-reseptistä kasaantui 1,1 Gt image, joka on Docker-skaalassa pullea, mutta edelliseen ympäristöön verrattuna todella paljon kevyempi.

Isoin käytännön parannus lokaalidevauksessa Dockerilla on perinteiseen VMware-setuppiin verrattuna se, että koodi elää nyt Vagrant-tyylisesti lokaalisti lokaalilla levyllä ja on käyttäytyy sen myötä paljon paremmin kuin sshfs-viritykset. Huippukätevää on myös se, että kun docker-resepti on sisällä versionhallinnassa, sen kloonaus täysin identtiseksi ympäristöksi mille tahansa muulle koneelle (ja käyttöjärjestelmälle!) kestää sen muutaman minuuttia.

Ensimmäinen päivä Dockerin parissa oli todella positiivinen ja silmiäavaava kokemus, mutta avoimia kysymyksiäkin jäi kyllä vielä tuhottomasti. Muun muassa:

  • kun tuotantokoneella pyörii jo valmiiksi nginx, kannattaako imagella pyörittää pelkkää sovelluspalvelinta (gunicorn, uwsgi tms)?
  • entä omaa tietokantaa?
  • mikä on järkevin tapa erottaa tuotanto, testaus ja dev-imaget siten, että ne ovat kuitenkin mahdollisimman identtiset (ilman copy-pastea)?
  • miten SSL toimii? entä websocketit?
  • jos haluaa dockeroida tuotannon, millä tavalla tehdään järkevin resurssein zero-downtime deploymentit? entä rollbackit?
  • 42, mutta mikä on se kysymys?

Tämä oli siis vain ensipuraisu. Kirjoittanen jotain vähän koherentimpaa parissa eri merkinnässä kun saan nörttiblogin takaisin linjoille, ja jonkun ajan päästä vielä uudestaan fiiliksiä ja kokemuksia. Mutta nyt on kuitenkin tosi hyvä fiilis uudesta työkalusta – juuri tähän tapaan työkalujen kuuluukin parantua!

Ville Säävuori on verkossa vuodesta -97 luovinut Web-ammattilainen, DJ, luonnontieteilijä, viestintänörtti, ja burnoutissa käristetty entinen yrittäjä. Someissa @Uninen ja @djUninen, oldskoolisti ville@unessa.net.