Używam docker-container na Amazon EC2. Obecnie dodałem poświadczenia AWS do Dockerfile. Czy możesz mi powiedzieć, jak najlepiej to zrobić?
amazon-web-services
docker
docker-compose
suraj chopade
źródło
źródło
Odpowiedzi:
Najlepszym sposobem jest użycie roli IAM i nie zajmowanie się w ogóle poświadczeniami. (patrz http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html )
Poświadczenia można pobrać z
http://169.254.169.254.....
Ponieważ jest to prywatny adres IP, może być dostępny tylko z instancji EC2.Wszystkie nowoczesne biblioteki klienckie AWS „wiedzą”, jak z tego miejsca pobierać, odświeżać i używać poświadczeń. W większości przypadków nie musisz nawet o tym wiedzieć. Po prostu uruchom ec2 z właściwą rolą IAM i gotowe.
Opcjonalnie możesz przekazać je w czasie wykonywania jako zmienne środowiskowe (tj.
docker run -e AWS_ACCESS_KEY_ID=xyz -e AWS_SECRET_ACCESS_KEY=aaa myimage
)Możesz uzyskać dostęp do tych zmiennych środowiskowych, uruchamiając printenv na terminalu.
źródło
AWS_SECRET_ACCESS_KEY
, nieAWS_SECRET_KEY
, w każdym razie Twoja odpowiedź była bardzo pomocna. Dziękuję Ci.Wiele się zmieniło w Dockerze od czasu zadania tego pytania, więc oto próba zaktualizowanej odpowiedzi.
Po pierwsze, w szczególności z poświadczeniami AWS na kontenerach już uruchomionych w chmurze, użycie ról IAM, jak sugeruje Vor, jest naprawdę dobrą opcją. Jeśli możesz to zrobić, dodaj jeszcze jeden plus jeden do jego odpowiedzi i pomiń resztę.
Gdy zaczniesz uruchamiać rzeczy poza chmurą lub masz inny typ sekretu, są dwa kluczowe miejsca, w których odradzam przechowywanie sekretów:
Zmienne środowiskowe: kiedy są zdefiniowane w kontenerze, każdy proces wewnątrz kontenera ma do nich dostęp, są widoczne przez / proc, aplikacje mogą zrzucić swoje środowisko na standardowe wyjście, gdzie jest przechowywane w dziennikach, a co najważniejsze, pojawiają się w czysty tekst podczas sprawdzania kontenera.
W samym obrazie: obrazy często są wypychane do rejestrów, w których wielu użytkowników ma dostęp do ściągania, czasami bez żadnych poświadczeń wymaganych do pobrania obrazu. Nawet jeśli usuniesz sekret z jednej warstwy, obraz można zdemontować za pomocą typowych narzędzi Linuksa, takich jak
tar
a sekret można znaleźć w kroku, w którym został po raz pierwszy dodany do obrazu.Więc jakie są inne opcje dla wpisów tajnych w kontenerach Docker?
Opcja A: Jeśli potrzebujesz tego sekretu tylko podczas budowania obrazu, nie możesz użyć sekretu przed rozpoczęciem kompilacji i nie masz jeszcze dostępu do BuildKit, wtedy kompilacja wieloetapowa jest najlepszą ze złych opcji. Należy dodać sekret do początkowych etapów kompilacji, użyć go tam, a następnie skopiować dane wyjściowe tego etapu bez klucza tajnego do etapu wydania i tylko wypchnąć ten etap wydania na serwery rejestru. Ten sekret nadal znajduje się w pamięci podręcznej obrazu na serwerze kompilacji, więc używam go tylko w ostateczności.
Opcja B: Również w czasie kompilacji, jeśli możesz użyć BuildKita, który został wydany w 18.09, istnieją obecnie eksperymentalne funkcje umożliwiające wstrzykiwanie sekretów jako montowanie woluminu dla pojedynczej linii RUN. To mocowanie nie jest zapisywane na warstwach obrazu, więc możesz uzyskać dostęp do sekretu podczas kompilacji bez obawy, że zostanie on przesłany na publiczny serwer rejestru. Wynikowy plik Dockerfile wygląda następująco:
Budujesz go za pomocą polecenia w wersji 18.09 lub nowszej, na przykład:
Opcja C:W czasie wykonywania na pojedynczym węźle, bez trybu Swarm lub innej aranżacji, możesz zamontować poświadczenia jako wolumin tylko do odczytu. Dostęp do tego poświadczenia wymaga takiego samego dostępu, jaki miałbyś poza platformą Docker do tego samego pliku poświadczeń, więc nie jest lepszy ani gorszy niż scenariusz bez platformy Docker. Co najważniejsze, zawartość tego pliku nie powinna być widoczna podczas sprawdzania kontenera, przeglądania dzienników lub wysyłania obrazu na serwer rejestru, ponieważ w każdym scenariuszu wolumin jest poza tym. Wymaga to skopiowania poświadczeń na hoście platformy Docker, niezależnie od wdrożenia kontenera. (Uwaga: każdy, kto może uruchamiać kontenery na tym hoście, może zobaczyć twoje poświadczenia, ponieważ dostęp do interfejsu docker API ma root na hoście, a root może przeglądać pliki dowolnego użytkownika. Jeśli nie ufasz użytkownikom z rootem na hoście ,
Dla a
docker run
wygląda to tak:Lub w przypadku pliku redagowania miałbyś:
Opcja D:Dzięki narzędziom do orkiestracji, takim jak Swarm Mode i Kubernetes, mamy teraz obsługę sekretów, która jest lepsza niż wolumen. W trybie Swarm plik jest szyfrowany w systemie plików menedżera (chociaż klucz odszyfrowywania również jest tam często, co pozwala na ponowne uruchomienie menedżera bez wprowadzania klucza deszyfrowania przez administratora). Co ważniejsze, sekret jest wysyłany tylko do pracowników, którzy go potrzebują (uruchamianie kontenera z tym sekretem), jest przechowywany tylko w pamięci pracownika, nigdy na dysku i jest wstrzykiwany jako plik do kontenera z tmpfs uchwyt. Użytkownicy na hoście spoza roju nie mogą zamontować tego sekretu bezpośrednio do własnego kontenera, jednak mając otwarty dostęp do interfejsu API platformy docker, mogliby wyodrębnić sekret z kontenera działającego w węźle, więc ponownie ogranicz dostęp do API. Z redagowania ten tajny zastrzyk wygląda tak:
Włączasz tryb roju
docker swarm init
za pomocą dla pojedynczego węzła, a następnie postępuj zgodnie ze wskazówkami dotyczącymi dodawania kolejnych węzłów. Możesz utworzyć sekret na zewnątrz za pomocądocker secret create aws_creds $HOME/.aws/credentials
. I wdrażasz plik redagowania zdocker stack deploy -c docker-compose.yml stack_name
.Często tworzę moje sekrety za pomocą skryptu z: https://github.com/sudo-bmitch/docker-config-update
Opcja E: Istnieją inne narzędzia do zarządzania tajemnicami, a moim ulubionym jest Vault, ponieważ daje możliwość tworzenia ograniczonych czasowo sekretów, które automatycznie wygasają. Każda aplikacja otrzymuje wtedy swój własny zestaw tokenów do żądania sekretów, a tokeny te dają im możliwość żądania tych ograniczonych czasowo sekretów tak długo, jak mogą dotrzeć do serwera repozytorium. Zmniejsza to ryzyko, jeśli sekret zostanie kiedykolwiek usunięty z sieci, ponieważ albo nie zadziała, albo szybko wygaśnie. Funkcjonalność specyficzna dla AWS for Vault jest udokumentowana pod adresem https://www.vaultproject.io/docs/secrets/aws/index.html
źródło
Innym podejściem jest przekazanie kluczy z komputera hosta do kontenera Dockera. Możesz dodać następujące wiersze do
docker-compose
pliku.źródło
AWS_DEFAULT_REGION
docs.aws.amazon.com/cli/latest/userguide/ ...AWS_SESSION_TOKEN=${AWS_SESSION_TOKEN}
Jeszcze innym podejściem jest utworzenie tymczasowego woluminu tylko do odczytu w docker-compose.yaml. AWS CLI i SDK (jak boto3 lub AWS SDK dla Java itp.) Szukają
default
profilu w~/.aws/credentials
pliku.Jeśli chcesz używać innych profili, wystarczy wyeksportować zmienną AWS_PROFILE przed uruchomieniem
docker-compose
poleceniaexport AWS_PROFILE=some_other_profile_name
W tym przykładzie użyłem użytkownika root w dockerze. Jeśli używasz innego użytkownika, po prostu przejdź
/root/.aws
do katalogu domowego użytkownika:ro
- oznacza tylko do odczytu objętość dockeraJest to bardzo przydatne, gdy masz wiele profili w
~/.aws/credentials
pliku i używasz również usługi MFA. Jest to również przydatne, gdy chcesz przetestować lokalnie docker-container przed wdrożeniem go w ECS, na którym masz role uprawnień, ale lokalnie tego nie robisz.źródło
"%UserProfile%\.aws"
. Zakładam więc, że trzeba się przesiąść:- ~/.aws/:/root/.aws:ro
na- %UserProfile%\.aws:/root/.aws:ro
- host:container
składni, jeśli plik / folder nie istnieje na hoście, który został utworzony (jako root), a awscli nie podziękuje ci za podanie mu zerobajtowego pliku. Powinieneś użyć "długiej formy", która określa typ to bind, ścieżkę hosta i ścieżkę kontenera w oddzielnych wierszach, to się nie powiedzie, jeśli plik nie istnieje, co chcesz w swoim docker-compose.dev. yml, ale nie w pliku docker-compose.yml (wdrożenie prod / AWS).Możesz stworzyć
~/aws_env_creds
zawierającądodaj poniżej wartość (Zastąp swój klucz)
„esc”, aby zapisać plik.
Uruchom i przetestuj pojemnik
źródło