Docker 生产环境之使用可信镜像 - Docker 中的内容信任(content trust)
2018-03-18 15:04
501 查看
原文地址
在联网系统间传输数据时,信任是一个核心问题。特别是,当通过互联网等不可信介质进行通信时,确保系统运行的所有数据的完整性和发布者至关重要。使用 Docker Engine 可以将镜像(数据)推送到公共或私有 registry。内容信任使你能够验证通过任何通道从 registry 接收的所有数据的完整性和发布者。
目前,内容信任被默认禁用。要启用它,请将
一旦启用内容信任,镜像发布者就可以对其镜像进行签名。镜像消费者可以确保他们使用的镜像已经经过签名。发布者和消费者可以是单独的个人或组织中的个人。Docker 的内容信任支持用户和自动化进程,如构建。
当启用内容信任时,如果你使用 Docker CE,则在客户端进行推送和验证后,在客户端上进行签名。如果将 Docker EE 与 UCP 一起使用,并且已将 UCP 配置为要求在部署之前对镜像进行签名,则签名将由 UCP 进行验证。
一个特定的镜像
内容信任与镜像的
镜像存储库可以包含同时具有已签名标签和未签名标签的镜像。例如,考虑
镜像发布者可以选择是否签名特定标签。这将导致未签名标签的内容与同名的已签名标签的内容可能不匹配。例如,镜像发布者可以将已经标记的镜像推送到
镜像使用者可以启用内容信任以确保他们使用的镜像已被签名。如果使用者启用内容信任,则只能使用受信任的镜像进行 pull,run 或 build。启用内容信任就像戴着一副有色眼镜。使用者“看到”只有签名的镜像标签,不想要的、未签名的镜像标签对他们来说是“不可见的”。
对于尚未启用内容信任的消费者,可以正常使用所有的 Docker 镜像。无论是否签名,每个镜像都可见。
push
build
create
pull
run
例如,开启内容信任后,
对镜像标签的信任通过使用签名密钥来管理。首次调用使用内容信任的操作时会创建密钥集。密钥集由以下几类密钥组成:
作为镜像标记的内容信任的根的脱机密钥
签名标签的仓库或标签密钥
服务器管理的密钥,如时间戳密钥,为仓库提供最新的安全保证
下图描述了各种签名密钥及其关系:
警告:丢失根密钥非常难以恢复。纠正这种损失需要 Docker 支持人员的干预来重置仓库状态。这种损失还需要所有使用此仓库中的签名标记的使用者在丢失之前进行手动干预。
应该将根密钥备份到安全的地方。鉴于根密钥仅用于创建新的仓库,最好将其脱机存储在硬件中。有关保护和备份密钥的详细信息,请务必阅读 如何为内容信任管理密钥。
Build 并 push 未签名镜像
Pull 未签名镜像
Build 并 push 签名镜像
Pull 之前 push 的签名镜像
Pull 之前 push 的未签名镜像
要在 bash shell 中启用内容信任,请输入以下命令:
一旦设置,每个“tag”操作都需要一个用于获取可信 tag 的密钥。
在设置了
看看使用不受信任的父镜像的 Dockerfile:
要通过这个 Dockerfile 成功构建容器,可以这么做:
其他命令的操作都类似:
要在调用命令时开启内容信任,而不管
所有受信任的操作都支持
开启内容信任后第一次推送标记镜像时,docker 客户端会识别出这是你第一次推送,并且会:
警告你这会创建一个新的根密钥
请求根密钥的密码
在
请求仓库密钥的密码
在
为根密钥和存储库密钥对选择的密码应随机生成并存储在密码管理器中。
注意:如果省略
它被跳过,因为消息指出,你没有提供镜像
一旦在系统上拥有 root 密钥,创建的后续镜像仓库就可以使用相同的 root 密钥:
新镜像具有自己的仓库密钥和时间戳密钥。
下面的例子中,命令没有指定 tag,所以系统使用默认的
因为
在联网系统间传输数据时,信任是一个核心问题。特别是,当通过互联网等不可信介质进行通信时,确保系统运行的所有数据的完整性和发布者至关重要。使用 Docker Engine 可以将镜像(数据)推送到公共或私有 registry。内容信任使你能够验证通过任何通道从 registry 接收的所有数据的完整性和发布者。
1. 关于 Docker 中的信任
内容信任允许使用远程 Docker registry 执行操作,以强制客户端对镜像的标记进行签名和验证。内容信任提供了使用数字签名来收发远程 Docker registry 数据的能力。这些签名允许客户端验证特定镜像标签的完整性和发布者。目前,内容信任被默认禁用。要启用它,请将
DOCKER_CONTENT_TRUST环境变量设置为
1。请参阅 Docker 客户端的 环境变量 和 Notary 配置以获取更多选项。
一旦启用内容信任,镜像发布者就可以对其镜像进行签名。镜像消费者可以确保他们使用的镜像已经经过签名。发布者和消费者可以是单独的个人或组织中的个人。Docker 的内容信任支持用户和自动化进程,如构建。
当启用内容信任时,如果你使用 Docker CE,则在客户端进行推送和验证后,在客户端上进行签名。如果将 Docker EE 与 UCP 一起使用,并且已将 UCP 配置为要求在部署之前对镜像进行签名,则签名将由 UCP 进行验证。
1.1 镜像标签和内容信任
单个镜像记录具有以下标识符:[REGISTRY_HOST[:REGISTRY_PORT]/]REPOSITORY[:TAG]
一个特定的镜像
REPOSITORY可以有多个标签。例如,
latest和
3.1.2都是
mongo镜像上的标签。镜像发布者可以在每次构建时多次更改镜像来构建镜像和标签组合。
内容信任与镜像的
TAG部分相关联。每个镜像仓库都有一组给镜像发布者使用的用于签署镜像标签的密钥。镜像发布者可以自行决定签署哪些标签。
镜像存储库可以包含同时具有已签名标签和未签名标签的镜像。例如,考虑
Mongo镜像仓库。
latest标签是未签名的,而
3.1.6标签是签名的。镜像发布者有责任决定镜像标签是否已签名。下图中,一些镜像标签被签名,而另一些则没有:
镜像发布者可以选择是否签名特定标签。这将导致未签名标签的内容与同名的已签名标签的内容可能不匹配。例如,镜像发布者可以将已经标记的镜像推送到
someimage:latest并签名。稍后,同一个发布者可以推送未签名的
someimage:latest镜像。第二次推送替换
latest未签名标签,但不会影响已签名的
latest版本。可以自由选择为哪个标签签名,使得镜像发布者可以在正式签名之前迭代未签名的镜像版本。
镜像使用者可以启用内容信任以确保他们使用的镜像已被签名。如果使用者启用内容信任,则只能使用受信任的镜像进行 pull,run 或 build。启用内容信任就像戴着一副有色眼镜。使用者“看到”只有签名的镜像标签,不想要的、未签名的镜像标签对他们来说是“不可见的”。
对于尚未启用内容信任的消费者,可以正常使用所有的 Docker 镜像。无论是否签名,每个镜像都可见。
1.2 内容信任操作和密钥
启用内容信任时,对标记镜像执行操作的 docker CLI 命令必须具有内容签名或显式内容散列。与内容信任一起运行的命令是:push
build
create
pull
run
例如,开启内容信任后,
docker pull someimage:latest命令只有在
someimage:latest确实被签名时才会成功执行。然而,附带显式内容散列的操作只要散列在匹配就会成功执行。
$ docker pull someimage@sha256:d149ab53f8718e987c3a3024bb8aa0e2caadf6c0328f1d9d850b2a2a67f2819a
对镜像标签的信任通过使用签名密钥来管理。首次调用使用内容信任的操作时会创建密钥集。密钥集由以下几类密钥组成:
作为镜像标记的内容信任的根的脱机密钥
签名标签的仓库或标签密钥
服务器管理的密钥,如时间戳密钥,为仓库提供最新的安全保证
下图描述了各种签名密钥及其关系:
警告:丢失根密钥非常难以恢复。纠正这种损失需要 Docker 支持人员的干预来重置仓库状态。这种损失还需要所有使用此仓库中的签名标记的使用者在丢失之前进行手动干预。
应该将根密钥备份到安全的地方。鉴于根密钥仅用于创建新的仓库,最好将其脱机存储在硬件中。有关保护和备份密钥的详细信息,请务必阅读 如何为内容信任管理密钥。
2. 典型内容信任操作
本节将学习使用 Docker 镜像执行的典型可信操作。具体来说,我们通过以下步骤来帮助我们执行这些可信操作:Build 并 push 未签名镜像
Pull 未签名镜像
Build 并 push 签名镜像
Pull 之前 push 的签名镜像
Pull 之前 push 的未签名镜像
2.1 启用和禁用每个 shell 或每个调用的内容信任
在 shell 中,可以通过设置DOCKER_CONTENT_TRUST环境变量来启用内容信任。在每个 shell 中启用是非常有用的,因为可以为可信操作配置一个 shell,为不可信操作配置另一个终端 shell。还可以将此声明添加到 shell 配置文件中,以便默认情况下始终打开它。
要在 bash shell 中启用内容信任,请输入以下命令:
export DOCKER_CONTENT_TRUST=1
一旦设置,每个“tag”操作都需要一个用于获取可信 tag 的密钥。
在设置了
DOCKER_CONTENT_TRUST环境变量的环境中,可以通过
--disable-content-trust标志关闭内容信任后在标记镜像上运行单独的操作。
看看使用不受信任的父镜像的 Dockerfile:
$ cat Dockerfile FROM docker/trusttest:latest RUN echo
要通过这个 Dockerfile 成功构建容器,可以这么做:
$ docker build --disable-content-trust -t <username>/nottrusttest:latest . Sending build context to Docker daemon 42.84 MB ... Successfully built f21b872447dc
其他命令的操作都类似:
$ docker pull --disable-content-trust docker/trusttest:latest ... $ docker push --disable-content-trust <username>/nottrusttest:latest ...
要在调用命令时开启内容信任,而不管
DOCKER_CONTENT_TRUST环境变量是如何设置的:
$ docker build --disable-content-trust=false -t <username>/trusttest:testing .
所有受信任的操作都支持
--disable-content-trust标志。
2.2 推送可信的内容
要为特定镜像标记创建签名内容,只需启用内容信任并推送标记的镜像即可。如果这是第一次在系统上使用内容信任推送镜像,则会话如下所示:$ docker push <username>/trusttest:testing The push refers to a repository [docker.io/<username>/trusttest] (len: 1) 9a61b6b1315e: Image already exists 902b87aaaec9: Image already exists latest: digest: sha256:d02adacee0ac7a5be140adb94fa1dae64f4e71a68696e7f8e7cbf9db8dd49418 size: 3220 Signing and pushing trust metadata You are about to create a new root signing key passphrase. This passphrase will be used to protect the most sensitive key in your signing system. Please choose a long, complex passphrase and be careful to keep the password and the key file itself secure and backed up. It is highly recommended that you use a password manager to generate the passphrase and keep it safe. There will be no way to recover this key. You can find the key in your config directory. Enter passphrase for new root key with id a1d96fb: Repeat passphrase for new root key with id a1d96fb: Enter passphrase for new repository key with id docker.io/<username>/trusttest (3a932f1): Repeat passphrase for new repository key with id docker.io/<username>/trusttest (3a932f1): Finished initializing "docker.io/<username>/trusttest"
开启内容信任后第一次推送标记镜像时,docker 客户端会识别出这是你第一次推送,并且会:
警告你这会创建一个新的根密钥
请求根密钥的密码
在
~/.docker/trust目录中生成一个根密钥
请求仓库密钥的密码
在
~/.docker/trust目录中生成一个仓库密钥
为根密钥和存储库密钥对选择的密码应随机生成并存储在密码管理器中。
注意:如果省略
testing标记,则跳过内容信任。即使启用了内容信任,即使这是第一次推送,情况也是如此。
$ docker push <username>/trusttest The push refers to a repository [docker.io/<username>/trusttest] (len: 1) 9a61b6b1315e: Image successfully pushed 902b87aaaec9: Image successfully pushed latest: digest: sha256:a9a9c4402604b703bed1c847f6d85faac97686e48c579bd9c3b0fa6694a398fc size: 3220 No tag specified, skipping trust metadata push
它被跳过,因为消息指出,你没有提供镜像
TAG值。在 Docker 内容信任中,签名与标签相关联。
一旦在系统上拥有 root 密钥,创建的后续镜像仓库就可以使用相同的 root 密钥:
$ docker push docker.io/<username>/otherimage:latest The push refers to a repository [docker.io/<username>/otherimage] (len: 1) a9539b34a6ab: Image successfully pushed b3dbab3810fc: Image successfully pushed latest: digest: sha256:d2ba1e603661a59940bfad7072eba698b79a8b20ccbb4e3bfb6f9e367ea43939 size: 3346 Signing and pushing trust metadata Enter key passphrase for root key with id a1d96fb: Enter passphrase for new repository key with id docker.io/<username>/otherimage (bb045e3): Repeat passphrase for new repository key with id docker.io/<username>/otherimage (bb045e3): Finished initializing "docker.io/<username>/otherimage"
新镜像具有自己的仓库密钥和时间戳密钥。
latest标签用这两个标签签名。
2.3 获取镜像内容
使用镜像的常用方法是pull镜像。启用内容信任后,Docker 客户端仅允许
docker pull检索已签名的镜像。让我们试着获取你之前签名和推送的镜像:
$ docker pull <username>/trusttest:testing Pull (1 of 1): <username>/trusttest:testing@sha256:d149ab53f871 ... Tagging <username>/trusttest@sha256:d149ab53f871 as docker/trusttest:testing
下面的例子中,命令没有指定 tag,所以系统使用默认的
latesttag,但是
docker/trusttest:latest并没有签名。
$ docker pull docker/trusttest Using default tag: latest no trust data available
因为
docker/trusttest:latest没有签名,所以
pull失败。
相关文章推荐
- Docker 生产环境之使用可信镜像 - 为内容信任(content trust)管理密钥
- Docker 生产环境之使用可信镜像 - 自动化内容信任(content trust)
- Docker 生产环境之使用可信镜像 - 在内容信任(content trust)沙盒中演示
- Docker 生产环境之使用可信镜像 - 内容信任(content trust)的委派 delegation
- Docker 生产环境之使用可信镜像 - 用 compose 部署 Notary 服务器
- 在生产环境使用Docker部署应用
- 生产环境中使用Docker Swarm的一些建议
- 新手的我在使用docker制作tomcat镜像时遇到环境变量问题
- 在生产环境使用Docker部署应用
- 使用SSL验证和Nginx做代理搭建生产环境的Docker仓库
- Centos下Docker使用镜像和DockerFile方式搭建JAVA Web 开发环境
- Docker新手入门之六:Docker在生产环境中的使用实践
- 三个生产环境中使用Docker的案例
- Docker 生产环境之配置对象 - 配置对象使用自定义元数据
- 使用 Docker 镜像构建 GO 语言环境
- Docker: 使用jupyter notebook基础镜像搭建自己的 pytorch 开发环境
- 在生产环境使用Docker部署应用
- 使用dockerfile来创建环境镜像images
- 无网络环境下使用docker加载镜像
- 在生产环境使用Docker部署应用