AWS kimlik bilgilerini Docker konteynerine geçirmenin en iyi yolu hangisidir?


110

Amazon EC2'de docker-container çalıştırıyorum. Şu anda Dockerfile'a AWS Kimlik Bilgilerini ekledim. Bunu yapmanın en iyi yolunu bana bildirir misin lütfen?


2
Dizüstü bilgisayarımda, onu oraya ittiğimde ECS'de sihirli bir şekilde çalışması gereken bir Docker kapsayıcısı çalıştırsam nasıl olur? Sanırım --volume bayrağını kullanıyorum ... birisi çoktan cevaplamış olmalı ...
Randy L

Yanıtlar:


114

En iyi yol, IAM Rolünü kullanmak ve kimlik bilgileriyle hiç uğraşmamaktır. (bkz. http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html )

Kimlik bilgileri buradan alınabilir. http://169.254.169.254..... Bu özel bir ip adresi olduğundan, yalnızca EC2 bulut sunucularından erişilebilir.

Tüm modern AWS istemci kitaplıkları, kimlik bilgilerinin buradan nasıl alınacağını, yenileneceğini ve kullanılacağını "bilir". Yani çoğu durumda bunu bilmenize bile gerek yok. Sadece ec2'yi doğru IAM rolüyle çalıştırın ve gitmeniz iyi olur.

Bir seçenek olarak, bunları çalışma zamanında ortam değişkenleri (yani docker run -e AWS_ACCESS_KEY_ID=xyz -e AWS_SECRET_ACCESS_KEY=aaa myimage) olarak iletebilirsiniz.

Bu ortam değişkenlerine terminalde printenv'i çalıştırarak erişebilirsiniz.


41
Üretimde güvenlikten ödün vermeyen yerel geliştirme / test sırasında bunu yapmanın iyi bir yolu var mı? Bir görüntünün tam olarak dağıtılmadan çalıştığından emin olmak isterim.
honktronic

3
ortam değişkenleriyle paylaştığım bir alternatif, geliştirici / yerel ortamda iyi çalışıyor.
Vor

5
Bunun bir yazım hatası olup olmadığını merak ediyorum, ama girmem gerekiyor AWS_SECRET_ACCESS_KEY, hayır AWS_SECRET_KEY, yine de cevabınız çok yardımcı oldu. Teşekkür ederim.
Akavall

14
Basitçe söylemek gerekirse (bu yanıta benim yaptığım gibi ulaşanlar için); EC2 üzerinde çalışan bir docker container, ana bilgisayar bulut sunucusuyla aynı rolü devralır. (Konteynırlarımdaki AWS CLI komutları kendilerine hiçbir kimlik bilgisi aktarılmamasına rağmen gizemli bir şekilde çalıştığında böyle bir "ELI5" e ihtiyacım vardı!)
Adam Westbrook

9
Geliştirme amacıyla ortam değişkenine atamak için yerel profilinizden anahtar değerleri almanın kolay yolu ( cameroneckelberry.co/words/… ' de önerildiği gibi ): "aws --profile default configure get aws_access_key_id"
Altair7852

106

Bu soru sorulduğundan beri Docker'da çok şey değişti, işte güncellenmiş bir cevap için bir deneme.

Öncelikle, özellikle bulutun içinde zaten çalışan konteynerler üzerindeki AWS kimlik bilgileriyle, Vor'un önerdiği gibi IAM rollerini kullanmak gerçekten iyi bir seçenek. Bunu yapabilirseniz, cevabına bir artı bir daha ekleyin ve geri kalanını atlayın.


Bulut dışında bir şeyler çalıştırmaya başladığınızda veya farklı türde bir sırrınız olduğunda, sır saklamaya karşı önerdiğim iki önemli yer vardır :

  1. Ortam değişkenleri: Bunlar bir kapsayıcıda tanımlandığında, kapsayıcı içindeki her işlem bunlara erişebilir, / proc aracılığıyla görülebilirler, uygulamalar ortamlarını günlüklerde depolandığı stdout'a atabilir ve en önemlisi, içinde görünürler. kabı incelerken metni temizle.

  2. Görüntünün kendisinde: görüntüler genellikle birçok kullanıcının çekerek erişebildiği, bazen görüntüyü çekmek için herhangi bir kimlik bilgisi gerekmeden kayıt defterlerine gönderilir. Sırrı bir katmandan silseniz bile, görüntü gibi yaygın Linux yardımcı programlarıyla demonte edilebilir tarve sır, görüntüye ilk eklendiği adımdan bulunabilir.


Peki Docker konteynerlerinde sırlar için başka hangi seçenekler var?

Seçenek A: Bu sırra yalnızca görüntünüzün oluşturulması sırasında ihtiyacınız varsa, sırrı derleme başlamadan önce kullanamıyorsanız ve henüz BuildKit'e erişiminiz yoksa, çok aşamalı bir derleme kötü seçeneklerin en iyisidir. Sırrı, yapının ilk aşamalarına eklersiniz, orada kullanırsınız ve ardından bu aşamanın çıktısını yayın aşamanızın sırrı olmadan kopyalarsınız ve yalnızca bu sürüm aşamasını kayıt sunucularına aktarırsınız. Bu sır hala yapı sunucusundaki görüntü önbelleğinde, bu yüzden bunu yalnızca son çare olarak kullanma eğilimindeyim.

Seçenek B: Ayrıca, derleme süresi boyunca, 18.09'da piyasaya sürülen BuildKit'i kullanabiliyorsanız, şu anda tek bir RUN hattı için bir birim bağlama olarak sırların enjeksiyonuna izin veren deneysel özellikler bulunmaktadır. Bu bağlama, görüntü katmanlarına yazılmaz, bu nedenle, derleme sırasında gizli bilgilere, genel bir kayıt sunucusuna gönderileceğinden endişelenmeden erişebilirsiniz. Ortaya çıkan Dockerfile şuna benzer:

# 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://... ...

Ve bunu 18.09 veya daha yeni bir komutla inşa edersiniz:

DOCKER_BUILDKIT=1 docker build -t your_image --secret id=aws,src=$HOME/.aws/credentials .

Seçenek C:Swarm Modu veya başka bir düzenleme olmadan tek bir düğümdeki çalışma zamanında, kimlik bilgilerini salt okunur bir birim olarak bağlayabilirsiniz. Bu kimlik bilgilerine erişim, docker dışında aynı kimlik bilgileri dosyasına sahip olacağınız erişimin aynısını gerektirir, bu nedenle docker olmadan senaryodan daha iyi veya daha kötü değildir. En önemlisi, kapsayıcıyı incelediğinizde, günlükleri görüntülediğinizde veya görüntüyü bir kayıt defteri sunucusuna gönderdiğinizde bu dosyanın içeriği görünmemelidir, çünkü birim her senaryoda bunun dışındadır. Bu, konteynırın dağıtımından ayrı olarak, kimlik bilgilerinizi docker ana bilgisayarına kopyalamanızı gerektirir. (Unutmayın, docker API'ye erişim ana bilgisayarda kök olduğundan ve kök herhangi bir kullanıcının dosyalarını görüntüleyebileceğinden, bu ana bilgisayarda kapsayıcıları çalıştırma becerisine sahip olan herkes kimlik bilgilerinizi görüntüleyebilir. ,

Bir için docker runbu şuna benzer:

docker run -v $HOME/.aws/credentials:/home/app/.aws/credentials:ro your_image

Veya bir oluşturma dosyası için şunlara sahip olursunuz:

version: '3'
services:
  app:
    image: your_image
    volumes:
    - $HOME/.aws/credentials:/home/app/.aws/credentials:ro

Seçenek D:Swarm Mode ve Kubernetes gibi düzenleme araçlarıyla, artık bir ciltten daha iyi sır desteğine sahibiz. Swarm Modu ile, dosya yönetici dosya sisteminde şifrelenir (şifre çözme anahtarı da genellikle oradadır ve yöneticinin şifre çözme anahtarı girmeden yöneticinin yeniden başlatılmasına izin verir). Daha da önemlisi, sır yalnızca sırra ihtiyaç duyan işçilere gönderilir (bu sır ile bir konteyner çalıştırılır), yalnızca çalışan belleğe kaydedilir, hiçbir zaman diskte saklanmaz ve kapsayıcıya tmpfs ile bir dosya olarak enjekte edilir. montaj. Sürü dışındaki ana bilgisayardaki kullanıcılar bu sırrı doğrudan kendi kapsayıcılarına bağlayamazlar, ancak docker API'sine açık erişimle, sırrı düğümdeki çalışan bir kapsayıcıdan çıkarabilirler, bu nedenle yine API. Oluşturmaktan bu gizli ekleme şuna benzer:

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

docker swarm initTek bir düğüm için ile sürü modunu açarsınız , ardından ek düğümler eklemek için talimatları izleyin. Sırrı harici olarak oluşturabilirsiniz docker secret create aws_creds $HOME/.aws/credentials. Ve oluşturma dosyasını docker stack deploy -c docker-compose.yml stack_name.

Sırlarımı genellikle şu adresten bir komut dosyası kullanarak değiştiririm: https://github.com/sudo-bmitch/docker-config-update

Seçenek E: Sırları yönetmek için başka araçlar da var ve benim favorim Vault'dur çünkü otomatik olarak sona eren zaman sınırlı sırlar oluşturma yeteneği verir. Her uygulama daha sonra gizli diziler istemek için kendi belirteç setine sahip olur ve bu belirteçler onlara kasa sunucusuna ulaşabildikleri sürece bu sınırlı sırları talep etme yeteneği sağlar. Bu, ağınızdan bir sır çıkarılırsa, işe yaramayacağı veya süresinin dolması hızlı olacağı için riski azaltır. AWS for Vault'a özgü işlevsellik https://www.vaultproject.io/docs/secrets/aws/index.html adresinde belgelenmiştir.


24

Diğer bir yaklaşım, anahtarları ana makineden docker konteynerine geçirmektir. docker-composeDosyaya aşağıdaki satırları ekleyebilirsiniz .

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}

3
Doğru bölge ortam değişkeni AWS_REGION'dır. Stackoverflow.com/questions/44151982/… sayfasına
John Camerin

3

7
AWS_DEFAULT_REGION kullandığımda, varsayılan bir bölgenin bulunamamasıyla ilgili bir istisna yaşadım. Arama yol açtı docs.aws.amazon.com/sdk-for-java/v1/developer-guide/... AWS_REGION ortam değişkeni belirtir hangi ve bu benim için çalıştı.
John Camerin

Geçici kimlik bilgileri kullanıyorsanız, o zaman da ihtiyacınız olabilirAWS_SESSION_TOKEN=${AWS_SESSION_TOKEN}
Davos

18

Yine başka bir yaklaşım, docker-compose.yaml'de geçici salt okunur birim oluşturmaktır. AWS CLI ve SDK (Java için boto3 veya AWS SDK gibi) dosyada defaultprofil arıyor ~/.aws/credentials.

Diğer profilleri kullanmak istiyorsanız, docker-composekomutu çalıştırmadan önce AWS_PROFILE değişkenini de dışa aktarmanız gerekir .

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

Bu örnekte docker üzerinde root user kullandım. Başka bir kullanıcı kullanıyorsanız, /root/.awskullanıcı ana dizinine geçin.

:ro - salt okunur docker hacmi anlamına gelir

~/.aws/credentialsDosyada birden çok profiliniz olduğunda ve ayrıca MFA kullanıyorsanız çok yararlıdır . Ayrıca, docker-container'ı IAM Rollerine sahip olduğunuz ancak yerel olarak sahip olmadığınız ECS'ye dağıtmadan önce yerel olarak test etmek istediğinizde de yararlıdır.


Windows üzerinde .aws` kataloğu bulunur "%UserProfile%\.aws". : Ben değiştirmek olduğunu varsayalım Yani - ~/.aws/:/root/.aws:roiçin- %UserProfile%\.aws:/root/.aws:ro
Artur Siepietowski

1
Bu, çok aşamalı değil, yalnızca tek derleme süreçleriyle çalışacaktır.
wlarcheveque

@wlarcheveque Detaylandırmak ister misiniz?
ErikE

- host:containerSözdizimini kullanırken ÇOK dikkatli olun , eğer dosya / klasör oluşturulduğu ana bilgisayarda (kök olarak) yoksa ve awscli onu sıfır baytlık bir dosya beslediğiniz için size teşekkür etmeyecektir. Tipin bind, ana bilgisayar yolu ve ayrı satırlarda konteyner yolu olduğunu belirten "uzun form" kullanmalısınız, bu dosya yoksa, docker-compose.dev'inizde istediğiniz şey budur. yml, ancak docker-compose.yml (prod / AWS dağıtımı) içinde değil.
dragon788

0

Şunları ~/aws_env_credsiçeren oluşturabilirsiniz :

touch ~/aws_env_creds
chmod 777 ~/aws_env_creds
vi ~/aws_env_creds

Bu değeri ekleyin (anahtarınızı değiştirin):

AWS_ACCESS_KEY_ID=AK_FAKE_KEY_88RD3PNY
AWS_SECRET_ACCESS_KEY=BividQsWW_FAKE_KEY_MuB5VAAsQNJtSxQQyDY2C

Dosyayı kaydetmek için "esc" tuşuna basın.

Konteyneri çalıştırın ve test edin:

 my_service:
      build: .
      image: my_image
      env_file:
        - ~/aws_env_creds
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.