Answers:
最好的方法是使用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角色是一个非常好的选择。如果可以的话,请在他的答案中再加上一个加一,然后跳过其余的内容。
一旦开始在云外部运行事物或拥有其他类型的秘密,建议您针对两个关键位置存储秘密:
环境变量:当在容器上定义这些变量时,容器内的每个进程都可以访问它们,可以通过/ proc看到它们,应用程序可以将其环境转储到stdout并存储在日志中,最重要的是,它们出现在检查容器时请清除文本。
在映像本身中:映像通常被推送到许多用户具有访问权限的注册表中,有时甚至不需要任何凭据即可提取映像。即使您从一个层中删除密钥,也可以使用常见的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 Mode或其他编排的单个节点上运行时,可以将凭据作为只读卷安装。访问此凭据需要与在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服务器即可。如果机密不起作用或很快就会过期,那么这将降低从机密中删除机密的风险。https://www.vaultproject.io/docs/secrets/aws/index.html记录了适用于Vault的AWS的特定功能
另一种方法是将密钥从主机传递到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或Java的AWS开发工具包等)正在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不会感谢您将其提供给零字节文件。您应该使用“长格式”来指定绑定的类型,主机路径和容器路径,如果文件不存在,则失败,这是您在docker-compose.dev中想要的。 yml,但不在您的docker-compose.yml中(产品/ 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