Ich verwende Docker-Container auf Amazon EC2. Derzeit habe ich AWS Credentials zu Dockerfile hinzugefügt. Könnten Sie mir bitte den besten Weg dazu mitteilen?
Ich verwende Docker-Container auf Amazon EC2. Derzeit habe ich AWS Credentials zu Dockerfile hinzugefügt. Könnten Sie mir bitte den besten Weg dazu mitteilen?
Antworten:
Der beste Weg ist, die IAM-Rolle zu verwenden und überhaupt nicht mit Anmeldeinformationen umzugehen. (sehen http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html )
Anmeldeinformationen konnten von abgerufen werden http://169.254.169.254.....
Da dies eine private IP-Adresse ist, kann nur von EC2-Instanzen aus darauf zugegriffen werden.
Alle modernen AWS-Client-Bibliotheken "wissen", wie Anmeldeinformationen von dort abgerufen, aktualisiert und verwendet werden. In den meisten Fällen müssen Sie also nicht einmal darüber Bescheid wissen. Führen Sie einfach ec2 mit der richtigen IAM-Rolle aus und los geht's.
Optional können Sie sie zur Laufzeit als Umgebungsvariablen übergeben (z docker run -e AWS_ACCESS_KEY_ID=xyz -e AWS_SECRET_ACCESS_KEY=aaa myimage
)
Sie können auf diese Umgebungsvariablen zugreifen, indem Sie printenv am Terminal ausführen.
AWS_SECRET_ACCESS_KEY
nicht eingeben AWS_SECRET_KEY
, trotzdem war Ihre Antwort sehr hilfreich. Danke.
In Docker hat sich viel geändert, seit diese Frage gestellt wurde. Hier ist ein Versuch, eine aktualisierte Antwort zu finden.
Erstens, insbesondere mit AWS-Anmeldeinformationen für Container, die bereits in der Cloud ausgeführt werden, ist die Verwendung von IAM-Rollen, wie Vor vorschlägt, eine wirklich gute Option. Wenn Sie das können, fügen Sie seiner Antwort ein weiteres plus eins hinzu und überspringen Sie den Rest.
Sobald Sie anfangen, Dinge außerhalb der Cloud auszuführen oder eine andere Art von Geheimnis haben, gibt es zwei wichtige Stellen, die ich gegen das Speichern von Geheimnissen empfehle :
Umgebungsvariablen: Wenn diese in einem Container definiert sind, hat jeder Prozess im Container Zugriff auf sie, sie sind über / proc sichtbar, Apps können ihre Umgebung an stdout ausgeben, wo sie in den Protokollen gespeichert wird, und vor allem in Klartext, wenn Sie den Behälter inspizieren.
Im Bild selbst: Bilder werden häufig in Register verschoben, in denen viele Benutzer Zugriff auf das Bild haben, manchmal ohne Anmeldeinformationen, die zum Abrufen des Bildes erforderlich sind. Selbst wenn Sie das Geheimnis aus einer Ebene löschen, kann das Image mit gängigen Linux-Dienstprogrammen wie zerlegt werden, tar
und das Geheimnis kann in dem Schritt gefunden werden, in dem es dem Image zum ersten Mal hinzugefügt wurde.
Welche anderen Optionen gibt es für Geheimnisse in Docker-Containern?
Option A: Wenn Sie dieses Geheimnis nur während der Erstellung Ihres Images benötigen, das Geheimnis vor Beginn der Erstellung nicht verwenden können und noch keinen Zugriff auf BuildKit haben, ist eine mehrstufige Erstellung die beste der schlechten Optionen. Sie würden das Geheimnis zu den Anfangsphasen des Builds hinzufügen, es dort verwenden und dann die Ausgabe dieser Stufe ohne das Geheimnis in Ihre Release-Phase kopieren und diese Release-Phase nur auf die Registrierungsserver übertragen. Dieses Geheimnis befindet sich immer noch im Image-Cache auf dem Build-Server, daher verwende ich dies normalerweise nur als letzten Ausweg.
Option B: Wenn Sie während der Build-Zeit BuildKit verwenden können, das am 18.09 veröffentlicht wurde, gibt es derzeit experimentelle Funktionen , mit denen Sie Geheimnisse als Volume-Mount für eine einzelne RUN-Zeile einfügen können. Dieser Mount wird nicht in die Image-Ebenen geschrieben, sodass Sie während des Builds auf das Geheimnis zugreifen können, ohne befürchten zu müssen, dass es auf einen öffentlichen Registrierungsserver übertragen wird. Das resultierende Dockerfile sieht folgendermaßen aus:
# syntax = docker/dockerfile:experimental
FROM python:3
RUN pip install awscli
RUN --mount=type=secret,id=aws,target=/root/.aws/credentials aws s3 cp s3://... ...
Und Sie erstellen es mit einem Befehl in 18.09 oder neuer wie:
DOCKER_BUILDKIT=1 docker build -t your_image --secret id=aws,src=$HOME/.aws/credentials .
Option C:Zur Laufzeit auf einem einzelnen Knoten ohne Swarm-Modus oder andere Orchestrierung können Sie die Anmeldeinformationen als schreibgeschütztes Volume bereitstellen. Für den Zugriff auf diese Anmeldeinformationen ist derselbe Zugriff erforderlich, den Sie außerhalb von Docker auf dieselbe Anmeldeinformationsdatei haben würden. Daher ist er nicht besser oder schlechter als das Szenario ohne Docker. Am wichtigsten ist, dass der Inhalt dieser Datei nicht sichtbar sein sollte, wenn Sie den Container untersuchen, die Protokolle anzeigen oder das Image an einen Registrierungsserver senden, da das Volume in jedem Szenario außerhalb davon liegt. Dies erfordert, dass Sie Ihre Anmeldeinformationen getrennt von der Bereitstellung des Containers auf den Docker-Host kopieren. (Beachten Sie, dass jeder, der Container auf diesem Host ausführen kann, Ihre Anmeldeinformationen anzeigen kann, da der Zugriff auf die Docker-API root auf dem Host ist und root die Dateien aller Benutzer anzeigen kann. Wenn Sie Benutzern mit root auf dem Host nicht vertrauen ,
Für a docker run
sieht das so aus:
docker run -v $HOME/.aws/credentials:/home/app/.aws/credentials:ro your_image
Oder für eine Erstellungsdatei hätten Sie:
version: '3'
services:
app:
image: your_image
volumes:
- $HOME/.aws/credentials:/home/app/.aws/credentials:ro
Option D:Mit Orchestrierungswerkzeugen wie Swarm Mode und Kubernetes haben wir jetzt Unterstützung für Geheimnisse, die besser ist als ein Volume. Im Schwarmmodus wird die Datei im Manager-Dateisystem verschlüsselt (obwohl der Entschlüsselungsschlüssel häufig auch vorhanden ist, sodass der Manager neu gestartet werden kann, ohne dass ein Administrator einen Entschlüsselungsschlüssel eingibt). Noch wichtiger ist, dass das Geheimnis nur an die Mitarbeiter gesendet wird, die das Geheimnis benötigen (einen Container mit diesem Geheimnis ausführen), nur im Speicher des Arbeiters gespeichert wird, niemals auf der Festplatte, und als Datei mit einem tmpfs in den Container eingefügt wird montieren. Benutzer auf dem Host außerhalb von Swarm können dieses Geheimnis nicht direkt in ihren eigenen Container einbinden. Mit offenem Zugriff auf die Docker-API können sie das Geheimnis jedoch aus einem laufenden Container auf dem Knoten extrahieren. Beschränken Sie also erneut, wer diesen Zugriff auf das hat API. Nach dem Verfassen sieht diese geheime Injektion so aus:
version: '3.7'
secrets:
aws_creds:
external: true
services:
app:
image: your_image
secrets:
- source: aws_creds
target: /home/user/.aws/credentials
uid: '1000'
gid: '1000'
mode: 0700
Sie aktivieren den Schwarmmodus mit docker swarm init
für einen einzelnen Knoten und folgen dann den Anweisungen zum Hinzufügen weiterer Knoten. Sie können das Geheimnis extern mit erstellen docker secret create aws_creds $HOME/.aws/credentials
. Und Sie stellen die Erstellungsdatei mit bereit docker stack deploy -c docker-compose.yml stack_name
.
Ich versioniere meine Geheimnisse oft mit einem Skript von: https://github.com/sudo-bmitch/docker-config-update
Option E: Es gibt andere Tools zum Verwalten von Geheimnissen. Mein Favorit ist Vault, da damit zeitlich begrenzte Geheimnisse erstellt werden können, die automatisch ablaufen. Jede Anwendung erhält dann einen eigenen Satz von Token, um Geheimnisse anzufordern, und diese Token geben ihnen die Möglichkeit, diese zeitlich begrenzten Geheimnisse anzufordern, solange sie den Tresorserver erreichen können. Dies verringert das Risiko, wenn jemals ein Geheimnis aus Ihrem Netzwerk entfernt wird, da es entweder nicht funktioniert oder schnell abläuft. Die für AWS for Vault spezifischen Funktionen sind unter https://www.vaultproject.io/docs/secrets/aws/index.html dokumentiert
Ein anderer Ansatz besteht darin, die Schlüssel vom Host-Computer an den Docker-Container zu übergeben. Sie können der docker-compose
Datei folgende Zeilen hinzufügen .
services:
web:
build: .
environment:
- AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}
- AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}
- AWS_DEFAULT_REGION=${AWS_DEFAULT_REGION}
AWS_DEFAULT_REGION
docs.aws.amazon.com/cli/latest/userguide/…
AWS_SESSION_TOKEN=${AWS_SESSION_TOKEN}
Ein weiterer Ansatz besteht darin, ein temporäres schreibgeschütztes Volume in docker-compose.yaml zu erstellen. AWS CLI und SDK (wie Boto3 oder AWS SDK für Java usw.) suchen nach default
Profilen in ~/.aws/credentials
Dateien.
Wenn Sie andere Profile verwenden möchten, müssen Sie nur die Variable AWS_PROFILE exportieren, bevor Sie den docker-compose
Befehl ausführen
export AWS_PROFILE=some_other_profile_name
version: '3'
services:
service-name:
image: docker-image-name:latest
environment:
- AWS_PROFILE=${AWS_PROFILE}
volumes:
- ~/.aws/:/root/.aws:ro
In diesem Beispiel habe ich Root-Benutzer auf Docker verwendet. Wenn Sie einen anderen Benutzer verwenden, wechseln Sie einfach in das Basisverzeichnis /root/.aws
des Benutzers
:ro
- steht für schreibgeschütztes Docker-Volume
Dies ist sehr hilfreich, wenn Sie mehrere Profile in der ~/.aws/credentials
Datei haben und auch MFA verwenden. Auch hilfreich, wenn Sie Docker-Container lokal testen möchten, bevor Sie ihn auf ECS bereitstellen, auf dem Sie IAM-Rollen haben, lokal jedoch nicht.
"%UserProfile%\.aws"
. Also - ~/.aws/:/root/.aws:ro
- %UserProfile%\.aws:/root/.aws:ro
- host:container
Syntax, wenn die Datei / der Ordner nicht auf dem Host vorhanden ist, der erstellt wird (als Root), und die awscli wird Ihnen nicht dafür danken, dass Sie ihr eine Null-Byte-Datei zugeführt haben. Sie sollten die "lange Form" verwenden, die angibt, dass der Typ bind, der Hostpfad und der Containerpfad in separaten Zeilen sind. Dies schlägt fehl, wenn die Datei nicht vorhanden ist. Dies ist das, was Sie in Ihrer docker-compose.dev möchten. yml aber nicht in Ihrer docker-compose.yml (prod / AWS-Bereitstellung).
Sie könnten ~/aws_env_creds
enthalten erstellen
touch ~/aws_env_creds
chmod 777 ~/aws_env_creds
vi ~/aws_env_creds
Fügen Sie den folgenden Wert hinzu (Ersetzen Sie Ihren Schlüssel)
AWS_ACCESS_KEY_ID=AK_FAKE_KEY_88RD3PNY
AWS_SECRET_ACCESS_KEY=BividQsWW_FAKE_KEY_MuB5VAAsQNJtSxQQyDY2C
"esc" zum Speichern der Datei.
Führen Sie den Container aus und testen Sie ihn
my_service:
build: .
image: my_image
env_file:
- ~/aws_env_creds