Heim > Fragen und Antworten > Hauptteil
P粉3995850242023-08-28 11:42:57
自从提出这个问题以来,Docker 发生了很多变化,所以这里尝试更新答案。
首先,特别是对于已在云中运行的容器上的 AWS 凭证,使用 IAM 角色,如 Vor 建议 是真的是不错的选择。如果你能做到这一点,那么在他的答案中再加一加一并跳过其余部分。
一旦您开始在云之外运行事物,或者拥有不同类型的机密,我建议不要在两个关键位置存储机密:
环境变量:当在容器上定义这些变量时,容器内的每个进程都可以访问它们,它们通过 /proc 可见,应用程序可以将其环境转储到 stdout,并将其存储在日志中,并且最重要的是,当您检查容器时,它们会以明文形式显示。
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.
那么 Docker 容器中的机密还有哪些其他选项?
选项 A:如果您仅在构建映像期间需要此密钥,在构建开始之前无法使用该密钥,并且尚无权访问 BuildKit,则 多阶段构建是最好的坏选择。您可以将机密添加到构建的初始阶段,在那里使用它,然后将没有机密的该阶段的输出复制到您的发布阶段,并且仅将该发布阶段推送到注册表服务器。这个秘密仍然在构建服务器上的图像缓存中,所以我倾向于仅将其用作最后的手段。
选项B:同样在构建期间,如果您可以使用18.09发布的BuildKit,目前有实验功能允许将机密注入作为单个运行线路的卷安装。该装载不会写入映像层,因此您可以在构建期间访问秘密,而不必担心它会被推送到公共注册表服务器。生成的 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 访问权限。)
For a docker run
, this looks like:
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 模式和 Kubernetes 等编排工具,我们现在拥有比卷更好的机密支持。使用 Swarm 模式,文件在管理器文件系统上进行加密(尽管解密密钥通常也在那里,允许在管理员不输入解密密钥的情况下重新启动管理器)。更重要的是,秘密仅发送给需要秘密的工作人员(使用该秘密运行容器),它仅存储在工作人员的内存中,而不是磁盘中,并且它作为文件注入到具有 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
You turn on swarm mode with docker swarm init
for a single node, then follow the directions for adding additional nodes. You can create the secret externally with docker secret create aws_creds $HOME/.aws/credentials
. And you deploy the compose file with docker stack deploy -c docker-compose.yml stack_name
.
我经常使用以下脚本来版本化我的秘密:https://github.com/ sudo-bmitch/docker-config-update
选项 E:还有其他工具可以管理机密,我最喜欢的是 Vault 因为它能够创建自动过期的有时间限制的秘密。然后,每个应用程序都会获取自己的一组令牌来请求机密,这些令牌使它们能够在能够到达保管库服务器的情况下请求这些有时间限制的机密。如果某个秘密被从您的网络中取出,这会降低风险,因为它要么不起作用,要么很快就会过期。 AWS for Vault 的特定功能记录在 https://www.vaultproject.io /docs/secrets/aws/index.html
P粉5236250802023-08-28 10:29:34
最好的方法是使用 IAM 角色并且根本不处理凭证。 (请参阅 http://docs.aws .amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html )
Credentials could be retrieved from http://169.254.169.254.....
Since this is a private ip address, it could be accessible only from EC2 instances.
所有现代 AWS 客户端库都“知道”如何从那里获取、刷新和使用凭证。因此,在大多数情况下,您甚至不需要了解它。只需使用正确的 IAM 角色运行 ec2 即可。
As an option you can pass them at the runtime as environment variables ( i.e docker run -e AWS_ACCESS_KEY_ID=xyz -e AWS_SECRET_ACCESS_KEY=aaa myimage
)
您可以通过在终端运行 printenv 来访问这些环境变量。