回答:
最善の方法は、IAMロールを使用し、認証情報をまったく扱わないことです。(http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.htmlを参照してください)
資格情報はから取得できます。http://169.254.169.254.....
これはプライベートIPアドレスであるため、EC2インスタンスからのみアクセスできます。
最新のAWSクライアントライブラリはすべて、そこから認証情報を取得、更新、使用する方法を「知っています」。したがって、ほとんどの場合、それについて知る必要すらありません。正しいIAMロールでec2を実行するだけで、問題ありません。
オプションとして、実行時に環境変数としてそれらを渡すことができます(つまりdocker run -e AWS_ACCESS_KEY_ID=xyz -e AWS_SECRET_ACCESS_KEY=aaa myimage
)
端末でprintenvを実行すると、これらの環境変数にアクセスできます。
AWS_SECRET_ACCESS_KEY
ませんがAWS_SECRET_KEY
、とにかくあなたの答えはとても役に立ちました。ありがとうございました。
この質問が行われてからDockerで多くの変更が行われたので、ここで更新された回答の試みを示します。
まず、具体的にはクラウド内で既に実行されているコンテナーのAWS認証情報で、Vorが示唆するように IAMロールを使用することは本当に良いオプションです。それができる場合は、彼の回答に1プラス1を追加し、残りの部分はスキップしてください。
クラウドの外で実行を開始したり、シークレットの種類が異なる場合、シークレットを保存しないことをお勧めする2つの重要な場所があります。
環境変数:これらがコンテナーで定義されている場合、コンテナー内のすべてのプロセスがそれらにアクセスでき、それらは/ procを介して表示され、アプリは環境をログに保存されるstdoutにダンプし、最も重要なのはコンテナを検査するときにクリアテキスト。
画像自体:画像は、多くの場合、多くのユーザーがプルアクセス権を持つレジストリにプッシュされます。画像をプルするために必要な認証情報がない場合もあります。シークレットを1つのレイヤーから削除した場合でも、イメージは一般的なLinuxユーティリティなどで逆アセンブルtar
でき、シークレットは最初にイメージに追加されたステップから見つけることができます。
では、Dockerコンテナのシークレットには他にどのようなオプションがありますか?
オプションA:イメージのビルド中にのみこのシークレットが必要で、ビルドの開始前にシークレットを使用できず、まだBuildKitにアクセスできない場合は、マルチステージビルドが最善のオプションではありません。ビルドの初期段階にシークレットを追加してそこで使用し、シークレットなしでそのステージの出力をリリースステージにコピーし、そのリリースステージのみをレジストリサーバーにプッシュします。この秘密はまだビルドサーバーのイメージキャッシュにあるため、これは最後の手段としてのみ使用する傾向があります。
オプションB:ビルド時にも、18.09にリリースされたBuildKitを使用できる場合、現在、単一のRUN行のボリュームマウントとしてシークレットを挿入できる実験的な機能があります。そのマウントはイメージレイヤーに書き込まれないため、ビルド中にパブリックレジストリサーバーにプッシュされることを心配せずにシークレットにアクセスできます。結果のDockerfileは次のようになります。
# 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://... ...
そして、あなたは18.09以降のコマンドでそれを構築します:
DOCKER_BUILDKIT=1 docker build -t your_image --secret id=aws,src=$HOME/.aws/credentials .
オプションC:単一ノードでの実行時に、Swarmモードまたは他のオーケストレーションなしで、認証情報を読み取り専用ボリュームとしてマウントできます。この資格情報にアクセスするには、Dockerの外部で同じ資格情報ファイルにアクセスするのと同じアクセス権が必要です。そのため、Dockerを使用しないシナリオよりも良くも悪くもありません。最も重要なのは、すべてのシナリオでボリュームがボリュームの外側にあるため、コンテナを検査したり、ログを表示したり、イメージをレジストリサーバーにプッシュしたりするときに、このファイルの内容が表示されないようにすることです。これには、コンテナのデプロイとは別に、Dockerホストに認証情報をコピーする必要があります。(注意:docker APIへのアクセスはホストのrootであり、rootは任意のユーザーのファイルを表示できるため、そのホストでコンテナーを実行する権限を持つ誰でも資格情報を表示できます。ホストにrootを持つユーザーを信頼しない場合、
の場合docker run
、これは次のようになります。
docker run -v $HOME/.aws/credentials:/home/app/.aws/credentials:ro your_image
または、作成ファイルの場合、次のようになります。
version: '3'
services:
app:
image: your_image
volumes:
- $HOME/.aws/credentials:/home/app/.aws/credentials:ro
オプションD:Swarm ModeやKubernetesなどのオーケストレーションツールを使用して、ボリュームよりも優れたシークレットサポートを利用できるようになりました。Swarmモードでは、ファイルはマネージャーファイルシステムで暗号化されます(ただし、復号化キーもそこにあることが多いため、管理者が復号化キーを入力しなくてもマネージャーを再起動できます)。さらに重要なことは、シークレットは、シークレットを必要とするワーカーにのみ送信され(そのシークレットを使用してコンテナーを実行)、ワーカーのメモリにのみ保存され、ディスクには保存されず、tmpfsを使用してコンテナーにファイルとして挿入されますマウント。swarm外のホスト上のユーザーは、そのシークレットを自分のコンテナーに直接マウントすることはできませんが、docker APIへのオープンアクセスがあれば、ノードで実行中のコンテナーからシークレットを抽出できるため、このアクセス権を持つユーザーを制限できます。 API。作成すると、このシークレットインジェクションは次のようになります。
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 init
単一ノードに対してでスウォームモードをオンにしてから、ノードを追加するための指示に従います。シークレットは、を使用して外部で作成できますdocker secret create aws_creds $HOME/.aws/credentials
。そして、作成ファイルをでデプロイしますdocker stack deploy -c docker-compose.yml stack_name
。
https://github.com/sudo-bmitch/docker-config-updateのスクリプトを使用してシークレットをバージョン管理することがよくあります
オプションE:シークレットを管理するための他のツールが存在します。私のお気に入りは、自動的に期限切れになる時間制限付きのシークレットを作成する機能を提供するVaultです。次に、すべてのアプリケーションが独自のトークンセットを取得してシークレットを要求します。これらのトークンは、Vaultサーバーにアクセスできる限り、これらのトークンに時間制限のあるシークレットを要求する機能を提供します。これは、シークレットが機能しないか、すぐに期限切れになるため、シークレットがネットワークから削除された場合のリスクを軽減します。Vault for AWSに固有の機能は、https://www.vaultproject.io/docs/secrets/aws/index.htmlに記載されています。
別のアプローチは、ホストマシンからDockerコンテナーにキーを渡すことです。docker-compose
ファイルに次の行を追加できます。
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}
さらに別のアプローチは、docker-compose.yamlに一時的な読み取り専用ボリュームを作成することです。AWS CLIとSDK(boto3やAWS SDK for Javaなど)がファイル内のdefault
プロファイルを探してい~/.aws/credentials
ます。
他のプロファイルを使用したい場合は、docker-compose
コマンドを実行する前にAWS_PROFILE変数もエクスポートする必要があります
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
この例では、Dockerでrootユーザーを使用しました。他のユーザーを使用している場合は/root/.aws
、ユーザーのホームディレクトリに移動するだけです
:ro
-読み取り専用のDockerボリュームを表します
~/.aws/credentials
ファイルに複数のプロファイルがあり、MFAも使用している場合に非常に役立ちます。IAMロールがあるECSにデプロイする前にdocker-containerをローカルでテストしたいがローカルではテストしない場合にも役立ちます。
"%UserProfile%\.aws"
ます。だから私はあなたが変更する必要があると思います: - ~/.aws/:/root/.aws:ro
へ- %UserProfile%\.aws:/root/.aws:ro
- host:container
(ルートとして)作成されたホストにファイル/フォルダーが存在せず、awscliが0バイトのファイルをフィードしてくれない場合は、構文の使用には十分注意してください。タイプがバインド、ホストパス、およびコンテナーパスを別々の行で指定する「長い形式」を使用する必要があります。これは、ファイルが存在しない場合に失敗します。これはdocker-compose.devに必要です。 ymlがdocker-compose.ymlにない(prod / AWSデプロイ)。
あなたは~/aws_env_creds
包含を作成することができます
touch ~/aws_env_creds
chmod 777 ~/aws_env_creds
vi ~/aws_env_creds
以下の値を追加します(自分のキーを置き換えます)
AWS_ACCESS_KEY_ID=AK_FAKE_KEY_88RD3PNY
AWS_SECRET_ACCESS_KEY=BividQsWW_FAKE_KEY_MuB5VAAsQNJtSxQQyDY2C
「esc」でファイルを保存します。
コンテナーを実行してテストする
my_service:
build: .
image: my_image
env_file:
- ~/aws_env_creds