docker swarm英文文档学习-10-使用Docker密钥管理敏感数据
Manage sensitive data with Docker secrets使用Docker secrets管理敏感数据
About secrets
对于Docker Swarm服务来说,secret是一组数据,比如密码、SSH私钥、SSL证书或其他不应该在网络上传输或存储在Dockerfile或应用程序源代码中未加密的数据。在Docker 1.13及更高版本中,可以使用Docker secrets集中管理该数据,并将其安全地传输到需要访问它的容器。Secrets在传输过程中和在Docker集群中被加密。给定的secret只对那些已被授予显式访问权限的服务可访问,并且仅在这些服务任务运行时可访问。
你可以使用secret来管理容器运行时需要但不希望存储在镜像或源代码控制中的任何敏感数据,例如:
- 用户名和密码
- TLS证书和密钥
- SSH密钥
- 其他重要数据,如数据库或内部服务器的名称
- 通用字符串或二进制内容(大小不超过500 kb)
注意:Docker的secrets只适用于集群服务,而不适用于独立容器。要使用此特性,请考虑将容器调整为作为服务运行。有状态容器通常可以在不更改容器代码的情况下以1的比例运行。
使用secrets的另一个用例是在容器和一组凭证之间提供一个抽象层。考虑这样一个场景:你的应用程序有独立的开发、测试和生产环境。这些环境中的每一个都可以具有不同的凭证,这些凭证存储在具有相同secret名称的开发、测试和生产集群中。容器只需要知道在所有三个环境中运行的secret的名称。
你还可以使用secret来管理非敏感数据,比如配置文件。但是,Docker 17.06和更高版本支持使用configs存储非敏感数据。配置直接挂载到容器的文件系统中,不需要使用RAM磁盘。
How Docker manages secrets Docker如何管理secrets
当你向群中添加一个secret时,Docker通过一个相互的TLS连接将该secret发送给群管理器。这个secret存储在raft子日志中,日志是加密的。整个raft日志被复制到其他管理器中,确保机密的高可用性保证与集群管理数据的其他部分相同。
警告:raft数据在Docker 1.13或更高版本中加密。如果你的任何集群管理器运行较早的版本,并且其中一个管理器成为集群的管理器,则secret将未加密地存储在该节点的raft日志中。在添加任何secret之前,请将所有管理器节点更新到Docker 1.13或更高版本,以防止将秘密写入纯文本raft日志。
当你授予新创建或正在运行的服务对secret的访问权限时,解密的secret将挂载到内存文件系统中的容器中。在Linux容器中,挂载点的位置默认为/run/secrets/<secret_name>,或者在Windows容器中默认为C: ProgramData\Docker\secrets。你可以在Docker 17.06或更高版本中指定自定义位置。
你可以更新服务以授予其对其他secret的访问权,或者随时撤销其对给定secret的访问权。
只有当节点是集群管理器或正在运行已被授予secret访问权的服务任务时,节点才能访问(加密的)secret。当容器任务停止运行时,共享给它的解密secret将从该容器的内存文件系统中卸载,并从节点的内存中刷新。
如果节点在运行具有secret访问权的任务容器时失去了与集群的连接,那么任务容器仍然可以访问其secret,但是在节点重新连接到集群之前不能接收更新。
你可以在任何时候添加或检查单个secret,或者列出所有secret。你无法删除正在运行的服务正在使用的secret。有关在不中断正在运行的服务的情况下删除secret的方法,请参见Rotate a secret。
为了更容易地更新或回滚secret,可以考虑在secret名称中添加版本号或日期。通过在给定容器中控制secret的挂载点,可以更容易地做到这一点。
Read more about docker secret
commands更多有关docker secret
命令的信息
使用这些链接可以阅读有关特定命令的信息,或者继续阅读example about using secrets with a service。
docker secret create
docker secret inspect
docker secret ls
docker secret rm
--secret
flag fordocker service create
--secret-add
and--secret-rm
flags fordocker service update
Examples
本节包括三个分级示例,演示如何使用Docker secrets。这些示例中使用的镜像已经进行了更新,以便更容易地使用Docker secrets。要了解如何以类似的方式修改自己的镜像,请参见Build support for Docker Secrets into your images。
注意:为了简单起见,这些示例使用单引擎集群和未扩展的服务。示例使用Linux容器,但Windows容器也支持Docker 17.06及更高版本中的secrets。看Windows support.
Defining and using secrets in compose files在compose文件中定义并使用secrets
docker-compose
和
docker stack命令支持在compose文件中定义secrets。详情看the Compose file reference
Simple example: Get started with secrets 开始
这个简单的例子展示了secrets是如何在几个命令中工作的。对于真实的示例,请继续Intermediate example: Use secrets with a Nginx service.。
1.向Docker添加一个secrets。docker secret create命令读取标准输入,因为最后一个参数,表示从中读取秘密的文件被设置为-。
- $ printf "This is a secret" | docker secret create my_secret_data -
2.创建一个redis服务,并授予它访问secret的权限。默认情况下,容器可以访问/run/secrets/上的secret,但是可以使用target选项定制容器上的文件名。
- $ docker service create --name redis --secret my_secret_data redis:alpine
3.使用docker service ps检查任务是否正常运行。如果一切正常,输出如下:
- $ docker service ps redis
- ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
- bkna6bpn8r1a redis. redis:alpine ip---- Running Running seconds ago
如果出现错误,并且任务失败并多次重新启动,你将看到如下内容:
- $ docker service ps redis
- NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
- redis..siftice35gla redis:alpine moby Running Running seconds ago
- \_ redis..whum5b7gu13e redis:alpine moby Shutdown Failed seconds ago "task: non-zero exit (1)"
- \_ redis..2s6yorvd9zow redis:alpine moby Shutdown Failed seconds ago "task: non-zero exit (1)"
- \_ redis..ulfzrcyaf6pg redis:alpine moby Shutdown Failed about a minute ago "task: non-zero exit (1)"
- \_ redis..wrny5v4xyps6 redis:alpine moby Shutdown Failed minutes ago "task: non-zero exit (1)"
4.使用docker ps命令得到redis的服务任务容器的ID,这样你可以使用docker container exec去连接到容器和阅读的secret数据文件的内容,其默认为所有人可读,并且有着和secret的名称相同的名称。下面的第一个命令演示了如何查找容器ID,第二个和第三个命令使用shell补全来自动查找容器ID。
- $ docker ps --filter name=redis -q
- 5cb1c2348a59
- $ docker container exec $(docker ps --filter name=redis -q) ls -l /run/secrets
- total
- -r--r--r-- root root Dec : my_secret_data
- $ docker container exec $(docker ps --filter name=redis -q) cat /run/secrets/my_secret_data
- This is a secret
5.如果提交容器,请验证该secret不可用。
- $ docker commit $(docker ps --filter name=redis -q) committed_redis
- $ docker run --rm -it committed_redis cat /run/secrets/my_secret_data
- cat: can't open '/run/secrets/my_secret_data': No such file or directory
6.移除这个secret。删除失败是因为redis服务正在运行,并且可以访问该secret。
- $ docker secret ls
- ID NAME CREATED UPDATED
- wwwrxza8sxy025bas86593fqs my_secret_data hours ago hours ago
- $ docker secret rm my_secret_data
- Error response from daemon: rpc error: code = desc = secret
- 'my_secret_data' is in use by the following service: redis
7.通过更新服务,从正在运行的redis服务中删除对该secret的访问。
- $ docker service update --secret-rm my_secret_data redis
8.再次重复步骤3和步骤4,验证服务不再具有访问secret的权限。容器ID是不同的,因为service update命令重新部署服务。
- $ docker container exec -it $(docker ps --filter name=redis -q) cat /run/secrets/my_secret_data
- cat: can't open '/run/secrets/my_secret_data': No such file or directory
9.停止并删除服务,并从Docker中删除秘密。
- $ docker service rm redis
- $ docker secret rm my_secret_data
Intermediate example: Use secrets with a Nginx service
本例分为两部分。第一部分是关于生成站点证书的,完全不直接涉及Docker secret,但是它设置了第二部分,在其中存储和使用站点证书和Nginx配置作为secret。
GENERATE THE SITE CERTIFICATE生成站点证书
为你的站点生成根CA和TLS证书和密钥。对于生产站点,你可能希望使用Let’s Encrypt之类的服务来生成TLS证书和密钥,但是本示例使用命令行工具。这一步有点复杂,但只是一个设置步骤,以便你可以将某些内容存储为Docker secret。如果你想跳过这些子步骤,可以使用Let 's Encrypt生成站点密钥和证书,命名文件site.key
和
site.crt
,然后跳到 Configure the Nginx container
1.生成一个根密钥:
- $ openssl genrsa -out "root-ca.key"
2.使用根密钥生成一个CSR:
- $ openssl req \
- -new -key "root-ca.key" \
- -out "root-ca.csr" -sha256 \
- -subj '/C=US/ST=CA/L=San Francisco/O=Docker/CN=Swarm Secret Example CA'
3.配置根CA.编辑一个名为root-ca.cnf的新文件,并将以下内容粘贴到其中。这限制根CA只签名叶证书,而不签名中间CA。
- [root_ca]
- basicConstraints = critical,CA:TRUE,pathlen:1
- keyUsage = critical, nonRepudiation, cRLSign, keyCertSign
- subjectKeyIdentifier=hash
4.签名证书
- $ openssl x509 -req -days 3650 -in "root-ca.csr" \
- -signkey "root-ca.key" -sha256 -out "root-ca.crt" \
- -extfile "root-ca.cnf" -extensions \
- root_ca
5.生成站点密钥
- $ openssl genrsa -out "site.key"
6.生成站点证书并使用站点密钥签名
- $ openssl req -new -key "site.key" -out "site.csr" -sha256 \
- -subj '/C=US/ST=CA/L=San Francisco/O=Docker/CN=localhost'
7.配置站点证书。编辑一个名为site.cnf的新文件,并将以下内容粘贴到其中。这限制了站点证书,因此它只能用于对服务器进行身份验证,而不能用于对证书进行签名。
- [server]
- authorityKeyIdentifier=keyid,issuer
- basicConstraints = critical,CA:FALSE
- extendedKeyUsage=serverAuth
- keyUsage = critical, digitalSignature, keyEncipherment
- subjectAltName = DNS:localhost, IP:127.0.0.1
- subjectKeyIdentifier=hash
8.对站点证书签名
- $ openssl x509 -req -days 750 -in "site.csr" -sha256 \
- -CA "root-ca.crt" -CAkey "root-ca.key" -CAcreateserial \
- -out "site.crt" -extfile "site.cnf" -extensions server
9.site.csr
和site.cnf
文件不被Nginx服务需要,但是如果你想生成一个新的站点证书,则需要它们。保护root-ca.key文件。
CONFIGURE THE NGINX CONTAINER 配置Ngnix容器
1.生成一个非常基本的Nginx配置,它通过HTTPS提供静态文件。TLS证书和密钥存储为Docker密钥,这样可以方便地轮转它们。
在当前目录中,创建一个带着下面内容的名为site.conf的新文件
- server {
- listen 443 ssl;
- server_name localhost;
- ssl_certificate /run/secrets/site.crt;
- ssl_certificate_key /run/secrets/site.key;
- location / {
- root /usr/share/nginx/html;
- index index.html index.htm;
- }
- }
2.创建两个秘密,分别表示密钥和证书。你可以将任何文件作为秘密存储,只要它小于500kb。这允许你将密钥和证书与使用它们的服务解耦。在这些示例中,密钥名称和文件名是相同的。
- $ docker secret create site.key site.key
- $ docker secret create site.crt site.crt
- $ docker secret create site.conf site.conf
- $ docker secret ls
- ID NAME CREATED UPDATED
- 2hvoi9mnnaof7olr3z5g3g7fp site.key seconds ago seconds ago
- aya1dh363719pkiuoldpter4b site.crt seconds ago seconds ago
- zoa5df26f7vpcoz42qf2csth8 site.conf seconds ago seconds ago
3.创建一个运行Nginx并可以访问这三个secret的服务。docker service create
命令的最后一部分从site.conf secret的位置创建一个符号链接到/etc/nginx.conf,其中Nginx查找额外的配置文件。这个步骤发生在Nginx实际启动之前,所以如果你更改了Nginx配置,就不需要重新构建镜像。
注意:通常你会创建一个复制site.conf到位置的Dockerfile,构建镜像,并使用自定义镜像运行容器。本例不需要自定义镜像。它把site.conf放到位置上,并在一步内运行容器。
在Docker 17.05和更早的版本中,secret总是位于/run/secrets/目录中。Docker 17.06及更高版本允许你为容器中的secret指定自定义位置。下面的两个例子说明了不同之处。这个命令的旧版本要求你创建指向site.conf真实位置的符号链接,以便Nginx可以读取它,但新版本不需要这样做。保留了较老的示例,以便你可以看到差异。
Docker 17.06 and higher:
- $ docker service create \
- --name nginx \
- --secret site.key \
- --secret site.crt \
- --secret source=site.conf,target=/etc/nginx/conf.d/site.conf \
- --publish published=,target= \
- nginx:latest \
- sh -c "exec nginx -g 'daemon off;'"
Docker 17.05 and earlier:
- $ docker service create \
- --name nginx \
- --secret site.key \
- --secret site.crt \
- --secret site.conf \
- --publish published=,target= \
- nginx:latest \
- sh -c "ln -s /run/secrets/site.conf /etc/nginx/conf.d/site.conf && exec nginx -g 'daemon off;'"
第一个示例同时显示了secret的短语法和长语法,第二个示例只显示了短语法。这个简短的语法在/run/secrets/中创建与secret同名的文件。在运行的容器中,现在存在以下三个文件:
/run/secrets/site.key
/run/secrets/site.crt
/etc/nginx/conf.d/site.conf
(or/run/secrets/site.conf
if you used the second example)
4.查看Nginx服务是否正在运行
- $ docker service ls
- ID NAME MODE REPLICAS IMAGE
- zeskcec62q24 nginx replicated / nginx:latest
- $ docker service ps nginx
- NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
- nginx..9ls3yo9ugcls nginx:latest moby Running Running minutes ago
5.核查服务是可操作的:你可以到达Ngnix服务端,并且正确的TLS证书正在被使用
- $ curl --cacert root-ca.crt https://localhost:3000
- <!DOCTYPE html>
- <html>
- <head>
- <title>Welcome to nginx!</title>
- <style>
- body {
- width: 35em;
- margin: auto;
- font-family: Tahoma, Verdana, Arial, sans-serif;
- }
- </style>
- </head>
- <body>
- <h1>Welcome to nginx!</h1>
- <p>If you see this page, the nginx web server is successfully installed and
- working. Further configuration is required.</p>
- <p>For online documentation and support. refer to
- <a href="http://nginx.org/">nginx.org</a>.<br/>
- Commercial support is available at
- <a href="http://nginx.com/">nginx.com</a>.</p>
- <p><em>Thank you for using nginx.</em></p>
- </body>
- </html>
- $ openssl s_client -connect localhost: -CAfile root-ca.crt
- CONNECTED()
- depth= /C=US/ST=CA/L=San Francisco/O=Docker/CN=Swarm Secret Example CA
- verify return:
- depth= /C=US/ST=CA/L=San Francisco/O=Docker/CN=localhost
- verify return:
- ---
- Certificate chain
- s:/C=US/ST=CA/L=San Francisco/O=Docker/CN=localhost
- i:/C=US/ST=CA/L=San Francisco/O=Docker/CN=Swarm Secret Example CA
- ---
- Server certificate
- -----BEGIN CERTIFICATE-----
- …
- -----END CERTIFICATE-----
- subject=/C=US/ST=CA/L=San Francisco/O=Docker/CN=localhost
- issuer=/C=US/ST=CA/L=San Francisco/O=Docker/CN=Swarm Secret Example CA
- ---
- No client certificate CA names sent
- ---
- SSL handshake has read bytes and written bytes
- ---
- New, TLSv1/SSLv3, Cipher is AES256-SHA
- Server public key is bit
- Secure Renegotiation IS supported
- Compression: NONE
- Expansion: NONE
- SSL-Session:
- Protocol : TLSv1
- Cipher : AES256-SHA
- Session-ID: A1A8BF35549C5715648A12FD7B7E3D861539316B03440187D9DA6C2E48822853
- Session-ID-ctx:
- Master-Key: F39D1B12274BA16D3A906F390A61438221E381952E9E1E05D3DD784F0135FB81353DA38C6D5C021CB926E844DFC49FC4
- Key-Arg : None
- Start Time:
- Timeout : (sec)
- Verify return code: (ok)
6.在运行此示例之后,请通过删除nginx服务以及存储的secrets来清理。
Build support for Docker Secrets into your images
如果你开发的容器可以部署为服务,并且需要敏感数据(例如凭据)作为环境变量,那么可以考虑调整镜像以利用Docker的secrets。一种方法是确保在创建容器时传递给镜像的每个参数也可以从文件中读取。
Docker库中的许多官方镜像,比如上面例子中使用的wordpress镜像,都是用这种方式更新的。
启动WordPress容器时,通过将其设置为环境变量,为其提供所需的参数。WordPress镜像已经更新,因此包含WordPress重要数据的环境变量,如WORDPRESS_DB_PASSWORD,也有可以从文件(WORDPRESS_DB_PASSWORD_FILE)读取其值的变量。这种策略确保了向后兼容性,同时允许容器从docker管理的secret中读取信息,而不是直接传递。
注意:Docker secrets不直接设置环境变量。这是一个有意识的决定,因为环境变量可能在容器之间无意地泄漏(例如,如果使用--link)。
Use Secrets in Compose
- version: '3.1'
- services:
- db:
- image: mysql:latest
- volumes:
- - db_data:/var/lib/mysql
- environment:
- MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_password
- MYSQL_DATABASE: wordpress
- MYSQL_USER: wordpress
- MYSQL_PASSWORD_FILE: /run/secrets/db_password
- secrets:
- - db_root_password
- - db_password
- wordpress:
- depends_on:
- - db
- image: wordpress:latest
- ports:
- - "8000:80"
- environment:
- WORDPRESS_DB_HOST: db:
- WORDPRESS_DB_USER: wordpress
- WORDPRESS_DB_PASSWORD_FILE: /run/secrets/db_password
- secrets:
- - db_password
- secrets:
- db_password:
- file: db_password.txt
- db_root_password:
- file: db_root_password.txt
- volumes:
- db_data:
这个例子使用一个compose文件中的两个secrets创建了一个简单的WordPress站点。
关键字secrets:定义两个secret db_password:和db_root_password:。
在部署时,Docker将创建这两个secrets,并用组成文件中指定的文件中的内容填充它们。
db服务同时使用这两个secrets,wordpress也在使用一个。
在部署时,Docker在服务中挂载/run/secrets/<secret_name>下的文件。</secret_name>这些文件从不保存在磁盘中,而是在内存中管理。
每个服务使用环境变量来指定服务应该在何处查找该secret数据。
有关secrets的短语法和长语法的更多信息,请参阅Compose file version 3 reference。
docker swarm英文文档学习-10-使用Docker密钥管理敏感数据的更多相关文章
- docker swarm英文文档学习-9-使用Docker Configs存储配置数据
Store configuration data using Docker Configs 使用Docker Configs存储配置数据 Docker 17.06引入了集群服务配置,允许你在服务镜像或 ...
- docker swarm英文文档学习-3-开始
https://docs.docker.com/engine/swarm/swarm-tutorial/ 1)Getting started with swarm mode 本教程向你介绍Docker ...
- docker swarm英文文档学习-8-在集群中部署服务
Deploy services to a swarm在集群中部署服务 集群服务使用声明式模型,这意味着你需要定义服务的所需状态,并依赖Docker来维护该状态.该状态包括以下信息(但不限于): 应该运 ...
- docker swarm英文文档学习-5-在swarm模式中运行Docker引擎
Run Docker Engine in swarm mode在swarm模式中运行Docker引擎 当你第一次安装并开始使用Docker引擎时,默认情况下禁用swarm模式.在启用集群模式时,需要处 ...
- docker swarm英文文档学习-1-概述
参考https://docs.docker.com/engine/swarm/ Swarm mode overview群模式概述 Docker的当前版本包括集群模式,用于本地管理称为集群的Docker ...
- docker swarm英文文档学习-11-上锁你的集群来保护你的加密密钥
Lock your swarm to protect its encryption key上锁你的集群来保护你的加密密钥 在Docker 1.13及更高版本中,默认情况下,群管理器使用的Raft日志在 ...
- docker swarm英文文档学习-12-在集群模式中的Raft共识
Raft consensus in swarm mode 在集群模式中的Raft共识 当Docker引擎在集群模式下运行时,manager节点实现Raft 共识算法来管理全局集群状态.Docker s ...
- docker swarm英文文档学习-6-添加节点到集群
Join nodes to a swarm添加节点到集群 当你第一次创建集群时,你将单个Docker引擎置于集群模式中.为了充分利用群体模式,可以在集群中添加节点: 添加工作节点可以增加容量.当你将服 ...
- docker swarm英文文档学习-7-在集群中管理节点
Manage nodes in a swarm在集群中管理节点 List nodes列举节点 为了查看集群中的节点列表,可以在管理节点中运行docker node ls: $ docker node ...
随机推荐
- 简单的SpringMVC经典案例
主题:构建一个基于SpringMVC的HelloWord Web 项目 目的:快速体验什么是SpringMVC 方案: 1.创建工程,命名:SpringMVC 2.导包 3.在SRC下添加spring ...
- groovy编程注意事点
集合中一些方法工作在集合的一个副本上并且完成的时候返回这个副本,而另外一些方法直接操作这个集合对象. 和Java一样不能通过迭代移除元素. list和map遵循java规则限制,但通过附加的方法降低了 ...
- hdu 1568 (log取对数 / Fib数通项公式)
hdu 1568 (log取对数 / Fib数通项公式) 2007年到来了.经过2006年一年的修炼,数学神童zouyu终于把0到100000000的Fibonacci数列 (f[0]=0,f[1]= ...
- 一个很好用的SqlHelper类
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- jdk源码->并发->Unsafe&Atomic
synchronized关键字类似于java中的悲观锁机制,接下来介绍一种java的乐观锁机制Unsafe类 CAS CAS简介 CAS全称是Compare And Swap,即比较交换,它是在并发执 ...
- css优化,提高性能
CSS 优化主要是四个方面: 加载性能比如不要用 @import 等等,@import会影响css文件的加载速度,考虑加载性能时,主要是从减少文件体积.减少阻塞加载.提高并发方面入手,任何 hint ...
- Software-Defined Networking A Comprehensive Survey --阅读_day2
3. 什么是SDN?(WHAT IS SOFTWARE-DEFINED NETWORKING?) The term SDN was originally coined to represent the ...
- 第三十天- 进程 Process模块 空间隔离
1.进程: 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.在早期面向进程设计的计算机结构中,进程是程序的基本执行实体: ...
- linux下将本地文件上传到github中?
今天编写一份Python基础代码,经过Linux上传到github上,遇到点问题,已经解决 1.首先sudo su 进入root 用户 2.ls 检查出当前文件下有什么文件 3. cd 进入你将要上传 ...
- CSS 小结笔记之变形、过渡与动画
1.过渡 transition 过渡属性用法: transition :ransition-property transition-duration transition-timing-func ...