如在先前的文章中提到的,Docker secrets 是一种安全地管理 Docker 化环境中敏感信息的方法。您可能已经知道如何在 compose 文件中使用 secrets,以及如何使用 docker secret
命令来管理它们。
作为上一篇文章的后续,我们将探讨 Docker secrets 的三个实用案例。我们将展示如何在 Dockerfile 中使用 Docker 密钥,如何使用 Docker 密钥管理 WordPress 密钥,以及如何回滚一个密钥。通过这些实际示例,你将更好地理解如何在实际环境中使用 Docker 密钥。
要充分理解本文中的实际示例,您应该对 Docker 和 Docker 密钥有一些基本的认识。如果您还不太了解 Docker 密钥,可以查看之前的博客文章了解更多信息。
此外,你需要在你的机器上安装 Docker,并且最好启用 Docker Swarm。
在某些情况下,您可能需要将密文直接嵌入到Docker镜像中。这在需要在构建时存在密文时构建镜像时可能是必要的。在这个例子中,我们将使用Dockerfile将机密信息嵌入到Docker镜像中。
首先,您必须创建一个秘密凭证,并将其包含进Docker镜像。可以使用docker secret create
命令创建。
在本教程中,你在主目录(如 $HOME/.aws/credentials
)里有一个名为 aws_credentials
的文件,里面存储了 AWS 访问密钥。
步骤 2:新建一个 Dockerfile
在你的项目目录中创建一个Dockerfile。这个Dockerfile将定义构建Docker镜像的步骤,包括如何访问及使用敏感信息。
FROM your_base_image # 从基础镜像开始 (chóng jīchǔ jìngxiàng kāishǐ)
# 创建一个存放凭证文件的文件夹 RUN mkdir -p /run/secrets # 将凭证文件复制到容器中 COPY $HOME/.aws/credentials /run/secrets/aws_credentials # 在构建过程中使用凭证 RUN --mount=type=secret,id=mytoken TOKEN=$(cat /run/secrets/aws_credentials) # 在此处添加你的构建命令
将 your_base_image
替换为你为 Docker 镜像所用的基础镜像。
此Dockerfile创建一个用于存放密钥文件的目录,将密钥文件复制到容器中,然后在构建过程中使用该密钥文件。--mount=type=secret,id=mytoken
标志可以让您将密钥文件安全传递给构建过程。
在实际情况中,你需要把 # Your build commands here
替换成用来构建你自己的 Docker 镜像的特定命令。
注意:如前文所述,不建议通过像Git这样的版本控制系统共享秘密。在这个例子中,假设这个秘密文件被存储在您本地的电脑上,因此不会被分享给其他人。
现在,记得要用 docker build
命令构建 Docker 镜像。记得要用 --secret
标志将秘密传递给构建流程。
docker build --secret id=mytoken . # 使用 --secret 选项设置密钥 id 为 mytoken
此命令将在构建您的Docker镜像时,安全地传递密文到构建过程。
你现在可以根据需要使用该密钥。例如,如果你的应用程序使用访问密钥(access key)与 AWS 服务进行交互,可以通过 Dockerfile 中设置的 TOKEN
环境变量来访问它。
注意哦: 记得将 mytoken
替换为有意义的标识符,用于您的密钥。例如本例中的 aws_credentials
文件应被安全存储,并且只能由授权用户访问,确保安全。
WordPress 是一个非常流行的内容管理系统,通常需要安全地管理比如数据库密码这样的敏感信息。
在这个示例中,我们将利用 Docker secrets 来管理敏感凭证,如数据库密码,创建单个节点的 MySQL 和 WordPress 服务。我们将为 WordPress 设置 MySQL 数据库,并配置 WordPress 连接到 MySQL。
下面是一个概要
这个教程可能会有点复杂,所以咱们一步一步来。
为 MySQL root 和 WordPress 网站的数据库生成一些随机密码:
# 生成 MySQL root 用户的密码 openssl rand -base64 20 | docker secret create mysql_root_password -
# 生成WordPress数据库密码的一个命令是这样的: openssl rand -base64 20 | docker secret create mysql_password - # 该命令使用openssl生成一个随机的Base64编码字符串,并将其设置为Docker秘密mysql_password。
你现在应该已经创建了两个 Docker secrets 文件,它们看起来像这样:输出类似于:
uxm1a4sjjsg7enq2m1dtmvnon 5judi7jm6d02xs99lj8061wul 注:以上为随机生成的字符序列,无需翻译或解释。
使用 Docker 的 secrets 创建一个 MySQL 服务:
docker network create -d overlay mysql_private # 创建一个名为mysql_private的overlay网络 (Create an overlay network named mysql_private)
docker service create \ --name mysql \ --replicas 1 \ --network mysql_private --使用网络 mysql_private \ --mount type=volume,source=mydata,destination=/var/lib/mysql --挂载类型为 volume, 源为 mydata, 目标为 /var/lib/mysql \ --secret source=mysql_root_password,target=mysql_root_password \ --secret source=mysql_password,target=mysql_password \ -e MYSQL_ROOT_PASSWORD_FILE="/run/secrets/mysql_root_password" # 设置 MYSQL_ROOT_PASSWORD_FILE 环境变量为指定路径 \ -e MYSQL_PASSWORD_FILE="/run/secrets/mysql_password" # 设置 MYSQL_PASSWORD_FILE 环境变量为指定路径 \ -e MYSQL_USER="wordpress" # 设置 MYSQL_USER 环境变量为 wordpress \ -e MYSQL_DATABASE="wordpress" # 设置 MYSQL_DATABASE 环境变量为 wordpress \ mysql:latest # 使用最新的 mysql 镜像
请提供具体的英文文本以供翻译。
v87xhur2iqhwhvmql11345l7k 总进度:1 项 1/1: 运行 [==================================================>] 验证中:服务已稳定
此命令创建一个带有指定密钥信息和环境变量的MySQL服务。该MySQL服务将连接到mysql_private
overlay网络。
搭建一个WordPress服务,使用Docker密钥连接到MySQL数据库:
docker service create \ --name wordpress \ --replicas 1 \ --network mysql_private \ --publish published=30000,target=80 \ --mount type=volume,source=wpdata,destination=/var/www/html \ --secret source=mysql_password,target=wp_db_password \ -e WORDPRESS_DB_USER="wordpress" \ -e WORDPRESS_DB_PASSWORD_FILE="/run/secrets/wp_db_password" \ -e WORDPRESS_DB_HOST="mysql:3306" \ -e WORDPRESS_DB_NAME="wordpress" \ wordpress:latest
你应该看到类似这样的输出:
whoumrpbcry3exply4fl9euue 总体进度:1/1 任务已完成 1/1: 运行 [==================================================>] 验证:服务已就绪
此命令创建了一个使用Docker secrets连接到MySQL的WordPress服务实例,该服务在端口30000上可访问。
最后,检查服务是否在运行,并测试一下 WordPress 的功能。
docker service ls
# 测试一下 WordPress docker service ps wordpress
你的结果应该类似于——
ID 名称 镜像 节点 期望状态 当前状态 错误信息 绑定的端口 q2qzd1d2hup1 wordpress.1 wordpress:latest docker-desktop 运行中 已运行 2 分钟了
访问 http://localhost:30000/
从任何 swarm 节点上,通过网页向导来设置 WordPress。确认 WordPress 可以正常运行,并且其状态能够保存在服务重启之后。
注意哦: 运行服务需要一个正在运行的Docker Swarm。如果你用的是Docker Desktop,可以通过docker swarm init
启用Swarm模式。
旋转一个密钥意味着改变其值而不干扰使用它的服务。这是重要的安全措施,旨在阻止未经授权获取敏感信息。
本教程将展示如何在Docker中更换密钥。我们将基于之前的用例,创建一个带有新MySQL密码的新密钥,更新MySQL和WordPress服务使其使用新密钥,最后移除旧密钥。
创建一个新密码,并将其保存为名为 mysql_password_v2
的密钥。
使用openssl生成一个20字节的base64随机字符串,然后用docker secret创建一个名为mysql_password_v2的秘密。
openssl rand -base64 20 | docker secret create mysql_password_v2 -
vwqvnkm1gploicqk2g32vwpf2
更新 MySQL 服务,使其能够访问旧密令和新密令。移除旧密令并添加新密令。
docker 服务更新 \ --secret-rm mysql_password mysql \ (移除名为 mysql_password 的密钥并更新服务 mysql)
docker service update \; # 更新docker服务以添加新的密钥配置 --密钥配置添加 source=mysql_password,target=old_mysql_password \; # 源密钥:mysql_password 目标密钥:old_mysql_password --密钥配置添加 source=mysql_password_v2,target=mysql_password \; # 源密钥:mysql_password_v2 目标密钥:mysql_password mysql # 更新mysql服务
你可以看到类似这样的输出:
mysql 总进度:1/1 任务 1/1: 运行 [==================================================>] 验证:等待 5 秒验证任务是否稳定... 服务更新暂停:任务 f98yfogvf606ddrdc0z3b1paf 失败或提前终止,更新暂停
mysql 总进度: 1 个任务中的第 1 个 1/1: 运行 [==================================================>] 验证: 服务已就绪
此命令将 MySQL 服务更新为使用新密钥,同时为了兼容旧版本保留了旧密钥。
使用 mysqladmin
命令行工具更改 WordPress 用户的 MySQL 密码。此命令从密钥文件中读取旧密码和新密码如下:
mysqladmin -u wp_user -p`cat old_password_file` password `cat new_password_file`
其中,mysqladmin
命令使用 -u
选项指定用户名,并通过反引号中的命令读取旧密码文件和新密码文件内容。
docker 容器执行 $(docker ps --filter name=mysql -q) \ bash -c 'mysqladmin --user=wordpress --password="$(< /run/secrets/old_mysql_password)" password "$(< /run/secrets/mysql_password)"'
解释:此命令用于执行 Docker 容器中的 bash 脚本,该脚本会更改 MySQL 数据库的密码。docker container exec
命令用于在指定的 Docker 容器中执行命令,bash -c
表示执行 Bash 脚本中的命令,mysqladmin
是用于管理 MySQL 数据库的命令,其中 --user
和 --password
分别用于指定用户名和密码。密码文件路径 /run/secrets/old_mysql_password
和 /run/secrets/mysql_password
分别用于读取旧密码和新密码。
你应该看到类似下面的输出,例如:……
mysqladmin: 警告:在命令行界面使用密码可能不安全。 警告:由于密码将以明文形式发送到服务器,建议使用 SSL 连接以增强密码安全性。
该命令将MySQL中的WordPress用户的密码改为新的密码。
将 WordPress 服务更新为使用新密码,并发起滚动重启。
更新 docker 服务 \ --移除密钥 mysql_password \ --添加密钥 source=mysql_password_v2,目标密钥为 wp_db_password \ wordpress # 这是 WordPress 服务
你应该看到类似以下的屏幕输出:
```bash wordpress 总进度:1 任务已完成 1 个 1/1: 运行中 [==================================================>] 验证:服务已就绪 ```此命令会更新 WordPress 服务,让它使用新密钥并移除旧密钥。
在 WordPress 网站上,验证您是否仍然能够按预期访问和互动。确认 MySQL 密码更改没有影响 WordPress 功能。
注意:您可能想知道这一切在像 Semaphore 这样的 CI/CD 流水线中是如何运作的。为了做到这一点,您需要脚本。这样您就不再需要手动在您的机器上运行这些命令了,CI/CD 流水线会在有新代码推送或触发事件时自动执行这些脚本和命令。要尝试,请参阅此 GitHub 项目,该项目详细介绍了这一过程。
不过,Semaphore 提供了一种更简单的方法来将机密信息纳入您的项目。您可以查看这个页面创建和管理机密以了解更多信息。
确认服务运行正常后,撤销对旧秘密的访问并清理旧秘密内容:
更新docker服务 \ --移除密钥 mysql_password \ mysql (这里mysql指的是服务名称)
docker secret rm mysql_password
执行上述命令可以删除名为 mysql_password
的 Docker 密钥。
你应该看到下面这样的输出 -
```bash mysql 总进度:1/1 任务 1/1: 运行 [==================================================>] 验证:服务已就绪 mysql_password // 注意:此处为MySQL密码
# 最后一点 在这篇文章中,我们探讨了Docker secrets的三个实用案例。我们讨论了如何利用Dockerfile将秘密整合进Docker镜像中,如何使用Docker secrets管理WordPress中的秘密,以及如何在Docker中轮换秘密。 通过这些示例,使用密文变得更加简单。现在,您可以在项目中使用 Docker 密文,以安全地管理敏感数据并提升您的 Docker 化应用的安全性能。 原发布于[_https://semaphoreci.com_](https://semaphoreci.com/blog/docker-secrets) 2024年5月29日。