Moby: Nur Build-Zeit -v-Option

Erstellt am 21. Juni 2015  ·  258Kommentare  ·  Quelle: moby/moby

Wie von @cpuguy83 in https://github.com/docker/docker/issues/3156 vorgeschlagen
Hier ist der Anwendungsfall für eine flexible -v-Option zur Build-Zeit.

Beim Erstellen eines Docker-Images muss ich eine Datenbank und eine App installieren. Es ist alles in zwei Tarballs verpackt: 1 für die DB und 1 für die App, die darin installiert werden muss (Schema, Objekte, statische Daten, Anmeldeinformationen usw.). Die gesamte Lösung wird dann über ein Shell-Skript ausgeführt, das mehrere Shell-Variablen verarbeitet und Betriebssystem-Anmeldeinformationen und andere Dinge entsprechend abstimmt.
Wenn ich den obigen Tarball explodiere (oder die Dockerfile ADD-Direktive verwende), bläht sich das Ganze auf etwa 1,5 GB (!) auf. Nicht ideal, wie Sie sich vorstellen können.

Ich möchte, dass diese Direktive '-v /distrib/ready2installApp:/distrib' weiterhin möglich ist (wie sie heute im Dockerfile steht).
aber

Ich möchte den deklarativen Build-Prozess (Infrastruktur als Code) von dem zur Containerlaufzeit bereitstellbaren Artefakt trennen. Ich möchte mich nicht mit dem Ballast von 1,5 GB auseinandersetzen müssen, die ich nicht benötige.

Könnten wir eine Option --unmount-volume haben, die ich am Ende der Dockerfile ausführen kann?
oder
Angesichts dessen, wie Volume derzeit in einem Dockerfile funktioniert, brauchen wir vielleicht eine neue Dockerfile-Direktive für ein temporäres Volume, das die Leute während der Installation verwenden? Ich denke, das von @fatherlinux bereitgestellte Puppet-Beispiel war auf einer ähnlichen Linie ...
oder
Was auch immer euch einfällt.
Das Ziel besteht darin, zu vermeiden, all das Ballast herumtragen zu müssen, das für eine bereitgestellte App oder einen bereitgestellten Dienst nutzlos ist. Dieses Eigengewicht ist jedoch zur Installationszeit erforderlich. Nicht jeder hat eine einfache "Yum-Installation" aus den offiziellen Repositories. :)

Danke sehr

arebuilder kinfeature

Hilfreichster Kommentar

Ich habe einen etwas anderen Anwendungsfall für diese Funktion - Caching-Pakete, die vom ASP.Net 5-Paketmanager heruntergeladen/aktualisiert werden. Der Paketmanager verwaltet seinen eigenen Cache-Ordner, also brauche ich letztendlich nur einen Ordner, den ich zwischen Builds wiederverwenden kann.

Dh:

docker build -v /home/dokku/cache/dnx/packages:/opt/dnx/packages -t "dokku/aspnettest" .

Alle 258 Kommentare

Ich suche nach einer ähnlichen Lösung.

Problem

Kürzlich hat das Unternehmen, in dem ich arbeite, den Zscaler-Proxy mit SSL-Überprüfung aktiviert, was bedeutet, dass Zertifikate installiert und einige Umgebungsvariablen während des Builds festgelegt wurden.

Eine vorübergehende Lösung bestand darin, ein neues Dockerfile mit festgelegten Zertifikaten und Umgebungsvariablen zu erstellen. Aber das erscheint langfristig nicht sinnvoll.

Mein erster Gedanke war also, einen transparenten Proxy mit HTTP und HTTPS festzulegen, aber auch hier muss ich während des Builds ein Zertifikat übergeben.

Das ideale Szenario ist, dass ich mit demselben Dockerfile mein Image auf meinem Laptop, zu Hause und im Unternehmen erstellen könnte.

Mögliche Lösung

# Enterprise
$ docker build -v /etc/ssl:/etc/ssl -t myimage .

# Home
$ docker build -t myimage .

Ich habe einen etwas anderen Anwendungsfall für diese Funktion - Caching-Pakete, die vom ASP.Net 5-Paketmanager heruntergeladen/aktualisiert werden. Der Paketmanager verwaltet seinen eigenen Cache-Ordner, also brauche ich letztendlich nur einen Ordner, den ich zwischen Builds wiederverwenden kann.

Dh:

docker build -v /home/dokku/cache/dnx/packages:/opt/dnx/packages -t "dokku/aspnettest" .

@yngndrw , was Sie vorschlagen, wäre auch für mich in Ordnung, dh wir müssen zur Erstellungszeit zusätzliche Ressourcen bereitstellen, die zur Laufzeit nicht erforderlich wären, da sie im Container installiert wurden.

FWIW Ich habe irgendwo auf diesen Seiten jemanden gesehen, der etwas in der Art sagte (und ich hoffe, ich paraphrasiere es richtig) "Lösen Sie Ihr Kompilierungsproblem auf einem ähnlichen Hostcomputer und installieren Sie dann einfach das bereitstellbare Artefakt oder die Exe im Container".
Ich fürchte, es ist nicht so einfach, Leute. Manchmal muss ich in /usr/bin installieren, aber ich muss auch einige Konfigurationsdateien bearbeiten. Ich überprüfe das Betriebssystem, auf dem ich laufe, die Kernel-Parameter, die ich anpassen muss, die Dateien, die ich abhängig von Variablen oder Manifest-Build-Dateien erstellen muss. Es gibt viele Abhängigkeiten, die mit einer einfachen Kopie eines kompilierten Produkts einfach nicht zufrieden sind.

Ich wiederhole, was ich gesagt habe, als ich das Problem öffne: Es gibt einen Unterschied zwischen einer Manifest-Deklarationsdatei und ihrem Prozess und der Laufzeit eines Artefakts.
Wenn wir wirklich an Infrastructure-as-Code und darüber hinaus an unveränderliche Infrastruktur glauben, die Docker selbst weiter fördert & ich mag es übrigens, dann muss dies meiner Meinung nach ernsthaft in Betracht gezogen werden (siehe das Aufblähen in Post 1 hiermit).

Danke nochmal

Ein weiterer sehr interessanter Anwendungsfall ist das Upgraden von Software. Es gibt Zeiten, wie bei FreeIPA, in denen Sie wirklich mit einer Kopie der Produktionsdaten testen sollten, um sicherzustellen, dass alle verschiedenen Komponenten sauber aktualisiert werden können. Sie möchten das Upgrade dennoch in einer „Build“-Umgebung durchführen. Sie möchten, dass die Produktionskopie der Daten an einem anderen Ort gespeichert wird, damit beim Verschieben der neuen aktualisierten Versionen der Container in die Produktion genau die Daten angehäuft werden können, für die Sie das Upgrade durchgeführt haben.

Ein weiteres Beispiel wäre Satellite/Spacewalk, das häufig das Schema ändert und sogar Datenbanken von Oracle auf Postgresql in Version 5.6 (IIRC) umgestellt hat.

Es gibt viele, viele Szenarien, in denen ich vorübergehend Zugriff auf Daten benötige, während ich ein Software-Upgrade in einem Container-Build durchführe, insbesondere bei verteilten/Micro-Services....

Im Wesentlichen bin ich jetzt gezwungen, ein manuelles Upgrade durchzuführen, indem ich einen regulären Container mit einem -v bind mount ausführe und dann einen „Docker-Commit“ durchführe. Ich kann nicht verstehen, warum die gleiche Funktion bei einem automatisierten Dockerfile-Build nicht verfügbar wäre?

Unterstützen von @yngndrw , der auf das Caching hinweist: Die exakt gleiche Argumentation gilt für viele beliebte Projekte wie Maven, npm, apt, rpm – das Zulassen eines gemeinsam genutzten Caches kann Builds dramatisch beschleunigen, darf es aber nicht in das endgültige Image schaffen.

Ich stimme @stevenschlansker zu. Es können viele Anforderungen für das Anhängen des Cache-Volumens oder eine Art von wenigen Daten-Gigabyte sein, die (im geparsten Zustand) auf dem endgültigen Bild vorhanden sein müssen, jedoch nicht als Rohdaten.

Ich bin auch von dem beständigen Widerstand gegen die Erweiterung docker build gebissen worden, um die Volumes zu unterstützen, die von docker run verwendet werden können. Ich fand das Mantra „Host-unabhängige Builds“ nicht sehr überzeugend, da es das Entwickeln und Iterieren von Docker-Images nur dann schwieriger und zeitaufwändiger zu machen scheint, wenn Sie bei jedem Neuaufbau das gesamte Paket-Repository erneut herunterladen müssen ein Bild.

Mein erster Anwendungsfall war der Wunsch, OS-Paket-Repositories zwischenzuspeichern, um die Entwicklungsiteration zu beschleunigen. Eine Problemumgehung, die ich mit einigem Erfolg verwendet habe, ähnelt dem von @fatherlinux vorgeschlagenen Ansatz, der darin besteht, einfach das Ringen mit docker build und den Dockerfile insgesamt aufzugeben und mit docker run von vorne anzufangen docker commit .

Als kleines Experiment habe ich meine Technik zu einem vollwertigen Ersatz für docker build erweitert, indem ich ein wenig POSIX-Shell-Skripting verwendet habe: dockerize .

Wenn jemand dieses Skript oder den allgemeinen Ansatz testen möchte, lassen Sie mich bitte wissen, ob es interessant oder hilfreich ist (oder ob es überhaupt für Sie funktioniert). Um es zu verwenden, fügen Sie das Skript irgendwo in Ihren PATH ein und fügen es als Shebang für Ihr Build-Skript hinzu (das #! -Ding). Legen Sie dann relevante Umgebungsvariablen fest, bevor eine zweite Shebang-Zeile den Beginn Ihres Docker-Installationsskripts markiert.

Die Variablen FROM , RUNDIR und VOLUME werden automatisch als Argumente an docker run übergeben.
Die Variablen TAG , EXPOSE und WORKDIR werden automatisch als Argumente an docker commit übergeben.

Alle anderen Variablen werden in der Shell ausgewertet und als Umgebungsargumente an docker run übergeben, wodurch sie in Ihrem Build-Skript verfügbar sind.

Dieses Skript wird beispielsweise Alpine Linux-Pakete zwischenspeichern und zwischen Builds wiederverwenden (das VOLUME stellt ein Home-Verzeichnis in CACHE bereit, das dann als symbolischer Link für den Paket-Repository-Cache des Betriebssystems im Installationsskript verwendet wird):

#!/usr/bin/env dockerize
FROM=alpine
TAG=${TAG:-wjordan/my-image}
WORKDIR=/var/cache/dockerize
CACHE=/var/cache/docker
EXPOSE=3001
VOLUME="${HOME}/.docker-cache:${CACHE} ${PWD}:${WORKDIR}:ro /tmp"
#!/bin/sh
ln -s ${CACHE}/apk /var/cache/apk
ln -s ${CACHE}/apk /etc/apk/cache
set -e
apk --update add gcc g++ make libc-dev python
[...etc etc build...]

Nachdem ich letzte Woche das französische Kontingent :) von Docker auf der MesoCon getroffen hatte (es war mir eine Freude, Leute), wurde ich darauf aufmerksam gemacht, dass sie das gleiche Problem intern haben und einen Hack entwickelt haben, der das, was sie brauchen, auf ein neues schlankes Image kopiert .
Ich würde sagen, dass Hacks in der Unternehmenswelt nicht willkommen sind ;) und diese Anfrage sollte ordnungsgemäß behandelt werden.
Danke fürs Zuhören Jungs...

Ich bin auch dafür, das Build-Zeit-Flag -v hinzuzufügen, um Builds zu beschleunigen, indem ein Cache-Verzeichnis zwischen ihnen geteilt wird.

@yngndrw Ich verstehe nicht, warum Sie zwei verwandte Probleme geschlossen haben. Ich habe Ihre Ausgabe Nr. 59 gelesen und verstehe nicht, wie das damit zusammenhängt. In einigen Fällen werden Container super aufgebläht, wenn sie zur Laufzeit nicht benötigt werden. Bitte lesen Sie den 1. Beitrag.
Ich hoffe, ich übersehe hier nichts... es war ein langer Tag :-o

@zrml Das Problem https://github.com/aspnet/aspnet-docker/issues/59 bezog sich auf das integrierte Zwischenspeichern pro Schicht, das Docker während eines Builds für alle Docker-Dateien bereitstellt, aber dieses aktuelle Problem unterscheidet sich geringfügig von Wir sprechen über die Verwendung von Host-Volumes, um Dockerfile-spezifisches Caching bereitzustellen, das davon abhängt, dass das Dockerfile das Volume speziell nutzt. Ich habe das Problem https://github.com/aspnet/aspnet-docker/issues/59 geschlossen, da es sich nicht speziell auf das aspnet-docker-Projekt/Repository bezieht.

Das andere Problem, auf das Sie sich meiner Meinung nach beziehen, ist das Problem https://github.com/progrium/dokku/issues/1231 , das sich auf die Dokku-Prozesse bezog, die das integrierte Docker-Layer-Caching explizit deaktivierten. Michael hat eine Änderung an Dokku vorgenommen, damit dieses Verhalten konfigurierbar ist, und dies löste das Problem in Bezug auf das Dokku-Projekt / Repository, sodass dieses Problem ebenfalls geschlossen wurde.

Es gibt möglicherweise noch ein Docker-bezogenes Problem, das noch offen ist (z. B. warum hat Docker das integrierte Layer-Caching nicht so behandelt, wie ich es in Ausgabe https://github.com/aspnet/aspnet-docker/issues/59 erwartet hatte), aber Ich hatte keine Gelegenheit, herauszufinden, warum das so ist, und zu bestätigen, ob es immer noch passiert. Wenn es immer noch ein Problem gibt, sollte ein neues Problem für dieses Projekt / Repository dafür erstellt werden, da es sich von diesem aktuellen Problem unterscheidet.

@yngndrw genau, also sind wir uns einig, dass dies anders und bekannt ist @docker.com, also öffne ich es wieder, wenn es Ihnen nichts ausmacht ... nun, ich kann nicht. Stört es Sie bitte?
Ich würde gerne einige Kommentare von unseren Kollegen in SF sehen, zumindest bevor wir es schließen

Übrigens wurde ich von @cpuguy83 gebeten, einen Benutzerfall zu öffnen und alles zu erklären, aus Protokoll Nr. 3156

@zrml Ich bin mir nicht sicher, ob ich folge - Ist es https://github.com/aspnet/aspnet-docker/issues/59 , das Sie erneut öffnen möchten? Es handelt sich nicht um ein /aspnet/aspnet-docker-Problem, daher halte ich es nicht für richtig, dieses Problem erneut zu öffnen. Es sollte wirklich ein neues Problem auf /docker/docker sein, aber es müsste verifiziert werden und es müssten zuerst reproduzierbare Schritte generiert werden.

nein, nein.. diese #14080, die du gestern geschlossen hast.

Dieses Thema ist noch offen?

@yngndrw Ich glaube, ich habe das rote Symbol "geschlossen" falsch gelesen. Entschuldigung.

Stimmen Sie herzlich zu, dass Build time -v eine große Hilfe wäre.

Build-Caching ist ein Anwendungsfall.

Ein weiterer Anwendungsfall ist die Verwendung von SSH-Schlüsseln zur Erstellungszeit zum Erstellen aus privaten Repos, ohne dass sie in der Ebene gespeichert werden, wodurch die Notwendigkeit von Hacks (obwohl gut entwickelt) wie diesem entfällt: https://github.com/dockito/vault

Ich kommentiere hier, weil dies in einer Unternehmenswelt die Hölle ist.
Wir haben einen SSL-Abfang-Proxy, während ich den Datenverkehr durch ihn leiten kann, gehen haufenweise Projekte davon aus, dass sie gute SSL-Verbindungen haben, also sterben sie schrecklich.

Obwohl meine Maschine (und damit der Docker-Builder) dem Proxy vertraut, tun Docker-Images dies nicht.
Am schlimmsten ist jedoch, dass die beste Methode jetzt ist, curl innerhalb des Containers zu verwenden, das ist also schmerzhaft, ich muss Dockerfiles ändern, damit sie überhaupt erstellt werden. Ich könnte die Zertifikate mit einer Option -v mounten und glücklich sein.

Nachdem das gesagt ist. Es ist weniger die Schuld von Docker, sondern eher die Schuld von Paketmanagern, die https verwenden, wenn sie ein System verwenden sollten, das der Funktionsweise von apt-get ähnelt. Da das immer noch sicher und überprüfbar ist und auch von einem http-Proxy zwischengespeichert werden kann.

@btrepp danke für einen weiteren guten Anwendungsfall.

Ich kann mir eine andere Situation vorstellen.

Eines der Dinge, die ich mit meinen Dockerfiles tun möchte, ist, die Build-Tools nicht mit der "kompilierten" Docker-Datei zu versenden. Es gibt keinen Grund, warum eine C-App gcc benötigt, noch eine Ruby-App Bundler im Image, aber die Verwendung von Docker Build hat dies derzeit.

Eine Idee, die ich hatte, ist die Angabe einer Dockerdatei, die mehrere Docker-Befehle ausführt, wenn sie darin erstellt wird. Pseudo-artige Dockerfiles unten.

Docker-Datei, die andere erstellt

FROM dockerbuilder
RUN docker build -t docker/builder myapp/builder/Dockerfile
RUN docker run -v /app:/app builder
RUN docker build -t btrepp/myapplication myapp/Dockerfile

btrepp/myapplication dockerfile

FROM debian:jessie+sayrubyruntime
ADD . /app //(this is code thats been build using the builder dockerfile
ENTRYPOINT ["rails s"]

Hier haben wir einen temporären Container, der die gesamte Bündelungsinstallation/Paketverwaltung und alle Build-Skripts übernimmt, aber die Dateien erzeugt, die der Runtime-Container benötigt.

Der Runtime-Container fügt dann nur die Ergebnisse hinzu, was bedeutet, dass nicht viel mehr als die Installation von Ruby erforderlich sein sollte. Im Fall von beispielsweise GCC oder noch besser statisch verknüpftem Go benötigen wir möglicherweise nichts anderes als die Kerndateien des Betriebssystems, um ausgeführt zu werden.

Das würde die Docker-Bilder superleicht halten.

Das Problem hier ist, dass der temporäre Builder-Container am Ende verschwinden würde, was bedeutet, dass es ohne die Möglichkeit, eine Art Cache zu laden, super teuer wäre, wir würden debian:jessie eine ganze Menge Male packen.

Ich habe Leute gesehen, die bestimmte Techniken wie diese verwenden, aber externe http-Server verwenden, um die Build-Dateien hinzuzufügen. Ich würde es vorziehen, alles von Docker zu bauen. Es gibt jedoch möglicherweise eine Möglichkeit, ein Docker-Image zu verwenden, um dies ordnungsgemäß zu tun. Ausführen verwenden und somit Volumes mounten können.

Hier ist ein weiteres Beispiel. Angenommen, ich möchte einen Container für systemtap erstellen, der alle Debug-Symbole für den Kernel enthält (die Yuuuuge sind). Ich muss die zugrunde liegenden /lib/modules mounten, damit der Befehl yum weiß, welche RPMs installiert werden sollen.

Außerdem würde ich diese vielleicht lieber an einem anderen Ort als im 1,5-GB-Image (aus den Debug-Symbolen) haben.

Ich wollte ein Dockerfile schreiben, dann wurde mir klar, dass es unmöglich war :-(

docker run --privileged -v /lib/modules:/lib/modules --tty=true --interactive=true rhel7/rhel-tools /bin/bash
yum --enablerepo=rhel-7-server-debug-rpms install kernel-debuginfo-$(uname -r) kernel-devel-$(uname -r)
docker ps -a
CONTAINER ID        IMAGE                     COMMAND             CREATED             STATUS                        PORTS               NAMES
52dac30dc495        rhel7/rhel-tools:latest   "/bin/bash"         34 minutes ago      Exited (0) 15 minutes ago                         dreamy_thompson
docker commit dreamy_thompson stap:latest

https://access.redhat.com/solutions/1420883

Ich möchte hier meinen Anwendungsfall aus #3949 wiederholen, da dieser Fehler aus anderen Gründen geschlossen wurde.

Ich würde wirklich gerne proprietäre Software in Docker sandboxen. Es ist für mich illegal, es irgendwo zu hosten, und der Download-Prozess kann realistisch (oder legal) nicht automatisiert werden. Insgesamt kommen die Installer auf ca. 22GB (und sie werden mit jedem Release größer). Ich denke, es ist albern zu erwarten, dass dies zur Build-Zeit in das Docker-Image kopiert werden sollte.

Irgendwelche Neuigkeiten in dieser benötigten Funktion?
Danke

_USER-UMFRAGE_

_Der beste Weg, um über Änderungen in dieser Diskussion benachrichtigt zu werden, besteht darin, oben rechts auf die Schaltfläche "Abonnieren" zu klicken._

Die unten aufgeführten Personen haben Ihre sinnvolle Diskussion mit einem zufälligen +1 gewürdigt:

@vad

+1 für diese Funktion!

Ein weiterer Anwendungsfall ist die Verwendung von SSH-Schlüsseln zur Erstellungszeit zum Erstellen aus privaten Repos, ohne dass sie in der Ebene gespeichert werden, wodurch die Notwendigkeit von Hacks (obwohl gut entwickelt) wie diesem entfällt: https://github.com/dockito/vault

Dies ist auch unser Anwendungsfall (in diesem Fall mit tmpfs auf dem Host gerenderte SSH-Schlüssel).

Ein weiterer Anwendungsfall dafür ist ein lokaler Cache des Verzeichnisses node_modules auf einem CI-Server, um die Build-Zeiten zu verkürzen.
npm install ist sehr langsam und selbst im aktuellen "besten" Fall, wo die package.json ADD an das Bild gekoppelt sind, werden npm install ausgeführt und erst dann ausgeführt die eigentlichen Projektquellen hinzugefügt und aufgebaut auf Änderungen an package.json müssen alle Abhängigkeiten erneut heruntergeladen werden.

Siehe npm/npm#8836 für ein Problem dazu auf der Node/npm-Seite.

Verwandtes Aspnet-Docker-Problem in Bezug auf die langsame Paketwiederherstellung und die resultierende Bildgröße beim Zwischenspeichern der aktuellen Pakete in der Ebene. Es wäre viel besser, ein gemountetes Volume für das Caching des Pakets zu verwenden.
https://github.com/aspnet/aspnet-docker/issues/123

Dies ist kein sprachspezifisches Problem, es wird viele Menschen betreffen, da Paketmanager jetzt ein akzeptierter Standard sind.

Das OP hat das Problem auf den Kopf gestellt, da "docker build -v" sehr dazu beitragen würde, den Build-Prozess von der Laufzeitumgebung zu entkoppeln.

Ich habe mehrere Projekte gesehen, die jetzt "Mulberry-Häfen" bauen, die dann verwendet werden, um den eigentlichen Docker zu bauen, der dann gepusht/verteilt wird. Dies ist sowohl aus Sicht der Verwaltung als auch der Rechenressourcen übermäßig komplex, was wiederum zu langsameren CI- und Einheitentests und insgesamt zu einem weniger produktiven Entwicklungsworkflow führt.

Ich habe darüber nachgedacht, und die andere Option, die mir einfällt, ist die Möglichkeit, Ebenen als "src" -Ebenen zu markieren.

Etwas in der Art, dass diese Ebenen nur während eines Docker-Builds zugänglich sind, aber nicht in die resultierende Bilddatei gezogen werden.

Auf diese Weise kann Docker frühere Ebenen/Images und temporäre Build-Artefakte zwischenspeichern, aber diese sind nicht erforderlich, um das endgültige Image zu verwenden.

Z.B.

FROM ubuntu
RUN apt-get install gcc
ADDPRIVATE . /tmp/src <--these can be cached by docker locally
RUNPRIVATE make     <-- basically these layers become scoped to the current build process/dockerfile
RUN make install <--result of this layer is required.

Das bedeutet natürlich, dass Sie wissen müssen, was Sie besser machen, da Sie kritische Dateien sehr gut weglassen könnten.

@yngndrw
Eine viel bessere Lösung für Situationen wie Netcore wäre für sie, HTTPS nicht für die Paketverwaltung zu verwenden, dann ist es trivial, iptables+squid einzurichten, um einen transparenten Caching-Proxy für Docker-Builds zu haben. Meine persönliche Meinung ist, dass diese Paketmanager ihre game, sind sie in Unternehmensumgebungen aufgrund von SSL-Aufgeben schrecklich zu verwenden, während Dinge wie apt-get einwandfrei funktionieren und bereits mit iptables + squid für Docker zwischengespeichert werden können.

Ich sehe auch einen Nachteil bei der Verwendung von Build-Time-Volumes, Dockerfiles sind nicht so reproduzierbar, und es wird eine zusätzliche Einrichtung außerhalb von docker build -t btrepp/myapp erfordern. Es wird auch automatisierte Builds auf Dockerhub erschweren.

@btrepp : Ich mag deinen Vorschlag. Ich könnte sogar für meine Anwendungsfälle mit einem fest codierten (ich weiß, dass es im Allgemeinen eine schlechte Sache ist) TMP-Verzeichnis leben, von dem Docker uns erzählt, damit sie wissen, wann sie das endgültige Artefakt aus allen Schichten erstellen, dass sie das eine vergessen / weglassen können bereitgestellt auf /this_is_the_tmp_explosion_folder_that_will_be_removed_from_your_final_container_image
leicht genug....

@btrepp Ich mag deine Quellschicht-Idee sehr.

In Bezug auf Paketmanager, die kein SSL verwenden, muss ich jedoch widersprechen.

Wenn Sie solche Pakete zwischenspeichern möchten, sollten Sie stattdessen wahrscheinlich einen (lokalen) privaten Paket-Feed verwenden, der die offizielle Quelle widerspiegelt. Die Rückkehr zu HTTP scheint mir eine schlechte Idee zu sein, insbesondere angesichts der Tatsache, dass viele Paketmanager ihre Pakete anscheinend nicht signieren und sich daher auf HTTPS verlassen.

Es gibt ein Tool Grammatik/Rocker , das verwendet werden kann, solange dieses Problem noch nicht behoben ist.

@yngndrw

Mein Punkt, der lokale Proxy usw. ist ein Problem, das seit langem gelöst wurde. Paketmanager müssen nur verifiziert werden, sie brauchen keinen Datenschutz. Die Verwendung von https ist eine faule Art der Überprüfung, aber es kommt mit dem Datenschutzanhang.

Es gibt keinen Grund, warum „super_awesome_ruby_lib“ privat sein muss, wenn es über http(s) heruntergezogen wird. Der bessere Weg wäre, wenn Rubin-Edelsteine ​​einen Schlüsselring haben. Oder sogar ein bekannter öffentlicher Schlüssel und damit Pakete signiert werden. So funktioniert apt-get mehr oder weniger und ermöglicht es Standard-http-Proxys, Dinge zwischenzuspeichern.

In Bezug auf einen lokalen privaten Paket-Feed unterstützt Docker dies nicht einmal selbst. Es gibt keine Möglichkeit, den Standard-Feed zu deaktivieren, und er verliert ihn _zu Recht_, wenn sich das https-Zertifikat nicht im Zertifikatsspeicher befindet. Ich bin mir ziemlich sicher, dass Docker beim Ziehen von Bildern immer zumindest den Haupt-Feed überprüfen möchte. Afaik die rocket/rkt-Implementierung wollte signing+http verwenden, um Container-Images zu erhalten.

Wenn die Hauptmotivation für Build-Time-Volumes nur das Zwischenspeichern von Paketen ist, dann sollte meiner Meinung nach Druck auf die Paketmanager ausgeübt werden, das Zwischenspeichern besser zu unterstützen, anstatt einen Teil der Automatisierung/Reinheit von Docker derzeit zu gefährden.

Um es klar zu sagen, ich befürworte nicht, dass Paketmanager auf die Verwendung von http umstellen und https fallen lassen. Sie benötigen eine Überprüfung von Paketen, um Man-in-the-Middle-Angriffe zu verhindern. Was sie nicht brauchen, ist der Datenschutzaspekt, der https als "Sicherheits-Catch-All-Vorschlag"-Angebote verwendet.

Das ist eine wirklich enge Sicht. Sie fordern das gesamte Universum der Paketmanager auf, ihr Verhalten zu ändern, um Dockers Vorgaben zu entsprechen, wie ihrer Meinung nach Anwendungen erstellt werden.

Es gibt auch eine Menge anderer Beispiele dafür, warum dies in diesem Thread notwendig ist. Zu sagen „Nun, Sie sollten einfach ändern, wie alle Tools funktionieren, die Sie zum Erstellen Ihrer Anwendungen verwenden“, vertreibt das Problem nicht, sondern vertreibt nur die Benutzer.

(Ich bin auch entschieden anderer Meinung als Dockers Anbindung an das öffentliche Register – ich würde es sehr bevorzugen, den Zugriff auf das öffentliche Register zu verbieten und nur die Verwendung unseres internen Registers zuzulassen. Aber das ist ein ganz anderes Thema.)

Für mich brauche ich auch docker build -v .

In unserem Fall möchten wir ein Image erstellen, das aus einer vorkonfigurierten Installation des betreffenden Produkts besteht und das Installationsprogramm über 2 GB groß ist. Da wir kein Host-Volume mounten können, können wir das Image nicht mit dem Installationsprogramm erstellen, obwohl wir es bereits in das Host-Betriebssystem heruntergeladen haben, für das wir verschiedene Tools/Protokolle verwenden können, z. B. Proxy mit https cert/auth , oder vielleicht sogar etwas Torrent.

Als Problemumgehung müssen wir wget verwenden, um das Installationsprogramm während docker build erneut herunterzuladen, was eine stark eingeschränkte Umgebung ist, viel unbequemer, zeitaufwändiger und fehleranfälliger.

Auch aufgrund der Flexibilität der Produktinstallations-/Konfigurationsoptionen ist es für uns viel sinnvoller, die Images mit dem vorinstallierten Produkt zu versenden, anstatt nur ein Image mit dem Installationsprogramm zu versenden.

@thaJeztah irgendeine Chance, dass das passiert?

Fwiw, das ist der einzige Grund, warum ich Docker nicht verwende (oder wirklich nicht kann).

Wir führen einen Patch in Red Hat-Versionen von Docker, die die Option -v enthalten. Aber die wahre Lösung dafür wäre, neue und andere Möglichkeiten zum Erstellen von OCI-Container-Images als Docker-Build zu entwickeln.

@rhatdan RHEL oder Fedora?

Wir haben auch die Option -v von Docker Build in unserer internen Version von Docker auf resin.io implementiert. Sie finden den Unterschied hier https://github.com/resin-io/docker/commit/9d155107b06c7f96a8951cbbc18287eeab8f60cc

@rhatdan @petrosagg kannst du dafür eine PR erstellen?

@jeremyherbert Der Patch befindet sich im Docker-Daemon, der in allen neueren Versionen von RHEL, CentOS und Fedora enthalten ist ...

@graingert Wir haben es in der Vergangenheit eingereicht und es wurde abgelehnt.

@rhatdan hast du einen Link dazu?

@runcom Hast du den Link?

@thaJeztah , hättet ihr das abgelehnt?

Hier ist eine Liste bestehender Probleme, die geschlossen oder nicht beantwortet wurden:
https://github.com/docker/docker/issues/3949
https://github.com/docker/docker/issues/3156
https://github.com/docker/docker/issues/14251
https://github.com/docker/docker/issues/18603

Informationen zu den in RHEL/CentOS/Fedora verwendeten Project Atomic-Patches finden Sie unter:
http://www.projectatomic.io/blog/2016/08/docker-patches/

@daveisfera sieht so aus, als würden sie nur R-Volumes hinzufügen, keine RW-Volumes, daher funktioniert es nicht für @yngndrw und meinen Anwendungsfall.

@graingert Warum brauchst du RW-Volumes? Ich verstehe Read-only als Workaround für bestimmte Fälle.

Das Testen von Schemamigrationen wäre ein guter Grund ...

Am 01.11.2016 um 10:36 Uhr schrieb Brian Goff:

@graingert https://github.com/graingert Warum brauchen Sie RW-Volumes?
Ich verstehe Read-only als Workaround für bestimmte Fälle.


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/docker/docker/issues/14080#issuecomment -257582035,
oder den Thread stumm schalten
https://github.com/notifications/unsubscribe-auth/AAHLZdp0D6fAtuNglajPBIwnpWGq3slOks5q5050gaJpZM4FIdOc.

Scott McCarty

schott. [email protected]

http://crunchtools.com

@fatherlinux

@ cpuguy83 Ein weiterer Anwendungsfall für RW wäre ccache

@fatherlinux Ich bin mir nicht sicher, ob ich folge. Warum braucht man dafür ein Volumen? Warum muss dies auch während der Bauphase erfolgen?

Ich habe einen etwas anderen Anwendungsfall für diese Funktion – Zwischenspeichern von Paketen, die vom ASP.Net 5-Paketmanager heruntergeladen/aktualisiert werden. Der Paketmanager verwaltet seinen eigenen Cache-Ordner, also brauche ich letztendlich nur einen Ordner, den ich zwischen Builds wiederverwenden kann.

Ich würde zum Beispiel Mount binden:

docker build -v /home/jenkins/pythonapp/cache/pip:/root/.cache/pip  -t pythonapp .
docker build -v /home/jenkins/scalaapp/cache/ivy2:/root/.ivy2  -t scalaapp .

Denn es gibt viele Male, in denen eine Schemamigration durchgeführt werden muss
Die Software ist installiert. Wenn Sie schreibgeschützte Container ausführen, sollten Sie dies tun
Installieren Sie niemals Software, außer wenn Sie sich in der befinden
Bauphase.....

Am 01.11.2016 um 10:42 Uhr schrieb Brian Goff:

@fatherlinux https://github.com/fatherlinux Ich bin mir nicht sicher, ob ich folge.
Warum braucht man dafür ein Volumen? Auch warum muss es während getan werden
die Bauphase?


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/docker/docker/issues/14080#issuecomment -257583693,
oder den Thread stumm schalten
https://github.com/notifications/unsubscribe-auth/AAHLZfhBG8RUWtqPD-6RaLC7uoCNc-3nks5q50_TgaJpZM4FIdOc.

Scott McCarty

schott. [email protected]

http://crunchtools.com

@fatherlinux

Ich weiß, dass der Inhalt dieser Verzeichnisse nicht dazu führt, dass der Build vom Host abhängig ist (das Fehlen dieser Mounts führt dazu, dass der Build trotzdem funktioniert, nur langsamer).

NFS löste dies wie vor 30 Jahren ...

Am 01.11.2016 10:45 schrieb Thomas Grainger:

Ich weiß, dass der Inhalt dieser Verzeichnisse den Build nicht stoppen wird
idempotent oder hostabhängig zu sein (das Fehlen dieser Mounts führt zu
der Build funktioniert sowieso)


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/docker/docker/issues/14080#issuecomment -257584576,
oder den Thread stumm schalten
https://github.com/notifications/unsubscribe-auth/AAHLZS75Vq0BSEvUjI2oXORsS0el2mwOks5q51CQgaJpZM4FIdOc.

Scott McCarty

schott. [email protected]

http://crunchtools.com

@fatherlinux

NFS löste dies wie vor 30 Jahren ...

Kein hilfreicher Kommentar

@graingert Entschuldigung, das ist ernsthaft falsch rübergekommen. Ich habe versucht, zu schnell zu antworten, und habe nicht genug Kontext gegeben. Im Ernst, wir betrachten NFS in Kombination mit CRIO, um einige dieser Arten von Problemen zu lösen.

Sowohl Image Registry als auch Builds haben viele Eigenschaften gemeinsam. Worüber Sie sprechen, ist im Grunde ein Caching-Problem. NFS und insbesondere das eingebaute Caching können Builds hostunabhängig machen und das gesamte Caching für Sie erledigen.

Daher muss ein Build selbst mit einer Option -v Build Time nicht nur an einen Host gebunden sein. Es ist möglicherweise nicht unabhängig von der Internetskalierung, aber für viele Menschen, die ihre Build-Umgebung auf einen einzelnen Standort oder Standort kontrollieren, reicht es völlig aus.

@fatherlinux Ich würde Gitlab oder Travis Caching verwenden, um das Cache-Verzeichnis zu übernehmen und in S3 hoch-/herunterzuladen

@graingert ja, aber das funktioniert nur bei bestimmten Arten von Daten/Apps, auch nur auf Bucket-Ebene, nicht auf Posix-Metadaten und Blockebene. Für bestimmte Arten von Frontend- und Middleware-Apps kein Problem. Für eine Datenbankschemamigration müssen Sie im Voraus testen und den Cache aus Geschwindigkeitsgründen lokal haben, und er muss normalerweise posix sein.

Stellen Sie sich vor, ich hätte einen MySQL Galera-Cluster mit 1 TB Daten und möchte ein Upgrade durchführen, und sie befinden sich alle in Containern. Containerisierte/orchestrierte Galera mit mehreren Knoten und Sharding ist wirklich praktisch. Ich möchte nicht bei jedem Upgrade eine Schemamigration manuell testen müssen.

Ich möchte das Datenvolumen (pv in der Kube-Welt) schnappen, es einem Build-Server zur Verfügung stellen und dann das Upgrade und die Schemamigration testen. Wenn alles richtig funktioniert und die Tests bestanden sind, bauen wir die Produktionscontainer und lassen die Schemamigrationi in der Produktion passieren....

@graingert Entschuldigung, vergessen hinzuzufügen und dann den Snapshot zu verwerfen, der im Testlauf verwendet wurde ... Ich möchte ein Build- und Testereignis nicht separat orchestrieren, obwohl dies möglich wäre ...

@fatherlinux Ich denke, das ist ein orthogonaler Anwendungsfall ...

@graingert kein nützlicher Kommentar. Orthogonal zu was? Orthogonal zur Anfrage nach einem -v während des Builds, worum ging es mir in diesem Gespräch?

Es gibt ein paar verschiedene Verwendungen, die ich für diese Flagge sehe.

  • ein Cache, der zwischen Docker-Build-Servern geteilt wird
  • ein ADD-ähnliches Schlüsselwort, das nur „während des Builds“ einer einzelnen Dockerfile gilt. ZB eine riesige Datei HINZUFÜGEN, dann aus den Bildern ausschließen.
  • Ein ADD+RUN-ähnliches Schlüsselwort, das alle Ausgaben ignoriert. ZB eine riesige Datei HINZUFÜGEN, dann einen Schritt AUSFÜHREN und alle Änderungen am Bild ignorieren - HINZUFÜGEN+AUSFÜHREN in einem Schritt, dann eine Ebene überspringen.

Die letzten beiden Use Cases konnten mit zwei neuen Keywords sauberer gelöst werden.

BUILDCONSTFILE <path>

Würde vor jedem RUN ein COPY <path> ausführen und danach <path> aus dem Bild löschen.

TEST <cmd> WITH <paths>

Was die Pfade KOPIEREN, den Befehl ausführen und dann mit dem Exit-Status 0 den Build vom übergeordneten Image fortsetzen würde, andernfalls den Build anhalten würde

Persönlich denke ich, dass TEST ... WITH besser in einem anderen CI-Schritt gehandhabt wird, der Ihren Container als Ganzes testet

Lassen Sie mich das vorwegnehmen: Ich _denke_, dass ich damit einverstanden bin, --mount zum Bauen hinzuzufügen ("-v" wahrscheinlich nicht so sehr). Nicht 100% sicher bei der Implementierung, wie das Caching gehandhabt (oder nicht gehandhabt) wird usw.

Für das Docker-Projekt erstellen wir ein Builder-Image.
Es hat im Grunde alles, was wir brauchen, kopiert Code hinein, baut aber keinen eigentlichen Docker.
Wir haben ein Makefile , das dies orchestriert. Also make build das Image, make binary erstellt die Binärdatei mit build als Abhängigkeit usw.

Das Erstellen einer Binärdatei führt das Build-Image aus und führt den Build durch. Damit können wir das einhängen, was wir brauchen, einschließlich Paket-Caches für inkrementelle Builds.
Das meiste davon ist ziemlich geradlinig und leicht orchestrierbar.
Es gibt also sicherlich Möglichkeiten, diesen Fall heute zu handhaben, nur Docker allein kann nicht 100% davon bewältigen (und das ist nicht unbedingt eine schlechte Sache), und Sie müssen dies mit Ihrem CI-System zum Laufen bringen.

@ cpuguy83 Ich denke, das würde die meisten meiner Anwendungsfälle treffen. Nur damit ich es verstehe, meinst du --mount bedeutet schreibgeschützt? und -v zum Lesen/Schreiben?

@ cpuguy83 Wir bauen auch hauptsächlich "Builder" -Images, die IMHO zu einem immer häufigeren Muster werden ...

@fatherlinux swarm services und jetzt (für 1.13) docker run unterstützt --mount , was viel präziser und flexibler ist: https://docs.docker.com/engine/reference/commandline/service_create/# /add -bind-mounts-or-volumes

Sieht so aus, als ob in den Dokumenten der dritte Mount-Typ fehlt, tmpfs .

Ahh, sehr cool, danke...

Am 01.11.2016 14:20 schrieb Brian Goff:

@fatherlinux https://github.com/fatherlinux Schwarmdienste und jetzt
(für 1.13) |docker run| unterstützt |--mount| was viel genauer ist
und flexibel:
https://docs.docker.com/engine/reference/commandline/service_create/#/add -bind-mounts-or-volumes

Sieht so aus, als ob in den Dokumenten der dritte Mount-Typ, |tmpfs|, fehlt.


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/docker/docker/issues/14080#issuecomment -257648598,
oder den Thread stumm schalten
https://github.com/notifications/unsubscribe-auth/AAHLZXv_VBfVi4WUAjVijE-SKR0ErRC4ks5q54L2gaJpZM4FIdOc.

Scott McCarty

schott. [email protected]

http://crunchtools.com

@fatherlinux

@ cpuguy83 Wir verwenden auch häufig das Builder-Muster und benötigen Caching, das nicht im Bild beibehalten wird und auch die Invalidierung der Ebene überlebt.

Wir erstellen Yocto-Images und haben einen gemeinsam genutzten Sstate-Cache auf NFS-Speicher. Ein weiterer Anwendungsfall ist der npm-Cache, sodass Sie den gesamten RUN npm install -Layer ungültig machen, ihn aber aufgrund von zwischengespeicherten Paketen schneller neu berechnen können.

Könnte man als möglichen Kompromiss basierend auf dem Beitrag von @graingert nicht einen optionalen Hash Ihrer riesigen Datei in der Dockerdatei haben, und Docker überprüft dies dann, wenn der Build ausgeführt wird? Es gäbe dann keine Probleme mit deterministischen Builds, und es wäre für die Person, die Builds erstellt, offensichtlich, dass sie nicht über die erforderlichen Abhängigkeiten verfügen, anstatt dass sie irgendwann mit einem seltsamen Fehler explodieren. Das Gleiche gilt für SSH-Schlüssel usw., die ohnehin mit der Dockerdatei verteilt werden müssten.

Ich denke auch, dass jede Idee, die ein _Kopieren_ der riesigen Datei erfordert, alles andere als ideal ist. Dateigrößen, die ich verwenden möchte, liegen in der Größenordnung von 10-40 GB, und selbst mit einer guten SSD ist das Kopieren mindestens ein oder zwei Minuten wert. Das ist mein Problem mit der ADD-Direktive bereits im Docker; Ich möchte meinem Image nicht jedes Mal 30 GB HINZUFÜGEN, wenn es erstellt wird, und mich damit auseinandersetzen müssen, all diesen zusätzlichen freien Speicherplatz zu haben und Images zu squashen.

Das würde nicht funktionieren für das, wofür wir es verwenden. Wir haben ein Volume, das sstate-Caches aus dem yocto-Build-System enthält, das im Build bind-mounted RW ist, da jeder Cache-Fehlschlag während des Builds berechnet und für zukünftige Caches in sstate gespeichert wird. Unsere Verzeichnisse haben ebenfalls ~30 GB, sodass selbst die Berechnung des Hashs eine Weile dauern würde.

Ich habe das deterministische Build-Konzept nie verstanden. Es gibt Möglichkeiten, sich selbst mit der heutigen Semantik ins Knie zu schießen. Zum Beispiel können Sie etwas von einer internen IP curl . Plötzlich funktioniert dieses Dockerfile nicht überall und ist hostabhängig. Aber es gibt legitime Fälle, warum Sie das tun möchten. Zum Beispiel ein lokaler HTTP-Cache.

Da Builds also sowieso nicht deterministisch sind und man das Bind-Mounted-Volume heute über das Netzwerk emulieren kann, warum nicht eine native Möglichkeit bieten, dies mit den entsprechenden Warnungen zu tun, falls dies erforderlich ist?

@petrosagg @zrml @thaJeztah Was wir wissen ist:

  • Wenn wir #7115 #3156 durchforsten, finden wir eine lange Liste von Problemen, die viele Jahre alt sind und dasselbe Problem diskutieren
  • Die meisten wurden entweder aus Gründen der Reproduzierbarkeit geschlossen (oder der alte Dockerfile syntax is frozen -Kommentar, und dann, nachdem die HEALTHCHECK -Anweisung hinzugefügt wurde, wurde das Einfrieren entfernt, aber die Probleme blieben geschlossen).
  • Dieses Problem hat viele Teams viele Jahre davon abgehalten, eine gute Container-Usability/Produktivität in der täglichen Entwicklung zu haben. Wie @btrepp sagte, das ist die Hölle
  • Docker-Leute sind sich dieses Problems bewusst, aber dies würde eine Klasse von Oh, mein Docker-Build ist kaputt! Probleme wegen gemeinsam genutztem Cache, was nicht gut ist
  • Aber der Wechsel vom Disk-Cache zum Netzwerk-Cache scheint die Build-Zuverlässigkeit in keiner Weise zu verbessern, wirkt nur wie ein verherrlichter Cache-über-http, und es wurde festgestellt, dass es die Dinge verschlimmert (Herunterladen des Internets für jeden Build, HTTPS, Größe von Dateien, Disk-Thrashing beim Erstellen von Containern, Layer-Caching, komplizierte Build-Orchestrierung usw.)

Nach allem, was wir wissen, denke ich, dass dies wahrscheinlich entweder als Dupe oder WontFix geschlossen wird. Es scheint keine Rolle zu spielen, welche Anwendungsfälle wir angeben. Update: Ich bin froh, hier falsch zu liegen. Der Vorschlag sieht offen aus :)

Unser Unternehmen ist auf eine agnostische Container-Laufzeitumgebung umgestiegen und wird bald auch auf eine agnostische Image-Building-Erfahrung umsteigen müssen. Aber das ist nicht der richtige Ort, um darüber zu diskutieren, weil Negativität nicht hilft. Das sollte ein separater Beitrag werden.

@rdsubmöchtest du den Link teilen, wenn du fertig bist?

@rdsubhas das ist eine schöne Zusammenfassung. Es sieht nicht so aus, als würde dieser Thread als Dupe/Wontfix geschlossen, da @cpuguy83 denkt, dass er damit einverstanden ist, --mount während des Builds hinzuzufügen, was die meisten Anwendungsfälle abdeckt.

Was ich wissen möchte, ist, dass der aktuelle Vorschlag:

  1. ändert die Dockerfile-Syntax nicht
  2. macht Builds nicht hostabhängiger, als sie es derzeit sind

Welche Gegenargumente bleiben zu der Idee übrig? Wenn es keine gibt, sollten wir vielleicht anfangen, die Implementierungsdetails für den --mount -Mechanismus zu diskutieren.

Um das Argument zu untermauern, dass Builds bereits hostabhängig und nicht reproduzierbar sind, stelle ich eine Liste von Dockerfile-Fragmenten mit dieser Eigenschaft bereit:

# Install different software depending on the kernel version of the host
RUN wget http://example.com/$(uname -r)/some_resource
# example.intranet is only accessible from specific hosts
RUN wget http://example.intranet/some_resource
# get something from localhost
RUN wget http://localhost/some_resource
# gcc will enable optimizations supported by the host's CPU
RUN gcc -march=native .....
# node:latest changes as time goes by
FROM node
# ubuntu package lists change as time goes by
RUN apt-get update
# install different software depending on the docker storage driver
RUN if [ $(mount | head -n 1 | awk '{print $5}') == "zfs" ]; then .....; fi

Ehrlich gesagt, wenn wir einfach --mount hinzufügen und den Benutzer die Cache-Invalidierung ( --no-cache ) handhaben lassen, denke ich, dass wir in Ordnung sein werden. Wir möchten uns vielleicht eine feinkörnigere Cache-Steuerung von der CLI aus ansehen als alles oder nichts, aber das ist ein separates Thema.

Mein Anwendungsfall

Ich habe seit einiger Zeit ein ähnliches Problem, aber ich habe mich für die Vergrößerung des Bildes entschieden, bis eine Lösung gefunden ist. Ich werde versuchen, mein Szenario hier zu beschreiben, falls jemand eine bessere Problemumgehung findet.

Bedingungen

  1. CircleCI verfügt über die ssh-Schlüssel, um alle internen Abhängigkeiten während des Builds herunterzuladen
  2. GitHub hostet interne Abhängigkeiten und andere können während des Builds aus dem Image heruntergeladen werden

Optionen

  1. Verwenden Sie --build-arg , um während des Builds ein Token zu übergeben (dringend davon abgeraten). Dies ist eine sehr attraktive und einfache Option, da es ohne zusätzliche Schritte "einfach funktioniert".
  2. Laden Sie alle Abhängigkeiten herunter und fügen Sie sie dem Build-Kontext hinzu. Leider werden ADD und COPY in separaten Ebenen ausgeführt, sodass ich mit Daten aus früheren Ebenen feststecke.

Die Größe einiger meiner Bilder hat sich in einigen Fällen mehr als verdoppelt, aber die Gesamtgröße ist vorerst erträglich. Ich glaube, es gab einen PR (ich kann ihn anscheinend nicht finden), um Build-Zeit-Argumente aus dem Build-Verlauf zu entfernen, aber es war aufgrund von Caching-Bedenken irrc nicht akzeptabel.
Ich würde mich freuen, von anderen Problemumgehungen zu hören, die da draußen verwendet werden.

@misakwa Wir werden wahrscheinlich Secrets auf Build in 1.14 unterstützen.

Das ist sehr aufregend, @cpuguy83 zu hören. Ich werde ein Auge darauf haben, wann es veröffentlicht wird. Es wird definitiv einige meiner Arbeitsabläufe vereinfachen.

Wir werden wahrscheinlich Secrets auf Build in 1.14 unterstützen.

Funktioniert es auch für die Zuordnung von Build-Time-Zuordnungen anderer Arten von Volumes wie zum Beispiel yarn-cache ?

Übrigens gibt es eine interessante Möglichkeit, Produktionsimages mit docker-compose zu erstellen, ich fand es funktioniert und ziemlich effektiv:

Sie haben also eine Compose-Datei docker-compose.build.yml in etwa so:

services: 
  my-app:
    image: mhart/alpine-node:7.1.0
    container_name: my-app-build-container # to have fixed name
    volumes:
    - ${YARN_CACHE}:/root/.cache/yarn # attach yarn cache from host
    - ${HOME}/.ssh:/.ssh:ro    # attach secrets
    - ./:/source
    environment: # set any vars you need
     TEST_VAR: "some value"    
    ports:
    - "3000"
    working_dir: /app/my-app # set needed correct working dir even if if doesn't exist in container while build type
    command: sh /source/my-app.docker.build.sh # build script

1) Sie bauen Container mit Docker Compose:

$ docker-compose -f docker-compose.build.yml up --force-recreate my-app

Es erstellt einen Container und führt das Shell-Build-Skript my-app.docker.build.sh aus. Ich verwende Dockerfile nicht und mache alles im Build-Skript:

  • Installieren Sie die erforderlichen Betriebssystempakete
  • Kopieren Sie den benötigten Quellcode (aus dem zugeordneten Ordner /source )
  • Abhängigkeiten installieren
  • bei Bedarf bauen/kompilieren/testen
  • Entfernen Sie Pakete und Dinge, die nicht benötigt werden, damit die Zielumgebung funktioniert (um die endgültige Bildgröße zu reduzieren).

Dann erstellen Sie ein Image aus dem Container und ersetzen CMD dafür, dass es in der Zielumgebung ausgeführt werden muss:

docker commit -c "CMD npm run serve" my-app-build-container my-app-build-image:tag

Ihr Image ist also fertig, verwendet externen Garn-Cache und externe geheime Schlüssel, die nur während der Erstellungszeit verfügbar waren.

@whitecolor ja, das funktioniert :) außer einer Sache: docker build ist wirklich effektiv beim Hochladen des Build-Kontexts. Gemountete Quellvolumes funktionieren leider nicht mit Remote-Docker-Daemons (z. B. Docker-Maschine in der Cloud für Laptops mit geringer Leistung/Bandbreite). Dafür müssen wir umständliche docker run , docker cp , docker run usw. Serien von Docker-Befehlen ausführen und dann das endgültige Bild schnappen, aber es ist wirklich hackig.

Es ist wirklich hilfreich, dies offiziell als Teil des Docker-Builds zu haben und Layering und Build-Kontext zu verwenden 😄

@rdsubhas Ja, du hast Recht

@whitecolor Das ist eine wirklich einfache und effektive Lösung. Ich habe gerade einen 30-40-minütigen Aufbau eines Projekts auf etwa 5 Minuten verkürzt. Ich freue mich auf die Möglichkeit, eine --mount on build-Funktion zu haben, aber im Moment entsperrt diese Lösung meine Pipeline wirklich.

Dies ist ein Kommentar, den ich für Ausgabe Nr. 17745 hinterlassen habe, von dem ich gehört hatte, dass er geschlossen, aber nicht als Duplikat markiert wurde. Anscheinend habe ich mich in diesem letzten Punkt geirrt: Ich gebe zu, dass ich an Systeme wie Bugzilla gewöhnt bin, die etwas explizit als "BEHOBENES DUPLIKAT" markieren und dies im oberen Beschreibungsbereich eines Fehlers anzeigen. Ich bin kein Gedankenleser. (Also meine Entschuldigung @graingert , ich hatte wenig Ahnung, daher gibt es keinen Grund, mich in 20pt-Schriftart anzuschreien - das war übertrieben.)


In meinem Fall wäre dies auf Debian-Systemen nützlich: Mounten /var/cache/apt als Volume, damit Sie nicht immer wieder dieselben .deb-Dateien herunterladen. (Ein wirklich „unbegrenztes“ Internetkontingent existiert einfach nicht, besonders hier in Australien, und selbst wenn es eines gäbe, wird Zeit mit dem Warten auf den Download verschwendet.)

Oder ein anderes Szenario: Sie führen einen Build durch, aber es werden auch Testberichte wie Fehlerlisten und Codeabdeckungsberichte erstellt, die Sie nicht mit dem Image versenden müssen, die jedoch nützliche Artefakte sind, die Sie immer dabei haben sollten. Diese könnten auf ein Volume geschrieben werden, wenn ein CI-Server das Image erstellt, das der CI-Server abholen und hosten kann.

Oder ich mache heute Abend ein paar Gentoo-basierte Images für mich selbst, ich möchte /usr/portage vom Host mounten. Es ist für einen Dockerfile nicht schwer zu erkennen, "Hey, /usr/portage (im Container) ist leer, kein Problem, ich nehme das einfach", wenn er ohne gemountetes Volume läuft, ODER, es verwendet einfach das Volume so, wie es ist, und spart Zeit beim Abrufen einer neuen Kopie.

Das Hinzufügen dieser Smarts ist eine triviale if-Anweisung in einem Bourne-Shell-Skript … WENN die zugrunde liegende Logik zum Mounten des Volumes überhaupt vorhanden ist. Im Moment muss ich für meine Gentoo-Images jedes Mal /usr/portage ziehen, wenn ich einen Build mache (zum Glück ist der Spiegel in meinem LAN), was bedeutet, dass es ein paar Minuten dauert, bis dieser eine Schritt abgeschlossen ist.

Es gibt also viele Gründe, warum dies ein lohnender Vorschlag ist, und ich bezweifle, dass die in #7115 vorgeschlagenen verschachtelten Builds in den oben genannten Fällen helfen werden.


@whitecolor hat einen interessanten Ansatz, aber wenn ich das tue, könnte ich genauso gut ein Makefile verwenden, das vollständig außerhalb des Docker-Systems ist, um den Build zu erreichen.

@sjlongland Ich habe dich nicht angeschrien, ich habe einen großen „RESOLVED DUPLICATE“-Hinweis mehrfach ausgefüllt

Ich verwende Docker und Docker-Compose, um mehrere Container für unsere Infrastruktur zu erstellen. Die Container sind Microservices, meist in nodeJS geschrieben, aber es gibt einen Microservice, der in Java geschrieben ist und das Maven-Framework verwendet.
Jedes Mal, wenn wir den Java-Container neu erstellen, werden Dutzende von Abhängigkeiten von Maven heruntergeladen. dies dauert einige Minuten. Dann ist der Code in ca. 15 Sekunden aufgebaut.

Das ist sehr hässlich und wirkt sich ziemlich stark auf unsere CI-Strategie aus.

In diesem Szenario spielt es keine Rolle, ob das Volume mit den Build-Abhängigkeiten fehlt oder leer ist, da in diesem Fall die Abhängigkeiten heruntergeladen würden. Die Reproduzierbarkeit wird nicht beeinträchtigt.

Ich verstehe, dass es Sicherheitsbedenken gibt, weil ich die Abhängigkeiten manipulieren und dort bösen Code einfügen könnte; IMHO könnte dies leicht umgangen werden, indem nicht zugelassen wird, dass Images, die mit "Build-Volumes" erstellt wurden, auf Docker-Hub oder Docker-Store veröffentlicht werden.
Um dies anders auszudrücken, sollte zwischen der Unternehmensnutzung und der persönlichen Nutzung von Docker unterschieden werden.

@stepps check out https://pypi.python.org/pypi/shipwright statt docker-compose

Ich verfolge diesen Thread schon eine Weile und suche nach einer guten Lösung für mich. Um minimale Container flexibel und mit minimalem Aufwand zu bauen, gefällt mir https://github.com/edannenberg/gentoo-bb von @edannenberg sehr gut.

  • Es trennt Build-Zeit-Abhängigkeiten von Laufzeit-Abhängigkeiten
  • Builds werden in Containern erstellt und sind isoliert, sauber und wiederholbar
  • Behandelt Abhängigkeiten zwischen Images und Build-Reihenfolge

Es basiert auf der Verwendung von Gentoos Portage und emerge, also @sjlongland Sie mögen es vielleicht für Ihre Gentoo-basierten Bilder. Dist-Dateien und Binärpakete werden zwischengespeichert, sodass sie nicht erneut heruntergeladen oder erstellt werden müssen, wodurch die Neuerstellung schnell erfolgt. Es hat Hooks, um den Build-Prozess einfach anzupassen. Die Installation von Software von Drittanbietern ist einfach, z. B. die Verwendung von Git zum Klonen eines Repos und das anschließende Erstellen, wobei nur der Build im endgültigen Image beibehalten wird. Es erstellt die Dockerfile-Vorlage.

Ein einfaches Beispiel für figlet ist: -

build.conf:

IMAGE_PARENT="gentoobb/glibc"

Dockerfile.template:

FROM ${IMAGE_PARENT}
ADD rootfs.tar /
USER figlet
CMD ["gentoo-bb"]
ENTRYPOINT ["figlet"]

buildd.sh

PACKAGES="app-misc/figlet"

configure_rootfs_build() {
        useradd figlet
}

Ich mag die Lösung von @whitecolor , es ist einfach, nur die Docker-Technologie und dann ein einfaches Shell-Skript oder alles andere zu verwenden, was Sie verwenden möchten. Ich verwende gentoo-bb, da es vollständiger ist. Shipwright sieht gut aus mit mehr auf Entwickler ausgerichteten Funktionen wie dem Umgang mit Zweigen. https://github.com/grammarly/rocker scheint auch interessant zu sein. Danke fürs Teilen.

Nur eine weitere Stimme, die dem Stapel hinzugefügt wurde. Unsere sehr komplexe Entwicklungsumgebung wäre erheblich einfacher, wenn wir lokale Volumes beim Build mounten könnten.

Eine Problemumgehung besteht darin, während eines Builds einen HTTP-Server auszuführen, der die lokalen Dateien verfügbar macht, und dann curl/wget usw. zu verwenden, um die Dateien in den Docker-Build zu bringen. Aber ich wünschte wirklich, solche Hacks wären unnötig.

Ein weiterer Anwendungsfall. Ich möchte Docker-Images zum Erstellen eines proprietären Betriebssystems erstellen, das aus 10 verschiedenen Versionen besteht. Das Installationsmedium ist >80 GB groß, daher kann ich es nicht einfach in die Docker-Build-Umgebung kopieren. Eine Bindungshalterung wäre viel besser.

Noch eins: Meine Projektnutzung verteilt Dockerfiles im Repository zum Bauen aus Quellen im Container. Derzeit ziehen wir einen weiteren Git-Klon in den Container von GitHub. Es gibt flache Klone und alles, aber trotzdem ...

Also habe ich gerade [1] auf einem rhel7-Build-Host getestet, und Red Hats Build des Docker-Daemons hat die Option -v für Build. Ich habe es nicht auf CentOS/Fedora getestet, aber man könnte sich vorstellen, dass Fedora/CentOS es wahrscheinlich auch hat. Es lohnt sich zu testen. Außerdem sind RHEL-Entwicklerabonnements jetzt kostenlos [2]:

@fatherlinux Unter Fedora ist auch `docker build -v' verfügbar.

@fatherlinux Die CentOS 7-Version enthält es.

+1 Ich denke, dies wäre eine wirklich nützliche Funktion, die dem offiziellen Docker hinzugefügt werden könnte.

Gerade auf Centos und Linuxmint aktualisiert (jetzt läuft 17.03.1-ce), fehlt mir hier etwas? Ich kann die Option -v nicht sehen

Auf Minze

$ docker build --help

Usage:  docker build [OPTIONS] PATH | URL | -

Build an image from a Dockerfile

Options:
      --build-arg list             Set build-time variables (default [])
      --cache-from stringSlice     Images to consider as cache sources
      --cgroup-parent string       Optional parent cgroup for the container
      --compress                   Compress the build context using gzip
      --cpu-period int             Limit the CPU CFS (Completely Fair Scheduler) period
      --cpu-quota int              Limit the CPU CFS (Completely Fair Scheduler) quota
  -c, --cpu-shares int             CPU shares (relative weight)
      --cpuset-cpus string         CPUs in which to allow execution (0-3, 0,1)
      --cpuset-mems string         MEMs in which to allow execution (0-3, 0,1)
      --disable-content-trust      Skip image verification (default true)
  -f, --file string                Name of the Dockerfile (Default is 'PATH/Dockerfile')
      --force-rm                   Always remove intermediate containers
      --help                       Print usage
      --isolation string           Container isolation technology
      --label list                 Set metadata for an image (default [])
  -m, --memory string              Memory limit
      --memory-swap string         Swap limit equal to memory plus swap: '-1' to enable unlimited swap
      --network string             Set the networking mode for the RUN instructions during build (default "default")
      --no-cache                   Do not use cache when building the image
      --pull                       Always attempt to pull a newer version of the image
  -q, --quiet                      Suppress the build output and print image ID on success
      --rm                         Remove intermediate containers after a successful build (default true)
      --security-opt stringSlice   Security options
      --shm-size string            Size of /dev/shm, default value is 64MB
  -t, --tag list                   Name and optionally a tag in the 'name:tag' format (default [])
      --ulimit ulimit              Ulimit options (default [])
$ cat /etc/lsb-release 
DISTRIB_ID=LinuxMint
DISTRIB_RELEASE=18
DISTRIB_CODENAME=sarah
DISTRIB_DESCRIPTION="Linux Mint 18 Sarah"
$ docker version
Client:
 Version:      17.03.1-ce
 API version:  1.27
 Go version:   go1.7.5
 Git commit:   c6d412e
 Built:        Fri Mar 24 00:45:26 2017
 OS/Arch:      linux/amd64

Server:
 Version:      17.03.1-ce
 API version:  1.27 (minimum version 1.12)
 Go version:   go1.7.5
 Git commit:   c6d412e
 Built:        Fri Mar 24 00:45:26 2017
 OS/Arch:      linux/amd64
 Experimental: false

Auf Centos 7

# docker build --help

Usage:  docker build [OPTIONS] PATH | URL | -

Build an image from a Dockerfile

Options:
      --build-arg list             Set build-time variables (default [])
      --cache-from stringSlice     Images to consider as cache sources
      --cgroup-parent string       Optional parent cgroup for the container
      --compress                   Compress the build context using gzip
      --cpu-period int             Limit the CPU CFS (Completely Fair Scheduler) period
      --cpu-quota int              Limit the CPU CFS (Completely Fair Scheduler) quota
  -c, --cpu-shares int             CPU shares (relative weight)
      --cpuset-cpus string         CPUs in which to allow execution (0-3, 0,1)
      --cpuset-mems string         MEMs in which to allow execution (0-3, 0,1)
      --disable-content-trust      Skip image verification (default true)
  -f, --file string                Name of the Dockerfile (Default is 'PATH/Dockerfile')
      --force-rm                   Always remove intermediate containers
      --help                       Print usage
      --isolation string           Container isolation technology
      --label list                 Set metadata for an image (default [])
  -m, --memory string              Memory limit
      --memory-swap string         Swap limit equal to memory plus swap: '-1' to enable unlimited swap
      --network string             Set the networking mode for the RUN instructions during build (default "default")
      --no-cache                   Do not use cache when building the image
      --pull                       Always attempt to pull a newer version of the image
  -q, --quiet                      Suppress the build output and print image ID on success
      --rm                         Remove intermediate containers after a successful build (default true)
      --security-opt stringSlice   Security options
      --shm-size string            Size of /dev/shm, default value is 64MB
  -t, --tag list                   Name and optionally a tag in the 'name:tag' format (default [])
      --ulimit ulimit              Ulimit options (default [])
# docker version
Client:
 Version:      17.03.1-ce
 API version:  1.27
 Go version:   go1.7.5
 Git commit:   c6d412e
 Built:        Mon Mar 27 17:05:44 2017
 OS/Arch:      linux/amd64
# cat /etc/centos-release
CentOS Linux release 7.3.1611 (Core) 

@wilfriedroset In CentOS 7 bieten die nicht offiziellen Docker-Pakete die Option. Ich denke, es ist Teil des EPEL-Repositorys.

danke @nathanjackson. Haben wir eine ETA für diese Funktion in der offiziellen Version?

@wilfriedroset AFAIK , es gibt KEINE ETA, weil (mehrmals) entschieden wurde, dass diese Funktion nicht im offiziellen Docker sein sollte, um die "Build-Portabilität" zu bewahren. aka ermöglichen, dass Ihre Dockerfiles überall ausgeführt werden, einschließlich des Docker-Build-Service.

Meiner Erfahrung nach ist eine begrenzte Build-Portabilität das, was Kunden wirklich wollen. Sie möchten eine Build-Umgebung/Farm einrichten und sicherstellen, dass Builds in dieser Umgebung immer neu erstellt werden können. Die Build-Option -v verhindert dies in keiner Weise.

Wenn Sie beispielsweise NFS-Mounts verwenden, stellen Sie einfach sicher, dass alle Build-Server diesen Mount in ihren fstabs haben und Ihr Build überall in der Farm ohne Probleme abgeschlossen wird.

Auf RHEL 7.3
````
[ root@rhel7 ~]# docker build --help

Verwendung: Docker-Build [OPTIONEN] PFAD | URL | -

Erstellen Sie ein Image aus einer Dockerfile

Optionen:
--build-arg value Legt Build-Time-Variablen fest (Standard [])
--cgroup-parent Zeichenfolge Optionale übergeordnete Kontrollgruppe für den Container
--cpu-period int Begrenzt die CPU-CFS-Periode (Completely Fair Scheduler).
--cpu-quota int Begrenzt die CPU-CFS-Quote (Completely Fair Scheduler).
-c, --cpu-shares int CPU-Anteile (relatives Gewicht)
--cpuset-cpus Zeichenfolge CPUs, in denen die Ausführung zugelassen werden soll (0-3, 0,1)
--cpuset-mems Zeichenfolge MEMs, in denen die Ausführung zugelassen werden soll (0-3, 0,1)
--disable-content-trust Bildüberprüfung überspringen (standardmäßig wahr)
-f, --file string Name der Dockerdatei (Standard ist 'PATH/Dockerfile')
--force-rm Zwischenbehälter immer entfernen
--help Drucknutzung
--isolation string Container-Isolationstechnologie
--label value Setze Metadaten für ein Bild (Standard [])
-m, --memory string Speicherbegrenzung
--memory-swap string Swap-Grenze gleich Speicher plus Swap: '-1', um unbegrenztes Swap zu ermöglichen
--no-cache Verwende keinen Cache beim Erstellen des Images
--pull Immer versuchen, eine neuere Version des Bildes zu ziehen
-q, --quiet Unterdrückt die Build-Ausgabe und gibt bei Erfolg die Bild-ID aus
--rm Zwischencontainer nach erfolgreichem Build entfernen (standardmäßig wahr)
--shm-size Zeichenfolge Größe von /dev/shm, Standardwert ist 64 MB
-t, --tag Wert Name und optional ein Tag im ' Name:Tag '-Format (Standard [])
--ulimit Wert Ulimit-Optionen (Standard [])
-v, --volume Wert Build-Time-Bind-Mounts festlegen (Standard [])
```

Ein weiterer Anwendungsfall bei Knotenprojekten zur CI-Erstellung ist die gemeinsame Nutzung des yarn -Cache des CI beim Erstellen aller Bilder.

+1: immer wieder node_modules zu installieren ist wirklich schrecklich, besonders für nodejs-Mikrodienste
Ich versuche, dieses Problem mit nfs zu lösen, ich denke, "wiederholbar" ist kein guter Grund, diese Funktion nicht zu implementieren ...

Dies scheint noch wichtiger zu werden, wenn # 31257 und # 32063 zusammengeführt werden.

Schauen Sie sich #32507 an

@fatherlinux könnten Sie erklären, wie die Build-Portabilität funktioniert, wenn Sie COPY-Befehle in der Dockerfile haben können? Ich habe ein Problem, bei dem ich die Anzahl der Kopien einer großen Datei (aus Gründen der Zeitkomplexität) vermeiden möchte und nach einer schreibgeschützten Option zur Erstellungszeit suche, um die Datei mit dem Container zu teilen.

@arunmk @cpuguy83 genau. Die Idee ist, dass Sie beim Build wirklich keine Daten in den Container KOPIEREN möchten. Das kann es sehr groß machen. Wir wollen nur, dass die Daten zur Build-Zeit verfügbar sind. Wie oben beschrieben, können Sie in Red Hats Version des Docker-Daemons ein -v bind mounten, mit dem Sie Daten verfügbar haben, aber im Moment sind sie nur lesbar (habe mich letzte Woche verbrannt).

Also, wenn Sie es heute brauchen, schauen Sie sich Fedora, CentOS oder RHEL an und Sie können eine schreibgeschützte Kopie der Daten zur Build-Zeit einhängen ...

Und wenn Sie Portabilität innerhalb einer Build-Farm benötigen, würde ich NFS oder ähnliches vorschlagen ....

Wenn Sie es nicht kopieren, sondern nur im endgültigen Image haben möchten, können Sie mehrstufige Builds verwenden, um dies zu handhaben.

Ein erfundenes Beispiel:

FROM fatImage AS build
COPY bigData /data
RUN some_stoff /data

FROM tinyImage
COPY --from=build /data/result

Danke für die Klarstellung @fatherlinux
@ cpuguy83 danke für die Details. Lassen Sie mich meinem Problem, das ungewöhnlich sein kann, weitere Details hinzufügen: Ich habe ein Build-System, das eine 3,3-GB-Datei generiert. Das wird zu einem RPM hinzugefügt, das in einem Docker-Container eingebaut ist. Es werden also zwei Kopien erstellt: eine aus dem Build-System in den Docker-Container, eine aus dem Docker-Container in das RPM. Jetzt komme ich um die zweite Kopie nicht herum. Ich dachte daran, die erste Kopie zu vermeiden, aber es sieht so aus, als wäre das auch nicht möglich, selbst bei den mehrstufigen Builds.
Ich kann verstehen, dass bei wiederholter Verwendung der großen Datei die mehrstufige Kopie die Anzahl der Kopiervorgänge auf '1' reduziert hätte. Ich benutze es einmal und wollte die Zahl auf '0' reduzieren. Sehe ich das richtig, dass das nicht möglich sein wird?

@arunmk Egal, was es vom Client in die Build-Instanz kopieren muss.

@ cpuguy83 danke für die Klarstellung. Sieht so aus, als müsste ich jetzt den Overhead übernehmen. Soll das Atomarität haben?

@fatherlinux

Ich habe versucht, was Sie gesagt haben, indem ich -v auf RHEL7 verwendet habe, um zu versuchen, ein Verzeichnis während des Builds schreibgeschützt zu mounten, aber ich bekomme diesen Fehler:

Volumes werden im Docker-Build nicht unterstützt. Bitte verwenden Sie nur Bindungshalterungen.

Dies funktioniert nur mit dem Docker-Paket von RHEL, nicht mit dem von Docker. Patch wurde vom Upstream nicht akzeptiert.

@fatherlinux

Ich habe versucht, was Sie gesagt haben, indem ich -v auf RHEL7 verwendet habe, um zu versuchen, ein Verzeichnis während des Builds schreibgeschützt zu mounten, aber ich bekomme diesen Fehler:

Volumes werden im Docker-Build nicht unterstützt. Bitte verwenden Sie nur Bindungshalterungen.

@fcntl

Sie müssen Bindungen verwenden, wie der Fehler sagte, Sie haben wahrscheinlich -v /something anstelle von /hostsomething:/containersomething verwendet

@thebigb und vielleicht andere, wir haben eine Infrastruktur eingerichtet, um Ccache während des Docker-Builds verwenden zu können. Wir haben es unter https://github.com/WebHare/ccache-memcached-server veröffentlicht, wenn es Ihnen hilft, obwohl eine ideale Lösung dieses Problems es wahrscheinlich überflüssig machen würde.

Ich wollte gerade hinzufügen, ein Anwendungsfall, für den ich das wirklich brauche, ist Ccache. Ich möchte in der Lage sein, meinen Ccache-Cache während eines Docker-Image-Builds bereitzustellen - es macht keinen Sinn, dass es im Image selbst enthalten ist. @unilynx Ich werde mir deine Problemumgehung ansehen - gutes Timing!

Nur eine andere Stimme.

Mein Anwendungsfall: Derzeit verwende ich den Befehl MOUNT rocker , um die Verzeichnisse /root/.cache und /var/cache/apk freizugeben.

Aus irgendeinem Grund habe ich einen sehr (sehr, sehr) langsamen Netzwerkzugriff auf apk-Pakete und Pip-Pakete. Jeder Umbau macht den Vorgang unglaublich zeitaufwändig. Es macht die Dinge viel einfacher mit dieser Build-Time-Funktion MOUNT .

@embray @roxma schau dir https://github.com/moby/moby/issues/32507 an, wenn das deinen Anwendungsfall ansprechen würde; Feedback willkommen

Mit der Einführung von mehrstufigen Builds halte ich die Notwendigkeit, einen Volume-Mount für den lokalen Cache von Maven anzugeben, für kritisch.

@gim913 So nehmen Sie nicht an einer Community teil. Wenn Sie einen Beitrag leisten möchten, überprüfen Sie bitte die hier verlinkten vorhandenen Vorschläge, um festzustellen, ob einer von ihnen Ihren Anwendungsfall löst.

@ gim913 In dieser Phase der Docker-Integration in verschiedene Distributionen scheint das Ändern von Umgebungen (dh das vollständige Löschen von Docker) viel störender zu sein als das Ändern Ihres "Betriebssystems" (ich nehme an, Sie meinen den Wechsel von einer anderen Linux-Distribution zum RedHat-Build, der anscheinend enthalten ist -v? )

Wäre es nicht einfacher, einfach die Docker-Version von RedHat zu nehmen? Vielleicht kann Sie jemand hier auf die relevanten Patches/Forks/Commits hinweisen, um die Option „-v“ im Build zu erhalten.

@unilynx bitte schön

Ich habe mir einige Beispiele angesehen, die wget verwendet haben, und bin hierher gekommen ... mein Anwendungsfall ist ähnlich ... Ich möchte einen großen Tarball entpacken und ihn einfach ausführen. Ich möchte die Docker-Datei nicht mit dem Tarball verunreinigen oder Zeit mit einem wget von einem lokalen Webserver verschwenden. Das Mounten, wie Sie es mit Docker Compose tun können, scheint eine vernünftige Sache zur Build-Zeit zu sein. Bitte führen Sie die Änderung von Puneeth zusammen, wenn sie in Ordnung aussieht :-)

Ich kompiliere Python-Räder vor und möchte diese im Container installieren, ohne sie zu kopieren und eine Ebene zu erstellen, die ich wirklich nicht brauche, oder irgendwie versuchen muss, sie zu quetschen. Tag 1 und ich schaue bereits in rocker 😢 😢 😢

Dies wäre einfach hinzuzufügen und äußerst nützlich (oder ein Mount-Befehl, siehe noch einmal rocker ). Wie viel Zeit wird (in der Community) damit verbracht, Skripte um diese oder ähnliche fehlende Funktionen herum zu schreiben?

@awbacker Multi-stag build löst das ziemlich gut, wo man so etwas machen kann

FROM something AS my_wheels
RUN compile_all_the_things

FROM something
COPY --from my_wheels /wherever
RUN do_stuff_with_wheels

Der erste Teil wird nur ausgeführt, wenn sich etwas ändert. Der Cache dafür kann auch mit anderen Builds/Dockerfiles geteilt werden.
Dies macht den gesamten Aufbau in sich abgeschlossen.

Es gibt auch einen Vorschlag, der RUN --mount erlauben würde, wo die Mount-Spezifikation es anweisen würde, ein Ding aus dem my_wheels -Build-Target zu mounten, anstatt es zu kopieren.

Wie bei @kenyee könnte dies etwas aus dem Build-Kontext bereitstellen, das in 17.07-experimental nur bei Bedarf inkrementell gesendet wird.

@ cpuguy83 Das funktioniert in der Praxis nicht - zumindest für Gradle Java-Builds. Ich habe ein Basis-Docker-Image, in dem die Gradle-Jar-Dateien vorab zwischengespeichert sind, aber der Gradle-Build Ihrer Quelle löst den Download aller Ihrer Abhängigkeiten in den Cache aus.

@ cpuguy83 mehrstufig erlaubt es nicht, kopierte Räder aus dem resultierenden Bild zu entfernen, davon spricht @awbacker . Daher wird der Inhalt im /wherever-Ordner zwischengespeichert und die Bildgröße erhöht.

@BryanHunt Ein Teil Ihres Build-Prozesses besteht also darin, die Deps herunterzuladen? Sicherlich muss Gradle eine Möglichkeit bieten, diese zwischenzuspeichern, ohne sie zu durchlaufen und tatsächlich zu bauen?

@cpuguy83 Ja , Deps werden als Teil des Builds heruntergeladen. Im Grunde das gleiche wie Maven. Als Referenz: https://github.com/gradle/gradle/issues/1049

Gab es irgendwo eine PR für Build Mounts?

@graingert Hier

👍 dafür. Bei Lunar Way möchten wir den vollständigen „Build -> Test -> Build Production Image“-Prozess in einem einzigen Docker-Build durchführen, um Build- und Testabhängigkeiten vom CI-Server zu entfernen. Bei mehrstufigen Builds können wir dies tun, aber wir können die Testergebnisse nicht aus dem Zwischencontainer im Build-Prozess holen. Wir müssen es daher jetzt in zwei Schritten tun - mit einem separaten Dockerfile zum Erstellen des Testimages, Ausführen dieses und dann nur mit dem Schritt zum Erstellen des Prod-Images fortfahren, wenn die Tests erfolgreich sind.

Eine Option -v beim Docker-Build würde es uns ermöglichen, die Testergebnisse in einem Ordner zu speichern, der vom CI-Server bereitgestellt wird, und den aktuellen 2-Schritte-Prozess überflüssig machen.

@tbflw Standardmäßig entfernt Docker-Build keine Zwischencontainer nach einem erfolglosen Build. Wenn also ein Test fehlschlägt, können Sie die Testergebnisse von diesen abrufen.

Bitte , wir brauchen diese Funktion auch wirklich! Der Rückgriff auf andere Tools wie Rocker oder Forking Docker mit Ad-hoc-Patches ist bei weitem hässlicher, als die evangelische Vorstellung von „Build-Portabilität“ zu brechen.

@BryanHunt @stepps @yngndrw andere auch @awhitford
Eine Möglichkeit, Build-Abhängigkeiten zwischenzuspeichern, besteht darin, Ihren Build wie das mehrstufige Go-Build-Beispiel in der Dokumentation oder das python onbuild Dockerfile funktionieren zu lassen .
Hier ist ein Beispiel, das ich gemacht habe und das für maven zu funktionieren scheint. Ich kopiere es hierher.

FROM maven
WORKDIR /usr/src/app
# /root/.m2 is a volume :(
ENV MAVEN_OPTS=-Dmaven.repo.local=../m2repo/
COPY pom.xml .
# v2.8 doesn't work :(
RUN mvn -B -e -C -T 1C org.apache.maven.plugins:maven-dependency-plugin:3.0.2:go-offline
COPY . .
RUN mvn -B -e -o -T 1C verify

FROM openjdk
COPY --from=0 /usr/src/app/target/*.jar ./

Es muss so eingerichtet werden, dass es Abhängigkeiten herunterlädt, bevor es den Rest der Codebasis hineinkopiert. Stellen Sie außerdem sicher, dass sich der Ort, an dem Ihre Artefakte gespeichert werden, nicht in einem VOLUME befindet .

@sixcorners Das funktioniert nicht für Gradle

@BryanHunt Dieses Dockerfile oder dieser Ansatz funktioniert nicht für Gradle? cpuguy83 fragte, ob es eine Möglichkeit gebe, Abhängigkeiten herunterzuladen, ohne tatsächlich einen Build durchzuführen. Sie haben eine Verknüpfung mit einer Aufgabe zum Auflösen von Abhängigkeiten hergestellt. Könnten Sie nicht einfach die Datei build.gradle hinzufügen und diese Aufgabe ausführen?

@sixcorners Wenn Sie viele Module haben, müssen Sie Ihre Verzeichnisstruktur zusammen mit den Build-Dateien und Eigenschaftendateien replizieren. Ich nehme an, es könnte getan werden, aber ich sehe dies als sehr fehleranfällig.

Das Multistage von @sixcorners ist ein interessanter Trick und ich habe gesehen, dass es für verschiedene Paketmanager verwendet wird (z. B. npm, composer).

Es gibt jedoch ein Problem, wenn die Liste der Abhängigkeiten geändert wird COPY pom.xml im Bild der Stufe 0 führt dazu, dass die Ebene ausgeworfen wird und somit der gesamte Cache weg ist. Das bedeutete, dass immer dann, wenn ein Entwickler etwas im Pom ändert (ein Kommentar, eine 1-kByte-Abhängigkeit), der gesamte Cache erneut heruntergeladen werden musste.

Für CI-Maschinen, die das Image erstellen und dann die Tests mit Abhängigkeiten ausführen, die sich ständig ändern, bedeutet dies Tausende und Abertausende von Paketen, die erneut heruntergeladen werden müssen (entweder von einem Proxy oder von Upstream) und die Neuerstellung ziemlich langsam machen. Ein lokaler dateibasierter Cache, der als Volume bereitgestellt wird, ist viel schneller.

Das ist auch ein Problem, wenn Entwickler den Build eines Images iterieren, insbesondere wenn sie langsame Verbindungen haben. Man kann zwar eine lokale Nexus-Instanz und http_proxy dafür einrichten, aber das hat andere Nebeneffekte (z. B. das Kanalisieren einer HTTP-Anfrage über Nexus).

Multistage ist eine nette Problemumgehung, aber es ist nicht ideal.

Eine Lösung, die wir versuchen werden, besteht darin, ein Image zu erstellen, indem wir unsere gemeinsam genutzten Bibliotheken erstellen und den Abhängigkeits-Cache beibehalten. Dieses Image würde dann unser Build-Image für unsere Apps werden. Es ist nicht ideal, aber wir denken, es ist einen Versuch wert.

Es gibt jedoch ein Problem, wenn COPY pom.xml im Image der Phase 0 die Liste der Abhängigkeiten ändert, was dazu führt, dass die Ebene ausgeworfen wird und somit der gesamte Cache weg ist. Das bedeutete, dass immer dann, wenn ein Entwickler etwas im Pom ändert (ein Kommentar, eine 1-kByte-Abhängigkeit), der gesamte Cache erneut heruntergeladen werden musste.

@hashar Beachten Sie, dass die Funktion COPY --from nicht auf Build-Phasen beschränkt ist; aus der Dockerfile-Referenz :

Optional akzeptiert COPY ein Flag --from=<name|index> , das verwendet werden kann, um den Quellspeicherort auf eine vorherige Build-Stufe (erstellt mit FROM .. AS <name> ) festzulegen, die anstelle eines gesendeten Build-Kontexts verwendet wird durch den Benutzer. Das Flag akzeptiert auch einen numerischen Index, der allen vorherigen Build-Stufen zugewiesen wurde, die mit der Anweisung FROM gestartet wurden. _ Falls eine Build-Stufe mit einem angegebenen Namen nicht gefunden werden kann, wird versucht, stattdessen ein Image mit demselben Namen zu verwenden. _

Auf diese Weise können Sie ein Image für Ihre Abhängigkeiten _erstellen_, es taggen und es zum Kopieren Ihrer Abhängigkeiten verwenden. Zum Beispiel:

FROM maven
WORKDIR /usr/src/app
# /root/.m2 is a volume :(
ENV MAVEN_OPTS=-Dmaven.repo.local=../m2repo/
COPY pom.xml .
# v2.8 doesn't work :(
RUN mvn -B -e -C -T 1C org.apache.maven.plugins:maven-dependency-plugin:3.0.2:go-offline
COPY . .
RUN mvn -B -e -o -T 1C verify
docker build -t dependencies:1.0.0 .

Und geben Sie die Verwendung des Bildes dependencies:1.0.0 für Ihre Abhängigkeiten an;

FROM openjdk
COPY --from=dependencies:1.0.0 /usr/src/app/target/*.jar ./

Oder (nur ein sehr einfaches Beispiel zum Testen);

$ mkdir example && cd example
$ touch dep-one.jar dep-two.jar dep-three.jar

$ docker build -t dependencies:1.0.0 . -f -<<'EOF'
FROM scratch
COPY . /usr/src/app/target/
EOF

$ docker build -t myimage -<<'EOF'
FROM busybox
RUN mkdir /foo
COPY --from=dependencies:1.0.0 /usr/src/app/target/*.jar /foo/
RUN ls -la /foo/
EOF

In der Ausgabe des Builds sehen Sie:

Step 4/4 : RUN ls -la /foo/
 ---> Running in 012a8dbef91d
total 8
drwxr-xr-x    1 root     root          4096 Oct  7 13:27 .
drwxr-xr-x    1 root     root          4096 Oct  7 13:27 ..
-rw-r--r--    1 root     root             0 Oct  7 13:26 dep-one.jar
-rw-r--r--    1 root     root             0 Oct  7 13:26 dep-three.jar
-rw-r--r--    1 root     root             0 Oct  7 13:26 dep-two.jar
 ---> 71fc7f4b8802

Ich weiß nicht, ob jemand diesen Anwendungsfall schon erwähnt hat (ich habe die Seite kurz durchsucht), aber das Einhängen eines SSH-Authentifizierungs-Sockets in den Build-Container würde die Verwendung von Abhängigkeiten, die über private Git-Repositories bereitgestellt werden, viel einfacher machen. Es wäre weniger erforderlich, Boilerplates in der Docker-Datei zu kopieren, um Schlüssel in nicht endgültigen Build-Phasen usw. zu kopieren.

buildkit bietet native Unterstützung für git
https://github.com/moby/buildkit

Lösen.
Erstellen Sie ein Bash-Skript (~/bin/docker-compose oder ähnliches):

#!/bin/bash

trap 'kill $(jobs -p)' EXIT
socat TCP-LISTEN:56789,reuseaddr,fork UNIX-CLIENT:${SSH_AUTH_SOCK} &

/usr/bin/docker-compose $@

Und in Dockerfile mit socat:

...
ENV SSH_AUTH_SOCK /tmp/auth.sock
...
  && apk add --no-cache socat openssh \
  && /bin/sh -c "socat -v UNIX-LISTEN:${SSH_AUTH_SOCK},unlink-early,mode=777,fork TCP:172.22.1.11:56789 &> /dev/null &" \
  && bundle install \
...
or any other ssh commands will works

Führen Sie dann docker-compose build aus

Um einen weiteren Anwendungsfall auf den Haufen zu werfen. Ich verwende Docker für Windows, um ein Dateisystem zum Erstellen eines eingebetteten Linux-Systems in einem Container zu generieren, und ich möchte dies während ihres Erstellungsschritts mit anderen Containern teilen. Ich interagiere mit diesem Container, der die Konfiguration ändert und neu erstellt usw., sodass das Ausführen des Builds in einer Docker-Datei und die Verwendung von mehrstufigen Builds nicht wirklich gut passt, da ich inkrementelle Builds verlieren würde. Ich möchte meine vorherigen Build-Artefakte zwischenspeichern, da ein sauberer Build etwa 1,5 Stunden dauert. Aufgrund der Art und Weise, wie Windows mit symbolischen Links umgeht, kann ich meinen Build nicht in ein vom Host bereitgestelltes Volume ausführen, daher verwende ich benannte Volumes. Idealerweise möchte ich diese benannten Volumes in den Build-Schritten meiner anderen Images freigeben; Im Moment muss ich ein Tar der Build-Ausgabe (ca. 4 GB) erstellen und dann eine Docker-Kopie erstellen, um sie für nachfolgende Builds auf dem Windows-Host verfügbar zu machen.

Im Falle von Python, wenn wir pip install package es und seine Abhängigkeiten in einen Cache-Ordner herunterladen und dann in Site-Packages installieren.
Als bewährte Methode verwenden wir pip --no-cache-dir install package , um keinen Müll/Cache in der aktuellen Ebene zu speichern. Als Best Practice ist es jedoch wünschenswert, den Cache-Ordner aus dem Build-Kontext zu entfernen. also Build time -v wird helfen.
Einige oben erwähnte Benutzer verwenden COPY . /somewhere/in/container/ . Dies ist in Ordnung für Benutzer-Apps oder -Dateien, aber nicht für den Cache. da COPY eine weitere Ebene als eigene erstellt und das Entfernen von Caches in späteren Ebenen nicht sinnvoll ist. Ein anderer schlechter Nebeneffekt ist, wenn der Cache geändert wird, wenn wir COPY verwenden, ändert sich der Kontext und die folgenden Ebenen werden ungültig und müssen neu erstellt werden.

@wtayyeb Wenn Sie Dockerfile haben, das pip install ... nur ausgeführt wird, wenn sich die Anforderungsdatei ändert, scheint die Build-Zeit -v nicht so wichtig zu sein, da sich die Anforderungen beim Erstellen nicht so oft ändern wie Anwendungen.

@wtayyeb Sie können ein mehrstufiges Dockerfile verwenden, um sowohl den Cache als auch ein schlankes Image zu haben. Das heißt, verwenden Sie ein Installer-Image, um Python in einem Verzeichnis zu installieren, und verwenden Sie dann für Ihr endgültiges Image COPY --from, um nur die erforderlichen Python-Dateien ohne Installationsartefakte oder sogar Pip selbst zu übertragen.

@manishtomar , Danke, ja und nein! Im sauberen Fall werden alle Abhängigkeiten erneut heruntergeladen und erstellt und in Räder konvertiert und zwischengespeichert und dann in der Zielumgebung installiert. Also, wenn man da Anforderungen reinschreibt, ist das eine einmalige Aufgabe. Aber wenn eine winzige Abhängigkeit aktualisiert wird, müssen alle Abhängigkeiten erneut heruntergeladen, neu erstellt und neu gerollt und neu zwischengespeichert werden, um verwendbar zu sein.
Wenn Sie ein CI verwenden, um Ihre Bibliotheken und Ihre Anwendungen in einer Matrix aus mehreren Jobs zu erstellen und zu testen, multiplizieren Sie die obige Arbeit mit der Anzahl gleichzeitiger Jobs in Ihrem CI-Server und Sie erhalten einen iowait-Anstieg auf mehr als 3 Sekunden und einen Lastdurchschnitt von über 15, selbst mit SSDs. (Diese Zahlen sind real für 2 gleichzeitige Builds und eine App mit ~ 20 Abhängigkeiten.) Ich denke, der Pip-Cache macht es auf die richtige Weise, indem er das erneute Herunterladen, erneute Erstellen und erneute Ausführen der fertigen Pakete vermeidet. und ohne bind -v verlieren wir Zeit und Serverressourcen.

@ibukanov , danke. Ich verwende ein mehrstufiges Dockerfile, um meine App-Pakete zu erstellen und sie später zu verwenden. Es würde helfen, wenn ich nur ein Dockerfile habe und es mehrmals erstellen möchte, aber was ist, wenn es mehrere Dockerfiles gibt und jedes gegen eine Python-Version (vorerst 2.7, 3.6) erstellt wird und auch mehrere C-Erweiterungen haben muss für ausgewähltes Basisimage erstellt werden? Was ist mit dem obigen Absatz?

@thaJeztah Ihr Vorschlag ist großartig und wird uns etwas Zeit sparen, aber im Fall von Build-Caches möchten wir wirklich nichts aus dem anderen Image kopieren müssen.
Warum können wir nicht auf ein anderes Bild zugreifen, ohne es zu kopieren?

@thedrow mein Beispiel war mit den Funktionen, die derzeit vorhanden sind; Sehen Sie sich den RUN --mount -Vorschlag (https://github.com/moby/moby/issues/32507) an, der Ihrem Anwendungsfall möglicherweise besser entspricht

Wenn ich den obigen Thread lese, sehe ich eine große Anzahl von Leuten, die versuchen, Kludges zu finden, um eine grundlegende Funktionslücke im Docker-Build-Prozess zu schließen. Ich sehe keine überzeugenden Argumente auf der Grundlage der Portabilität, ohne unbedingt Host-Mounts mit Image-Mounts zu verschmelzen - Argumente, die ehrlich gesagt fadenscheinig und faul sind.

Ich bin auch ein Gentoo-Container-Benutzer und wurde von https://github.com/moby/moby/issues/3156 umgeleitet, was ein vollständig gültiger Anwendungsfall für diese fehlende Funktionalität ist.

Alles, was ich wirklich will, ist die Möglichkeit, den Inhalt eines anderen Images zur Build-Zeit zu mounten, damit ich meine Images nicht aufblähe.

@kbaegis klingt wie eine exakte Übereinstimmung mit der Funktion, die in https://github.com/moby/moby/issues/32507 vorgeschlagen wird

Sicher. Dass man nur seit einem Jahr ein nicht implementierter P3 im Rückstand ist, anstatt 3 Jahre.

Es sieht so aus, als würde https://github.com/projectatomic/buildah Docker Build hier für diese grundlegende Funktionalität ziemlich schnell überflügeln. Ich denke, ich werde meine Pipeline einfach umstellen, sobald das passiert.

@kbaegis , was bist du hierher gekommen, um dieser Diskussion etwas hinzuzufügen? Sie haben einen Anwendungsfall beschrieben, der _exakt_ mit einem anderen Vorschlag übereinstimmt;

Alles, was ich wirklich will, ist die Möglichkeit, den Inhalt eines anderen Images zur Build-Zeit zu mounten, damit ich meine Images nicht aufblähe.

Es ist Open Source, Dinge entstehen nicht auf magische Weise.

Was möchte ich der Diskussion hinzufügen?

Kurz gesagt, dass ich von diesem Toolset weiterkomme. Ich bin mir sicher, dass das wertvolle Informationen für das Entwicklungsteam sind, da ich mir sicher bin, dass ich da nicht allein bin.

Die eisige Geschwindigkeit und niedrige Priorität für die Unterstützung dieses Anwendungsfalls (und jede zuverlässige Problemumgehung, die diese Funktionalität bietet) hat mich zu anderen Tools gezwungen und dazu, dass ich diese Build-Pipeline aufgrund fehlender Funktionalität verlasse.

Ich habe einen (Wiederaufgewärmt, da bin ich sicher) Anwendungsfall hinzuzufügen. #32507 passt vielleicht besser dazu.

Ich erstelle ein Docker-Image für einige Bioinformatik-Pipelines. Einige der Tools erfordern, dass einige Datenbanken vor ihrer Kompilierung/Installation vorhanden sind (bitte nicht fragen, es ist nicht mein Code ). Diese Datenbanken wiegen mindestens 30 GB.

Während der Laufzeit beabsichtige ich auf jeden Fall, dass diese Datenbanken auf -v Volumes gemountet werden. Leider kann ich dies während des Build-Prozesses nicht tun, ohne sie "einzubacken", was zu einem ziemlich obszön großen Bild führt.

@draeath schau dir https://github.com/grammarly/rocker an. Es unterstützt bereits eine schöne MOUNT-Anweisung.

@draeath auch, schau dir Buildah an, es unterstützt standardmäßig Mounts, weil es eher wie ein Programmiertool eingerichtet ist. Unterstützt auch Mounts mit einem Dockerfile:

https://github.com/projectatomic/buildah

Vielen Dank an @fatherlinux und @lig - das wird mir helfen, meine Aufgabe zu erledigen. Ich denke immer noch, dass ich das Projekt nicht verlassen muss, um es zu tun, und würde immer noch gerne sehen, wie dies und # 32507 implementiert werden;)

Ich bin über etwas Googeln hierher gekommen, um nach der gleichen Funktion zu fragen, Volumes zur „Docker Build“-Zeit, nicht zur „Docker Run“-Zeit.

Wir haben ein eingebettetes System, das eine CPU enthält. Der Hersteller stellt Tools bereit, um ein Systemabbild zu erstellen und das Abbild dann in die CPU zu übertragen. Dieses Werkzeug ist für mich ein Drittanbieter und ich kann es nicht ändern. Es ist auch unwahrscheinlich, dass der Hersteller es auf meine Bitte hin ändert.

Ich möchte ein Docker-Image erstellen, das einen ersten Durchgang "Firmware-Image erstellen" ausführt, und dann in der Lage sein, Container zu erzeugen, die das Firmware-Image einfach auf die frischen PCBs schieben. Ein Dockerfile könnte so aussehen:
----------[ Schneiden Sie hier ]----------
FROM base-image als Builder
Quelle kopieren Quelle
RUN build-src

FROM Basis-Image als Flasher
COPY --from=builder build-artifacts
Führen Sie cpu-build-and-flash --build-only aus
----------[ Schneiden Sie hier ]----------
Leider erfordert der CPU-Build-and-Flash-Schritt den Zugriff auf das Zielgerät über den USB-Bus, obwohl das Firmware-Image nicht auf das Gerät übertragen wird. Daher muss ich das '-v /dev/usb/bus:/dev/usb/bus' aus dem Befehl 'docker run' nehmen und es stattdessen im Build haben.

Es ist klar, dass dies derzeit nicht möglich ist.

Die Problemumgehung, mit der ich fortfahre, besteht darin, ein blinkendes Image manuell zu erstellen, indem ein Container mit einem Docker-Container in ein Image übernommen wird. Ich würde viel lieber nur den USB-Bus zur Bauzeit montieren.

Update für alle Interessierten: Ich habe kürzlich mein komplettes Rohr erfolgreich mit buildah umgebaut. Ich habe derzeit die beiden Build-Pipelines parallel laufen lassen und die oci/buildah-Pipeline generiert kleinere Images (insbesondere das Entfernen von /usr/portage in meinem Fall durch Maskieren mit einem anderen Mount).

Und schließlich ist dieses Feature hier: https://github.com/docker/docker-py/issues/1498

Aber ich möchte RW-Volumes für einen Build-Cache

Am Samstag, 28. April 2018, 17:29 Uhr schrieb Коренберг Марк, [email protected] :

Und schließlich ist dieses Feature hier: docker/docker-py#1498
https://github.com/docker/docker-py/issues/1498


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/14080#issuecomment-385188262 , oder stumm
der Faden
https://github.com/notifications/unsubscribe-auth/AAZQTJodLCCzyDdPFtNiIUZ_z85YvLWbks5ttJjagaJpZM4FIdOc
.

Ich würde diese Funktion (mit Schreibfunktionen) auch gerne sehen, damit eine Unit-Test-Ergebnisdatei während des mehrstufigen Build-Prozesses in eine CI-Pipeline exportiert werden kann. Um im Sinne der Build-Portabilität zu bleiben, würde die Datei zu diesem Zeitpunkt einfach intern in das Test-Image geschrieben, wenn der Schalter -v nicht bereitgestellt wurde.

Das ideale Ziel besteht darin, einmal zu bauen, einmal zu testen und trotzdem die Ergebnisdatei an das Hostsystem zu übergeben, selbst für den Fall (und insbesondere für den Fall), dass die Tests fehlschlagen und der Aufbau gestoppt wird.

Ja bitte. Den ganzen Tag.

Nicht ganz relevant, aber wir migrieren einen Teil unserer Bereitstellungsinfrastruktur und brauchten eine Möglichkeit, Dateien nach dem Build aus einem Image zu kopieren. Folgendes hat es geschafft:

docker build -t x .
ID=$(docker create x)
docker cp $ID:/package.deb .
docker rm $ID

Es sollte bereits hinzugefügt worden sein, als die mehrstufige Docker-Datei eingeführt wurde. Irgendwann werden alle mit diesem Problem konfrontiert, sobald sie Unit-Tests als Phase in einer mehrstufigen Docker-Datei ausführen, insbesondere im Fall von CI-Build-Pipelines. Wir stehen auch vor diesem Problem, bei dem wir Unit-Testberichte für VSTS veröffentlichen müssen. Ich habe bereits die Problemumgehung angewendet, die @hoffa erwähnt hat. Aber schließlich ist es eine Problemumgehung und macht die Dinge kompliziert.

Sollten wir ein anderes Problem für Leute machen, die Build-Time-Volumes für einen Build-Cache wollen/benötigen?

@ajbouh Ja, wahrscheinlich unter https://github.com/moby/buildkit/issues

Siehe https://github.com/moby/moby/issues/32507#issuecomment -391685221

Am Mi, 23. Mai 2018, 19:22 schrieb Akihiro Suda [email protected] :

@ajbouh https://github.com/ajbouh Ja, wahrscheinlich bei
https://github.com/moby/buildkit/issues


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/14080#issuecomment-391566368 , oder stumm
der Faden
https://github.com/notifications/unsubscribe-auth/AAAcnSqNoVc4j34ElECy53gIfPecQFKfks5t1hlkgaJpZM4FIdOc
.

Während Sie zur Build-Zeit keine Volumes hinzufügen können, können Sie Hosts hinzufügen, also baue ich jetzt alle meine Docker-Images mit etwas wie --add-host yum-mirror:$MIRROR_IP , das einen Yum-Spiegel bereitstellt, den meine Build-Images dann über einen Wrapper erkennen Lecker. Praktisch, wenn mein Projekt mehrmals am Tag Abhängigkeiten ändert und ich offline bin oder eine schlechte Verbindung habe (ein Teil des Projekts besteht darin, seine vielen Abhängigkeiten zu aktualisieren und zu bereinigen).

Ich finde Dockers Widerstand gegen die Lösung dieses Problems ärgerlich.

Die experimentelle Unterstützung für Buildkit wurde kürzlich zusammengeführt, was mit einer Option zu RUN --mount=<opts> <command> einhergeht.

Link zu @cpuguy83 Hinweis: https://github.com/moby/buildkit/pull/442

@glensc @cpuguy83 Wann können wir mit einer Veröffentlichung dieser zusammengeführten Funktion rechnen?

+1

RUN --mount hat keine Volumenunterstützung, daher bleiben Dinge wie https://github.com/avsm/docker-ssh-agent-forward zur Build-Zeit unmöglich, was ist die Lösung dafür?

docker build --secret ist endlich in Docker 18.09 verfügbar https://medium.com/@tonistiigi/build -secrets-and-ssh-forwarding-in-docker-18-09-ae8161d066

Können wir dieses Thema schließen?

--secret ist für den Caching-Anwendungsfall nicht verwendbar, soweit ich das beurteilen kann.

@AkihiroSuda RUN --mount sieht im Allgemeinen nach etwas aus, das möglicherweise als Lösung für dieses Problem geeignet ist.

Ja, ich nehme an, RUN --mount=type=cache (für Cache-Volumen) und --mount=type=secret mit docker build --secret (für geheimes Volume) decken das Problem fast ab.

@AkihiroSuda , also wäre ein funktionierendes Beispiel zur Lösung des ursprünglichen Problems gut zu sehen

@AkihiroSuda Aus dem Artikel (https://medium.com/@tonistiigi/build-secrets-and-ssh-forwarding-in-docker-18-09-ae8161d066) habe ich 2 Anwendungsfälle für die Verwendung von mount während des Builds gesehen: Secret und SSH

[Geheimnis]

docker build --secret id=mysite.key,src=path/to/mysite.key .
RUN --mount=type=secret,id=mysite.key,required <command-to-run>

[SSH]

RUN --mount=type=ssh git clone [email protected]:myorg/myproject.git myproject

Es gibt 2 andere Anwendungsfälle (an die ich mich erinnere), deren Verwendung weder im Artikel noch in dieser Ausgabe erklärt wird:

1) [Cache] RUN --mount=type=cache
2) Volumes im Allgemeinen (z. B. zum Mounten von SSL-Zertifikaten oder im Fall von großen Volumes, die während des Builds verwendet, aber nicht in das generierte Image aufgenommen werden sollen, usw.)

Sobald der Anwendungsfall den Arbeitsbereich yarn einbindet, bevor webpack ausgeführt wird

Das kannst du alles..

RUN --mount=type=cache,from=<some image>,source=<path in from image>,target=<target>

Sie können auch from=<some image> durch from=<some build stage> ersetzen

Hier ist ein erfundenes Beispiel:

# syntax=docker/dockerfile:1.0.0-experimental
FROM busybox as hello
RUN  echo hello > /hello.txt

FROM scratch
RUN --mount=type=cache,from=busybox,source=/bin,target=/bin --mount=type=cache,from=hello,source=/hello.txt,target=/tmp/hello.txt echo /tmp/hello.txt

Ich stimme @AkihiroSuda zu, dies sollte alle Fälle behandeln ... aber bitte lassen Sie es uns wissen, wenn dies nicht der Fall ist.

@AkihiroSuda @cpuguy83 : Leider hat die aktuelle Implementierung (Buildkit in Docker 18.09) Probleme mit privaten Registrierungen. Ab sofort können diese neuen Funktionen nicht verwendet werden, wenn Sie Ihre Bilder über eine private Registrierung abrufen müssen. Siehe meine Tests in https://github.com/moby/moby/issues/38303.

Ich denke, dies würde auch für Jenkins-Artefakte verwendet werden. Wenn ich also beispielsweise ein Docker-Image erstelle und etwas darin kompiliere, möchte ich einige Artefakte erhalten, z. B. die Ausgabe von junit pytest

Dies wäre sehr nützlich. Ich würde wirklich lieber nicht --experimental hinzufügen müssen, um $#$1 RUN --mount=type=cache /user/.cache/pip pip install #$ zu unterstützen (um Tonnen von Paketindexbandbreite zu sparen).

buildah bud ( buildah build-using-dockerfile ) hat eine --volume / -v Option:
https://github.com/containers/buildah/blob/master/docs/buildah-bud.md

buildah kann Builds als Nicht-Root ohne Docker-Socket ausführen.

Weil Paket-Downloads aus dem Netz besser reproduzierbar sind?

Es muss kein „--experimental“ hinzugefügt werden, nur „DOCKER_BUILDKIT=1“ auf dem Client.

Ja, Netzwerk-Builds sind besser reproduzierbar, da sich der Kontext vollständig in der Dockerfile befindet. Wenn Sie Kontext vom Host bereitstellen müssen, damit der Build funktioniert, ist dies eine schlechte Erfahrung.

Beachten Sie, dass Sie auch ein Image in den Build einbinden können.

Ja, Netzwerk-Builds sind besser reproduzierbar, da sich der Kontext vollständig in der Dockerfile befindet.

Wenn Sie RUN apt-get update in der Docker-Datei haben, stellen Sie sicher sicher, dass Sie alle Schritte haben, die zum Erstellen des Images erforderlich sind. Es ist jedoch nicht reproduzierbar, da zusätzlicher Kontext von einem Drittanbieter heruntergeladen wird. Der einzige Unterschied zu einem Mount besteht darin, dass alle externen Kontexte tatsächlich im Dockerfile definiert sind.

Wenn Sie Kontext vom Host bereitstellen müssen, damit der Build funktioniert, ist dies eine schlechte Erfahrung.

Meine schlechte Erfahrung mit dem Docker-Build ist, dass es nie reproduzierbar ist und wir definitiv davon profitieren könnten, einen Cache vom Host bereitzustellen, was einige Anwendungsfälle wohl beschleunigen würde.

Was ich am Ende mache, ist ein mehrstufiger Build. Ein Bild, das den Kontext aus dem Netzwerk erhält, das somit als Momentaufnahme des entfernten Kontexts fungiert. Dann markieren Sie das mit einer beliebigen Version, das Datum funktioniert gut. Z.B:

RUN apt-get update

docker build -t aptupdate-20190417

Und im eigentlichen Bild:

FROM aptupdate-20190417
FROM somebaseimage

COPY --from=aptupdate-20190417 /var/apt /var/apt

Wiederholen Sie dies mit einem anderen Remote-Kontext, und Sie haben mehr oder weniger etwas, das reproduzierbar ist.

Oder kurz gesagt: Ein Dockerfile, das auf Netzwerkzugriff angewiesen ist, ist wahrscheinlich nicht reproduzierbar. Ein Mount macht es möglicherweise nicht reproduzierbar, würde aber dazu beitragen, einige Anwendungsfälle reproduzierbar zu machen. Aber ich denke, der Punkt, an dem Dockerfile alle Schritte haben sollte, die erforderlich sind, um das Image tatsächlich zu erstellen, obwohl meiner Erfahrung nach die meisten ihre eigenen Tools schreiben, um das Erstellen von Images zu instrumentieren.

Ich meine, RUN --mount=type=cache ist genau dafür.
Oder Sie können sogar von einem anderen Image aus einer Registrierung mounten und es wird abgerufen.

Ihre apt -Befehle können (relativ) reproduzierbar gemacht werden, indem Sie festlegen, was Sie abrufen möchten.
Aber wenn Sie wirklich alle Bits kontrollieren wollen, warum verwenden Sie dann apt in Ihrem Build? Das Speichern auf einem Build-Host ist nicht reproduzierbar und bricht leicht von Host zu Host.
Es ist nicht schlimm, es in einer Registrierung zu halten, abgesehen von der Möglichkeit eines Netzwerkausfalls ... was natürlich eine faire Kritik ist.

-v auf buildah und redhat's Fork wurde hier ausdrücklich abgelehnt, weil es zu breit ist ... um nicht zu sagen, dass es nicht nützlich ist, aber es bricht leicht von Host zu Host, was gegen das Design von docker build .
In der Zwischenzeit war der Grund, warum RH es hinzugefügt hat (oder genauer gesagt, warum sie sich entschieden haben, daran zu arbeiten), in der Lage zu sein, RHEL-Anmeldeinformationen in die Build-Umgebung einzubinden.

Ja, Netzwerk-Builds sind besser reproduzierbar, da sich der Kontext vollständig in der Dockerfile befindet. Wenn Sie Kontext vom Host bereitstellen müssen, damit der Build funktioniert, ist dies eine schlechte Erfahrung.

Ich widerspreche vehement. Das Netzwerk ist möglicherweise ausgefallen oder kompromittiert; In diesem Fall verhindert ein lokaler Cache, dass der gesamte Build fehlschlägt, während das Internet ausgefallen ist.

Ich könnte volumes: einmal in meiner docker-compose.yml angeben; aber müssen Sie stattdessen DOCKER_BUILDKIT=1 tun und RUN --mount=type=cache in Dockerfiles hinzufügen, die stromaufwärts verwaltet werden? Warum?

Bei CI-Builds sprechen wir über eine nicht triviale Menge an unnötigem erneutem Herunterladen von Zehn- bis Tausenden von Paketen (Zehn- oder Hunderte Male am Tag), die einfach in einem Volume-Mount zwischengespeichert werden könnten (in einem Build, der als Nicht-Root ohne die Fähigkeit, privilegierte Container mit ihren eigenen Volumes auf dem Host auszuführen).

Paketverzeichnisse werden in vielen Fällen großzügig durch Spenden unterstützt. Dieses Geld für Bandbreite zu verschwenden, um eine falsche Vorstellung von Reproduzierbarkeit zu befriedigen, die auf dem falschen Glauben beruht, dass Remote-Ressourcen ein besser reproduzierbarer Cache von Build-Komponenten sind, ist furchtbar frustrierend.

Bitte fügen Sie einfach --volume hinzu, damit meine docker-compose.yml funktioniert.

Bitte fügen Sie einfach --volume hinzu, damit meine docker-compose.yml funktioniert.

Ihr "Docker-Compose" einfach zum Laufen zu bringen, ist rückwärts.
Docker-Compose-Verbraucher dieses Projekts, nicht umgekehrt.

Docker-Compose interagiert mit dem Docker-Socket. docker-compose YAML ist eine konsolidierte Methode zum Speichern von Containeroptionen (die in k8s-Pod-Defs konvertiert werden können (die Podman bis zu einem gewissen Grad unterstützt)). Wie soll ich DOCKER_BUILDKIT=1 reproduzierbar angeben? Ich könnte build_volumes: reproduzierbar in einer docker-compose.yml angeben.

Wenn ich – in meinem CI-Build-Skript, das n-mal am Tag ausgeführt wird – ein Image baue, indem ich beispielsweise $# packer docker-compose build (z habe ein paar Ziele:

  • Ressourcen sparen / keine Ressourcen verschwenden

    • Laden Sie Betriebssystem- und Sprachpakete nicht ständig neu herunter.

    • Speichern Sie die Bandbreitenressourcen meiner Organisation im Paketindex.

  • Verfügbarkeit sicherstellen

    • Es soll/muss offline funktionieren

    • Es sollte von so wenigen Komponenten wie nötig abhängen

  • Stellen Sie die Build-Integrität sicher

    • In der Lage sein, dasselbe Bild mit denselben Parametern neu zu erstellen

    • Varianz isolieren / Reproduzierbare Builds liefern

    • Wir kontrollieren keine Remote-Ressourcen wie Paketindizes.

    • Wir kontrollieren den Netzwerkpfad nicht



      • DNSSEC und DNS über HTTPS sind wahrscheinlich nicht richtig implementiert



    • Wir können gebannt und ziemlich ratenbegrenzt werden

    • Wir sollten signierte Prüfsummen verwenden, um signierte Ressourcen zu verifizieren



      • Die Autorisierung für den Zugriff und das Signieren mit Schlüsseln wird irgendwo delegiert


      • ENVironment-Variablen stehen allen Prozessen im Container-Namespace zur Verfügung


      • Build-Time-Volume-Mounts sind eine Möglichkeit, Schlüssel gemeinsam zu nutzen, die nur zur Build-Zeit benötigt werden (ohne sie in den Image-Cache zu übertragen).



  • Halten Sie Builds schnell

    • Zwischenspeichern und merken Sie sich häufige Vorgänge.

    • Caches fügen Fehlerquellen, potenzielle Abweichungen und das Risiko der Nichtreproduzierbarkeit hinzu.



      • HTTP(S!)-Proxy-Cache


      • Anwendungsschicht-Cache über das Netzwerk


      • Lokaler Dateisystem-Cache



    • Implementieren Sie dumme, spülbare Caches ohne externe Abhängigkeiten



      • Lokaler Dateisystem-Cache



Wenn ich das Cache-Volume leeren muss, kann ich das Cache-Volume leeren.

0. Status quo

RUN pip install app && rm -rf /root/.cache
  • Heute möglich
  • O(n_builds): Bandbreitennutzung
  • Funktioniert nicht offline: Hängt vom Netzwerk ab
  • Langsamere Wiederherstellungen

A. Kopien

COPY . /app/src/app
COPY .cache/pip /app/.cache/pip
RUN pip install /app/src/app \
    && rm -rf /app/.cache/pip
  • Heute möglich
  • ~O(1) Paketindexbandbreite
  • O(n): Bei jedem Build (* ONBUILD )

    • Kopiert den Cache

    • Entarchiviert Pakete

    • Löscht den Cache

  • Funktioniert offline
  • Langsamere Wiederherstellungen

B. Verzweigen und ändern Sie jede Docker-Datei von Upstream, um RUN --mount=type=cache hinzuzufügen und eine Umgebungsvariable festzulegen

# Fork by copying to modify every pip install line
RUN --mount=type=cache /app/.cache/pip pip install /app/src/pip
$ DOCKER_BUILDKIT=1 docker build . [...]
  • Heute möglich
  • Dies führt bereits zu Nichtreproduzierbarkeit: Es gibt einen zusätzlichen Dockerfile-, extra-docker-compose.yml-Parameter, der Abweichungen in die Ausgabe einführt: das benannte erstellte Image.
  • Docs: So leeren Sie den --mount=type=cache -Cache (?)
  • ~O(1) Paketindexbandbreite
  • Funktioniert offline
  • Schnelle Umbauten

C. Geben Sie ein Volume an, das zur Erstellungszeit gemountet wird

C.1. bauenah
$ buildah bud -v .cache/pip:/app/.cache.pip
  • Heute möglich
  • Führt auch Nichtreproduzierbarkeit ein
  • Docs: So leeren Sie den Cache
  • ~O(1) Paketindexbandbreite
  • Funktioniert offline
  • Schnelle Umbauten
C.2. Docker (wonach dieses Problem fragt)
C.2.1 Docker-CLI
$ docker build -v .cache/pip:/app/.cache.pip
  • Heute nicht möglich
  • Führt auch Nichtreproduzierbarkeit ein
  • Docs: So leeren Sie den Cache
  • ~O(1) Paketindexbandbreite
  • Würde offline funktionieren
  • Schnelle Umbauten
C.2.2 Docker-Komposition
services:
  app:
    image: imgname:latest
    build: .
    build_volumes:  # "build_volumes" ?
    - ./.cache/pip:/app/.cache/pip
$ docker-compose build
  • Heute nicht möglich
  • Führt auch Nichtreproduzierbarkeit ein
  • Docs: So leeren Sie den Cache
  • Würde eine Überarbeitung des Docker-Compose-Schemas erfordern
  • ~O(1) Paketindexbandbreite
  • Würde offline funktionieren
  • Schnelle Umbauten

...

  • KOPIEREN || REMOTE_FETCH || lesen()

    • Welche davon sind am besten reproduzierbar?

:point_up: Nur zur Erinnerung. Sie können eine heruntergeladene Datei anheften, indem Sie ihre Prüfsumme überprüfen. Einige Paketmanager wie Pip unterstützen dies ebenfalls.

@westturner Danke für die ausführliche Erklärung.

Ich denke, das Folgende wäre Ihrem Fall B ähnlich, aber Sie könnten den Cache leeren und es würde wie Ihr Fall C2 enden (was Sie fragen, denke ich):

_docker-compose.yml:_

services:
  my-cache:
    build: ./my-cache
    image: local/my-cache

  my-image:
    build: ./my-image

_my-cache/Dockerfile:_

FROM python

RUN pip install app

_my-image/Dockerfile:_

FROM my-repo/my-image

RUN --mount=target=/export,type=bind,from=local/my-cache

RUN pip install /app/src/app

(https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/experimental.md#run---mounttypecache)

Sie können das Cache-Image erstellen mit:

docker-compose build my-cache

Der Befehl RUN --mount=target=/export,type=bind,from=local/my-cache sollte an das Bild binden. Wenn Sie den Cache aktualisieren möchten, können Sie das Cache-Image entfernen und neu erstellen.

Wenn dies immer noch den Cache in RUN --mount... verwendet, können Sie eine .env -Datei mit einer Version verwenden, fügen Sie die Version in image: local/my-cache:$MY_VERSION und from=local/my-cache:$MY_VERSION ein (sollte es sein als Build-Arg enthalten).

Sie können den my-cache -Dienst in eine andere docker-compose -Datei einfügen, wenn Sie nicht möchten, dass er sich in derselben Datei wie Ihre Hauptdienste befindet.

Sie müssten immer noch DOCKER_BUILDKIT=1 verwenden (wie in Ihrem B-Fall, aber ich denke, das wird in zukünftigen Versionen nicht notwendig sein) und es wäre immer noch nicht reproduzierbar (aber Ihr C2-Fall ist es auch nicht).

Was wäre die Strafe, die Sie sehen, wenn es nicht reproduzierbar ist? Wenn Sie das Cache-Image local/my-cache im Docker-Hub (mit einem anderen Repo-Namen) oder in einer privaten Registrierung ablegen und Versionen für jeden Build verwenden (das wird einen anderen Cache erstellen), wobei dieselbe Version immer dieselbe hat Cache, würde es es nicht reproduzierbar machen? Sie müssten nicht einmal den Dienst in die docker-compose -Datei aufnehmen und den build-Befehl aufrufen. (Auf den Docker Hub sollte aus dem Netzwerk zugegriffen werden, aber es ist das gleiche für Ihre anderen Images, nehme ich an, und nachdem Sie es einmal heruntergeladen haben, sollte es nicht mehr benötigt werden, es sei denn, Sie generieren eine neue Version mit einem neuen Cache.)

HAFTUNGSAUSSCHLUSS: Ich habe den obigen Code nicht getestet.

@Yajo Die Prüfsummenunterstützung in pip wurde ursprünglich in 'peep' implementiert und dann in pip zusammengeführt. Sie können bekannte gute Hashes als URL-Fragmente in Pip-Anforderungsdateieinträgen hinzufügen. (Dieses Jahr werden Mittel für Sicherheitsverbesserungen im PyPA-Projekt bereitgestellt; die Unterstützung von TUF (The Update Framework; genau wie Docker Notary) in PyPI ist für später in diesem Jahr geplant.) Korrektes Bootstrapping von Pip und PyPI (mit Schlüsseln und Vertrauen) in Docker-Images wird wahrscheinlich später in diesem Jahr ein Thema sein.
(bearbeiten; etwas OT, aber für die Betroffenen) https://discuss.python.org/t/pypi-security-work-multifactor-auth-progress-help-needed/1042/

@lucasbasquerotto Danke für deine Hilfe. Dies ist erheblich komplizierter, als nur --volume zur Build-Zeit anzugeben. Es scheint nämlich zu erfordern:

  • Angeben DOCKER_BUILDKIT=1 in der Shell-Umgebung $ docker build
  • Ändern einer/jeder Upstream-Dockerfile-RUN-Anweisung mit (edit) RUN --mount=type=cache und args
  • Lese-/Schreibzugriff auf ein anderes Image? Wandlungsfähigkeit! Oder ist der Cache mit wahrscheinlich veralteten Versionen eingefroren?

Wenn ich Dateien vom Host KOPIEREN oder Build-Time-Parameter angeben kann, die nicht anderswo gespeichert sind, sehe ich nicht, inwiefern das Mounten eines Volumes zur Build-Zeit weniger reproduzierbar ist?

KOPIEREN || REMOTE_FETCH || lesen()

  • Welche davon sind am besten reproduzierbar?

@westturner

Angabe von DOCKER_BUILDKIT=1 in der Docker-Build-Shell-env

Wenn Sie docker-compose verwenden, wie ich in Ihren anderen Posts gesehen habe, und wenn Sie es von einem Container aus ausführen, wie zum Beispiel:

$ sudo curl -L --fail https://github.com/docker/compose/releases/download/1.24.0/run.sh -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose

Dann können Sie die heruntergeladene Datei in /usr/local/bin/docker-compose bearbeiten, um diese Umgebungsvariable zu verwenden. Wechsel von:

exec docker run --rm $DOCKER_RUN_OPTIONS $DOCKER_ADDR $COMPOSE_OPTIONS $VOLUMES -w "$(pwd)" $IMAGE "$@"

zu

DOCKER_BUILDKIT=1
exec docker run --rm $DOCKER_RUN_OPTIONS $DOCKER_ADDR $COMPOSE_OPTIONS $VOLUMES -w "$(pwd)" --env DOCKER_BUILDKIT=$DOCKER_BUILDKIT $IMAGE "$@"

Dies ist eine sehr einfache Änderung und für jeden, der den Befehl ausführt, transparent.

_(Wenn Sie nicht als Container ausgeführt werden, gilt das oben Genannte nicht)_

Ändern einer/jeder Upstream-Dockerfile-RUN-Anweisung mit RUN --cache und args

In dem Fall, den ich aufgedeckt habe, wären es RUN --mount=type=bind... , aber auf jeden Fall ist es meiner Meinung nach auch schlecht, die Dockerfile ändern zu müssen. Eine -v -Option wäre wirklich viel besser und transparenter .

Lese-/Schreibzugriff auf ein anderes Image? Wandlungsfähigkeit! Oder ist der Cache mit wahrscheinlich veralteten Versionen eingefroren?

Wenn Sie das Image binden, würde es wahrscheinlich einen Container erstellen (oder wie auch immer der Name lautet, mit einem replizierten Dateisystem), und Änderungen, die dort während des Erstellens vorgenommen werden, sollten das ursprüngliche Image nicht ändern (es würde keinen Sinn ergeben). Wenn Sie also in einem Build ein Cache-Image namens my-repo/my-cache:my-version verwenden, wäre es im nächsten Build genau dasselbe (Unveränderlichkeit). Wenn Sie einen aktuelleren Cache verwenden möchten, können Sie ein neues Image mit einer neuen Version erstellen und verwenden, z. B. my-repo/my-cache:my-new-version .

Welche davon sind am besten reproduzierbar?

Ich betrachte reproduzierbar als etwas, das genau gleich wäre, selbst wenn Sie es auf einem anderen Computer ausführen. In diesem Sinne würde ich es als reproduzierbar betrachten, wenn Sie ein Image in eine (sichere und zuverlässige) Docker-Registrierung verschieben und dieses Image niemals ändern (wenn Sie Bedenken hinsichtlich der Internetverbindung haben, können Sie eine private Registrierung verwenden und darauf in a VPN oder so ähnlich (habe selbst nie eine private Registry verwendet)).

Wenn der COPY-Befehl Ihren Computer-Cache kopiert, halte ich ihn nicht für reproduzierbar, denn wenn Sie pip install (oder apt-get oder was auch immer) auf einem anderen Computer zu einem anderen Zeitpunkt ausführen, können Sie dies garantieren dass der Inhalt des Caches derselbe sein wird? Vielleicht könnte dies ein Anliegen für Sie sein. Vielleicht nicht.

Wenn Sie andererseits Dateien haben, die Sie an einem zuverlässigen Ort besitzen, den Sie "besitzen" (wie ein S3-Bucket), laden Sie diese Dateien auf Ihren Computer herunter und kopieren Sie diese Dateien mit dem COPY-Befehl, dann können Sie sie von einem anderen reproduzieren Computer mit den gleichen Ergebnissen (vorausgesetzt, die Dateien haben sich nicht geändert und der andere Computer ist identisch mit dem vorherigen). Daher würde ich das als reproduzierbar einstufen. Es hängt davon ab, woher diese Dateien kommen und wie viel Kontrolle Sie über sie haben.

Um ehrlich zu sein, ich halte nichts für 100% reproduzierbar in allen Fällen (schließlich kann Hardware ausfallen), aber je zuverlässiger, desto besser. Wenn ich mich darauf beziehe, dass ein Prozess reproduzierbar ist, beziehe ich mich hauptsächlich darauf, dass sein Inhalt und Ergebnis gleich sind, und dies würde etwas beinhalten, das aus dem Netzwerk heruntergeladen wird, vorausgesetzt, dass sich der Inhalt im Laufe der Zeit nicht ändert (ich ziehe die Möglichkeit von network Fehler in diesem Fall).

Es gibt eine Art Docker-Netzwerkfehler, der go mod download auch innerhalb eines Containers unzuverlässig macht (zumindest für Anwendungen unserer Größe), also einfach jedes Mal ausführen, um alle meine GOPATH/pkg/mod erneut herunterzuladen nicht nur verschwenderisch, sondern kaputt. 🤷‍♀

Ich könnte jede Menge unnötiges Kopieren von Dateien vermeiden, wenn ich --volume verwenden könnte!

@kevincantu RUN --mount=type=cache sollte Ihren Anwendungsfall abdecken

Das erfordert mindestens einen erfolgreichen Download von Modulen aus einem Docker-Build, und in diesem speziellen Fall habe ich das noch nie gesehen.

https://github.com/moby/moby/issues/14080#issuecomment -484314314 von @westurner ist eine ziemlich gute Übersicht, aber ich konnte buildkit nicht zum Laufen bringen:

$ sudo docker -v
Docker version 19.03.1, build 74b1e89

$ sudo DOCKER_BUILDKIT=1 docker build .
Ä+Ü Building 0.1s (2/2) FINISHED                                                                                                                
 => ÄinternalÜ load build definition from Dockerfile                                                                                       0.0s
 => => transferring dockerfile: 407B                                                                                                       0.0s
 => ÄinternalÜ load .dockerignore                                                                                                          0.0s
 => => transferring context: 2B                                                                                                            0.0s
failed to create LLB definition: Dockerfile parse error line 8: Unknown flag: mount

Mein Dockerfile beginnt mit # syntax=docker/dockerfile:experimental .

Ich würde es eigentlich gerne über docker-compose verwenden. Habe ENV DOCKER_BUILDKIT 1 in Dockerfile versucht und auch von docker-compose.yml über ARG DOCKER_BUILDKIT weitergegeben, aber es ist alles dasselbe:

$ sudo docker-compose up --build
Building web
ERROR: Dockerfile parse error line 10: Unknown flag: mount

@lucasbasquerotto Wie würde das, was Sie in https://github.com/moby/moby/issues/14080#issuecomment -484639378 vorgeschlagen haben, in eine installierte Version von docker-compose übersetzen?

Schließlich bin ich mir nicht einmal sicher, ob dies meinen Anwendungsfall abdecken würde, vielleicht können mir einige von Ihnen sagen, ob ich das weiterverfolgen sollte. Ich möchte einen Build-Time-Cache für die lokale Entwicklung verwenden, der zwischen Builds überlebt, sodass beim Aktualisieren von Abhängigkeiten nur die neuen heruntergeladen werden müssen. Also würde ich RUN --mount=type=cache,target=/deps zu Dockerfile hinzufügen und den Cache des Abhängigkeitsmanagers auf /deps setzen.

für docker compose siehe https://github.com/docker/compose/pull/6865 , das in einem kommenden Release Candidate von compose enthalten sein wird

Ich habe einen anderen Anwendungsfall ... Ich möchte Container für Arm auf einem x86_64-Host mit konfiguriertem binfmt erstellen. Dies erfordert, dass ich den architekturspezifischen statischen Qemu-CPU-Emulator in /usr/bin habe.

Meine aktuelle Lösung besteht darin, qemu-arm-static als Datei wie folgt in den Container einzufügen:

FROM arm32v7/alpine:3.10
COPY qemu-arm-static /usr/bin/qemu-arm-static
RUN apk update && apk upgrade
RUN apk add alpine-sdk cmake
...

Die einfachere Lösung wäre, meine Datei nur bei Bedarf innerhalb des Containers zu mounten:
docker build -v /usr/bin/qemu-arm-static:/usr/bin/qemu-arm-static -t test:arm32v7 .
Dies funktioniert sehr gut für Docker Run, aber ich vermisse diese Funktionalität zum Erstellen von Containern.

Gibt es eine andere Lösung, wie ich einen Arm-Container auf x86_64-Hosts erstellen kann, oder können wir zumindest für diesen Fall Volumes zur Erstellungszeit zulassen?

Die neuesten Kernel von @jneuhauser ermöglichen das statische Laden dieser Binärdateien, sodass sie nicht jedes Mal konfiguriert werden müssen. Sie können dies zB erreichen, indem Sie das Image linuxkit/binfmt einmal nach dem Booten im privilegierten Modus ausführen.

Die neuesten Kernel erlauben das statische Laden dieser Binärdateien, sodass sie nicht jedes Mal konfiguriert werden müssen.

@alehaa Brauchst du nicht immer noch die statische qemu-Emulator-Binärdatei im Container?

@cybe Dies ist nicht mehr erforderlich, wenn das F -Flag verwendet wird (was das Paket linuxkit/binfmt tut). Weitere Informationen dazu finden Sie hier .

Könnte jemand ein funktionierendes Setup zum Ausprobieren von Buildkit bereitstellen? Unter Ubuntu bekomme ich es nicht zum Laufen. Mein Setup ist wie folgt:

cat /etc/docker/daemon.json

{
  "experimental": true
}

Dockerfile

# syntax=docker/dockerfile:experimental

FROM ruby:2.6.3

RUN --mount=type=cache,target=/bundle/vendor

sudo docker -v

Docker-Version 19.03.1, Build 74b1e89

DOCKER_BUILDKIT=1 sudo docker build .

Fehlerantwort vom Daemon: Dockerfile parse error line 12: Unknown flag: mount

sudo enthält keine env-Variablen, es sei denn, Sie sagen es mit sudo -E oder deklarieren die Variable innerhalb des sudo.

Ich habe ein paar Worte zu dieser Funktion geschrieben und einige Minimalbeispiele erstellt, die zeigen, wie man cachet

Bearbeiten: siehe unten

@ cpuguy83 danke!

@thisismydesign tut mir leid, dass ich deine Aufregung ruiniere, aber du kannst node_modules nicht --cachen, es wird im endgültigen Bild nicht vorhanden sein, also ist deine App kaputt.

@glensc Verdammt, du hast recht. Gibt es eine Möglichkeit, einen Build-Time-Cache zu einem Teil des endgültigen Bildes zu machen?

Ehrlich gesagt dachte ich, dass dies für eine beworbene Funktion in Betracht gezogen werden würde

ermöglicht dem Build-Container, Verzeichnisse für Compiler und Paketmanager zwischenzuspeichern.

Sie sollten stattdessen ~/.npm zuordnen können… https://docs.npmjs.com/files/folders.html#cache

@Das ist mein Design

Sie können jedoch ein anderes Image als Cache verwenden, indem Sie es entweder in Ihrer Docker-Datei erstellen oder ein wörtliches Image, das irgendwo in einer Registrierung gespeichert ist, und COPY --from verwenden

FROM example/my_node_modules:latest AS node_modules

FROM nodejs AS build
COPY --from=/node_modules node_modules 
...

Dies ist nur ein Beispiel, das Sie für viele verschiedene Dinge verwenden können.

Ugh, ich hasse es, das anzusprechen und mich hier zu engagieren (auch hallo Freunde)

aber wir haben einen Anwendungsfall dafür.


Gibt es einen guten Ort, an dem ich mich engagieren kann, oder einen Anruf oder eine Liste, der ich beitreten kann, um hier eine Zusammenfassung zu erhalten?

Auch wenn wir jemanden brauchen, der einige Ressourcen dafür bereitstellt, habe ich 1 Kris Nova und ein kleines Team, das ich wahrscheinlich dazu überreden kann, sich das anzusehen.

TLDR Kann ich das bitte codieren? Gibt es jemanden, mit dem ich darüber sprechen kann?

_TLDR_ Kann ich das bitte codieren? Gibt es jemanden, mit dem ich darüber sprechen kann?

Ich kann nicht für Docker sprechen, aber ich habe den Eindruck, dass sie nicht bereit sind, Volume-Mounting zu Builds hinzuzufügen (und dass sie dieses Problem wahrscheinlich schließen sollten).

Viele der Anwendungsfälle für buildtime -v werden jetzt von buildkit abgedeckt. Bei mir hat es sich zumindest gelöst.

Ich werde mir dann das Buildkit ansehen - ich habe auch ein paar Hacky Bash, die die Arbeit erledigen, falls jemand interessiert ist.

danke @unilynx

+1 an @unilynx beim Schließen dieses Problems, Buildkit hat die Probleme mit dem Build-Zeitvolumen auch für mich gelöst.

Ich wette, wenn jemand ein paar Links und ein Beispiel fallen lässt, könnten wir unsere Freunde davon überzeugen, den glänzenden Schließen-Button zu drücken.


(Ich würde auch davon profitieren)

Der Anwendungsfall des Cachings ist für mich und viele andere nicht gelöst, da die Build-Time-Volumes mit Buildkit im endgültigen Image nicht vorhanden sind.

So konnte ich alle meine Build-Artefakte aus dem temporären Volume ziehen, das zur Zeit von build verwendet wurde, und das Image mit dem vorherigen Cache mithilfe dieser oben erwähnten Bash erneut rekonstruieren.

Ich konnte mein Image über sich selbst neu erstellen, sodass das Overlay-Dateisystem nur ein kleines Delta erfasste.

Ich konnte das Volume sogar während der Erstellungszeit für andere Bilder wiederverwenden.


können andere das nicht?

(Cache-)Mounts befinden sich im "experimentellen" Front-End; beschrieben in https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/experimental.md (kurz vor einem Meeting, aber ich kann ausführlichere Beispiele verlinken)

danke @thaJeztah LMK, wenn ich hier irgendwie helfen kann :)

https://github.com/moby/moby/issues/14080#issuecomment -547662701

@thisismydesign tut mir leid, dass ich deine Aufregung ruiniere, aber du kannst node_modules nicht --cachen, es wird im endgültigen Bild nicht vorhanden sein, also ist deine App kaputt.

@thaJeztah Ich glaube nicht, dass das obige Problem gelöst ist. Würde gerne einen Blick auf einige Beispiele werfen, bei denen es möglich ist, zB npm install während der Erstellungszeit zwischenzuspeichern, wodurch auch das resultierende Image die zwischengespeicherte Installation verwenden kann.

@kris-nova Ich habe dieses Problem nicht gelöst, aber andererseits möchte ich keine Bash-Skripte verwenden. Vielleicht brauchen wir ein neues Problem, aber dies ist ein ziemlich häufiger Anwendungsfall, den AFAIK noch nicht gelöst hat.

@thaJeztah Hier sind einige Beispiele für die Verwendung von Cache-Mounts, die zeigen, wie das endgültige Image das Mount nicht enthält und dort viele Anwendungsfälle des Build-Time-Caching nicht abdeckt:

Für npm: Würde man nicht die Cache-Mounts für das npm-Cache-Verzeichnis verwenden (siehe https://docs.npmjs.com/cli-commands/cache.html, normalerweise ~/.npm )?

@ankon Das könnte funktionieren, danke, ich werde es versuchen. Ein weiterer Anwendungsfall, bei dem ich mir nicht sicher bin, ist Bundler und Ruby.

Ich denke (noch nicht getestet) für Bundler, dass Sie zumindest die Netzwerkabhängigkeit beseitigen können, indem Sie ein Build-Volume bei $BUNDLE_PATH und dann während des Builds verwenden

bundle install
bundle package
bundle install --standalone --local

Das bedeutet im Grunde, dass Sie ein gecachtes Bundle-Installationsverzeichnis haben, von dort aus packen Sie Gems in ./vendor/cache und installieren in ./bundle neu. Dies spart jedoch nicht die Zeit für die Installation und den Bau von Edelsteinen, es könnte den Bauschritt tatsächlich verlängern.

Wenn Sie die zwischengespeicherten Daten im Image speichern möchten, kopieren Sie sie aus dem Cache in das Image.

Danke, aber es ist immer noch eher ein Workaround, weil

  • Sie müssen eine zusätzliche Kopie erstellen
  • Ich gehe davon aus, dass Sie unterschiedliche Verzeichnisse zwischen Build- und Run-Umgebungen haben müssen (Sie können nicht das Verzeichnis verwenden, in dem Sie während des Builds ein Volume gemountet haben, oder?), Daher ist eine zusätzliche Einrichtung erforderlich

Ich weiß nicht, wie viel Aufwand es wäre, einfach eine native Option zum Mounten des gleichen Volumes in das endgültige Image zu haben, aber ich bin mir ziemlich sicher, dass dies die Verwendung vereinfachen würde. Dies sind nur 2 Beispiele aus Skriptsprachen, bei denen die Verwendung dieses Caches für mich nicht offensichtlich war. Ich kann mir durchaus vorstellen, dass dies auch in anderen Zusammenhängen auftauchen wird.

@thisismydesign Anscheinend möchten Sie einen Cache zwischen Build und Ausführung gemeinsam nutzen können?

buildkit ist eine reine Linux-Lösung, was machen wir unter Windows?

@thisismydesign Ich bin mir nicht sicher, warum Sie erwarten, dass ein (Cache-) Mount im endgültigen Image bleibt. Ich würde das nicht erwarten und ich möchte nicht ~ 1 GB in meinem Image haben, nur weil ich Download-Cache-Mount verwende.

buildkit ist eine reine Linux-Lösung, was machen wir unter Windows?

Sie können das Buildkit unter Windows verwenden.

https://docs.docker.com/develop/develop-images/build_enhancements/

Möglicherweise finden Sie es einfacher, die Daemon-Einstellung über die Docker für Windows-Benutzeroberfläche festzulegen, anstatt die Umgebungsvariable vor der Ausführung festzulegen.

@nigelgbanks oben in deinem Link:

Only supported for building Linux containers

Oh, tut mir leid, ich nehme nur an, Sie haben Linux-Container unter Windows erstellt.

@thisismydesign Anscheinend möchten Sie einen Cache zwischen Build und Ausführung gemeinsam nutzen können?

Das würde meinen Anwendungsfall rund ums Caching lösen, ja.

Wenn Sie dies einfacher machen, könnten Millionen von erneuten Downloads von Paketen in CI eingespart werden
baut pro Jahr.

Unterstützen irgendwelche CI-Dienste experimentelle Buildkit-Funktionen?

Am Sa, 13.06.2020, 14:08 schrieb Csaba Apagyi [email protected] :

@thisismydesign https://github.com/thisismydesign Es scheint wie was
Sie möchten in der Lage sein, einen Cache zwischen Build und Run zu teilen?

Das würde meinen Anwendungsfall rund ums Caching lösen, ja.


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/14080#issuecomment-643657987 oder
Abmelden
https://github.com/notifications/unsubscribe-auth/AAAMNS6IEQDCO5F3LNHJK5TRWO6AJANCNFSM4BJB2OOA
.

Unterstützen irgendwelche CI-Dienste experimentelle Buildkit-Funktionen?

Müssen sie das explizit unterstützen? Ich verwende gitlab-ci mit Buildkit und es funktioniert einfach. Schließlich ist es nur eine andere Art, „Docker Build“ aufzurufen.

Natürlich sind die Chancen, während des Builds einen Cache-Treffer zu bekommen, ohnehin gering, es sei denn, Sie bringen Ihre eigenen Runner zu gitlab.

Das Kopieren aus einer benannten Stufe eines mehrstufigen Builds ist eine weitere Lösung

FROM golang:1.7.3 AS builder
COPY --from=builder

Aber die Container-Image-Lokalität ist immer noch ein größtenteils ungelöstes Problem für die CI-Auftragsplanung

Runner müssten klebriger sein und (Zwischen-)Images in einem gemeinsamen Dateisystem teilen, um unnötige Anfragen an (ständig unterfinanzierte) Paket-Repos zu minimieren.

Ich habe gerade buildkit ausprobiert, aber es verbessert meinen Arbeitsablauf nur geringfügig, was zu 100% durch "echte" Volume- oder Bind-Mounts an den Host unterstützt würde.

Ich verwende docker build , um alte glibc -Versionen zu kompilieren, die dann Teil neuer Build-Container sein sollten, die diese glibc s zum Builden und Verlinken bereitstellen.

Jetzt wird der wiederholte glibc Source-Download durch ein Bind-Mount (ab buildkit ) gelöst, das Archiv kann nur gelesen werden, kein Problem. Aber ich habe keine Möglichkeit, nach fehlgeschlagenen Builds zur Analyse auf das Build-Verzeichnis zuzugreifen, da der Container bei einem Fehler abstürzt. (Wenn ich es neu starte, um darauf zuzugreifen, wird der Build neu gestartet, das hilft also nicht).

Außerdem sehe ich nicht ein, warum ich durch Reifen springen sollte, wie einen neuen Container aus einem alten zu bauen, nur um mein Build-Verzeichnis loszuwerden, wo, wenn das Build-Verzeichnis überhaupt ein Mount gewesen wäre, es gewesen wäre so einfach. (Machen Sie einfach make install nach dem Build und ich habe einen sauberen Container ohne Build-Verzeichnis und ohne die heruntergeladenen Quellen).

Ich glaube also immer noch, dass dies eine sehr gültige Feature-Anfrage ist und unser Leben viel einfacher machen würde. Nur weil eine Funktion missbraucht werden könnte und andere Funktionen bei Verwendung beeinträchtigen könnte, heißt das nicht, dass man sie um jeden Preis vermeiden sollte. Betrachten Sie es einfach als zusätzliche Verwendung für ein leistungsfähigeres Werkzeug.

Aber ich habe keine Möglichkeit, nach fehlgeschlagenen Builds zur Analyse auf das Build-Verzeichnis zuzugreifen

Klingt wie eine Feature-Anfrage für Buildkit. Dies ist definitiv ein bekanntes fehlendes Stück.

Man könnte dies heute tun, indem man ein Ziel zum Abrufen des "Build-Verzeichnisses" hat. Sie würden das einfach nach einem fehlgeschlagenen Lauf ausführen, alles sollte noch zwischengespeichert werden, Sie brauchen nur den letzten Schritt, um die Daten abzurufen.
Verstehe jedoch, dass dies ein kleiner Workaround ist.

Außerdem verstehe ich nicht, warum ich durch Reifen springen sollte, wie einen neuen Container aus einem alten zu bauen, nur um mein Build-Verzeichnis loszuwerden

Können Sie näher erklären, was Sie hier wollen/erwarten?

Können Sie näher erklären, was Sie hier wollen/erwarten?

In diesem Fall wollen Sie nur 2 Fliegen mit einer Klappe schlagen:

  • eine einfache Möglichkeit haben, auf Zwischenergebnisse des Hosts zuzugreifen (hier "build dir analysis")
  • Stellen Sie sicher, dass dieser Speicherplatz das neu erstellte Image nicht verschmutzt

Da dies und alle anderen Fälle, in denen der Build-Container (sowie "Container-Build") das Bauen so schmerzlos wie möglich machen muss, so viel eleganter gelöst werden würden, indem man einfach -v -Funktionalität bereitstellt, habe ich eine schwierig, den Widerstand zu verstehen, um diese Funktion bereitzustellen. Abgesehen von der "cache-aware"-Funktionalität, die buildkit scheinbar bietet, sehe ich darin nur einen verworrenen und umständlichen Weg, um genau diese Funktionalität zu erreichen, und das auch nur teilweise. (Und in vielen Fällen, in denen Caching das Hauptziel ist, würde es auch durch -v gelöst werden, auf Kosten der Notwendigkeit, das gemountete Volume für einen bestimmten Container zu sperren, solange es läuft, aber der Cache mit buildkit hat die gleichen Einschränkungen.)

Können Sie näher erklären, was Sie hier wollen/erwarten?

Ich verwende einen mehrstufigen Build-Prozess, bei dem die Build-Umgebung selbst containerisiert ist und das Endergebnis ein Image ist, das nur die Anwendung und die Laufzeitumgebung (ohne die Build-Tools) enthält.

Was ich möchte, ist eine Möglichkeit für den vorläufigen Docker-Build-Container, Unit-Test- und Code-Coverage-Ergebnisdateien sowohl bei einem erfolgreichen Build als auch bei einem fehlgeschlagenen Build an das Hostsystem auszugeben, ohne sie an das Build-Ausgabe-Image übergeben zu müssen für die Extraktion (weil der gesamte Build-Prozess kurzgeschlossen wird, wenn die Komponententests im früheren Schritt nicht bestanden werden, sodass in dieser Situation kein Ausgabebild vorhanden ist, und dann benötigen wir die Ergebnisse der Komponententests am meisten) . Ich denke, wenn ein Host-Volume im Docker-Build-Prozess bereitgestellt werden könnte, können die internen Testbefehle ihre Ausgabe an den bereitgestellten Ordner leiten.

@Mcattle
In der Tat sehr ähnlich auch zu (einer der Funktionalitäten), die ich brauche.
Seit ich vor ein paar Tagen zu buildah gewechselt bin, habe ich alle Funktionen, die ich brauchte, und noch mehr. Das Debuggen meines Build-Containers wäre ohne die Möglichkeit, den verlassenen Container und die Links zum Host flexibel einzugeben, absolut unmöglich gewesen. Jetzt bin ich ein glücklicher Camper. (Es tut mir leid, die Party mit einem "Konkurrenten" zum Absturz zu bringen, ich würde diesen Kommentar gerne entfernen, wenn ich Anstoß nehme, aber es war eine so effektive Lösung für die in diesem Thread vorgestellten Anwendungsfälle, dass ich dachte, ich sollte es erwähnen.) .

Es ist kein Vergehen zu sagen, dass ein anderes Tool besser zu Ihren Anforderungen passt.

Wenn etwas für Sie funktioniert, ist das wunderbar.

Die Mängel sowohl des v1-Builders in Docker als auch des Buildkit-Builders sind in diesem Zusammenhang ziemlich gut bekannt und es wird untersucht, wie diese behoben werden können, nur vorzugsweise ohne auf Bind-Mounts vom Client zurückgreifen zu müssen.
GitHub [email protected] schrieb:
„@mcattle
In der Tat sehr ähnlich auch zu (einer der Funktionalitäten), die ich brauche.
Seit ich vor ein paar Tagen zu buildah gewechselt bin, habe ich alle Funktionen, die ich brauchte, und noch mehr. Das Debuggen meines Build-Containers wäre ohne die Möglichkeit, den verlassenen Container und die Links zum Host flexibel einzugeben, absolut unmöglich gewesen. Jetzt bin ich ein glücklicher Camper. (Es tut mir leid, die Party mit einem "Konkurrenten" zum Absturz zu bringen, ich würde diesen Kommentar gerne entfernen, wenn ich Anstoß nehme, aber es war eine so effektive Lösung für die in diesem Thread vorgestellten Anwendungsfälle, dass ich dachte, ich sollte es erwähnen.) .“


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail, zeigen Sie sie auf GitHub an oder kündigen Sie sie.

ohne auf Bindungshalterungen des Clients zurückgreifen zu müssen.

Hier erkläre ich, warum eine Build-Time-Option -v nicht mehr auf die Reproduzierbarkeit zurückgreift oder diese opfert, als dass sie zum Build-Zeitpunkt von den Netzwerkressourcen abhängt.

https://github.com/moby/moby/issues/14080#issuecomment -484314314 :

KOPIEREN || REMOTE_FETCH || lesen()

  • Welche davon sind am besten reproduzierbar?

Ich gehe mit buildah für die Build-Zeit -v (und cgroupsv2) auch.

@mcattle Ich hatte die gleiche Anforderung. Ich habe es mit Beschriftung gelöst.

Ich gehe mit buildah für die Build-Zeit -v (und cgroupsv2) auch.

Ich erwäge ernsthaft den Wechsel von Ubuntu (das nur Docker hat) zu Fedora (das Docker durch Podman/Buildah ersetzt hat) auf unserem Build-Server wegen der "-v"-Unterstützung.

Übrigens. Podman unterstützt auch den Rootless-Modus und schien bisher vollständig Docker-kompatibel zu sein (mit Ausnahme von Unterschieden in den Auswirkungen von --user/USER und dem Zwischenspeichern von Bildern, die sich aus der Verwendung des Rootless-Modus ergeben, anstatt wie der Docker-Daemon als Root ausgeführt zu werden).

PS. während cgroups v2 für den Rootless-Betrieb benötigt wird, geht es bei der Unterstützung dafür mehr um die Container-Laufzeit als um Docker. Wenn Sie CRun anstelle von RunC verwenden (wie es Fedora tut), hätten Sie cgroups v2-Unterstützung. RunC hat etwas Unterstützung für v2 und rootless in Git, aber ich hatte einige Probleme, als ich es vor einigen Monaten auf Fedora (31) getestet habe.

BEARBEITEN: Ubuntu hat podman/buildah/etc in Groovy, nur nicht in der neuesten Version 20.04 LTS, ich glaube, von Debian instabil importiert. Es wurde nicht auf LTS zurückportiert, zumindest noch nicht. Während es seit 2018 in Fedora ist, denke ich.

@eero-t Vielleicht könnten Sie Ihren Anwendungsfall beschreiben und was in den Optionen fehlt, die BuildKit derzeit bietet, die nicht für diese geeignet sind.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen