Docker Compose: fra utvikling til produksjon

Oversettelse av podcast-transkripsjonen utarbeidet i påvente av kursstart "Linux-administrator"

Docker Compose: fra utvikling til produksjon

Docker Compose er et fantastisk verktøy for å lage en fungerende
miljøet for stabelen som brukes i applikasjonen din. Den lar deg definere
hver komponent i applikasjonen din, etter en klar og enkel syntaks i YAML-
filer
.

Med ankomsten av docker compose v3 disse YAML-filene kan brukes direkte i produksjonsmiljøet når du arbeider med
klynge Docker sverm.

Men betyr dette at du kan bruke den samme docker-compose-filen i
utviklingsprosessen og i produksjonsmiljøet? Eller bruk den samme filen for
iscenesettelse? Vel, generelt sett, ja, men for denne funksjonaliteten trenger vi følgende:

  • Variabel interpolasjon: bruker miljøvariabler for noen
    verdier som endres i hvert miljø.
  • Konfigurasjonsoverstyring: muligheten til å definere et sekund (eller hvilken som helst
    en annen påfølgende) docker-compose-fil som vil endre noe mht
    først, og docker compose vil ta seg av å slå sammen begge filene.

Forskjeller mellom utviklings- og produksjonsfiler

Under utviklingen vil du mest sannsynlig ønsker å sjekke kodeendringer i
sanntid. For å gjøre dette, er vanligvis volumet med kildekoden montert i
beholder som inneholder kjøretid for applikasjonen din. Men for et produksjonsmiljø
Denne metoden er ikke egnet.

I produksjonen har man en klynge med mange noder, og volumet er lokalt
i forhold til noden som beholderen din (eller tjenesten) kjører på, så du gjør det ikke
du kan montere kildekoden uten komplekse operasjoner som inkluderer
kodesynkronisering, signaler osv.

I stedet ønsker vi vanligvis å lage et bilde med en bestemt versjon av koden din.
Det er vanlig å merke det med passende tag (du kan bruke semantikk
versjonering eller et annet system etter eget skjønn).

Konfigurasjonsoverstyring

Gitt forskjellene og at avhengighetene dine kan variere i scenarier
utvikling og produksjon, er det klart at vi vil trenge forskjellige konfigurasjonsfiler.

Docker compose støtter sammenslåing av forskjellige compose-filer til
få den endelige konfigurasjonen. Hvordan dette fungerer kan ses i eksemplet:

$ cat docker-compose.yml
version: "3.2"

services:
  whale:
    image: docker/whalesay
    command: ["cowsay", "hello!"]
$ docker-compose up
Creating network "composeconfigs_default" with the default driver
Starting composeconfigs_whale_1
Attaching to composeconfigs_whale_1
whale_1  |  ________
whale_1  | < hello! >
whale_1  |  --------
whale_1  |     
whale_1  |      
whale_1  |       
whale_1  |                     ##        .
whale_1  |               ## ## ##       ==
whale_1  |            ## ## ## ##      ===
whale_1  |        /""""""""""""""""___/ ===
whale_1  |   ~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ /  ===- ~~~
whale_1  |        ______ o          __/
whale_1  |                     __/
whale_1  |           __________/
composeconfigs_whale_1 exited with code 0

Som sagt støtter docker compose å kombinere flere komposisjoner -
filer, lar dette deg overstyre ulike parametere i den andre filen. For eksempel:

$ cat docker-compose.second.yml
version: "3.2"
services:
  whale:
    command: ["cowsay", "bye!"]

$ docker-compose -f docker-compose.yml -f docker-compose.second.yml up
Creating composeconfigs_whale_1
Attaching to composeconfigs_whale_1
whale_1  |  ______
whale_1  | < bye! >
whale_1  |  ------
whale_1  |     
whale_1  |      
whale_1  |       
whale_1  |                     ##        .
whale_1  |               ## ## ##       ==
whale_1  |            ## ## ## ##      ===
whale_1  |        /""""""""""""""""___/ ===
whale_1  |   ~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ /  ===- ~~~
whale_1  |        ______ o          __/
whale_1  |                     __/
whale_1  |           __________/
composeconfigs_whale_1 exited with code 0

Denne syntaksen er ikke veldig praktisk under utvikling, når kommandoen
må gjøres mange ganger.

Heldigvis ser docker compose automatisk etter en spesiell fil kalt
docker-compose.override.yml å overstyre verdier Docker-compose.yml. om
gi nytt navn til den andre filen, du får det samme resultatet, bare ved å bruke den opprinnelige kommandoen:

$ mv docker-compose.second.yml docker-compose.override.yml
$ docker-compose up
Starting composeconfigs_whale_1
Attaching to composeconfigs_whale_1
whale_1  |  ______
whale_1  | < bye! >
whale_1  |  ------
whale_1  |     
whale_1  |      
whale_1  |       
whale_1  |                     ##        .
whale_1  |               ## ## ##       ==
whale_1  |            ## ## ## ##      ===
whale_1  |        /""""""""""""""""___/ ===
whale_1  |   ~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ /  ===- ~~~
whale_1  |        ______ o          __/
whale_1  |                     __/
whale_1  |           __________/
composeconfigs_whale_1 exited with code 0

Ok, det er lettere å huske.

Interpolering av variabler

Støtte for konfigurasjonsfiler interpolasjon
variabler
og standardverdier. Det vil si at du kan gjøre følgende:

services:
  my-service:
    build:
      context: .
    image: private.registry.mine/my-stack/my-service:${MY_SERVICE_VERSION:-latest}
...

Og hvis du gjør det docker-compose build (eller push) uten miljøvariabel
$MY_SERVICE_VERSION, vil verdien bli brukt sistemen hvis du setter
verdien av miljøvariabelen før byggingen, vil den bli brukt når du bygger eller skyver
til registeret private.registry.mine.

Mine prinsipper

Tilnærmingene som fungerer for meg kan fungere for deg også. Jeg følger disse
enkle regler:

  • Alle mine stabler for produksjon, utvikling (eller andre miljøer) er definert gjennom
    docker-compose-filer
  • Konfigurasjonsfiler som trengs for å dekke alle miljøene mine, så mye som mulig
    unngå duplisering.
  • Jeg trenger én enkel kommando for å fungere i hvert miljø.
  • Hovedkonfigurasjonen er definert i filen Docker-compose.yml.
  • Miljøvariabler brukes til å definere bildekoder eller annet
    variabler som kan variere fra miljø til miljø (iscenesettelse, integrasjon,
    produksjon).
  • Verdiene til produksjonsvariabler brukes som verdier for
    som standard minimerer dette risikoen hvis stabelen lanseres i produksjon uten
    angi miljøvariabel.
  • For å starte en tjeneste i et produksjonsmiljø, bruk kommandoen docker stack deploy - komponer-fil docker-compose.yml -with-register-author my-stack-name.
  • Arbeidsmiljøet startes ved hjelp av kommandoen docker-komponere opp -d.

La oss se på et enkelt eksempel.

# docker-compose.yml
...
services:
  my-service:
    build:
      context: .
    image: private.registry.mine/my-stack/my-service:${MY_SERVICE_VERSION:-latest}
    environment:
      API_ENDPOINT: ${API_ENDPOINT:-https://production.my-api.com}
...

И

# docker-compose.override.yml
...
services:
  my-service:
    ports: # This is needed for development!
      - 80:80
    environment:
      API_ENDPOINT: https://devel.my-api.com
    volumes:
      - ./:/project/src
...

jeg kan bruke docker-compose (docker-compose up)å kjøre stabelen inn
utviklingsmodus med kildekode montert i /project/src.

Jeg kan bruke de samme filene i produksjonen! Og jeg kunne definitivt brukt
samme fil Docker-compose.yml for iscenesettelse. For å utvide dette til
produksjon, jeg trenger bare å bygge og sende bildet med en forhåndsdefinert tag
på CI-stadiet:

export MY_SERVICE_VERSION=1.2.3
docker-compose -f docker-compose.yml build
docker-compose -f docker-compose.yml push

I produksjon kan dette kjøres ved hjelp av følgende kommandoer:

export MY_SERVICE_VERSION=1.2.3
docker stack deploy my-stack --compose-file docker-compose.yml --with-registry-auth

Og hvis du vil gjøre det samme på scenen, trenger du bare å definere
nødvendige miljøvariabler for å jobbe i iscenesettelsesmiljøet:

export MY_SERVICE_VERSION=1.2.3
export API_ENDPOINT=http://staging.my-api.com
docker stack deploy my-stack --compose-file docker-compose.yml --with-registry-auth

Som et resultat brukte vi to forskjellige docker-compose-filer, som uten
Dupliserte konfigurasjoner kan brukes for ethvert miljø du har!

Lær mer om kurset "Linux-administrator"

Kilde: www.habr.com

Legg til en kommentar