Docker 运维入门实战:密码和配置别写死——Swarm 的 secret 与 config

举报
yd_274623194 发表于 2026/11/05 09:27:11 2026/11/05
【摘要】 关键词:secret、config、密码管理、配置分离、Docker Swarm这个系列写到现在,有一样东西一直明晃晃地躺在 Compose 文件里:数据库密码、接口密钥,全是明文。练习时无所谓,可这份文件迟早要进代码仓库、要发给同事看、要出现在截图里——密码写在里面,等于把钥匙和门牌号一起公开。今天把它们收起来:敏感的进 secret,不敏感的进 config,代码和 Compose 文件...

关键词:secret、config、密码管理、配置分离、Docker Swarm

这个系列写到现在,有一样东西一直明晃晃地躺在 Compose 文件里:数据库密码、接口密钥,全是明文。练习时无所谓,可这份文件迟早要进代码仓库、要发给同事看、要出现在截图里——密码写在里面,等于把钥匙和门牌号一起公开。今天把它们收起来:敏感的进 secret,不敏感的进 config,代码和 Compose 文件里只留名字,不留内容。

先认清问题有多大。明文密码通常从三个地方漏出去:一是代码仓库,Compose 文件提交进 Git,密码就进了历史记录,删掉当前版本也没用,历史里还在;二是镜像,有人把带密码的配置文件打进镜像,谁能拉镜像谁就能解开看;三是日常沟通,排障时贴配置、发截图,密码跟着满天飞。三个口子都不是黑客攻击,全是自己人无意中漏的,所以解法也得是机制性的:让密码根本不出现在这些文件里。

一、secret:密码只以名字出现

Swarm 的 secret 是专门存敏感数据的机制:数据存在管理节点的加密存储里,只在服务真正运行、且副本被调度到的节点上,才以文件形式临时挂进容器;容器删掉,文件随之消失,不落在磁盘的普通目录里。

创建 secret(在管理节点上执行一次):

printf '你的数据库密码' | docker secret create db_password -
docker secret ls

注意用管道把密码送进去,不要写成 docker secret create db_password 密码 这种形式——那样密码会留在 shell 历史里,等于又多漏一个地方(也可以从文件创建:docker secret create db_password ./password.txt,用完把源文件删掉)。

在 Compose 文件里引用它,密码本身从此不再出现:

services:
  api:
    secrets:
      - db_password
  db:
    secrets:
      - db_password

secrets:
  db_password:
    external: true

服务跑起来后,容器里会多出一个文件 /run/secrets/db_password,程序改成从这个文件读密码,而不是从环境变量或配置文件里读明文。Compose 文件进仓库、发给谁看,都只剩 db_password 这个名字。

二、config:不敏感的配置也别塞进镜像

配置文件(比如 Nginx 的站点配置、服务的参数文件)不敏感,但同样不该打进镜像:改一行配置就要重新构建镜像、重新发布,太笨重。Swarm 的 config 机制和 secret 几乎一样,只是存的是普通配置:

docker config create nginx_main ./nginx.conf
services:
  gateway:
    configs:
      - source: nginx_main
        target: /etc/nginx/conf.d/default.conf

配置内容存在集群里,挂载到容器内指定的路径。要改配置时,新建一个新 config,再更新服务引用,副本滚动替换,逐个用上新配置——和滚动更新一篇讲的节奏是一回事,老副本在新副本就绪前继续干活。

分工记牢:密码、密钥、令牌进 secret;普通配置进 config。别为了省事把密码塞进 config,它没有 secret 的保护级别;也别把大段普通配置塞进 secret,改起来别扭。

三、不上 Swarm 时的底线做法

如果还在单机 Compose 阶段,也有退一步的做法,至少守住底线:

  • 密码放进 .env 文件,Compose 里只写 ${DB_PASSWORD} 这样的引用;.env 写进 .gitignore,永远不进仓库。
  • 仓库里放一份 .env.example,只写变量名和示例占位,让别人知道要配哪些项,但不含真值。
  • Compose 也支持 secrets: 语法引用本地文件,形式和 Swarm 版接近,先把程序改成"从文件读密码",将来上 Swarm 时改动最小。

底线做法保护的是"不进仓库",文件本身还在机器上明文躺着,所以只是底线,不是终点。

四、三个新手最容易踩的坑

1. 想着"改一下"secret,结果发现改不了
secret 创建后内容不可修改,这是故意的(防止悄悄替换)。要换密码:新建一个新名字的 secret(如 db_password_v2),更新服务引用,滚动生效后删掉旧的。命名带版本号,后面排障时一眼能看出谁在用哪版。

2. 把 secret 打印出来排障
程序启动时把读到的密码打进日志"确认一下",日志系统(前面讲过集中看日志)立刻把密码存了无数份。排障只确认"文件存在、长度对不对",永远不打印内容。

3. 旧密码在 Git 历史里躺着,以为删了文件就没事
把密码移进 secret 之后,仓库当前版本是干净了,但历史提交里那份明文还在。正确顺序是:先换新密码(让旧密码作废),再做清理;只删文件不换密码,等于掩耳盗铃。

结语

配置管理的分工收成一句:代码只认名字,内容各回各家——敏感内容进 secret,不敏感配置进 config,两者都不进镜像、不进仓库。到这里,服务从单机一路走到了带调度、自愈、配置管理的集群。下一篇给集群装上眼睛:副本分散在两台机器上之后,怎么一眼看清每个服务还活着没、资源吃多少——用最简的监控把集群状态收进一个面板。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。