Table of Contents
La sfida del contenitore di forma trasversale
I contenitori Docker promettono portabilità a un'once-run-anywhere, ma la realtà è più sfumata quando i tuoi obiettivi di distribuzione coprono Windows e Linux host. Ogni famiglia di sistema operativo espone interfacce del kernel fondamentalmente diverse: i contenitori Linux dipendono da cgroup, namespaces e Ext4 filesystems, mentre i contenitori di Windows NT richiedono il kernel di Windows, l'isolamento Hyper-V e i volumi NTFS o ReFS.
Questo incompatibilità nasce perché un'immagine del contenitore non è una macchina completamente virtualizzata, condivide il kernel dell'host. Un contenitore Linux utilizza il kernel Linux dell'host; un contenitore di Windows utilizza il kernel Windows dell'host. Non è previsto alcun livello di emulazione o di traduzione per impostazione predefinita. Per le organizzazioni che gestiscono l'infrastruttura ibrida, questo crea una pressante necessità di un approccio disciplinato e utilizzato dagli strumenti per la costruzione e la distribuzione di immagini che funzionano in entrambi gli ecosistemi.
Gli operatori di flotta e gli ingegneri della piattaforma devono quindi adottare strategie che producono immagini separate per piattaforma o sfruttano le capacità di visualizzazione multi-architettura di Docker per presentare un unico riferimento di immagine che si risolve alla variante corretta per ogni host. La scelta dipende dal modello di distribuzione, supporto del registro e dalla maturità CI/CD.
Architettura di Windows vs. Linux Immagini
Selezione delle immagini di base e di accoppiamento del kernel
Ogni immagine di Docker parte da un'immagine di base che è basata su Linux (ad esempio, , ], [)) o Windows-based (ad esempio, , ]]). L'immagine di base determina l'ambiente di runtime e l'insieme delle librerie di sistema disponibili.
I contenitori Windows hanno anche una versione più rigorosa: un'immagine del contenitore di Windows costruita per una costruzione del sistema operativo host (ad esempio, 20H2) non può essere eseguita su una diversa costruzione (ad esempio, 21H2). Microsoft mitiga questo con il concetto di Linux isolamento del processo vs. ]]] L'isolamento del kernel Hyper-V, ma la versione minore deve corrispondere
Filesystem e autorizzazioni
Le immagini di Linux utilizzano le autorizzazioni POSIX (utente, gruppo, altro) e i percorsi di file sensibili al caso. Le immagini di Windows si basano su ACL (Access Control Lists) e su percorsi insensibili. L'esecuzione di un'immagine Linux con codice che si aspetta la gestione dei file sensibili al caso su un host Windows (anche in un contenitore) può portare a bug sottili.
Immagini multi-architettura con Docker Buildx
Come funziona il Buildx
Docker Buildx è il modo consigliato per creare immagini che possono essere eseguite su più piattaforme da un'unica invocazione di compilazione. Utilizza l'emulazione basata su QEMU (per Linux-on-Linux cross-compilation) o i costruttori nativi su nodi separati per compilare l'immagine per ogni architettura di destinazione.
Buildx produce un manifesto multi-architettura (chiamato anche un ]]elenco manifesto[]] o ]] che richiama una o più immagini, ognuna contrassegnata con la sua piattaforma. Quando un utente esegue su una macchina Windows, Docker seleziona automaticamente la variante Windows dal manifesto.
Impostazione di un Costruttore di Buildx per Cross-Platform
Per creare un'immagine multi-architettura che include sia le varianti Linux che Windows, è necessario registrare un costruttore che può accedere sia ad un host Linux che ad un host Windows.
Una volta configurato il costruttore, è possibile costruire e spingere il manifesto in un unico passo:
La bandiera spinge automaticamente sia le singole immagini che l'elenco manifesto al registro di sistema.
Limitazioni e Gotchas
- La configurazione trasversale di Windows-on-Linux non è possibile[ perché non è possibile utilizzare QEMU per emulare il kernel di Windows. È necessario disporre di un nodo di costruzione di Windows nativo accessibile al driver Buildx.
- Il supporto per i registri deve includere liste manifeste[. La maggior parte dei registri principali (Docker Hub, AWS ECR, Azure ACR, GitHub Container Registry) li supporta. Alcuni registri privati possono richiedere di verificare la compatibilità.
- Layer caching è per-platform[[]. Caching costruito su un nodo Linux non si applica alla costruzione di Windows. Pianificare passi CI separati o utilizzare una posizione cache condivisa che rispetta la piattaforma.
- Tag immutabilità[[]: Una volta che si spinge un elenco manifesto, non si può modificare senza ristorare tutte le immagini di riferimento.
Progettazione Dockerfiles per Cross-Platform
Passi condizionali con Multi-Stage Builds
Invece di mantenere due Dockerfile completamente separati, è possibile utilizzare argomenti di costruzione e multistadio per gestire le differenze di piattaforma all'interno di un singolo file. Le variabili e sono automaticamente impostate da Buildx quando si specifica la bandiera :
ARG BASE_IMAGE
FROM ${BASE_IMAGE} AS base
FROM base AS install-linux
RUN apt-get update && apt-get install -y libfoo
FROM base AS install-windows
RUN powershell -Command Install-Package -Name Foo
FROM install-${TARGETOS} AS final
COPY app /app
CMD ["/app/start"]
In questo modello, ] si risolve a [] o , e la fase []] seleziona la fase di installazione appropriata. È inoltre possibile utilizzare nella [] per pin specifiche fasi a Linux o Windows, anche se questo richiede Dockerfiles separati se avete bisogno di immagini di base completamente diverse.
Variabili dell'ambiente e iniezione di conflitti
Utilizzare variabili di ambiente per astratto valori specifici della piattaforma come i percorsi di file, le terminazioni di riga o i nomi dei comandi.
ARG TARGETOS
ENV CONFIG_DIR=/etc/myapp
ENV CONFIG_DIR=C:\\ProgramData\\MyApp
Tuttavia, essere cauti: l'esempio precedente è illustrativo ma non può funzionare come-è perché la direttiva viene valutata al momento della costruzione, ma il [ arg è disponibile al momento della costruzione per piattaforma. È possibile utilizzare un "traccia" con uno script con la piattaforma o un modello di tempo di costruzione.
Maneggiare la linea di terminazioni e bit eseguibili
Linux si aspetta che la linea LF finisca in script di shell e file di configurazione; Windows utilizza CRLF. Quando si controlla i file in un repository Git, impostare per memorizzare gli script come LF e convertire il checkout solo per gli host Windows. Nel Dockerfile, contrassegnare esplicitamente gli script di entrypoint come eseguibile con (solo Linux) o utilizzare una [FLT funziona identica] direttiva che funziona esattamente come piattaforme.
Integrazione CI/CD Pipeline
Matrix costruisce per ogni piattaforma
In GitHub Actions, GitLab CI, o Azure Pipelines, utilizzare una strategia di matrice per costruire e testare l'immagine su Linux e Windows runner pool separatamente. Dopo ogni costruzione, spingere l'immagine specifica della piattaforma al Registro con un tag che include il suffisso della piattaforma (ad esempio, , ]).
Esempio GitHub Azioni Flusso di lavoro (Semplificati)
jobs:
build:
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
include:
- os: ubuntu-latest
platform: linux/amd64
- os: windows-latest
platform: windows/amd64
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- name: Build and push
uses: docker/build-push-action@v5
with:
platforms: ${{ matrix.platform }}
tags: myapp:${{ matrix.platform }}-${{ github.sha }}
push: true
manifest:
needs: build
runs-on: ubuntu-latest
steps:
- uses: docker/setup-buildx-action@v3
- name: Create manifest list
run: |
docker buildx imagetools create \
-t myregistry.io/myapp:latest \
myregistry.io/myapp:linux-amd64-${{ github.sha }} \
myregistry.io/myapp:windows-amd64-${{ github.sha }}
Test su entrambe le piattaforme
Integrare i test di integrazione specifici della piattaforma nella stessa matrice costruisce. Ad esempio, dopo aver costruito l'immagine di Windows su un runner di Windows, eseguire un test di fumo che verifica l'applicazione inizia e risponde sulla porta prevista. Per Linux, fare lo stesso. Solo se entrambi i set di test passano dovrebbe procedere la creazione manifesta.
Tip:] Usa [] per forzare una specifica variante della piattaforma durante i test locali. Questo è prezioso quando si dispone solo di una workstation Linux, ma si desidera verificare la struttura manifesta prima di impegnarsi.
Disboscamento di problemi di forma trasversale
Modalità di fallimento comune
- Base image mismatch[[]: La versione Windows Server Core (ad esempio, ltsc2022 vs. ltsc2019) non corrisponde alla versione OS host.
- Limiti di memoria e parametri del kernel[[[]: I contenitori di Windows possono richiedere l'isolamento Hyper-V per far rispettare i limiti di memoria, mentre i contenitori Linux possono usare CFS (Completamente Fair Scheduler).
- Differenze di rete[: I contenitori di Windows utilizzano un interruttore basato su NAT per impostazione predefinita, e il binding della porta si comporta in modo diverso. ] non è supportato su Windows.
- File locking and segnali[[[]: Windows non supporta i segnali POSIX nello stesso modo in cui Linux fa. Inviare un SIGTERM ad un processo all'interno di un contenitore di Windows non può innescare un arresto grazioso.
Strumenti di registrazione e di introspezione
Quando si debugga un problema cross-platform, utilizzare [] per verificare il sistema operativo e l'architettura dell'immagine.
Se la piattaforma manca o mostra una sola variante, l'immagine non è un manifesto multi-architettivo.
Se si vede solo una voce, il passo di creazione manifesto è stato incompleto o la costruzione non ha preso di mira entrambe le famiglie del sistema operativo.
Modelli e pitfalls reali del mondo
Modello: Utilizzo di Docker Desktop per lo sviluppo locale
Docker Desktop su Windows può passare tra Linux e Windows modalità contenitore, ma non può essere eseguito contemporaneamente. Per lo sviluppo cross-platform, utilizzare diversi costruttori remoti o macchine virtuali. La capacità di Docker Desktop di eseguire contenitori Linux in modo nativo (via WSL 2) ha ridotto la necessità di contenitori Windows su workstation sviluppatore, ma è ancora necessario contenitori Windows per il test di integrazione di Windows solo le caratteristiche di immagine.
Modello: LTS Allineamento per immagini Windows
Microsoft rilascia una nuova versione di Long-Term Servicing Channel (LTSC) di Windows Server circa ogni due o tre anni. Ogni versione di LTSC ha un'immagine corrispondente di base del contenitore. Se il vostro Windows porta ltsc2022 immagine del contenitore, è necessario costruirla su un host di Linux molto meno e eseguirla su host ltsc2022. Non c'è garanzia di compatibilità all'indietro.
Pitfall: Ignorando ARM64
Mentre l'articolo si concentra su Windows e Linux, il futuro del calcolo è eterogeneo: AWS Graviton, Azure Ampere, Apple Silicon e Raspberry Pi clusters tutti eseguire ARM64 Linux. Se si sta costruendo un'immagine multi-architettura per Windows e Linux, considerare anche incluso nel vostro manifesto.
Pitfall: Vista autorizzazioni Filesystem in COPY
Se si COPY uno script da un host Linux, mantiene le sue terminazioni di bit e LF linea. Se si COPY da un host Windows, il file si atterra senza il bit eseguibile e con terminazioni CRLF. Per garantire un comportamento coerente, utilizzare e garantire LF
Conclusioni
Gestire le immagini Docker multipiattaforma per Windows e Linux non è più un caso di utilizzo esotico. È un requisito pratico per qualsiasi flotta che si estende su infrastrutture eterogenee, dai cluster di Windows Server on-premises ai Kubernetes Linux nativi cloud.Adottando Docker Buildx per i manifesti multi-architettura, mantenendo Dockerfiles condizionabili su piattaforma, integrando un'immagine basata su piattaforma OS/CD e basata su piattaforma
I takeaway chiave sono semplici:
- Usa con nodi di configurazione nativo di Windows e Linux per produrre liste manifeste.
- Progettare i file Docker con e per evitare duplicazioni di codice.
- Automatizza le costruzioni e i test specifici della piattaforma in CI; unisci solo i manifesti dopo entrambi i passaggi.
- Resta corrente con i cicli di rilascio LTSC di Microsoft per evitare errori di versione di immagine di base.
Con queste pratiche in atto, puoi concentrarti sulla fornitura di valore dell'applicazione piuttosto che sul wrestling con le incompatibilità della piattaforma. Per ulteriori informazioni, consulta la Docker multi-platform build documentazione, la Windows container Overview su Microsoft Learn]], e la Buildkit repository evolution builder [[FLT] [[FLT] [FLT]