Oppretting av Docker-bilder. Forstå Docker. Hovedkomponentene til Docker

Docker er det vanligste containeriseringssystemet som lar deg kjøre programvaren som kreves for utvikling i containere uten å installere den på det lokale systemet. Innenfor rammen av dette materialet vil vi analysere docker container management.

Docker består av flere komponenter:
  1. Bilde- et sett med programvare konfigurert av utviklerne, som lastes ned fra den offisielle nettsiden
  2. Container- bildeimplementering - en enhet på serveren opprettet fra den, beholderen skal ikke være en eksakt kopi og kan justeres ved hjelp av Dockerfile
  3. Volum- området på disken som brukes av beholderen og hvor dataene er lagret. Etter sletting av beholderen forblir ikke programvaren, dataene kan brukes i fremtiden

Et nettverk bygges over hele strukturen på en spesiell måte, som lar deg videresende porter på ønsket måte og gjøre containeren tilgjengelig fra utsiden (som standard kjører den på en lokal IP-adresse) gjennom en virtuell bro. I dette tilfellet kan beholderen være tilgjengelig både for verden og til én adresse.

Docker containeradministrasjon: grunnleggende funksjoner

Installer Docker på Ubuntu eller Debian server hvis den ikke allerede er installert i henhold til instruksjonene. Bedre å kjøre kommandoer som en uprivilegert bruker via sudo

Å kjøre den enkleste beholderen vil vise at alt fungerer

Grunnleggende kommandoer for å administrere containere

Du kan vise alle aktive beholdere på denne måten

Med -a-bryteren vil alle beholdere vises, inkludert inaktive

Dicker tildeler navn til beholdere tilfeldig, om nødvendig kan du spesifisere navnet direkte

docker run — navn hello-world

Start en beholder kalt my-linux-container basert på ubuntu-bildet og gå til beholderkonsollen ved å spesifisere bash-skallet

docker run -it —navn min-linux-container ubuntu bash

For å gå ut av beholderen og gå tilbake til verten, må systemet kjøres

Alle bilder som er opprettet containere på grunnlag av lastes automatisk ned fra hub.docker.com når containeren først opprettes, de som allerede finnes lokalt kan sees ved å kjøre docker-bilder

Å lage en beholder fra et allerede nedlastet bilde vil gå mye raskere (nesten umiddelbart)

Når du går ut av beholderen med utgang stopper den, slik at dette ikke skjer, kan du avslutte med hurtigtasten CTRL + A + P

Du kan fjerne alle beholdere som ikke er aktive

docker rm $ (docker ps -a -f status = avsluttet -q)

Eller slett dem én om gangen

I stedet for en identifikator i den siste kommandoen, kan du angi et navn

I docker administreres containere ved hjelp av et lite antall intuitive kommandoer:

docker container start ID

docker container stopp ID

ID for omstart av docker-beholder

docker container inspeksjons-ID

Sistnevnte er spesielt nyttig, den viser all informasjon om beholderen, konfigurasjonsfiler og brukte diskpartisjoner. Hele listen over kommandoer kan enkelt finnes i hjelpen eller på den offisielle Docker-nettsiden.

Bygg Docker-bildet ditt og bruk Dockerfilen

Bilder lages vanligvis fra eksisterende ved å bruke tilleggsalternativer spesifisert i Dockerfilen

FRA ubuntu
CMD ekko "hallo verden"

Nå lages et nytt bilde basert på standarden c ubuntu

Bygg bildet ved å gi det et navn (prikken på slutten av kommandoen betyr at gjeldende katalog brukes, og derfor Dockerfilen i den)

docker build -t my-ubuntu.

docker-bilder vil nå vise og det nyopprettede my-ubuntu-bildet

Den kan kjøres, og konsollen vises Hei Verden og dette er den eneste forskjellen fra standardbildet

Vanligvis trenger vi mer komplekse regler, for eksempel må vi inkludere python3 i bildet - la oss gå til en ny katalog og lage en Dockerfile

FRA ubuntu
CMD apt-get update && apt-get install python3

Alle instruksjoner er skrevet på én linje

docker build -t my-ubuntu-with-python3.

Vi starter beholderen ved å gå inn

docker run -it my-ubuntu-with-python3 bash

Inne, som root, må du utføre dpkg -l | grep python3, vil kommandoen vise at pakken er til stede i systemet, noe som betyr suksess

Det faktum at Docker virkelig er et must-ha-verktøy for en utvikler og administrator av ethvert stort prosjekt. Men selv om dette ikke er tilfelle, trenger Docker fortsatt å vite: i nær fremtid vil det være overalt, fra en desktop Linux-distribusjon til en pool av servere på AWS. Og det beste er at det er ganske enkelt å håndtere Docker, hvis du selvfølgelig forstår hvordan det fungerer.

Godt å komme inn i verden av virtuelle miljøer

Docker er basert på navnerom og cgroups-teknologier (den første gir isolasjon, den andre gir prosessgruppering og ressursbegrensning), derfor er den, når det gjelder virtualisering, ikke mye forskjellig fra LXC / OpenVZ vi er vant til, og det er ikke mye å snakke om her. Samme native hastighet, samme isolasjonsmetoder basert på Linux-kjernemekanismer. Ovenfor begynner imidlertid en helt annen historie. Høydepunktet til Docker er at den lar deg distribuere et fullverdig virtuelt miljø og starte en applikasjon i det like enkelt som å starte en webserver på nytt.

Vi abstraherer fra detaljene i spesifikke distribusjoner og forestiller oss at vi har et rent CentOS og vi ønsker å kjøre en spesifikk kommando i det i et fullstendig virtuelt miljø uten tilgang til hovedsystemet. Må du laste ned bilder av distribusjoner, distribuere dem til systemet og sette opp et virtuelt miljø? Ikke i det hele tatt, alt du trenger å gjøre er å kjøre to kommandoer:

$ sudo yum installer docker-io $ sudo docker run -t ubuntu: siste / usr / bin / topp

Og det er alt. Vi kjørte nettopp toppverktøyet inne i en container med et miljø basert på den nyeste Ubuntu-versjonen som er tilgjengelig for øyeblikket, og sendte ut informasjon til gjeldende terminal. Og alt dette med en enkel kommando (installasjon teller ikke). Ikke verst, er det ikke? Generelt kan vi til og med "gå" inn i denne beholderen og gjøre alt som vanligvis gjøres med et nyinstallert system:

$ sudo docker run -t -i ubuntu: siste / bin / bash # apt-get update # apt-get install nginx #

Som du kan se, er alt OK med nettverket også, så vi kan oppdatere systemet, installere og konfigurere programvare. Det ser litt ut som magi, men det er faktisk veldig enkelt. Docker er en slags apt-get i containerverdenen, bare i stedet for pakker er det filsystembilder, og i stedet for de offisielle Debian / Ubuntu-repositoriene, er det en skylagring kalt Docker Hub.

Da vi gjorde "docker run ..." gjorde systemet følgende:

  1. Docker-verktøyet kontaktet dockerd-demonen på vår lokale maskin, sa hei fra oss og ba om å kjøre den nyeste versjonen av Ubuntu (som indikert av den siste taggen i kommandoen) i en isolert beholder.
  2. Dockerd-demonen sjekket notatboken sin, gikk til / var / lib / docker-katalogen og fant ut at filsystembildet fra den nyeste Ubuntu ikke er på maskinen vår, så han bestemte seg for å kontakte Docker Hub for å finne ut om det er et slikt bilde der.
  3. Etter å ha snakket med Docker Hub forsikret han seg om at bildet fortsatt eksisterer, og ba om å sende det til oss.
  4. Etter å ha mottatt det nødvendige bildet, monterte dockerd filsystemet sitt, laget en chroot i det og kjørte kommandoen spesifisert i det siste argumentet, og begrenset "omfanget" ved å bruke navneområder (faktisk kuttet den tilgangen til hovedfilsystemet, vert systemprosesser, IPC og andre , låst i sandkassen), men kastet enhetsfilene til den nåværende terminalen inn i den (-t-flagget) slik at toppen vår kan tegne sitt pseudografiske grensesnitt.

Høydepunktet med denne modellen er at Docker Hub er åpen for alle og alle kan forberede sitt eget bilde (mer om det senere) og publisere det for installasjon på en annen maskin og/eller av en annen person. Når dette skrives, har mer enn 45 tusen bilder blitt publisert på Docker Hub for alle anledninger, fra bilder av "nakne" distribusjoner til bilder med forhåndskonfigurerte server- og skrivebordsapplikasjoner som kjører i et minimalistisk Linux-miljø.

Hva om vi vil kjøre Firefox i et virtuelt miljø? Det kunne ikke vært enklere, åpne Docker Hub i en nettleser, klikk på Bla gjennom og søk og skriv inn firefox. En liste over resultater vises på skjermen. Vi ser, kennethkl / firefox ser ut til å være ganske passende. Vi klikker på den og ser informasjon om hvordan du starter det hele. Forfatteren ber oss kjøre en kommando som dette:

$ sudo docker run -d --name firefox -e DISPLAY = $ DISPLAY \ -v /tmp/.X11-unix:/tmp/.X11-unix kennethkl / firefox

La oss prøve. Ja, faktisk, etter en kort nedlasting av bildet får vi standard Firefox på skjermen. Ved å bruke samme eksempel kan du forresten gjøre deg kjent med fire flere nyttige alternativer for docker run-kommandoen:

  • -d - "demoniserer" beholderen, det vil si at den kobler Docker fra det virtuelle STDOUT-miljøet og lar den kjøre i bakgrunnen;
  • --name - navnet på beholderen, som den vil motta i stedet for identifikatoren;
  • -e - lar deg "videre" en miljøvariabel til den virtuelle maskinen;
  • -v - videresender den angitte filen eller katalogen (format / fil / på / vert / system: / fil / i / virtuell maskin eller bare / fil / på / vert / system, hvis banene samsvarer).

I dette tilfellet er variabelen og filen nødvendig slik at Firefox kan få tilgang til visningen av den lokale maskinen. Dette er ganske usikkert, siden enhver prosess i beholderen ikke bare vil kunne kjøre hvilken som helst programvare på skrivebordet ditt, men også for eksempel avskjære tastetrykk eller markørbevegelser. Men det vil for eksempel gjøre det.

Det er en enklere måte å finne Docker-bilder ved å bruke docker-søkekommandoen:

$ sudo docker søk nginx

INFO

Enhver Docker-bruker kan kjøre sin egen private Hub. Det kalles "registeret" og er tilgjengelig som et ferdig bilde. Alt du trenger å gjøre er bare å kjøre det: docker run -p 5555: 5555 register.

Docker-demonen er tilgjengelig ikke bare ved å bruke klienten, men også ved å bruke RESTful API, både lokalt og fra en ekstern maskin. Standard Docker-porter er tcp / 2375 e tcp / 2376.

Docker-bildet trenger ikke å kjøres umiddelbart etter nedlasting, du kan først laste det ned til din lokale maskin ved å bruke docker pull-kommandoen, og først deretter kjøre: docker pull ubuntu.

Lagdelt kake

Docker lar deg gjøre arbeidet med virtuelle miljøer så praktisk som mulig, og forenkler både prosessen med å distribuere miljøer og sette opp deres interaksjon med vertssystemet (som bare er det siste eksemplet). Men dette er ikke det eneste høydepunktet.

Hvis du allerede har lekt med Ubuntu-bildet fra de to første eksemplene, har du sannsynligvis lagt merke til at hver ny lansering av beholderen skjer fra bunnen av, og alle endringer som ble gjort i forrige økt går tapt. Dette er ikke en feil i det hele tatt, det er en av nøkkelfunksjonene til Docker-arkitekturen som gjør den enda mer interessant og attraktiv løsning.

Faktum er at i de aller fleste tilfeller er "Docker-bildet" ikke et monolitisk filsystembilde i det hele tatt, men en slags lagkake, bestående av flere filsystembilder, på grunnlag av hvilke beholderen er dannet. Samtidig er individuelle FS-bilder ikke i det hele tatt ansvarlige for visse deler av katalogstrukturen (som for eksempel ved partisjonering av en disk under Linux i partisjoner / home, / var, / boot), men er lagdelte. oppå hverandre ved hjelp av AUFS-kjernemekanismen Linux (det er også støtte for samme funksjonalitet gjennom bruk av btrfs, enhetsmapper og overlegg).

For å forstå hvordan dette fungerer, la oss gå tilbake til vår containeriserte Ubuntu. Vi starter beholderen og installerer nginx, som vist i det andre eksemplet i begynnelsen av artikkelen, men avslutter den ikke. I stedet starter vi en annen terminal og ser listen over kjørende containere:

$ sudo docker ps

Denne kommandoen vil vise alle kjørende beholdere sammen med deres ID, bilde brukt, kommando lansert, oppetid og mer. Vi er interessert i verdien i CONTEINER ID-kolonnen. Kopier den og kjør følgende kommando:

$ sudo docker commit container id ubuntu-nginx

Etter at den er fullført, kan du gå ut av beholderen og dermed avslutte arbeidet. Og så starter vi bare ubuntu-nginx-beholderen og ser at nginx ikke har forsvunnet noe sted og er på sin plass:

$ sudo docker kjøre -i -t ubuntu-nginx / bin / bash # som nginx / usr / sbin / nginx

Hva har vi gjort? Vi opprettet et nytt lag, det vil si et ekstra FS-bilde, og genererte et nytt Docker-bilde basert på det allerede eksisterende Ubuntu Docker-bildet, inkludert FS-bildet vårt, som inneholder nginx. Høres litt forvirrende ut, ikke sant? Det er faktisk ganske enkelt.

Vi har allerede funnet ut at hvert Docker-bilde består av flere filsystembilder. Når vi starter containeren, blir disse bildene montert og satt sammen til én katalogstruktur ved hjelp av AUFS. For eksempel kan det første bildet bare inneholde en grunnleggende Ubuntu-installasjon, det andre legger til et sett med standard demoner til det, det tredje - administrasjonsverktøy, og så videre. Docker monterer alle lagene i skrivebeskyttet modus, men slik at vi kan endre innholdet i bildet, kobles et annet opprinnelig tomt lag på toppen i lese/skrivemodus.


Som standard, etter at beholderen er ferdig (som skjer etter den siste prosessen som kjører i den), slettes det siste laget og alle endringene våre går tapt. Ved å bruke docker commit-kommandoen kan vi imidlertid "commit" endringene ved å lage et nytt Docker-bilde basert på de eksisterende FS-bildene pluss FS-bildet med endringene våre. Dette vil lagre endringene vi har gjort. Eventuelt kan vi starte ubuntu-nginx-beholderen, gjøre endringer i den, og på samme måte lagre til et nytt Docker-bilde ved å bruke commit, legge til et nytt lag. Du kan bruke docker images-kommandoen for å se en liste over alle de resulterende bildene (og fra Docker Hub), og docker history-kommandoen for å se historien om lagdannelse:

$ sudo docker historie ubuntu-nginx

Denne tilnærmingen til bildebehandling gir mer fleksibilitet i containeradministrasjon, sparer mye tid og lar deg enkelt overføre allerede konfigurerte Docker-bilder mellom maskiner (bildet kan lastes opp til Docker Hub og deretter distribueres til en annen maskin). Et mindre åpenbart pluss er sparing av diskplass. Hvis vi distribuerer en hel dyrehage med containere på en maskin, som hver i utgangspunktet vil være basert på ett basisbilde (samme Ubuntu, for eksempel) - de vil alle referere til dette basisbildet og ikke duplisere innholdet.


Docker utenfor Linux

Den eneste måten å kjøre Docker på OS X eller Windows er å installere den på en virtuell maskin. Du trenger ikke gjøre det manuelt, du kan bruke en ferdig løsning, for eksempel boot2docker. Dette er et sett med skript som lar deg raskt distribuere en virtuell Linux- og Docker-maskin inne i VirtualBox og starte den opp med automatisk SSH-tilgang. Instruksjoner for bruk av den og selve installasjonsprogrammet finner du på den offisielle Docker-nettsiden.

Nettverkskonfigurasjon

For at containere skal kommunisere med hverandre og med omverdenen, løfter Docker automatisk den virtuelle nettverksbroen og konfigurerer maskeringsregler (NAT) for det eksterne nettverksgrensesnittet. Det betyr at det ikke vil være mulig å nå containerne fra utsiden. Vi kan imidlertid konfigurere portvideresending slik at en forespørsel til spesifikke porter på maskinens eksterne nettverksgrensesnitt automatisk omdirigeres til de angitte containerportene. For eksempel, på Mirantis, kjører hoveddrivstoffnoden (dette er GUI for distribusjon og konfigurering av OpenStack) i Docker og bruker portvideresending for å åpne tilgang til ful / nginx-beholderen (port 8000):

$ sudo docker run -d -p 8000: 8000 fuel / nginx_6.0: siste /usr/local/bin/start.sh

Vi kan videresende port 8000 til en hvilken som helst annen port i containeren ved ganske enkelt å endre det andre tallet i -p-alternativet, men dette gir ikke mening i denne konfigurasjonen.

Filvideresending og Dockerfile

I begynnelsen av artikkelen ble vi allerede kjent med flagget -v, som lar deg videresende hvilken som helst fil eller katalog fra vertssystemet til containeren. Dette er en veldig praktisk funksjon, den kan brukes både for å lagre noen midlertidige data, og for å dele filer mellom flere containere. I Mirantis brukes denne funksjonen til å videresende konfigurasjonsfiler for drivstoff / skarpsinnede tjenesten (/ etc / kloke) inne i beholderen:

$ sudo docker run -d -v / etc / astute fuel / astute_6.0: siste /usr/local/bin/start.sh

Det samme kan gjøres ved å bruke VOLUME-kommandoen i Dockerfilen. Selve Dockerfilen er den lokale ekvivalenten til Makefile, men hvis sistnevnte er for å bygge applikasjoner fra kilden, lar Dockerfilen deg bygge bilder for Docker. Hensikten er å forenkle opprettelsen av nye bilder uten å måtte starte en beholder, utføre operasjoner i den og utføre en forpliktelse. Du kan bare skrive en Dockerfile og Docker vil gjøre alt for deg. Tenk for eksempel på Dockerfilen for å bygge drivstoff / klok:

FRA drivstoff / centos VEDLIKEHOLDER Matthew Mosesohn [e-postbeskyttet] KJØR rm -rf /etc/yum.repos.d / *; \ echo -e "\ nname = Nailgun Local Repo \ nbaseurl = http: // $ (rute -n | awk" /^0.0.0.0/ (skriv ut $ 2 ) "): _ PORT_ / os / x86_64 / \ ngpgcheck = 0"> /etc/yum.repos.d/nailgun.repo; \ nam rens alt; \ nam --quiet install -y ruby21-nailgun-mcagents sysstat ADD etc / etc ADD start.sh /usr/local/bin/start.sh RUN puppet apply --detailed-exitcodes -d -v /etc/puppet/modules/nailgun/examples/astute-only.pp; [[$? == 0 || $? == 2]] KJØR chmod + x /usr/local/bin/start.sh; \ echo -e "\ nname = Nailgun Local Repo \ nbaseurl = file: / var / www / nailgun / centos / x86_64 \ ngpgcheck = 0 "> /etc/yum.repos.d/nailgun.repo; nam ren alt VOLUME / etc / skarpsindig CMD /usr/local/bin/start.sh

Det er ikke vanskelig å forstå hva det er for noe. Den lager et bilde basert på drivstoff / centos, kjører flere kommandoer for å forberede bildet, legger til filer fra gjeldende katalog til bildet, bruker Puppet-manifestet, endrer tillatelser på noen filer, videresender / etc / asture / katalogen fra verten systemet til beholderen, og starter beholderen ved å bruke kommandoen /usr/local/bin/start.sh.

For å bygge en beholder, legg bare Dockerfilen og alle filene som vil bli lagt til den i en katalog og kjør følgende kommando:

$ sudo docker bygge drivstoff / astute_6.0: siste

I dette tilfellet valgte vi navnet fuel / astute_6.0: siste, selv om det kan være hva som helst.

Nyanser ved å jobbe med Docker

Docker er bygget rundt ideen om at kun én tjeneste skal kjøres i hver container. Du pakker Apache, MySQL, nginx, Varnish og hva prosjektet ditt trenger i forskjellige containere, og bruker deretter Docker til å bygge alt sammen. Denne tilnærmingen gir stor fleksibilitet ettersom den lar deg enkelt endre konfigurasjon, teste oppdateringer og migrere individuelle tjenester til andre maskiner.

Av samme grunn er det ikke vanlig å bruke Docker til å kjøre fullverdige Linux-miljøer med en init-demon, cron- og syslog-demoner og andre standard distribusjonskomponenter. I stedet starter vi bare tjenesten vi trenger, og den kjører i et virtuelt miljø helt alene:

$ sudo docker run -d -p 80 ubuntu-nginx / usr / sbin / nginx

Men det er et lite problem her. Docker slår av beholderen umiddelbart etter at prosessen som kjører i den (i dette tilfellet nginx) er avsluttet, og siden nginx er demonisert som standard, det vil si at den deler en ny prosess og avslutter den vi startet for hånd, så Docker går umiddelbart ut og en container ved å spikre en gaffelformet Docker.

Når det gjelder nginx, kan du omgå dette problemet ved å legge til daemon off; den første linjen i konfigurasjonen. Andre demoner vil kreve sine egne innstillinger, og noen kan forhindres fra å demonisere direkte fra kommandolinjen. For eksempel gir sshd flagget -D for dette:

$ sudo docker kjøre -d -p 22 ubuntu-ssh / usr / sbin / sshd -D

Du kan når som helst koble deg til containeren ved å bruke docker exec-kommandoen for å se loggene eller endre innstillingene (heretter er container-IDen enten IDen som kan sees i docker ps-utgangen, eller navnet spesifisert på oppstart i --name-alternativet):

$ sudo docker exec -ti container ID / bin / bash

Men det er også en liten hake her. Som vi vet, vil all informasjon akkumulert under driften av det virtuelle miljøet gå tapt hvis vi avslutter arbeidet med det virtuelle miljøet, og med det forsvinner loggene og endringene i innstillingene. Vi kan heller ikke lage lag i det uendelige (om bare fordi det ikke kan være mer enn 127 av dem), men vi kan ta en litt annen vei og bruke loggaggregeringssystemet som er innebygd i Docker. Selvfølgelig kan Docker ikke samle logger av individuelle applikasjoner, men den kan samle STDOUT-utgang, det vil si hvilken som helst konsollutgang. Alt som gjenstår for oss er å endre nginx-konfigurasjonen slik at loggene helles inn i / dev / stdout, og deretter se dem ved å bruke docker logs-kommandoen:

$ sudo docker logger container-ID

Et annet og mer riktig alternativ er å ganske enkelt flytte loggene (og, om nødvendig, innstillinger) til vertssystemet ved å bruke -v-alternativet som allerede er beskrevet:

$ sudo mkdir / root / logs $ sudo docker kjøre -d -v / root / logs: / var / logs -p 80 ubuntu-nginx / usr / sbin / nginx

Om nødvendig kan containeren stoppes på riktig måte ved å avslutte tjenesten som kjører i den ved å bruke docker stop-kommandoen:

$ sudo docker stop container ID

Og hvis det av en eller annen grunn ikke fungerer riktig, kan du drepe det med kill:

$ sudo docker kill container ID

Når du gjør dette, skjer en viktig ting som mange nybegynnere glemmer: Docker bevarer metainformasjon om containeren. Faktisk betyr dette at hvis du starter for eksempel nginx, spesifiserer navnet ved hjelp av argumentene til docker run-kommandoen, kataloger som må sendes til containeren, porter, miljøvariabler og lignende, så er all denne informasjonen vil bli lagret når beholderen slutter og for å kjøre den neste gang, trenger du ikke spesifisere den, men bare kjør følgende kommando (du kan bruke et navn i stedet for ID):

$ sudo docker startbeholder-ID

Hvis du ikke trenger å lagre tilstanden (for eksempel for å teste eller sjekke funksjonalitet), kan du bruke --rm-flagget, som vil tvinge Docker til å ødelegge beholderen fullstendig etter at den er ferdig (lagre bildet):

$ sudo docker run --rm -i -t busybox / bin / bash

Du kan ødelegge alle tidligere lagrede beholdere ved å bruke følgende kommando:

# docker rm $ (docker ps -a -q)

Docker er i stand til uavhengig å starte containere på nytt hvis de krasjer og til og med starte dem under systemoppstart. Alt du trenger å gjøre er å bruke --restart-alternativet:

$ sudo docker run --restart = alltid \ -d -v / root / logs: / var / logs -p 80 \ ubuntu-nginx / usr / sbin / nginx

Når som helst kan bildet eksporteres til én enkelt fil og deretter importeres til en annen maskin. Kommandoene docker save og docker restore er gitt for dette. Det er veldig enkelt å bruke dem, eksporten gjøres slik:

$ sudo docker lagre -o ubuntu-nginx.img ubuntu-nginx

Og importen er slik:

$ sudo docker last -i ubuntu-nginx.img

konklusjoner

Docker er et utmerket verktøy. For en uinnvidd person kan det virke som et leketøy som ikke lenger egner seg til annet enn å kjøre programvare i en sandkasse, men det kan bidra til å løse et stort spekter av oppgaver, som vi skal snakke om i neste artikkel.

Docker-fordeler fremfor LXC, OpenVZ og andre virtualiseringsløsninger på OS-nivå

  1. Docker bruker et bærbart generisk bildeformat. Dette betyr at disse bildene kan overføres til en annen maskin uten problemer og deles for bruk av andre brukere.
  2. Bildet kan tjene som base for andre bilder. I Docker anses det som normalt å bruke flere lag for å danne det endelige bildet. Du kan starte med et grunnleggende Ubuntu-bilde, og deretter legge til Apache 2.4 for å lage en Ubuntu + Apache-mikrotjeneste.
  3. Når du forplikter, kan bildet bli versjonert, akkurat som i GIT.
  4. Docker har et stort fellesskap og et omfattende økosystem som inkluderer et betydelig antall verktøy for skalering, gruppering, overvåking, distribusjon og administrasjon av containere.

Vi har berørt emnet mer enn én gang og vurdert mange systemer for deres konstruksjon. I dag vil vi introdusere et annet flott system med Docker-containere.

La oss starte med å beskrive den grunnleggende funksjonaliteten som vil komme godt med i flere artikler i serien, og kort huske Docker-arkitekturen. Docker bruker en klient-server-arkitektur og består av et klient - docker-verktøy som får tilgang til serveren ved hjelp av RESTful API, og en demon i Linux-operativsystemet (se fig. 1). Selv om Docker fungerer på ikke-Linux-operativsystemer, dekkes de ikke i denne artikkelen.

Hovedkomponentene til Docker:
    • Containere- brukermiljøer isolert ved bruk av operativsystemteknologier, der applikasjoner kjøres. Den enkleste måten er å definere en Docker-beholder som en applikasjon som startes fra et bilde. Det er forresten akkurat det Docker ideologisk skiller seg fra for eksempel fra LXC ( Linux-beholdere), selv om de bruker de samme Linux-kjerneteknologiene. Utviklerne av Docker-prosjektet er forpliktet til prinsippet om at én beholder er én applikasjon.
    • Bilder- skrivebeskyttede søknadsmaler. Nye nivåer kan legges på toppen av eksisterende bilder, som sammen representerer filsystemet, og endrer eller supplerer forrige nivå. Vanligvis opprettes et nytt bilde enten ved å lagre en allerede kjørende beholder til et nytt bilde over et eksisterende, eller ved å bruke spesielle instruksjoner for verktøyet. For å skille de forskjellige nivåene til en beholder på filsystemnivå, AUFS, btrfs, vfs og Device Mapper... Hvis du har tenkt å bruke Docker sammen med SELinux, da kreves det Enhetskartlegger.
    • Registre som inneholder depoter ( oppbevaringssted) bilder, - nettverksbildelagring. De kan være både private og offentlige. Det mest kjente registeret er.

GNU / Linux-operativsystemer bruker standard Linux-kjerneteknologier for å isolere containere, for eksempel:
  • navneområder ( Linux navnerom).
  • Kontrollgrupper ( C-grupper).
  • Privilege Management Tools ( Linux-funksjoner).
  • Ytterligere, obligatoriske sikkerhetssystemer, som f.eks AppArmor eller SELinux.

La oss vurdere de listede teknologiene litt mer detaljert.

Kontrollgruppemekanisme (C-grupper) gir et verktøy for å finjustere allokering, prioritering og styring av systemressurser. Kontrollgrupper er implementert i Linux-kjernen. I moderne distribusjoner implementeres cgroup management gjennom systemd, men det er fortsatt mulig å kontrollere ved hjelp av biblioteket libcgruppe og verktøy cgconfig... De viktigste cgroup-hierarkiene (også kalt kontrollere) er oppført nedenfor:

  • blkio- setter grenser for inngang-ut-operasjoner og tilgang til blokkeringsenheter;
  • prosessor- ved å bruke prosessplanleggeren, fordeler prosessortid mellom oppgaver;
  • cpuacct- Genererer automatiske rapporter om bruk av CPU-ressurser. Fungerer sammen med kontrolleren prosessor beskrevet ovenfor;
  • cpuset- tildeler visse prosessorer og minnenoder til oppgaver;
  • enheter- regulerer tilgang til oppgaver til spesifikke enheter;
  • fryseboks- suspenderer eller gjenopptar oppgaver;
  • hukommelse- setter grenser og genererer rapporter om minnebruk etter oppgaver til kontrollgruppen;
  • net_cls- utfører merking av nettverkspakker med en klasseidentifikator ( klassid). Dette gjør at trafikklederen ( tc kommando) og brannmur ( iptables) ta disse kodene i betraktning når du behandler trafikk;
  • perf_event- lar deg overvåke kontrollgrupper ved hjelp av verktøyet perf;
  • hugetlb- lar deg bruke store virtuelle minnesider og bruke begrensninger på dem.

navneområder, på sin side kontrollerer de ikke ressursallokering, men tilgang til kjernedatastrukturer. Dette betyr faktisk isolering av prosesser fra hverandre og muligheten til å ha parallelt "identiske", men ikke overlappende med hverandre hierarkier av prosesser, brukere og nettverksgrensesnitt. Om ønskelig kan ulike tjenester til og med ha sine egne loopback-grensesnitt.

Eksempler på navneområder brukt av Docker:
  • PID, prosess-ID- isolering av hierarkiet av prosesser.
  • NET, nettverk- isolering av nettverksgrensesnitt.
  • PC, InterProcess Communication- styring av samhandling mellom prosesser.
  • MNT, Mount- håndtering av monteringspunkter.
  • UTS, Unix tidsdelingssystem- isolering av kjernen og versjonsidentifikatorer.

En mekanisme kalt Evner lar deg dele rettighetene til rotbrukeren i små grupper med rettigheter og tildele dem separat. Denne funksjonaliteten har dukket opp i GNU / Linux siden versjon kjerner 2.2. Til å begynne med startes containere med et begrenset sett med privilegier.

Du kan aktivere og deaktivere docker-kommandoalternativene:
  • montere operasjoner;
  • tilgang til stikkontakter;
  • Utføre noen av operasjonene på filsystemet, for eksempel å endre attributtene til filene eller eieren.

Du kan lære mer om rettighetene ved å bruke man-siden. KAPABILITETER (7).

Installerer Docker

La oss ta en titt på å installere Docker ved å bruke CentOS som eksempel. Når du arbeider med CentOS, har du et valg: bruk den nyeste versjonen fra u pstream eller en versjon bygget av CentOS-prosjektet med Red Hat-tillegg. En beskrivelse av endringene er tilgjengelig på siden.

I utgangspunktet er dette en omvendt portering av rettelser fra nye oppstrømsversjoner og endringer foreslått av Red Hat-utviklerne, men som ennå ikke er akseptert i hovedkoden. Den mest merkbare forskjellen da dette ble skrevet var at i nyere versjoner har docker-tjenesten blitt delt inn i tre deler: en demon docker, containerd og runc... Red Hat anser ennå ikke denne endringen for å være stabil og sender en monolitisk versjon 1.10 kjørbar.

Lagringsinnstillinger for installasjon oppstrømsversjoner, samt instruksjoner for installasjon på andre distribusjoner og operativsystemer, er gitt i installasjonsveiledningen på den offisielle nettsiden. Nærmere bestemt, innstillingene for CentOS 7-depotet:

# cat /etc/yum.repos.d/docker.repo name = Docker Repository baseurl = https: //yum.dockerproject.org/repo/main/centos/7 aktivert = 1 gpgcheck = 1 gpgkey = https: // yum .dockerproject.org / gpg

# cat /etc/yum.repos.d/docker.repo

navn = Repository

baseurl = https: / / yum .dockerproject .org / repo / main / centos / 7

aktivert = 1

gpgcheck = 1 gpgkey = https: / / yum .dockerproject .org / gpg

Installer de nødvendige pakkene på og start og aktiver tjenesten:

# nam installer -y docker-motor # systemctl start docker.service # systemctl aktiver docker.service

# nam installer -y docker-motor

# systemctl start docker.service

# systemctl aktiver docker.service

Sjekke tjenestestatusen:

# systemctl status docker.service

# systemctl status docker.service

Du kan også se systeminformasjon om Docker og miljøet:

# docker info

Hvis du kjører en lignende kommando og installerer Docker fra CentOS-lagrene, vil du se mindre forskjeller på grunn av bruk av en eldre versjon av programvaren. Fra utgangen docker info vi kan finne ut hva som brukes som driver for lagring av data Enhetskartlegging, og som lagring - en fil i / var / lib / docker /:

# ls -lh / var / lib / docker / devicemapper / devicemapper / data -rw -------. 1 rotrot 100G 27. desember 12:00 / var / lib / docker / devicemapper / devicemapper / data

# ls -lh / var / lib / docker / devicemapper / devicemapper / data

Rw - - - -. 1 rotrot 100G 27. desember 12:00 / var / lib / / devicemapper / devicemapper / data

Daemon-oppstartsalternativene, som vanligvis er tilfellet på CentOS, er lagret i / etc / sysconfig /... I dette tilfellet, navnet på docker-filen. Tilsvarende linje / etc / sysconfig / docker som beskriver alternativer:

OPTIONS = "- selinux-aktivert --log-driver = journalført"

Hvis du kjørte docker-kommandoen som en ikke-rootbruker eller medlem av docker-gruppen, vil du se en feil som dette:

$ docker søk mysql

$ søk mysql

Advarsel: klarte ikke å hente standard registerendepunkt fra daemon (Kan ikke koble til Docker-demonen. Kjører docker-demonen på denne verten?). Bruker systemets standard: https: // index. docker.io/v1/

Kan ikke koble til Docker-demonen. Kjører docker-demonen på denne verten?

Merk at å faktisk legge til en bruker i docker-gruppen er ensbetydende med å legge den brukeren til rotgruppen.

RHEL / CentOS-utviklerne har en litt annen tilnærming til Docker-demonsikkerhet enn oppstrøms Docker-utviklerne selv. For mer informasjon om Red Hats tilnærming, se en artikkel av RHEL-utvikler Dan Walsh.

Hvis du vil ha "standard" oppførselen til Docker installert fra CentOS-depotene (det vil si beskrevet i den offisielle dokumentasjonen), må du opprette en docker-gruppe og legge til demonens startalternativer:

OPTIONS = "- selinux-aktivert --log-driver = journalført ↵ --gruppe = docker"

ALTERNATIVER = "--selinux-aktivert --log-driver = journalført ↵ --gruppe = docker"

Deretter starter vi tjenesten på nytt og sjekker at docker-socket-filen tilhører docker-gruppen, og ikke root:

# ls -l /var/run/docker.sock

Finne bilder og Docker-tagger

La oss prøve å finne en container på Docker Hub.

$ docker søk haproxy

$ søk haproxy


I denne utgangen har vi fått en liste over en rekke HA Proxy-bilder. Det øverste elementet på listen er HA Proxy fra det offisielle depotet. Slike bilder er forskjellige ved at det ikke er noe symbol i navnet «/» skiller navnet på brukerens depot fra navnet på selve beholderen. Eksemplet bak den offisielle viser to haproxy-bilder fra åpne brukerlagre eeacms og million12.

Bilder som de to nedenfor kan du lage selv ved å registrere deg på Docker Hub. De offisielle støttes av et dedikert team sponset av Docker, Inc. Funksjoner til det offisielle depotet:

  • Dette er anbefalte bilder for bruk, basert på beste praksis og beste praksis.
  • De er basisbilder som kan være et utgangspunkt for mer tilpasning. For eksempel basisbilder av Ubuntu, CentOS eller biblioteker og utviklingsmiljøer.
  • Inneholder de nyeste programvareversjonene med faste sårbarheter.
  • Dette er den offisielle distribusjonskanalen for produktene. For å søke kun etter offisielle bilder, kan du bruke alternativet –Filter "er-offisiell = sant" kommandoer docker søk.

Stjerner i kommandoutgang docker søk tilsvarer populariteten til bildet. Dette er analogen til knappen Som på sosiale nettverk eller bokmerke for andre brukere. Automatisert betyr at bildet bygges automatisk fra et tilpasset skript ved hjelp av Docker Hub. Vanligvis bør du foretrekke automatisk innsamlede bilder på grunn av det faktum at innholdet kan kontrolleres ved å være kjent med den tilsvarende filen.

Last ned det offisielle HA Proxy-bildet:

$ docker pull haproxy Bruker standard tag: siste

Det fulle navnet på bildet kan se slik ut:

[brukernavn] bildenavn [: tag]

Du kan se listen over nedlastede bilder med kommandoen docker-bilder:

Utsetting av containere

Det er ikke nødvendig å laste ned bildet for å kjøre beholderen. Hvis tilgjengelig, vil den lastes inn automatisk. La oss prøve å starte en container med Ubuntu. Vi vil ikke liste opp depotet og vil laste ned det siste offisielle bildet som støttes av Canonical.

$ docker run -it ubuntu [e-postbeskyttet]:/#

$ løp - det ubuntu

root @ d7402d1f7c54: / #

Foruten laget løpe, har vi spesifisert to alternativer: -Jeg- beholderen skal kjøre interaktivt og -t- en pseudoterminal må utheves. Som du kan se fra utdataene, har vi root-brukerrettigheter i containeren, og container-ID-en vises som vertsnavnet. Det siste er kanskje ikke sant for alle containere og avhenger av containerutvikleren. La oss sjekke at dette virkelig er Ubuntu-miljøet:

[e-postbeskyttet]: / # katt / etc / * release | grep DISTRIB_DESCRIPTION DISTRIB_DESCRIPTION = "Ubuntu 16.04.1 LTS"

root @ d7402d1f7c54: / # cat / etc / * release | grep DISTRIB_DESCRIPTION

DISTRIB_DESCRIPTION = "Ubuntu 16.04.1 LTS"

Unavn kommando -en for slike formål vil det ikke fungere, siden beholderen fungerer med vertskjernen.

Et av alternativene kan være et unikt beholdernavn som kan refereres til for enkelhets skyld, i tillegg til Beholder-ID. Det er gitt som -Navn<имя>. Hvis alternativet utelates, genereres navnet automatisk.

De automatisk genererte beholdernavnene har ikke en semantisk belastning, men som et interessant faktum kan det bemerkes at navnene genereres tilfeldig fra adjektivet og navnet til en kjent vitenskapsmann, oppfinner eller hacker. I generatorkoden, for hvert navn, kan du finne en kort beskrivelse av hva den gitte figuren er kjent for.

Du kan se listen over kjørende beholdere med kommandoen. For å gjøre dette, åpne en annen terminal:

Men hvis vi utsteder kommandoen, vil vi ikke finne beholderen opprettet fra mysql-bildet. La oss bruke alternativet -en som viser alle containere, ikke bare kjørende containere:

Tydeligvis ble de nødvendige parameterne ikke spesifisert når du startet beholderen. For en beskrivelse av miljøvariablene som kreves for å kjøre en container, se det offisielle MySQL-bildet på Docker Hub. La oss prøve igjen ved å bruke alternativet -e som setter miljøvariablene i beholderen:

$ docker run --name mysql-test ↵ -e MYSQL_ROOT_PASSWORD = docker -d mysql

Den siste parameteren er kommandoen vi ønsker å utføre inne i beholderen. I dette tilfellet er det kommandotolken. Bash... Alternativer -den har samme formål som de som ble brukt tidligere i kommandoen docker run.

Faktisk etter å ha kjørt denne kommandoen inn i container mysql-test enda en prosess er lagt til - bash... Dette kan tydelig sees ved å bruke pstree-kommandoen. Forkortet utgang til kommando docker exec: