Docker - гэта цацка ці не? Ці ўсё ж так?

Усім прывітанне!

Вельмі хочацца адразу адразу прыступіць да тэмы, але правільней будзе крыху распавесці пра маю гісторыю:

Уступленне

Я праграміст з вопытам распрацоўкі frontend аднастаронкавых прыкладанняў, scala/java і nodejs на сэрвэры.

Даволі доўга (ужо сапраўды пару - тройку гадоў), я прытрымваўся меркаванні, што docker гэта манна нябесная і наогул вельмі крутая прылада і абсалютна кожны распрацоўнік павінен умець карыстацца ім. А адгэтуль выцякае, што і ў кожнага распрацоўніка павінен стаяць docker на лакальнай машыне. Ды што тамака пра маё меркаванне, вы пагартайце вакансіі, якія размяшчаюцца на тым жа hh. У кожнай другой ёсць згадка пра docker і калі вы ім валодаеце - гэта будзе вашай канкурэнтнай перавагай 😉

На сваім шляху я сустракаўся са шматлікімі людзьмі, з іх розным стаўленнем да docker і да яго экасістэмы. Адны казалі, што гэта зручная рэч, якая гарантуе кросплатформеннасць. Другія не разумелі навошта ім запускацца ў кантэйнерах і які профіт ад гэтага, трэцім было наогул пофіг і яны не парыліся (проста пісалі код і сыходзілі дадому - зайздрошчу, дарэчы, ім 🙂 )

Прычыны выкарыстання

Чаму я выкарыстоўваў docker? Мусіць па наступных чынніках:

  • запуск базы дадзеных, 99% прыкладанняў карыстаюцца імі
  • запуск nginx для раздачы frontend і праксіравання на backend
  • можна спакаваць прыкладанне ў docker вобраз, такім чынам маё прыкладанне будзе працаваць усюды, дзе ёсць docker, праблема дыстрыбутацыі вырашана ўжо адразу
  • service discovery са скрынкі, можна рабіць мікрасэрвісы, кожны кантэйнер (падлучаны да агульнай сеткі) лёгка дастукаецца да іншага па аліясу, вельмі зручна
  • прышпільна стварыць кантэйнер і "пагуляцца" у ім.

Што мне заўседы НЕ падабалася ў docker:

  • для таго каб маё прыкладанне працавала, патрэбен сам docker на серверы. А навошта мне гэта, калі мае прыкладанні працуюць на jre ці на nodejs і асяроддзе для іх ужо ёсць на серверы?
  • калі я жадаю запусціць сваю (прыватную) лакальна сабраную выяву на выдаленым серверы, то мне патрэбен свой docker рэпазітар, трэба каб дзесьці працаваў registry і яшчэ трэба наладзіць https, таму што docker cli працуе толькі па https. Ох блін… ёсць варыянты, вядома, захаваць выяву лакальна праз docker save і праз scp проста скінуць выяву… Але гэта гэтулькі рухаў цела. І да таго ж выглядае «кастыльным» рашэннем, пакуль не з'явіцца свой рэпазітар.
  • docker-compose. Ён патрэбен толькі для запуску кантэйнераў. І ўсё. Болей нічога ён не можа. Docker-compose мае кучу версій сваіх файлаў, свой сінтаксіс. Якім дэкларатыўным ён бы ні быў, я не хачу чытаць іх дакументацыю. Мне яна больш нідзе не спатрэбіцца.
  • пры працы ў камандзе, у большасці сваёй людзі пішуць Dockerfile вельмі крыва, не разумеюць як гэта кэшуецца, дадаюць у выяву ўсё што трэба і не трэба, успадкоўваюцца ад выяў якіх няма ў dockerhub або прыватным рэпазітары, ствараюць нейкія docker-compose файлы з базамі дадзеных і нічога не персістуюць. Пры гэтым распрацоўшчыкі ганарліва заяўляюць, што docker круты, у іх усё працуе лакальна і HR важна піша ў вакансіі: «Мы выкарыстоўваем docker і нам патрэбен кандыдат з такім досведам працы»
  • увесь час пераследуюць думкі аб падняцці ў docker усяго і ўся: postgresql, kafka, redis. Шкада, што не ўсё працуе ў кантэйнерах, не ўсё лёгка сканфігураваць і запусціць. Падтрымліваюцца гэта іншымі распрацоўшчыкамі, а не самімі вендарамі. І дарэчы адразу ўзнікае пытанне, вендары не парацца наконт падтрымання сваіх прадуктаў у docker, чаму ж гэта, можа яны нешта ведаюць?
  • заўсёды ўзнікае пытанне пра персістэнцыю дадзеных кантэйнера. і тут думаеш, мне проста прымантаваць хаставую дырэкторыю ці стварыць docker volume ці зрабіць data container які цяпер deprecated? Калі я мантую дырэкторыю то мне трэба пераканацца што uid і gid карыстача ў кантэйнеры адпавядае id карыстача які запусціў кантэйнер, інакш файлы створаныя кантэйнерам будуць створаны з правамі ўладальніка root. Калі выкарыстоўваю volume то дадзеныя проста буду створаны ў якім небудзь /usr/* і будзе такая ж гісторыя з uid і gid як у першым выпадку. Калі запускаеш іншы кампанент то трэба ўчытвацца ў дакументацыю і шукаць адказ на пытанне: "а ў якія дырэкторыі кантэйнера кампанент піша файлы?"

Мне заўсёды не падабалася, што даводзіцца занадта доўга важдацца з docker-ом на пачатковым этапе: я прыдумляў як запускаць кантэйнеры, з якіх выяў запускацца, рабіў Makefile, якія ўтрымоўвалі аліасы да доўгіх docker камандам. Цярпець не мог docker-compose, таму што не жадаў вучыць яшчэ адну прыладу экасістэмы docker. І docker-compose up мяне напружвала, асабліва, калі там яшчэ сустракаліся build канструкцыі, а не ўжо сабраныя выявы. Усё, што я рэальна хацеў - гэта проста рабіць прадукт эфектыўна і хутка. Але я ніяк не мог раскласці па палічках выкарыстанне docker.

Знаёмства з Ansible

Нядаўна (тройку месяцаў таму), я папрацаваў з DevOps камандай, амаль кожны ўдзельнік якой, негатыўна ставіўся да docker. Па прычынах:

  • docker кіруе iptables (хоць можна адключыць у daemon.json)
  • docker вежны і ў продзе запускаць яго не будзем
  • калі docker daemon падае, то адпаведна, падаюць усе кантэйнеры з інфраструктурай
  • у docker няма неабходнасці
  • навошта docker калі, есць Ansible і віртуальныя машыны

На той жа працы я і пазнаёміўся з яшчэ адным інструментам - Ansible. Калісьці я чуў пра яго, але не спрабаваў пісаць свае плэйбукі. А зараз я пачаў пісаць свае цягі і тут маё бачанне памянялася канчаткова! Таму што я зразумеў: у Ansible ёсць модулі для запуску тых жа docker кантэйнераў, зборак выяў, сетак і інш., пры гэтым кантэйнеры можна запусціць не толькі лакальна, але і на выдаленых серверах! Майму захапленню не было мяжы - я знайшоў ЗВЫЧАЙНЫ інструмент і выкінуў свае Makefile і docker-compose файлы, яны былі замененыя на yaml цягі. Быў паменшаны код за рахунак выкарыстання канструкцый тыпу loop, when, І г.д.

Docker для запуску іншых кампанентаў тыпу бд

Нядаўна я пазнаёміўся з ssh тунэлямі. Аказалася, што вельмі проста "пракінуць" порт выдаленага сервера на лакальны порт. Выдалены сервер можа быць як машынай у воблаку, так і віртуальнай машынай, запушчанай у VirtualBox. Калі мне ці майму калегу патрэбна бд (ці які небудзь іншы іншы кампанент), можна проста запусціць сервер з гэтым кампанентам і загасіць, калі сервер не патрэбен. Пракід партоў дае такі ж эфект, як і бд, запушчаная ў docker кантэйнеры.

Гэтая каманда прабівае мой лакальны порт на выдалены сервер з postgresql:

ssh -L 9000:localhost:5432 [электронная пошта абаронена]

Выкарыстанне выдаленага сервера вырашае праблему з распрацоўкай у камандзе. Такім серверам могуць карыстацца адразу некалькі распрацоўнікаў, ім не трэба ўмець наладжваць postgresql, разбірацца c docker і з іншымі выдасканаленнямі. На выдаленым серверы можна ўсталяваць тую ж бд у самым docker, калі паставіць спецэфічную версію цяжка. Усё, што будзе трэба распрацоўнікам - гэта выдаць ssh доступ!

Нядаўна прачытаў што SSH тунэлі гэта абмежаваная функцыянальнасць звычайнага VPN! Можна проста настаяць OpenVPN ці іншыя рэалізацыі VPN, наладзіць інфраструктуру і даць яе ў карыстанне распрацоўнікам. Гэта ж так крута!

Добра, AWS, GoogleCloud і іншыя, даюць год бясплатнага выкарыстання, так выкарыстоўвайце іх! Яны капейкавыя, калі іх гасіць, калі не выкарыстоўваюцца. Я заўсёды думаў, у якіх мэтах мне б спатрэбіўся выдалены сервер тыпу gcloud, здаецца што я знайшоў іх.

У якасці віртуальнай машыны на лакалі можна выкарыстоўваць той жа Alpine які актыўна выкарыстоўваецца ў docker кантэйнерах. Ну ці якія небудзь іншыя палегчаныя дыстрыбутывы каб барзджэй загружалася машына.

Вынік: запускаць бд і іншыя інфраструктурныя плюшкі можна і трэба на выдаленых серверах або ў virtualbox. мне не патрэбен docker для гэтых мэт.

Трохі пра docker выявы і дыстрыбуцыю

Я ўжо пісаў артыкул у якой хацеў данесці, што выкарыстанне docker вобразаў не дае ніякай гарантыі. Docker выявы патрэбныя толькі для таго каб стварыць docker кантэйнер. Калі вы зашываецеся на docker вобраз значыць вы зашываецеся на выкарыстанне docker кантэйнераў і вы будзеце толькі з імі.

Вы бачылі дзе небудзь каб распрацоўшчыкі ПА партавалі свае прадукты толькі ў docker выяве?
Вынік большасці прадуктаў гэта бінарныя файлы пад пэўную платформу, менавіта іх проста дадаюць у docker выява які ўспадкоўваецца ад патрэбнай платформы. Вы не задумваліся, чаму ў dockerhub так шмат падобных выяў? Убіце напрыклад nginx, вы ўбачыце 100500 выяў ад розных людзей. Гэтыя людзі не распрацоўвалі сам nginx, яны проста ў свой docker выява дадалі афіцыйны nginx і заправілі сваімі канфігамі для выгоды запуску кантэйнераў.

Наогул захоўваць можна проста ў tgz, калі каму то спатрэбіцца запускаць гэта ў docker то хай у Dockerfile дадаюць tgz, успадкоўваюцца ад патрэбнага асяроддзя і ствараюць дадатковыя плюшкі якія не мяняюць самога прыкладання ў tgz. Той, хто будзе ствараць docker выява, будзе ведаць, што гэта за tgz і што яму трэба для працы. Менавіта так я выкарыстоўваю docker тут

Вынік: мне не патрэбен docker registry, скарыстаюся якім небудзь S3 ці проста файлавым сховішчам тыпу google drive/dropbox

Docker у CI

Усе кампаніі, у якіх я працаваў, падобныя сябар на сябра. Яны, як правіла, прадуктовыя. Гэта значыць, у іх ёсць нейкае адно прыкладанне, адзін стэк тэхналогій (ну можа пара – тройка моў праграмавання).

Гэтыя кампаніі выкарыстоўваюць docker на сваіх серверах, дзе запускаецца CI працэс. Пытанне - навошта трэба збіраць праекты ў docker кантэйнеры на сваіх серверах? Чаму проста не падрыхтаваць асяроддзе для зборкі, напрыклад напісаць Ansible плэйбук які будзе ставіць патрэбныя версіі nodejs, php, jdk, капіяваць ssh ключы і інш. на сервер, у якім будзе адбывацца зборка?

Цяпер я разумею, што гэта стральба сабе па нагах, таму што docker не прыносіць ніякага профіту са сваёй ізаляцыяй. Праблемы з CI у docker з якімі я сутыкнуўся:

  • зноў патрэбен docker выява для зборкі. трэба шукаць выяву або пісаць свой dockerfile.
  • 90% што трэба пракінуць якія небудзь ssh ключы, сакрэтныя дадзеныя, якія не жадаецца пісаць у docker выява.
  • кантэйнер ствараецца і памірае, губляюцца ўсе кэшы разам з ім. наступная зборка будзе зноўку спампоўваць усе залежнасці праекта, а гэта доўга і не эфектыўна, а час - грошы.

Распрацоўнікі не збіраюць праекты ў docker кантэйнерах ( я калі то быў такім фанатам праўда, шкада сябе ў мінулым xD ). У java ёсць магчымасць мець некалькі версій і мяняць адной камандай на тую, якая патрэбна цяпер. У nodejs таксама самае, есць nvm.

Выснова

Я лічу што docker вельмі магутны і гнуткі інструмент, у гэтым яго недахоп (гучыць дзіўна, так). З дапамогай яго кампаніі лёгка "падсаджваюцца" на яго, выкарыстоўваюць дзе трэба і не трэба. Распрацоўнікі запускаюць свае кантэйнеры, нейкае сваё асяроддзе, потым гэта ўсё плыўна перацякае ў CI, прадакшн. DevOps каманда піша нейкія ровары каб запусціць гэтыя кантэйнеры.

Выкарыстоўвайце docker толькі на самым апошнім этапе ў вашым працоўным працэсе, не цягнеце яго ў праект у пачатку. Ён не вырашыць вашых бізнес праблем. Ён толькі ссуне праблемы на ІНШЫ ўзровень і будзе прапаноўваць свае варыянты рашэння, вы будзеце рабіць падвойную працу.

Калі docker патрэбен: прыйшоў да думкі, што docker вельмі добры ў аптымізацыі пастаўленага працэсу, але не ў пабудове базавага функцыяналу.

Калі вы ўсёткі вырашылі выкарыстоўваць docker, то:

  • будзьце вельмі асцярожныя
  • не навязвайце выкарыстанне docker распрацоўшчыкам
  • лакалізуйце яго выкарыстанне ў адным месцы, не размазвайце па ўсіх рэпазітарах Dockefile і docker-compose

PS:

Дзякуй што дачыталі, жадаю вам празрыстых рашэнняў у вашых справах і прадуктыўных працоўных дзён!

Крыніца: habr.com

Дадаць каментар