Çfarë është Docker: një ekskursion i shkurtër në histori dhe abstraksione themelore

Filloi më 10 gusht në Slurm Kursi video Docker, në të cilën ne e analizojmë plotësisht - nga abstraksionet bazë deri te parametrat e rrjetit.

Në këtë artikull do të flasim për historinë e Docker dhe abstraksionet kryesore të tij: Image, Cli, Dockerfile. Ligjërata është menduar për fillestarët, kështu që nuk ka gjasa të jetë me interes për përdoruesit me përvojë. Nuk do të ketë gjak, apendiks apo zhytje të thellë. Vetë bazat.

Çfarë është Docker: një ekskursion i shkurtër në histori dhe abstraksione themelore

Çfarë është Docker

Le të shohim përkufizimin e Docker nga Wikipedia.

Docker është softuer për automatizimin e vendosjes dhe menaxhimit të aplikacioneve në mjedise me kontejnerë.

Asgjë nuk është e qartë nga ky përkufizim. Është veçanërisht e paqartë se çfarë do të thotë "në mjedise që mbështesin kontejnerizimin". Për ta zbuluar, le të kthehemi pas në kohë. Le të fillojmë me epokën që unë e quaj në mënyrë konvencionale "Epoka Monolitike".

Epoka monolitike

Epoka monolitike është fillimi i viteve 2000, kur të gjitha aplikacionet ishin monolite, me një mori varësish. Zhvillimi zgjati shumë. Në të njëjtën kohë, nuk kishte shumë serverë; ne i njihnim të gjithë me emër dhe i monitoronim. Ekziston një krahasim kaq qesharak:

Kafshët shtëpiake janë kafshë shtëpiake. Në epokën monolitike, ne i trajtonim serverët tanë si kafshë shtëpiake, të rregulluara dhe të dashura, duke hequr njolla pluhuri. Dhe për menaxhim më të mirë të burimeve, ne përdorëm virtualizimin: morëm një server dhe e premë në disa makina virtuale, duke siguruar kështu izolimin e mjedisit.

Sistemet e virtualizimit të bazuara në hipervizor

Të gjithë ndoshta kanë dëgjuar për sistemet e virtualizimit: VMware, VirtualBox, Hyper-V, Qemu KVM, etj. Ato ofrojnë izolim të aplikacioneve dhe menaxhim të burimeve, por kanë edhe disavantazhe. Për të bërë virtualizimin, ju duhet një hipervizor. Dhe hipervizori është një burim i lartë. Dhe vetë makina virtuale është zakonisht një kolos i tërë - një imazh i rëndë që përmban një sistem operativ, Nginx, Apache dhe ndoshta MySQL. Imazhi është i madh dhe makina virtuale është e papërshtatshme për t'u përdorur. Si rezultat, puna me makina virtuale mund të jetë e ngadaltë. Për të zgjidhur këtë problem, sistemet e virtualizimit u krijuan në nivelin e kernelit.

Sistemet e virtualizimit në nivel kernel

Virtualizimi i nivelit të kernelit mbështetet nga sistemet OpenVZ, Systemd-nspawn, LXC. Një shembull i mrekullueshëm i një virtualizimi të tillë është LXC (Linux Containers).

LXC është një sistem virtualizimi i nivelit të sistemit operativ për ekzekutimin e instancave të shumta të izoluara të sistemit operativ Linux në një nyje të vetme. LXC nuk përdor makina virtuale, por krijon një mjedis virtual me hapësirën e vet të procesit dhe grupin e rrjetit.

Në thelb LXC krijon kontejnerë. Cili është ndryshimi midis makinave virtuale dhe kontejnerëve?

Çfarë është Docker: një ekskursion i shkurtër në histori dhe abstraksione themelore

Kontejneri nuk është i përshtatshëm për izolimin e proceseve: dobësitë gjenden në sistemet e virtualizimit në nivelin e kernelit që i lejojnë ata të largohen nga kontejneri në host. Prandaj, nëse keni nevojë të izoloni diçka, është më mirë të përdorni një makinë virtuale.

Dallimet midis virtualizimit dhe kontejnerizimit mund të shihen në diagram.
Ka hipervizorë harduerësh, hipervizorë në krye të sistemit operativ dhe kontejnerë.

Çfarë është Docker: një ekskursion i shkurtër në histori dhe abstraksione themelore

Hipervizorët e harduerit janë të mirë nëse vërtet dëshironi të izoloni diçka. Sepse është e mundur të izolohen në nivelin e faqeve dhe procesorëve të memories.

Ka hipervizorë si program, dhe ka kontejnerë, dhe ne do të flasim për to më tej. Sistemet e kontejnerizimit nuk kanë një hipervisor, por ekziston një Motor Container që krijon dhe menaxhon kontejnerët. Kjo gjë është më e lehtë, kështu që për shkak të punës me bërthamën ka më pak shpenzime ose aspak.

Çfarë përdoret për kontejnerizimin në nivelin e bërthamës

Teknologjitë kryesore që ju lejojnë të krijoni një kontejner të izoluar nga proceset e tjera janë hapësirat e emrave dhe grupet e kontrollit.

Hapësirat e emrave: PID, Rrjeti, Montimi dhe Përdoruesi. Ka më shumë, por për lehtësinë e të kuptuarit do të fokusohemi në këto.

Hapësira e emrave PID kufizon proceset. Kur, për shembull, krijojmë një hapësirë ​​emrash PID dhe vendosim një proces aty, ai bëhet me PID 1. Zakonisht në sisteme PID 1 është sistemuar ose init. Prandaj, kur vendosim një proces në një hapësirë ​​të re emri, ai gjithashtu merr PID 1.

Hapësira e emrave në rrjet ju lejon të kufizoni/izoloni rrjetin dhe të vendosni ndërfaqet tuaja brenda. Montimi është një kufizim i sistemit të skedarëve. Përdorues - kufizim për përdoruesit.

Grupet e kontrollit: Memoria, CPU, IOPS, Rrjeti - rreth 12 cilësime në total. Ndryshe quhen edhe Cgroups (“C-grupet”).

Grupet e kontrollit menaxhojnë burimet për një kontejner. Nëpërmjet Grupeve të Kontrollit mund të themi se kontejneri nuk duhet të konsumojë më shumë se një sasi e caktuar burimesh.

Që kontejnerizimi të funksionojë plotësisht, përdoren teknologji shtesë: Aftësitë, Kopjo-në-Shkruaj dhe të tjera.

Aftësitë janë kur i tregojmë një procesi se çfarë mund dhe çfarë nuk mund të bëjë. Në nivelin e kernelit, këto janë thjesht bitmap me shumë parametra. Për shembull, përdoruesi rrënjë ka privilegje të plota dhe mund të bëjë gjithçka. Serveri i kohës mund të ndryshojë kohën e sistemit: ai ka aftësi në Kapsulën e Kohës dhe kaq. Duke përdorur privilegjet, mund të konfiguroni në mënyrë fleksibël kufizimet për proceset dhe në këtë mënyrë të mbroni veten.

Sistemi Copy-on-Writ na lejon të punojmë me imazhet Docker dhe t'i përdorim ato në mënyrë më efikase.

Docker aktualisht ka probleme me pajtueshmërinë me Cgroups v2, kështu që ky artikull fokusohet në mënyrë specifike në Cgroups v1.

Por le të kthehemi në histori.

Kur sistemet e virtualizimit u shfaqën në nivelin e kernelit, ato filluan të përdoren në mënyrë aktive. Kostoja e sipërme në hipervizor u zhduk, por disa probleme mbetën:

  • imazhe të mëdha: ata shtyjnë një sistem operativ, biblioteka, një tufë softuerësh të ndryshëm në të njëjtin OpenVZ, dhe në fund imazhi ende rezulton të jetë mjaft i madh;
  • Nuk ka asnjë standard normal për paketimin dhe dorëzimin, kështu që problemi i varësive mbetet. Ka situata kur dy pjesë kodi përdorin të njëjtën bibliotekë, por me versione të ndryshme. Mund të ketë një konflikt mes tyre.

Për të zgjidhur të gjitha këto probleme, ka ardhur epoka tjetër.

Epoka e kontejnerëve

Kur erdhi epoka e kontejnerëve, filozofia e punës me ta ndryshoi:

  • Një proces - një enë.
  • Ne dorëzojmë të gjitha varësitë që i nevojiten procesit në kontejnerin e tij. Kjo kërkon prerjen e monoliteve në mikroshërbime.
  • Sa më i vogël të jetë imazhi, aq më mirë - ka më pak dobësi të mundshme, ai shpërndahet më shpejt, etj.
  • Rastet bëhen kalimtare.

E mbani mend atë që thashë për kafshët shtëpiake kundër bagëtive? Më parë, rastet ishin si kafshë shtëpiake, por tani janë bërë si bagëti. Më parë, kishte një monolit - një aplikim. Tani janë 100 mikroshërbime, 100 kontejnerë. Disa kontejnerë mund të kenë 2-3 kopje. Është më pak e rëndësishme për ne që të kontrollojmë çdo enë. Ajo që është më e rëndësishme për ne është disponueshmëria e vetë shërbimit: çfarë bën ky grup kontejnerësh. Kjo ndryshon qasjet ndaj monitorimit.

Në 2014-2015, Docker lulëzoi - teknologjia për të cilën do të flasim tani.

Docker ndryshoi filozofinë dhe paketimin e standardizuar të aplikacionit. Duke përdorur Docker, ne mund të paketojmë një aplikacion, ta dërgojmë në një depo, ta shkarkojmë nga atje dhe ta vendosim atë.

Ne vendosim gjithçka që na nevojitet në kontejnerin Docker, kështu që problemi i varësisë zgjidhet. Docker garanton riprodhueshmëri. Unë mendoj se shumë njerëz kanë hasur në papërsëritshmëri: gjithçka funksionon për ju, ju e shtyni atë në prodhim dhe atje ai ndalon së punuari. Me Docker ky problem largohet. Nëse kontejneri juaj Docker fillon dhe bën atë që duhet të bëjë, atëherë me një shkallë të lartë probabiliteti do të fillojë të prodhohet dhe të bëjë të njëjtën gjë atje.

Digresioni rreth shpenzimeve të sipërme

Gjithmonë ka mosmarrëveshje për shpenzimet e përgjithshme. Disa njerëz besojnë se Docker nuk mbart një ngarkesë shtesë, pasi përdor kernelin Linux dhe të gjitha proceset e tij të nevojshme për kontejnerizimin. Për shembull, "nëse thoni se Docker është lart, atëherë kerneli i Linux është lart".

Nga ana tjetër, nëse shkoni më thellë, ka vërtet disa gjëra në Docker që, me një shtrirje, mund të thuhet se janë lart.

E para është hapësira e emrave PID. Kur vendosim një proces në një hapësirë ​​emri, atij i caktohet PID 1. Në të njëjtën kohë, ky proces ka një PID tjetër, i cili ndodhet në hapësirën e emrave të hostit, jashtë kontejnerit. Për shembull, ne lëshuam Nginx në një enë, ai u bë PID 1 (procesi kryesor). Dhe në host ka PID 12623. Dhe është e vështirë të thuhet se sa shpenzim i lartë është.

Gjëja e dytë është Cgroups. Le të marrim Cgroups sipas memories, domethënë aftësinë për të kufizuar kujtesën e një kontejneri. Kur aktivizohet, numëruesit dhe llogaritja e memories aktivizohen: kerneli duhet të kuptojë sa faqe janë ndarë dhe sa janë ende të lira për këtë kontejner. Kjo është ndoshta një shpenzim i lartë, por unë nuk kam parë ndonjë studim të saktë se si ndikon në performancën. Dhe unë vetë nuk e vura re që aplikacioni që funksionon në Docker papritmas pësoi një humbje të mprehtë në performancë.

Dhe një shënim tjetër për performancën. Disa parametra të kernelit kalohen nga hosti në kontejner. Në veçanti, disa parametra të rrjetit. Prandaj, nëse doni të ekzekutoni diçka me performancë të lartë në Docker, për shembull, diçka që do të përdorë në mënyrë aktive rrjetin, atëherë të paktën duhet të rregulloni këto parametra. Disa nf_conntrack, për shembull.

Rreth konceptit Docker

Docker përbëhet nga disa komponentë:

  1. Docker Daemon është i njëjti Container Engine; lëshon kontejnerë.
  2. Docker CII është një mjet i menaxhimit të Docker.
  3. Dockerfile - udhëzime se si të ndërtoni një imazh.
  4. Imazhi - imazhi nga i cili është hedhur kontejneri.
  5. Kontejner.
  6. Regjistri Docker është një depo imazhesh.

Skematikisht duket diçka si kjo:

Çfarë është Docker: një ekskursion i shkurtër në histori dhe abstraksione themelore

Daemon Docker funksionon në Docker_host dhe lëshon kontejnerë. Ekziston një Klient që dërgon komanda: ndërto imazhin, shkarko imazhin, lësho kontejnerin. Daemon Docker shkon në regjistër dhe i ekzekuton ato. Klienti Docker mund të hyjë si në nivel lokal (në një prizë Unix) ashtu edhe përmes TCP nga një host në distancë.

Le të kalojmë nëpër secilin komponent.

Daemon docker - kjo është pjesa e serverit, funksionon në makinën pritës: shkarkon imazhe dhe lëshon kontejnerë prej tyre, krijon një rrjet midis kontejnerëve, mbledh regjistrat. Kur themi "krijo një imazh", demoni po e bën gjithashtu këtë.

Docker CLI — Pjesa e klientit Docker, mjeti i konsolës për të punuar me daemon. E përsëris, mund të funksionojë jo vetëm në nivel lokal, por edhe përmes rrjetit.

Komandat bazë:

docker ps - shfaq kontejnerët që aktualisht po funksionojnë në hostin Docker.
imazhet e dokerit - shfaqni imazhet e shkarkuara në nivel lokal.
kërkimi docker <> - kërkoni për një imazh në regjistër.
docker pull <> - shkarko një imazh nga regjistri në makinë.
docker build < > - mblidhni imazhin.
docker run <> - nis kontejnerin.
docker rm <> - hiqni kontejnerin.
logs docker <> - regjistrat e kontejnerëve
docker start/stop/restart <> - duke punuar me kontejnerin

Nëse i zotëroni këto komanda dhe jeni të sigurt në përdorimin e tyre, konsiderojeni veten 70% të aftë në Docker në nivelin e përdoruesit.

dockerfile - udhëzime për krijimin e një imazhi. Pothuajse çdo komandë instruksioni është një shtresë e re. Le të shohim një shembull.

Çfarë është Docker: një ekskursion i shkurtër në histori dhe abstraksione themelore

Kështu duket Dockerfile: komandat në të majtë, argumentet në të djathtë. Çdo komandë që është këtu (dhe përgjithësisht e shkruar në Dockerfile) krijon një shtresë të re në Image.

Edhe duke parë anën e majtë, mund të kuptoni përafërsisht se çfarë po ndodh. Ne themi: "krijo një dosje për ne" - kjo është një shtresë. "Bëni dosjen të funksionojë" është një shtresë tjetër, e kështu me radhë. Torta me shtresa e bën jetën më të lehtë. Nëse krijoj një Dockerfile tjetër dhe ndryshoj diçka në rreshtin e fundit - ekzekutoj diçka tjetër përveç "python" "main.py", ose instaloj varësi nga një skedar tjetër - atëherë shtresat e mëparshme do të ripërdoren si një cache.

Imazh - ky është paketimi i kontejnerëve; kontejnerët lëshohen nga imazhi. Nëse e shikojmë Docker nga këndvështrimi i një menaxheri paketash (sikur të punonim me paketa deb ose rpm), atëherë imazhi është në thelb një paketë rpm. Nëpërmjet yum install ne mund ta instalojmë aplikacionin, ta fshijmë, ta gjejmë në depo dhe ta shkarkojmë. Është pothuajse e njëjta gjë këtu: kontejnerët lëshohen nga imazhi, ato ruhen në regjistrin Docker (të ngjashëm me yum, në një depo) dhe çdo imazh ka një hash SHA-256, një emër dhe një etiketë.

Imazhi është ndërtuar sipas udhëzimeve nga Dockerfile. Çdo udhëzim nga Dockerfile krijon një shtresë të re. Shtresat mund të ripërdoren.

Regjistri doker është një depo imazhi Docker. Ngjashëm me OS, Docker ka një regjistër standard publik - dockerhub. Por ju mund të ndërtoni depon tuaj, regjistrin tuaj Docker.

Enë - çfarë është nisur nga imazhi. Ne ndërtuam një imazh sipas udhëzimeve nga Dockerfile, më pas e nisim nga ky imazh. Ky enë është i izoluar nga kontejnerët e tjerë dhe duhet të përmbajë gjithçka të nevojshme për funksionimin e aplikacionit. Në këtë rast, një enë - një proces. Ndodh që duhet të bësh dy procese, por kjo është disi në kundërshtim me ideologjinë Docker.

Kërkesa "një kontejner, një proces" lidhet me hapësirën e emrave PID. Kur një proces me PID 1 fillon në Hapësirën e Emrave, nëse ai papritmas vdes, atëherë i gjithë kontejneri gjithashtu vdes. Nëse dy procese po zhvillohen atje: njëri është i gjallë dhe tjetri është i vdekur, atëherë kontejneri do të vazhdojë të jetojë. Por kjo është një çështje e praktikave më të mira, ne do të flasim për to në materiale të tjera.

Për të studiuar më në detaje veçoritë dhe programin e plotë të kursit, ju lutemi ndiqni lidhjen: "Kursi video Docker'.

Autor: Marcel Ibraev, administrator i certifikuar i Kubernetes, inxhinier praktikues në Southbridge, folës dhe zhvillues i kurseve Slurm.

Burimi: www.habr.com

Shto një koment