Hoe efficiënte Python Docker-afbeeldingen maken
Docker is de standaardsoftware voor het verpakken en implementeren van applicaties in containers. Docker-images zijn de hoeksteen waarop je je applicaties kunt bouwen en uitvoeren.
Om de volledige mogelijkheden van Docker te benutten, is het essentieel om je container-images te verfijnen met de focus op het optimaliseren van hun gebruik van bronnen, het verbeteren van beveiligingsmaatregelen en het verbeteren van de algehele prestaties. Door dit te doen, kunt u een naadloze werking van uw applicaties binnen de Docker-omgeving vergemakkelijken.
Krijg inzicht in het proces door een praktische illustratie te bestuderen die de inzet van een Python-rekenapplicatie binnen een gecontaineriseerde omgeving demonstreert.
Beginnen met een minimale basisimage
De selectie van een basisimage kan de prestaties van een Docker-container aanzienlijk beïnvloeden, en het wordt aanbevolen om te beginnen met een minimale image die alleen de fundamentele elementen bevat die nodig zijn om de gewenste toepassing uit te voeren.
Kies een image met een betrouwbare staat van dienst voor het leveren van tijdige beveiligingsupdates, patches en onderhoudt een betrokken gebruikersbasis ondersteund door uitgebreide documentatie. Dergelijke functies zijn van onschatbare waarde voor het oplossen van technische problemen of het zoeken naar begeleiding tijdens de ontwikkeling van je project.
Het selecteren van “python:3.11-slim-bookworm” als programmeertaal voor de rekentoepassing leidt tot een geoptimaliseerde afbeelding die minder bronnen vereist. Bijgevolg resulteert dit in een lager verbruik van bronnen tijdens de implementatie en snellere downloads van de toepassing.
# Starting With a Minimal Base Image
FROM python:3.11-slim-bookworm AS builder
Je hebt de optie om een compactere Alpine Linux-distributie te gebruiken door “python:3.11-alpine” te selecteren. Het is echter belangrijk om op te merken dat deze afbeelding geen Python-interpreter, pakketbeheerder en essentiële Python-bibliotheken bevat.
Applicaties draaien als niet-rootgebruiker
Docker-containers draaien met beheerdersrechten, zoals die van de root-gebruiker, kan leiden tot ernstige beveiligingsimplicaties als een onbevoegde partij toegang krijgt tot de container. In zulke scenario’s kunnen aanvallers mogelijk gebruik maken van bestaande kwetsbaarheden in de containerapplicatie of de afhankelijkheden ervan om hun privilegeniveau te verhogen. Als dit eenmaal is bereikt, kunnen ze willekeurige commando’s uitvoeren op het onderliggende hostsysteem, waardoor de integriteit en vertrouwelijkheid in gevaar komen. Het is cruciaal voor organisaties om robuuste beveiligingsmaatregelen en best practices te implementeren bij het inzetten en beheren van Docker-containers om deze potentiële bedreigingen te beperken.
Applicaties draaien met beperkte rechten, zoals onder een niet-root gebruikersaccount, kan een effectieve beveiligingsmaatregel zijn om potentiële risico’s te beperken die gepaard gaan met het verlenen van volledige toegangsrechten tot kritieke systeembronnen. Door deze praktijk te implementeren, worden de processen van de applicatie geïsoleerd van gevoelige delen van het besturingssysteem, waardoor de reikwijdte van kwaadaardige activiteiten die binnen de context van de applicatie kunnen plaatsvinden, wordt beperkt. Deze aanpak zorgt ook voor betere controlemogelijkheden doordat acties die door de applicatie worden uitgevoerd nauwkeuriger kunnen worden gevolgd. Daarnaast helpt het de integriteit van het onderliggende systeem te behouden door ongeautoriseerde wijzigingen of geknoei met essentiële instellingen te voorkomen.
# Set non-root user for security
RUN adduser calculator --system
# Add the user to the calculator group
RUN addgroup calculator && adduser calculator calculator
Door specifiek voor uw software een gebruikersaccount met beperkte rechten te implementeren, kunt u de beveiligingsrisico’s effectief beperken door de reikwijdte van de toegang te beperken die potentiële indringers kunnen proberen te gebruiken om kwetsbaarheden in het systeem aan te boren.
Noodzakelijke bestanden kopiëren en een virtuele omgeving creëren
Het gebruik van een gevirtualiseerde omgeving ingekapseld in een Docker container vergemakkelijkt het beheer van afhankelijkheden door potentiële conflicten met globale softwarepakketten en andere programma’s af te schermen. Daarnaast garandeert het consistentie in pakketversies omdat precieze edities van vereiste afhankelijkheden geïnstalleerd kunnen worden terwijl de integriteit van het hele systeem behouden blijft.
Zeker! Hier is mijn poging om de instructies op een meer verfijnde manier te parafraseren:Om de calculatorapplicatie in de Docker-container op te zetten, volg je deze stappen zorgvuldig:1. Ten eerste, verplaats alle essentiële bestanden van je lokale machine naar de aangewezen map op de server waar de Docker-image zich bevindt. Dit proces omvat het kopiëren van de vereiste gegevens om de soepele werking van de software te vergemakkelijken.2. Maak vervolgens gebruik van de efficiënte venv
module die vooraf geïnstalleerd is met Python om een geïsoleerde virtuele omgeving binnen de container te creëren. Door dit te doen, kunnen we ervoor zorgen dat de applicatie naadloos draait zonder interferentie of conflicten met andere geïnstalleerde pakketten. Het doel van deze stap is om een zelfstandige en veilige omgeving te creëren waarin het rekenprogramma optimaal kan functioneren.
# Set working directory and copy necessary files
WORKDIR /app
COPY app.py .
COPY requirements.txt .
COPY config.json ./
# Copy config.json from the local directory
# Create a virtual environment and install dependencies
RUN python -m venv /venv
ENV PATH="/venv/bin:$PATH"
RUN /venv/bin/pip install --upgrade pip --no-cache-dir --requirement requirements.txt
Het gebruik van virtuele omgevingen zorgt voor een gestroomlijnde aanpak van pakketbeheer binnen Docker-containers, door duplicatie van systeembrede componenten te vermijden. Dit resulteert in een compactere afbeeldingsgrootte en minder gebruik van bronnen tijdens runtime.
Lagen minimaliseren voor efficiëntie
Docker gebruikt een copy-on-write strategie bij het bouwen van images, waarbij elke richtlijn in een Dockerbestand aanleiding geeft tot een extra laag. Om image-afmetingen en constructiesnelheid te optimaliseren, is het verstandig om het aantal lagen in de Docker-image te minimaliseren. Een praktische benadering om dit doel te bereiken is het combineren van verschillende instructies in een enkele RUN
verklaring.
# Minimizing Layers for Efficiency
# Combine commands to reduce the number of layers
RUN echo "Build process goes here" && \
/venv/bin/python -m compileall . && \
rm -rf __pycache__
Door de bovenstaande aanbevelingen te gebruiken, kunnen we het genereren van tussenlagen tijdens het bouwen van een image effectief minimaliseren.
Beveiligen van Configuratieverwerking
Het gebruik van Docker-images voor het verwerken van gevoelige gegevens vormt een potentiële bedreiging voor de veiligheid. Om dit risico te beperken, wordt het aangeraden om omgevingsvariabelen en externe configuratiebestanden te gebruiken. In het geval van de rekentoepassing kan bijvoorbeeld een map genaamd “/config” aangemaakt worden om het configuratiebestand in onder te brengen en ervoor te zorgen dat de juiste eigendomsrechten worden toegewezen.
# Securing Configuration Handling
RUN mkdir /config && chown calculator:calculator /config
Na het plaatsen van een duplicaat van het “config.json” bestand in deze map, terwijl het gescheiden blijft van de broncode van de applicatie.
# Copy the config.json file into the container
RUN cp config.json /config/config.json
ENV CONFIG_PATH=/config/config.json
Het isoleren van configuratie-informatie van de codebase en het implementeren van geschikte permissies is een belangrijk aspect in het versterken van de uitgebreide beveiligingshouding van je Docker-container. Deze aanpak beperkt onbevoegde entiteiten, zoals malafide processen of individuen, van toegang tot gevoelige configuratiedetails.
Bouwen in meerdere fasen gebruiken
Door een bouwproces in meerdere fasen te implementeren, kan men het bouwmilieu isoleren van de uiteindelijke grafische weergave. Bijgevolg levert deze aanpak compactere en meer gespecialiseerde eindproducten op. Bovendien verhoogt het de veiligheid door ontwikkelingsbronnen en gegevens uit de uiteindelijke weergave te weren. Op deze manier wordt het aanvalsoppervlak verkleind en worden bijkomende gevaren die kunnen ontstaan door onterechte insluitsels geminimaliseerd.
# Leveraging Multi-Stage Builds
FROM python:3.11-slim-bookworm
COPY --from=builder /etc/passwd /etc/passwd
COPY --from=builder /etc/group /etc/group
COPY --from=builder /venv /venv
COPY --from=builder /config /config
COPY --from=builder /app /app
# Copy the application code
De eerder genoemde code verplaatst selectief essentiële onderdelen van de bouwfase (de bouwer genoemd) naar de uiteindelijke afbeelding. Door onnodige bouwgerelateerde bronnen en gegevens te elimineren, stroomlijnt het de afmetingen van de afbeelding en zorgt het voor optimale prestaties van de softwareapplicatie van de calculator.
Beveiliging verbeteren met image scanning
Om de veiligheid van je Docker-images te vergroten, gebruik je image scanning tools zoals Trivy of Clair.Deze tools zijn speciaal ontworpen voor het detecteren van kwetsbaarheden binnen je image lagen en betrouwbare elementen en bieden een robuuste oplossing voor het waarborgen van de integriteit van je gecontaineriseerde applicaties. Je kunt Trivy bijvoorbeeld gebruiken om kwetsbaarheidsscans uit te voeren op de rekenmachineapplicatie.
# Install Trivy for Debian/Ubuntu
RUN apt-get update && \
apt-get install -y wget apt-transport-https gnupg lsb-release && \
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | apt-key add - && \
echo "deb https://aquasecurity.github.io/trivy-repo/deb bookworm main" \
| tee -a /etc/apt/sources.list.d/trivy.list && \
apt-get update && \
apt-get install -y trivy
De integratie van Trivy’s mogelijkheden om kwetsbaarheden te scannen in een Docker-image is van het grootste belang omdat het vertrouwt op de algemeen erkende Common Vulnerabilities and Exposures (CVE)-database. De CVE-database biedt tijdige updates met betrekking tot geïdentificeerde kwetsbaarheden, waardoor de beveiliging van de image continu kan worden gehandhaafd door de meest recente patches te implementeren. Hierdoor worden potentiële risico’s in verband met bekende exploits beperkt en wordt bescherming geboden tegen onbevoegde toegang of inbreuken op gegevens.
Om een beveiligingsbeoordeling van je image te krijgen, kun je de volgende instructie gebruiken. Door deze opdracht uit te voeren, ontvang je een uitgebreid rapport met alle mogelijke zwakke plekken of gevoeligheden in de softwarecomponenten van je image.
docker run --rm `
-v /var/run/docker.sock:/var/run/docker.sock `
-v $HOME/Library/Caches:/root/.cache/ `
aquasec/trivy:0.18.3 `
<your image name>
De voorgaande instructie kan een langere uitvoeringsduur vereisen. Daarom zal het na voltooiing een document produceren dat analoog is aan het volgende voorbeeld.
Het is van het grootste belang dat een kwetsbaarheid in de beveiliging direct wordt aangepakt in overeenstemming met de ernst ervan, want hoe ernstiger het probleem, hoe sneller het moet worden aangepakt.
Applicaties uitvoeren als niet-hoofdgebruikers
Om de beveiliging van deze applicatie te verbeteren, wordt aangeraden om deze te gebruiken onder de auspiciën van de systeembeheerder, zodat eventuele latente kwetsbaarheden worden geminimaliseerd.
# Running Applications as Non-Root Users
WORKDIR /app
USER calculator
# Activate the virtual environment and run the application
CMD ["/bin/bash", "-c", "source /venv/bin/activate && python app.py"]
De overgang naar een niet-administratieve gebruiker vermindert potentiële kwetsbaarheden aanzienlijk door de toegangsprivileges te beperken en de reikwijdte van mogelijke exploits te verkleinen.
Het containeriseren van niet-Python toepassingen
Het proces van het containeriseren van toepassingen die gebruik maken van andere talen dan JavaScript kan enigszins verschillen, waardoor begrip van verschillende containerisatietechnieken nodig is. Door deze nuances te begrijpen, kan men de optimale aanpak bepalen voor het implementeren van hun specifieke applicatie, rekening houdend met de programmeertaal.