Introduksjon til Docker Compose

1. Oversikt

Når du bruker Docker mye, blir administrasjonen av flere forskjellige containere raskt tungvint.

Docker Compose er et verktøy som hjelper oss med å løse dette problemet og enkelt å håndtere flere containere samtidig.

I denne opplæringen vil vi se på hovedfunksjonene og kraftige mekanismene.

2. YAML-konfigurasjonen forklart

Kort sagt, Docker Compose fungerer ved å bruke mange regler som er erklært innenfor en eneste docker-compose.yml konfigurasjonsfil.

Disse YAML-reglene, både lesbare og maskinoptimaliserte, gir oss en effektiv måte å øyeblikksbilde hele prosjektet fra ti tusen fot i noen få linjer.

Nesten hver regel erstatter en spesifikk Docker-kommando, slik at til slutt trenger vi bare å kjøre:

docker-komponere opp

Vi kan få dusinvis av konfigurasjoner brukt av Compose under panseret. Dette vil spare oss for bryet med å skriptere dem med Bash eller noe annet.

I denne filen må vi spesifisere versjon av formatet Compose, minst ett service, og valgfritt volumer og nettverk:

versjon: "3.7" tjenester: ... volumer: ... nettverk: ... 

La oss se hva disse elementene faktisk er.

2.1. Tjenester

Først av alt, tjenester se containernes konfigurasjon.

La oss for eksempel ta en dockerisert webapplikasjon som består av en frontend, en backend og en database: Vi vil sannsynligvis dele disse komponentene i tre bilder og definere dem som tre forskjellige tjenester i konfigurasjonen:

tjenester: frontend: image: my-vue-app ... backend: image: my-springboot-app ... db: image: postgres ... 

Det er flere innstillinger som vi kan bruke på tjenester, og vi vil utforske dem dypt senere.

2.2. Volumer og nettverk

Volumerderimot, er fysiske områder med diskplass delt mellom verten og en container, eller til og med mellom containere. Med andre ord, et volum er en delt katalog i verten, synlig fra noen eller alle containere.

På samme måte, nettverk definere kommunikasjonsreglene mellom containere, og mellom en container og verten. Vanlige nettverkssoner vil gjøre containertjenester synlige av hverandre, mens private soner vil adskille dem i virtuelle sandkasser.

Igjen lærer vi mer om dem i neste avsnitt.

3. Dissekere en tjeneste

La oss nå begynne å inspisere hovedinnstillingene til en tjeneste.

3.1. Trekker et bilde

Noen ganger har bildet vi trenger for tjenesten vår allerede blitt publisert (av oss eller andre) i Docker Hub eller et annet Docker-register.

Hvis det er tilfelle, så refererer vi til det med bilde attributt, ved å spesifisere navn og merke:

tjenester: min tjeneste: image: ubuntu: siste ... 

3.2. Å bygge et bilde

I stedet må vi kanskje bygge et bilde fra kildekoden ved å lese dets Dockerfil.

Denne gangen bruker vi bygge nøkkelord, som sender banen til Dockerfile som verdien:

tjenester: min-tilpassede app: build: / path / to / dockerfile / ... 

Vi kan også bruke en URL i stedet for en bane:

tjenester: min-tilpassede app: bygg: //github.com/my-company/my-project.git ... 

I tillegg kan vi spesifisere en bilde navn i forbindelse med bygge attributt, som vil gi navnet navnet når det er opprettet, slik at det blir tilgjengelig for bruk av andre tjenester:

tjenester: min-tilpassede app: build: //github.com/my-company/my-project.git image: mitt prosjektbilde ... 

3.3. Konfigurere nettverk

Docker-containere kommuniserer seg imellom i nettverk opprettet, implisitt eller gjennom konfigurasjon, av Docker Compose. En tjeneste kan kommunisere med en annen tjeneste på samme nettverk ved å bare henvise til den etter containernavn og port (for eksempel nettverk-eksempel-tjeneste: 80), forutsatt at vi har gjort porten tilgjengelig gjennom avdekke nøkkelord:

tjenester: nettverk-eksempel-tjeneste: image: karthequian / helloworld: siste eksponering: - "80" 

I dette tilfellet vil det forresten også fungere uten å utsette det, fordi avdekke direktivet er allerede i bildet Dockerfile.

Å nå en container fra verten, havnene må eksponeres deklarativt gjennom porter nøkkelord, som også lar oss velge om vi vil eksportere porten annerledes i verten:

tjenester: nettverk-eksempel-tjeneste: image: karthequian / helloworld: siste porter: - "80:80" ... min-tilpassede app: image: myapp: siste porter: - "8080: 3000" ... my- custom-app-replica: image: myapp: siste porter: - "8081: 3000" ... 

Port 80 vil nå være synlig fra verten, mens port 3000 av de to andre containerne vil være tilgjengelig på portene 8080 og 8081 i verten. Denne kraftige mekanismen lar oss kjøre forskjellige containere som utsetter de samme portene uten kollisjoner.

Til slutt kan vi definere flere virtuelle nettverk for å adskille containerne våre:

tjenester: nettverk-eksempel-tjeneste: image: karthequian / helloworld: nyeste nettverk: - mitt delte nettverk ... en annen tjeneste i samme nettverk: bilde: alpint: siste nettverk: - mitt delte- nettverk ... en annen tjeneste-i-sitt-eget-nettverk: image: alpine: siste nettverk: - mitt-private-nettverk ... nettverk: mitt-delte-nettverk: {} mitt-private-nettverk: {} 

I dette siste eksemplet kan vi se det en annen tjeneste i samme nettverk vil være i stand til å pinge og nå port 80 i nettverk-eksempel-tjeneste, samtidig som en annen tjeneste-i-sitt-eget-nettverk vil ikke.

3.4. Sette opp volumene

Det er tre typer bind: anonym, heter, og vert de.

Docker administrerer både anonyme og navngitte volumer, monterer dem automatisk i egengenererte kataloger i verten. Mens anonyme volumer var nyttige med eldre versjoner av Docker (pre 1.9), er navngitte de foreslåtte veiene å gå i dag. Vertsvolumer lar oss også spesifisere en eksisterende mappe i verten.

Vi kan konfigurere vertsvolumer på tjenestenivå og navngitte volumer i det ytre nivået i konfigurasjonen, for å gjøre sistnevnte synlige for andre containere og ikke bare for den de tilhører:

tjenester: volumer-eksempel-tjeneste: bilde: alpine: siste volumer: - mitt navn-globale-volum: / mitt-volumer / navngitt-globalt volum - / tmp: / mitt-volumer / vertsvolum - / hjem: / my-volumes / readonly-host-volume: ro ... another-volumes-example-service: image: alpine: latest volumes: - my-called-global-volume: / another-path / the same-named- global-volume ... volumes: my-named-global-volume: 

Her vil begge containere ha lese- / skrivetilgang til my-named-global-volume delt mappe, uansett de forskjellige banene de har tilordnet den. De to vertvolumene vil i stedet bare være tilgjengelige for volum-eksempel-tjeneste.

De / tmp mappen til vertsens filsystem er kartlagt til / my-volumes / host-volume mappen til containeren.

Denne delen av filsystemet er skrivbar, noe som betyr at beholderen ikke bare kan lese, men også skrive (og slette) filer i vertsmaskinen.

Vi kan montere et volum i skrivebeskyttet modus ved å legge til : ro til regelen, som for /hjem -mappen (vi vil ikke at en Docker-container sletter brukerne våre ved en feiltakelse).

3.5. Erklære avhengighet

Ofte må vi lage en avhengighetskjede mellom tjenestene våre, slik at noen tjenester lastes inn før (og lastes ut etter) andre. Vi kan oppnå dette resultatet gjennom kommer an på nøkkelord:

tjenester: kafka: image: wurstmeister / kafka: 2.11-0.11.0.3 avhenger av: - dyrehage ... dyrehage: bilde: wurstmeister / dyrehage ... 

Vi bør imidlertid være klar over at Compose ikke vil vente på dyrepasser for å fullføre lasting før du starter kafka tjeneste: den vil bare vente til den starter. Hvis vi trenger en tjeneste for å være fullastet før vi starter en annen tjeneste, må vi få dypere kontroll over oppstarts- og nedleggelsesrekkefølgen i Compose.

4. Administrere miljøvariabler

Å jobbe med miljøvariabler er enkelt i Compose. Vi kan definere statiske miljøvariabler, og også definere dynamiske variabler med ${} notasjon:

tjenester: database: image: "postgres: $ {POSTGRES_VERSION}" miljø: DB: mydb BRUKER: "$ {USER}" 

Det er forskjellige metoder for å gi disse verdiene til å komponere.

For eksempel setter man dem i en .env filen i samme katalog, strukturert som en .eiendommer fil, nøkkel = verdi:

POSTGRES_VERSION = alpin USER = foo

Ellers kan vi sette dem i operativsystemet før vi ringer til kommandoen:

eksporter POSTGRES_VERSION = alpin eksport USER = foo docker-compose up 

Til slutt kan det hende at vi er nyttige ved å bruke en enkel en-liner i skallet:

POSTGRES_VERSION = alpin USER = foo docker-komponer opp 

Vi kan blande tilnærmingene, men la oss huske på at Compose bruker følgende prioritetsrekkefølge, og overskriver de mindre viktige med de høyere:

  1. Skriv filen
  2. Shell miljøvariabler
  3. Miljøfil
  4. Dockerfil
  5. Variabel ikke definert

5. Skalering og kopier

I eldre Compose-versjoner fikk vi lov til å skalere forekomster av en container gjennom docker-compose-skala kommando. Nyere versjoner utfaset den og erstattet den med skala alternativ.

På den andre siden kan vi utnytte Docker Swarm - en klynge av Docker Engines - og autoskalere våre containere på en erklærende måte gjennom kopier attributt til utplassere seksjon:

tjenester: arbeider: image: dockersamples / examplevotingapp_worker nettverk: - frontend - backend distribusjon: modus: replikerte replikaer: 6 ressurser: grenser: cpus: '0.50' minne: 50M reservasjoner: cpus: '0.25' minne: 20M ... 

Under utplassere, Vi kan også spesifisere mange andre alternativer, som ressursterskler. Skriv imidlertid vurderer helheten utplassere seksjonen bare når du distribuerer til Swarm, og ignorerer det ellers.

6. Et eksempel fra den virkelige verden: Spring Cloud Data Flow

Mens små eksperimenter hjelper oss med å forstå enkeltgirene, vil det å se den virkelige koden i aksjon definitivt avdekke det store bildet.

Spring Cloud Data Flow er et komplekst prosjekt, men enkelt nok til å være forståelig. La oss laste ned YAML-filen og kjøre:

DATAFLOW_VERSION = 2.1.0.RELEASE SKIPPER_VERSION = 2.0.2.RELEASE docker-compose up 

Compose vil laste ned, konfigurere og starte hver komponent, og deretter kryss beholderens logger til en enkelt strøm i gjeldende terminal.

Det vil også bruke unike farger på hver av dem for en flott brukeropplevelse:

Vi kan få følgende feil under kjøring av en helt ny Docker Compose-installasjon:

oppslag registry-1.docker.io: ingen slik vert

Mens det er forskjellige løsninger på denne vanlige fallgruven, bruker 8.8.8.8 som DNS er sannsynligvis det enkleste.

7. Styring av livssyklus

La oss endelig se nærmere på syntaksen til Docker Compose:

docker-compose [-f ...] [options] [COMMAND] [ARGS ...] 

Selv om det er mange alternativer og kommandoer tilgjengelig, trenger vi i det minste å kjenne de som aktiverer og deaktiverer hele systemet riktig.

7.1. Oppstart

Vi har sett at vi kan opprette og starte containere, nettverk og volumer som er definert i konfigurasjonen med opp:

docker-komponere opp

Etter første gang kan vi imidlertid bare bruke start for å starte tjenestene:

docker-compose start

Hvis filen vår har et annet navn enn standardnavnet (docker-compose.yml), kan vi utnytte -f og fil flagger for å spesifisere et alternativt filnavn:

docker-compose -f custom-compose-file.yml start

Compose kan også kjøre i bakgrunnen som en demon når den lanseres med -d alternativ:

docker-komponere opp -d

7.2. Skru av

For å trygt stoppe de aktive tjenestene, kan vi bruke Stoppe, som vil bevare containere, volumer og nettverk, sammen med alle modifikasjoner som er gjort på dem:

docker-compose stopp

For å tilbakestille statusen til prosjektet vårt, i stedet, kjører vi bare ned, som vil ødelegge alt med bare unntak av eksterne volumer:

docker-komponer ned

8. Konklusjon

I denne opplæringen har vi lært om Docker Compose og hvordan det fungerer.

Som vanlig kan vi finne kilden docker-compose.yml fil på GitHub, sammen med et nyttig batteri med tester som umiddelbart er tilgjengelige i følgende bilde:


$config[zx-auto] not found$config[zx-overlay] not found