Kai kam perskaičius antraštę kilo mintis „wtf”, kai kas atėjo tikėdamiesi rasti kažką kito. Šiandien papasakosiu kaip tvarkingai dėliotis savo serveriukus, programėles ir visą kitą brūdą, kad būtų lengva migruoti į kitą avietę arba tiesiog atstatyti senąją po tragedijos – žinoma jei turit atsarginę kopiją. Tikiuosi skaitėt įrašą apie patikimą saugyklą avietei. Jei ne – siūlau paskaityti. Čia parodysiu kaip į tą saugyklą dėti duomenis, kad paskui patys sau (ir man) padėkotumėte. Taip pat konteinerius aktyviai naudoju ir naudosiu vėlesniuose įrašuose su pavyzdžiais, tad pravartu dabar susipažinti.

Tai prie ko čia tie konteineriai?

Konteineriai prie to, kad parodysiu kaip naudoti norimus serverius konteineryje, o ne tiesiai ant serverio. Pabandysiu pateikti tiek informacijos, kad perskaitę šį įrašą norėtumėte ir galėtumėte patys pradėti draugauti su konteineriais.

Konteinerizacija yra kieta

P kaip normalus, tuomet dar pradedantis programeris maksimalistas, o ne koks nors ten Microsoft technologijų gerbėjas (vis gi karjerą pradėjau nuo .NET, bakalaurinį ir magistrinį ir rašiau su .NET), konteinerius atrado kokiais 2014-2015 metais. Skaitinėdavau https://www.javacodegeeks.com blogą ir vienu metu ten tiek padavė įrašų, kad kas antras, o kartais net keli iš eilės buvo apie konteinerizaciją. Paskaičiau – užkabino. Pasibandžiau – veikia, patiko. Pabandžiau savo kažką paleist, ir nors ir paleidau, bet kažkaip stabiliai su pirmuoju raspberiu dar neveikė. Trūko image’ų ant pirmos avietės, tad eksperimentiniu rėžimu bandinėjausi iki kokių 2017.

Fun fact, kad darbo tikslais, taip ir neteko panaudoti šio gėrio, bet „backloge” jau guli vieno serviso perdarymas, kad veiktų konteineryje.

Kodėl kieta? Todėl kad kartais net kiečiausi programeriai nežino apie konteinerius, arba yra kažką girdėję, bet savo rankom nelietė.

True story: kartą reikėjo trumpam užkurti mongoDB, tai aš tik ant konteinerio šast ir paleidau. Net pataikiau pavadinimą neatsidaręs naršyklės. Kolega, kuris net ne senior, o pats kitos komandos tech lead’as nustebęs: kaip tu čia paleidai nematytu būdu? Ai čia ant docker’io? Nu mldc.

Tad jei turit draugų programuotojų ir pasakysit, kad viską leidžiat ant konteinerių – duos respekto taškų. Faktas.

Tai kas ta konteinerizacija?

Bene populiariausia platforma konteineriams – docker. Į kitas net nebandysiu gilintis. Grubiai ir ūkiškai kalbant, konteineris kažkuo panašus į virtualią mašiną (kaip kad VMware ar VirtualBox, Parallels(jei esat mac fanas su pinigais)), bet esminis skirtumas, kad virtualios mašinos atveju, geležis (hardware) yra virtualizuojama, o konteinerio atveju dalinamasi tuo pačiu „host” mašinos kerneliu. Einant prie reikalo – dockeris leidžia supakuoti visą Jūsų norimą serverį, su visom bibliotekom ir su visa operacine sistema! Primetat?

Pagrindinė docker terminologija:

  • Paveikslas (image) – tai paketas, kuriame supakuota viskas ko reikia, kad būtų galima paleisti aplikaciją. Pati aplikacija – operacinė sistema su reikalingomis bibliotekomis. Paketus galima kurti pačiam arba parsisiųsti. „Padefaultu” dockerio instaliacija yra surišta su https://hub.docker.com todėl jei neras paveikslo pas jus kompe, bandys parsiųsti iš hub’o. Image atitikmuo objektiniam programavime būtų klasė – vienai versijai vienas paveiklas.
  • Konteineris (container) – tai su tam tikra konfiguracija veikiantis paveikslas. Objektiniam programavime atitikmuo iš dalies galėtų būti objektas. Galima turėti daug skirtingom konfiguracijom veikiančių konteinerių naudojančių tą patį image.

Kam to reikia?

Matyt daug kam kyla klausimas, kam to reikia? Vardinu privalumus:

  • Paprastumas. Host mašinoj užtenka turėti dockerį įrašytą, ir viskas. Nereikia galvot ar python įrašytas, ar java yra, ar tinkamos jų versijos ir pan.
  • Saugumas. Kiekvienas konteineris yra izoliuotas nuo host aplinkos ar kitų konteinerių, tiek networku, tiek ir failų sistema. Tik jūs sukonfiguruosit ką jis gali pasiekti.
  • Laisvė konfigūruoti. Docker leidžia lengvai sieti ar tuneliuoti portus, taip pat leidžia lengvai „moun’inti” host mašinos failų sistemą į konteinerio failų sistemas. Taip galima visų programų failus laikyti vienoj vietoj ir iš to pasidaro lengva kurti atsargines kopijas.
  • Jokių problemų, kad atnaujinot savo raspberio OS ir nebeliko kažkokios versijos bibliotekų. Arba, kad kažkur skirtingiems serveriams reikia skirtingų versijų bibliotekų. Tiesiog Jūsų konteineris pats turi savo OS ir savo bibliotekas. Viskas ko jums reikia – dockerio ant host mašinos.
  • Laisvė eksperimentuoti. Sumastėt, kad norit šiandien pasibandyti HomeAssistant ar OpenHAB ar dar ką nors? Ne problema! Galima net 5 HomeAssistant pasileisti vienu metu! Norėčiau pamatyti kiek užtruktumėt tą padaryt su standartine instaliacija. Nepatiko? Ištrinti dar lengviau! Skaityk toliau ir pamatysi.

Trumpam nutrūksta vaizdo klipas ir įsiterpia D. Praskaidrino mano saviizoliacijos vakarą šito teksto redagavimas žinokit. P varo kaip koks Top Shop’as. Nieko nesuprantu, bet pirkčiau. 😀 Atleiskit… tęsiam toliau.

  • Net Microsoft technologijų fanai nėra pamiršti…. su tam tikrais niuansais. Dockerio host’ą galima naudoti tik ant Windows 10. Bent jau taip buvo kažkada.

Demo

Tai labai paprastai, dviem komandom paleidau OpenHAB 2.5.1 versiją, ir naujausią Home Assistant. Kaip ir minėjau, jei tokių paveikslų neranda pas jus, bando parsiųst iš https://hub.docker.com. Ir dar HA standartinį port’ą nukreipiau į 8081. O kiek užtruktumėt su standartine instaliacija ir kiek rankinio darbo būtų atlikta tam?

docker run -d -p 8081:8123 --name ha homeassistant/home-assistant

-d – atjungia konsolę nuo conteinerio tekstinės išvesties – t.y. be šios komandos matysite visą konteinerio log’ą.

-p – nurodo kokį host mašinos portą nukreipti į kokį konteinerio port’ą. Nenurodžius -p iš host ar iš išorės savo konteinerio nepasieksite. Šiuo atveju 8081 host portas, 8123 default HA port’as.

–name – priskiria konteineriui vardą. Turint vardą lengviau paskui dirbti su konteineriu.

homeassistant/home-assistant – paveikslo pavadinimas. Juos galima rasti adresu https://hub.docker.com . Kaip pavyzdį paimsiu openHAB, nes jie turi daug detalesnį aprašymą kaip paleisti konteinerį. Taip pat detaliai aprašyta kaip sukonfigūruoti: kokios direktorijos reikalingos (tas reikalinga, jei norėsit nukreipti į savo vietą host mašinoj). https://hub.docker.com/r/openhab/openhab

Docker compose

Leidimas iš komandinės eilutės yra patogus jei norima tik pasižaisti su kažkokiu konteineriu. Aš taip pasižaidžiau su openHAB ir HA savo laiku, kad pasižiūrėt. Jei galvojat apie ilgalaikį konteinerį, siūlyčiau prie dockerio papildomai dar įsirašyti docker-compose. Tokiu atveju galima visą konfigūraciją pasidaryti faile.

version: '3.2'

services:

  wordpress:
    image: wordpress
    restart: always
    environment:
      VIRTUAL_HOST: 'pdnamas.lt,www.pdnamas.lt' # naudojant nginx-proxy užtenka tik tiek, kad nukreipti domain'ą į savo konteinerį. Lygiai taip pat galima kurti ir subdomain.
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: kažkoks_user
      WORDPRESS_DB_PASSWORD: kažkoks_password
      WORDPRESS_DB_NAME: wordpress
    volumes:
            - /mnt/raid/docker_volumes/pdnamas_wp:/var/www/html  # galima būtų naudoti ir ./docker_volumes/pdnamas_wp:/var/www/html tada pasiims iš ten, kur paleistas yaml failas

  db: # šiuo atveju WORDPRESS_DB_HOST reikšmė turi būt tokia kaip čia
    image: biarms/mysql # kaip ir nėra oficialaus MySQL ant ARM architektūros
    restart: always
    environment: # 
      MYSQL_DATABASE: wordpress
      MYSQL_USER: kažkoks_user
      MYSQL_PASSWORD: kažkoks_password
      MYSQL_RANDOM_ROOT_PASSWORD: '1'
    volumes:
            - /mnt/raid/docker_volumes/pdnamas_sql:/var/lib/mysql
networks:
  default:
    external:
      name: nginx-proxy-network  # 

Startuojam su:

docker-compose -f kazkoks.yaml up -d

Ir pasileis mums du konteineriai (wordpressui ir duombazei), ir kadangi jie vienam yaml faile, tai konteineriams automatiškai bus priskirtas vienas tinklas, tam kad wordpress pasiektų duombazę. Pats paveikslas paruoštas taip, kad jei nieko neras „pri’mount’intose” direktorijose, sukurs viską naujai, jei ras, naudos tai, ką ras. Šiuo atveju mysql konteineris net nebus pasiekiamas iš host mašinos, nes neturi „iškišto” porto į išorę. Papildomai dar esu pridėjęs nginx-proxy-network tinklą, nes naudoju nginx-proxy konteinerį, kad galėčiau domenus nukreipinėt į norimus konteinerius, todėl konteineriai turi kažkaip vienas kitą matyti tinkle. Iš tikro tai net ir wordpress’o portas nėra iškištas. Visą 80 portą ir kur ką nukreipti tvarko nginx-proxy konteineris pagal tai, su kokiu domenu ateinama:

version: "3"
services:
  nginx-proxy:
    image: braingamer/nginx-proxy-arm
    restart: always
    container_name: nginx-proxy
    ports:
      - "80:80"
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro
      - /mnt/raid/docker_volumes/nginx-proxy/client_max_body_size.conf:/etc/nginx/conf.d/client_max_body_size.conf:ro

networks:
  default:
    external:
      name: nginx-proxy

Su tokia konfigūracija užtenka daryti atsargines kopijas folderio, kur visi yaml failiukai ir programų mount’inamos direktorijos. Mano atveju /mnt/raid/docker_volumes ir viskas. Numiro raspberis? Ant naujo raspberio pasistartuojat visas savo yaml konfigūracijas ir viskas.

P patirtis

Kaip ir minėjau, aktyviai konreinerizuoju savo projektus kažkur nuo 2017 metų. Taip pat į konteinerius perkėliau ir OpenVPN serverį, liko dar Samba su NFS išsikelti. Paskutinį Raspberry pirkau specialiai su 8GB RAM, bet iš patirties, šiuo metu ant mano odroid sukasi 13 konteinerių (2 wordpress, 3 duombazės, visokie python skriptukai (kurių kiekvienas turi savo OS’ą) keli MQTT brokeriai ir pan., tai naudojasi ~1GB RAM, tad resursų problemos nebuvo. Juntamo spartos sumažėjimo ir nesijaučia. Net ant pirmos avietės esu paleidęs vieną konteinerį (signalizacijos projektas, kurį minėjau ankstesniame įraše).

Galbūt kam nors kyla klausimas kam man dviem wordpressams du MySQL, kai galima sukurti skirtingas duombazes tam pačiam MySQL’e, tai pasakysiu taip: resursai seniai jau nebėra problema.

  • resursai seniai jau nebėra problema.
  • remiantis mikroservisų architektūra, kuri yra dabar ant bangos, kiekvienas servisas turėtų turėti savo duombazę.
  • daug lengvesnė migracija (jei sugalvosit perkelti svetainę į kitą serverį), daug lengviau „scale’inti”, jei prireiktų.
  • jokia kita programa/serveris „nesufackins duomenų viena kitai”.

Naudingos komandos ir ką svarbu žinoti

  • Svarbu! Nuliūdinsiu Microsoft technologijų gerbėjus (nes mačiau paveikslų ir windows pagrindu), bet paveikslas turi būti pritaikytas jūsų procesoriaus architektūrai. T.y. ant avietės nepaleisit x86/x64 paveikslų, o ant x86/x64 nepaleisit ARM paveikslų.
  • Pridedant prie pirmo punkto, nors dauguma paveikslų turi ARM versijas (nors ir ne visi), bet kartais reikia labiau pasidomėti ar palaiko būtent jūsų turimą ARM versiją. Tarkim ARMv8 (Raspberry pi 4), kuris jau gali būti ir 64bit, neveiks ant pirmojo Raspberry kuris yra ARMv6. Apskritai ARMv6 dažnai pamirštamas tarp dockerio paveikslų, tai jau galit iškart ieškoti paveikslo, skirto būtent pirmai versijai (tokių egzistuoja).
  • Siūlyčiau visada nurodyt konkrečią paveikslo versiją. Naudojant latest gali nutikti taip, kad kada nors prasitrinsit savo paveikslus ir, iš naujo įsirašius, gausite naujesnę versiją. Pvz.: vietoj PHP5 į PHP7 ir nebeveiks dalykai. Aišku su konteineriais nesunku tą ištaisyt 🙂

Keletas naudingų komandų:

docker ps  arba docker container ls #parodo veikiančius konteinerius
docker ps --all # parodo visus konteinerius, ir veikiančius ir sustojusius
docker image ls # paveikslų peržiūra
docker network ls # tinklų peržiūra
docker volume ls # saugyklų peržiūra
docker container rm kažkoks_id # trina konkretų konteinerį
docker image rm kažkoks_id # trina konkretų paveikslą
....

docker container prune # trina visus užgesusius (sustojusius) konteinerus
docker image prune # trina visus konteineriuose nepanaudotus paveikslus
...
docker exec -it konteinerio_pavadinimas_arba_id bash # galite prisijungt prie konteinerio taip, kaip jungtumėtės prie avietės per SSH. Kai kurie paveikslai neturi bash, tai tada galima naudot sh vietoj bash. Tačiau stipriai nerekomenduoju atilikinėti kažkokių pakeitimų konteineryje, nes naujai suintaliavus galite prarasti pakeitimus. Visada geriau prisimountint'i kažkokį failą ar direktoriją iš host mašinos.
docker start konteinerio_id arba vardas # paleidžia sustojusį konteinerį
docker stop konteinerio_id arba vardas
docker restart konteinerio_id arba vardas
docker logs konteinerio_id arba vardas # galima pažiūrėti, ką konteineris spausdina į tekstinę išvestį, bet čia užkraus visus log'us
docker logs --tail 100 -f -t konteinerio_id arba vardas # maano dažniausiai naudojama komanda atspausdins 100 paskutinių eilučių ir laikys sesiją prijungtą, tad matysit visus log'us kol pats neišeisite su ctrl+c.

Tikiuosi kažkokius pagrindus pavyko suteikti, o kita jau galima ir pasigooglinti. Arba komentaruose rašykite, padėsiu. Kituose įrašuose parodysiu ir kaip savo konteinerius kurti.

Bonus: dabartinis statusas

Kaip tik neseniai (lapkričio 16) pasidarėm pirminį sandarumo testą. Tepliojau aš ten viską ilgai ir nuobodžiai. Ir D tepliojo. Džiaugėsi paskui, kad pro jos tepliotus langus nieko neleido. Smulkmenėlių žinoma vistiek rado, bet rezultatas 0.22. Smagu ir yra potencialo pagerinti rezultatą užsikaišius tas smulkmenas. Tai dabar planas: susidėti rekuperatorių (jau beveik yra projektas) ir lubų karkasą ir tada jau daryti normalų dokumentuotą testą.

Kažkur stringa dujų popierizmas todėl name vis dar šalta.

Kadangi norėjau užfiksuoti šilumos paleidimo momentą, tai iš to ką turėjau padariau geležį ir pradėjau po truputį užkūrinėti duomenų surinkinėjimo infrastruktūrą, tai tikrai žinau, kad name tikrai šalta ir drėgna:

Drėgmės/temperatūros rinkimo įrenginys

Programinė infrastruktūra kolkas alfa versijoj ir vis dar stovi ant odroid, o ne namui dedikuotos avietės, bet ant konteinerių! Testuojuosi, bandinėju skirtingas duombazes ir duomenų rinkimo būdus. Kitaip sakant ieškau geriausių praktikų, todėl įrašas apie duomenų rinkimą bus kiek vėliau.

Geležis kolkas ir tik „proof of concept”:

  • T.y. numesta belenkur – ten kur yra elektra, tad kartais apšviečia saulė (dabar, kai cepelininis dangus, tai nelabai apšviečia) ar dar kas nors darko matavimus.
  • Naudoju DHT22 sensorių, nes turėjau stalčiui. Neplanuoju jų naudoti galutiniam variante.
  • Internetui naudoju mezon hot spotą, o ne PDnamo šviesolaidį, kuris yra ir veikia. Skyde vis dar nėra normalios elektros, o ant snarglių routerių prikabinėti nenoriu.
  • Mezon modemas kažkoks nestabilus ir kartais po 3 dienų nusprendžia, kad reik atjungt krovimą, ir atsijungia išsikrovus baterijai. Todėl kartais duomenų srautas nutrūksta. Galvoju pakeist kokiu nenaudojamu telefonu iš stalčiaus.
  • Kaip kontrolerį naudoju ESP32 nes ir turėjau stalčiui ir patogu per wi-fi prisijungt prie modemo, bet jo ir nenaudosiu galutiniam variante.

Pradėjau bandinėti šviesos valdymo prototipą ir kažką sudeginau ne taip pajungęs, todėl vienas pirktas kontroleris nebereguoja į komandas. 😀

PAGALIAU pajudėjo elektros skydo tvarkymas, tai jau gal tuoj prasidės protinimo infrastruktūros diegimai ir minimalus svarbiausių funkcijų paleidimas.

D ir toliau ketinėja dizainus, nes gali. Tai galimai kažką aprašys dar kartą iki darant įrengimą.

Dar kartą nutrūksta vaizdo klipas ir įsiterpia D… P pažadukas, o D tyli, ką? 🙂 „Apšiltino fasadą ir nepataikė su dekoratyvinio tinko spalva. D gal norės kada prie progos apstumt mane dėl to, tai sukals kokį įrašą.” Čia praeitam įraše porino pažadukas. Klausykit, kiek laiko praėjo, o dar tebetrollinu už tą spalvą. Trumpai kaip ten su tuo fasadu buvo:

Parašyk ano gamintojo kodą, šitas padarys tokią pačią – sakė jie. Kodas sutampa – sakė jie. Tai dabar rezultate turim ne pilką spalvą, o rudai-violetinį-nuo-saulės-priklausantį-chameleoną. Ant. Namo. Fasado. Graži spalva – sako jie. O aš sakiau, kad REIKĖJO PIRMA TESTUOTI!!! 😀 Kita žinokit lieptų nugraužt tą tinką. Tai nekartokit (sakyčiau mūsų, bet šiaip tai…) jų klaidos ir testuokit spalvas. Jūsų moteris nebūtinai bus tokia chill. 😀

Kitas įrašas

Kitą įrašą bandysiu daugiau į statybas orientuoti, o ne į išmanius techninius dalykus, kad neatsibostų. Galimai tai bus įrašas apie ventiliaciją.