Hvorfor kombinere systemisert med Docker for produksjonsdistribusjoner

Moderne infrastruktur krever at containeriserte tjenester overlever uventet omstart, maskinvarefeil eller pakkeoppdateringer. Mens Docker gir omstartspolicyer (), fungerer disse retningslinjene bare så lenge Docker-nissen kjører. System ⁇ init-systemet som brukes av Ubuntu, Debian, Fedora, CentOS og de fleste moderne Linux-distribusjonene ⁇ tar dette videre ved å administrere livssyklusen til Docker-nissen selv og kan starte beholdere selv før Docker-socketten blir tilgjengelig. Fordelene ved å bruke systemet inkluderer:

  • Garantert oppstartsordre gjennom avhengighetsdirektiver (f.eks. etter network.target, etter docker.service)
  • Samlede logging via , noe som gjør feilsøking enklere
  • Finkornet kontroll over ressursgrenser (CPU, minne, I/O) ved bruk av systembaserte enhetsdirektiver
  • Automatisk omstart ved feil ved konfigurerbar forsinkelse og bruddgrenser
  • Støtte for aktivering av sokkel og tidsstyrt oppstart

Ved å pakke hver Docker-beholder i en systembasert tjenestefil, får operasjonsteam et konsistent grensesnitt for å starte, stoppe og overvåke beholdere, redusere avhengigheten av annonseskripter og manuell intervensjon.

Opprette en systembasert tjeneste for en enkelt Docker Container

Standardtilnærmingen innebærer å skrive en tjenesteenhetsfil som ringer til Docker-kommandoer for å kjøre og stoppe beholderen. Nedenfor går vi gjennom prosessen trinnvis, starter med et grunnleggende eksempel og deretter dekker felles produksjonskrav.

Trinn 1: Skriv tjenesteenhetens fil

Opprett en fil som heter [[FLT: 2]]. Bruk følgende mal som utgangspunkt:

[Unit]
Description=My Application Container
After=network-online.target docker.service
Wants=network-online.target
Requires=docker.service

[Service]
Restart=always
RestartSec=10
StartLimitBurst=3
ExecStartPre=-/usr/bin/docker kill myapp
ExecStartPre=-/usr/bin/docker rm myapp
ExecStart=/usr/bin/docker run --rm --name myapp \
 -e DB_HOST=10.0.1.50 \
 -e DB_PORT=5432 \
 -v /data/myapp:/app/data \
 -p 8080:8080 \
 myregistry/myapp:latest
ExecStop=/usr/bin/docker stop -t 10 myapp
ExecStopPost=-/usr/bin/docker rm myapp

[Install]
WantedBy=multi-user.target

Utforsking av nøkkeldirektiver:]

  • ] - sikrer at Docker-nissen kjører før du starter beholderen.
  • ] ⁇ Hvis Docker er stoppet, stopper denne tjenesten også.
  • ]] ⁇ rengjør alle restbeholdere fra en tidligere løp (] prefiks betyr feil her er ikke-faktale).
  • ]] ⁇ bruker til å automatisk fjerne beholderen når den stopper.
  • ]] ⁇ Nydelig stopper beholderen med en tidsavbrudd (10 sekunder).
  • ]] ⁇ starter beholderen på nytt uavhengig av utgangskode.
  • ]] ⁇ venter 10 sekunder før omstart.
  • ]] ⁇ begrenser omstart til 3 forsøk per intervall (standard 10 sekunder) for å unngå å starte om.

Trinn 2: Aktiver og start tjenesten

sudo systemctl daemon-reload
sudo systemctl enable myapp.service
sudo systemctl start myapp.service

forteller systemstyrt å lese om servicefiler. skaper symbolsk lenke slik at tjenesten starter på oppstart.

Administrere tjenesten med standard systemkommandoer

Når tjenesten kjører, kontrollerer du det akkurat som alle andre systemtjenester:

  • Start: ]
  • Stopp: ]
  • Start på nytt:
  • Status:
  • Logg: ] (følg live-logger)

Avanserte konfigurasjonsmønster

Produksjonsutdelinger krever ofte mer enn en enkel . Nedenfor er vanlige forbedringer du kan legge til i systembaserte tjenestefiler.

Passerer miljøvariabler

Harde kodende hemmeligheter eller konfigurasjon i tjenestefilen anbefales ikke. I stedet kan du bruke en separat miljøfil:

[Service]
EnvironmentFile=-/etc/myapp/env.conf
ExecStart=/usr/bin/docker run --rm --name myapp \
 --env-file /etc/myapp/env.conf \
 myregistry/myapp:latest

Forstavelsen før banen betyr at tjenesten starter selv om filen ikke eksisterer (brukes under første oppsett).

Nettverk og portbindinger

For beholdere som trenger å kommunisere med hverandre på samme vert, vurdere å bruke eller brukerdefinerte bronettverk. Eksempel:

ExecStart=/usr/bin/docker run --rm --name web \
 --network=my-net \
 -p 443:443 \
 -v /etc/ssl/certs:/etc/ssl/certs:ro \
 myregistry/web:latest

Hvis du bruker et egendefinert nettverk, kan du sørge for at nettverket eksisterer før tjenesten starter. Du kan legge til en [FLT: 27] -kommando for å opprette det:

ExecStartPre=/usr/bin/docker network create my-net

Inter-Container avhengighet

Når en beholder krever at en annen skal være klar før du starter (f.eks. en webapp som venter på en database), kan systemstyrt håndheve bestilling. Opprett en annen tjenestefil for databasen og deretter:

[Unit]
Description=Web App Container
After=network-online.target docker.service mydb.service
BindsTo=mydb.service

knytter webappens livssyklus til databasebeholderen ⁇ hvis databasen stopper, blir webappen også stoppet.

Helse sjekker og resialitet

Docker helsekontroll kan integreres med system for å hindre for tidlig tilgjengelighet i tjenesten. Bruk med et skript som vurderer helseendpoint:

ExecStartPost=/usr/local/bin/wait-for-health.sh http://localhost:8080/health 30

Skriptet skal avsluttes 0 bare når beholderen er frisk. Hvis det ikke mislykkes, markerer systemet enheten som feil.

Ressursgrenser via Systemd

Du kan begrense en beholders CPU og minne på cgroup-nivå uten Dockers egne ressursflagg. Dette er spesielt nyttig når du kjører flere beholdere på en enkelt vert:

[Service]
MemoryMax=512M
CPUQuota=50%

Disse innstillingene skaper en hard grense som systemstyres håndhever uavhengig av Docker.

Manageing Flere beholdere: Systemd vs. Docker Komponere

For et lite antall beholdere (f.eks. 2-5) er individuelle systembaserte tjenestefiler enkle og vedlikeholdbare. Men når et prosjekt involverer mange sammenkoblede tjenester, blir Docker Composite mer praktisk. Du kan fortsatt bruke systemstyrt til å orkestere hele Docker Composite stabelen ved å opprette en enkelt tjenesteenhet som ringer [[FLT: 34]]. Eksempel:

[Unit]
Description=My Application Stack
After=network-online.target docker.service
Requires=docker.service

[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/opt/myapp
ExecStart=/usr/local/bin/docker-compose up -d
ExecStop=/usr/local/bin/docker-compose down

[Install]
WantedBy=multi-user.target

Denne tilnærmingen gir deg enkelheten i å komponere for å definere tjenester kombinert med systemads livssyklusstyring. Merk at brukes fordi utgår umiddelbart. holder enheten i en «aktiv» tilstand inntil kalles.

Hvilken metode bør du velge?

  • Individuelle systembaserte tjenester ⁇ beste for eldre programmer, tjenester med streng oppstartsbestilling, eller når du trenger per-inneholder ressursgrenser.
  • Docker Composite with systemed ⁇ ideell for mikrotjenester stabler der avhengighet håndteres internt av Composite, og du vil at en enkelt enhet skal administrere hele gruppen.

Feilsøking av felles problemer

Selv med nøye installasjon kan du møte problemer. Nedenfor er hyppige fallgruber og deres løsninger.

Tjenesten mislykkes med «Kan ikke koble til Docker-nissen»

Dette betyr vanligvis at tjenesten starter før Docker-kontakten er klar. Sørg for at enheten din inneholder [[FLT: 40]] og [[FLT: 41]]. Sjekk også at Docker-nissen er aktivert: [[FLT: 42]].

Container starter om i en loop

Hvis beholderen avsluttes umiddelbart, vil systemet fortsette å starte den på nytt i henhold til og . Sjekk containerlogger med . Øk (f.eks. 30 sekunder) og sett for å hindre en travel sløyfe.

Tjenesten stopper ikke rent

En feil konfigurert kan la beholderen kjøre. Kontroller at bruker riktig beholdernavn. Bruk til å kraftig fjerne beholderen hvis stopp mislykkes.

Miljøvariabler som ikke lastes

Hvis du bruker , bekrefter du at filen eksisterer og er lesbar ved rot. Unngå å sitere problemer ⁇ systemstyrte striper sitater fra variable verdier. For hemmelig injeksjon, vurdere å bruke systembaserte legitimasjoner eller en dedikert hemmelig manager.

Sikkerhetsoverveielser

Running Docker containere gjennom systemed øker noen sikkerhetspunkter:

  • Kjør alltid systemtjenesten som ikke-rot bruker om mulig (bruk og ] direktiver, men sørg for at brukeren har tilgang til Docker sokkel eller kjøre i rotløs modus).
  • Unngå å bruke i systemstyrte enheter med mindre absolutt nødvendig.
  • Bruk skrivebeskyttede bindingsmonter (]) når beholderen ikke trenger å skrive til verten.
  • og å herde enheten mot unnslipper.
[Service]
ProtectSystem=strict
ReadWritePaths=/var/log/myapp
PrivateTmp=true
User=myappuser

Eksterne ressurser

For videre lesing, se disse offisielle referansene:

Konklusjon

Integreringssystem med Docker-beholdere gir deg en robust, automatisert oppstartsmekanisme som integrerer sømløst med resten av Linux-systemet. Ved å skrive velstrukturerte tjenesteenhetsfiler kan du styre oppstartsbestilling, administrere avhengigheter, sette ressursgrenser og overvåke logger ved hjelp av verktøy som driftsteamet allerede vet. Enten du velger individuelle tjenester for hver beholder eller en enkelt enhet for å orkesterlegge en Composite-stabel, gir systemad påliteligheten og forutsigbarhetenheten som produksjonsmiljøene krever.

Start med en enkel enhetsfil, test den grundig, deretter lag på avanserte alternativer som miljøfiler, helsekontroll og sikkerhetsherding. Med denne tilnærmingen vil Docker-beholdere overleve omstart, krasjer og konfigurasjon endringer uten manuell intervensjon, frigjør teamet til å fokusere på å bygge programmer.