I am running docker-container on Amazon EC2. Currently I have added AWS Credentials to Dockerfile. Could you please let me know the best way to do this?
ベストアンサー1
A lot has changed in Docker since this question was asked, so here's an attempt at an updated answer.
First, specifically with AWS credentials on containers already running inside of the cloud, using IAM roles as Vor suggests is a really good option. If you can do that, then add one more plus one to his answer and skip the rest of this.
Once you start running things outside of the cloud, or have a different type of secret, there are two key places that I recommend against storing secrets:
Environment variables: when these are defined on a container, every process inside the container has access to them, they are visible via /proc, apps may dump their environment to stdout where it gets stored in the logs, and most importantly, they appear in clear text when you inspect the container.
In the image itself: images often get pushed to registries where many users have pull access, sometimes without any credentials required to pull the image. Even if you delete the secret from one layer, the image can be disassembled with common Linux utilities like
tar
and the secret can be found from the step where it was first added to the image.
So what other options are there for secrets in Docker containers?
オプション 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 API アクセスを与えないでください)。
の場合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 Mode では、ファイルはマネージャーのファイルシステム上で暗号化されます (ただし、復号化キーもそこにあることが多いため、管理者が復号化キーを入力しなくてもマネージャーを再起動できます)。さらに重要なのは、シークレットはシークレットを必要とするワーカー (そのシークレットを使用してコンテナーを実行) にのみ送信され、ワーカーのメモリにのみ保存され、ディスクには保存されず、tmpfs マウントを使用してファイルとしてコンテナーに挿入されることです。Swarm の外部のホスト上のユーザーは、そのシークレットを自分のコンテナーに直接マウントすることはできませんが、docker API へのオープン アクセスにより、ノード上で実行中のコンテナーからシークレットを抽出できるため、ここでも API へのアクセス権を持つユーザーを制限します。Compose から、このシークレット挿入は次のようになります。
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
単一ノードに対してで swarm モードをオンにしdocker swarm init
、追加のノードを追加するための指示に従います。 でシークレットを外部に作成できますdocker secret create aws_creds $HOME/.aws/credentials
。 で Compose ファイルをデプロイしますdocker stack deploy -c docker-compose.yml stack_name
。
私はよく、次のスクリプトを使用してシークレットをバージョン管理します: https://github.com/sudo-bmitch/docker-config-update
オプション E:シークレットを管理するツールは他にもありますが、私のお気に入りはVaultです。これは、自動的に期限切れになる時間制限付きのシークレットを作成できるからです。すべてのアプリケーションは、シークレットを要求するための独自のトークン セットを取得し、それらのトークンにより、ボールト サーバーにアクセスできる限り、時間制限付きのシークレットを要求できるようになります。これにより、シークレットがネットワークから持ち出された場合に、機能しないかすぐに期限切れになるため、リスクが軽減されます。AWS の Vault 固有の機能については、https://www.vaultproject.io/docs/secrets/aws/index.htmlで説明されています。