一、什么是Docker Secret
(一)情景展现
我们知道有的service是需要设置密码的,比如mysql服务是需要设置密码的:
version: 3 services: web: image: wordpress ports: – 8080:80 volumes: – ./www:/var/www/html environment: WORDPRESS_DB_NAME=wordpress WORDPRESS_DB_HOST: mysql WORDPRESS_DB_PASSWORD: root networks: – my-network depends_on: – mysql deploy: mode: replicated replicas: 3 restart_policy: condition: on-failure delay: 5s max_attempts: 3 update_config: parallelism: 1 delay: 10s mysql: image: mysql environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: wordpress volumes: – mysql-data:/var/lib/mysql networks: – my-network deploy: mode: global placement: constraints: – node.role == manager volumes: mysql-data: networks: my-network: driver: overlay可以看到在这个docker-compose.yml中的两个service密码都是明文,这样就导致了不是很安全,那么究竟什么是Docker secret以及能否解决上面的问题呢?
(二)Docker Secret
我们知道manager节点保持状态的一致是通过Raft Database这个分布式存储的数据库,它本身就是将信息进行了secret,所以可以利用这个数据库将一些敏感信息,例如账号、密码等信息保存在这里,然后通过给service授权的方式允许它进行访问,这样达到避免密码明文显示的效果。
总之,secret的Swarm中secret的管理通过以下步骤完成:
secret存在于Swarm Manager节点的的Raft Database里 secret可以assign给一个service,然后这个service就可以看到这个secret 在container内部secret看起来像文件,实际上就是内存二、Docker Secret的创建与使用
(一)创建
我们先看看创建的一些帮助说明:
[root@centos-7 ~]# docker secret –help Usage: docker secret COMMAND Manage Docker secrets Commands: create Create a secret from a file or STDIN as content inspect Display detailed information on one or more secrets ls List secrets rm Remove one or more secrets Run docker secret COMMAND –help for more information on a command.第一个命令就是创建的命令,我们再来看看它有什么帮助信息:
[root@centos-7 ~]# docker secret create –help Usage: docker secret create [OPTIONS] SECRET [file|-] Create a secret from a file or STDIN as content Options: -d, –driver string Secret driver -l, –label list Secret labels –template-driver string Template driver可以看到说明secret可以来自于一个文件或者一个标准输出。那么也就是Secret的创建有两种方式,分别是:
基于文件的创建 基于命令行创建1、基于文件创建
首先先创建一个文件用于存放密码
[root@centos-7 ~]# vim mysql-password root然后再进行创建secret
[root@centos-7 ~]# docker secret create mysql-pass mysql-password texcct9ojqcz6n40woe97dd7k其中,mysql-pass是secret的名称,mysql-password是我们建立存储密码的文件,这样执行后就相当于将文件中的密码存储在Swarm中manager节点的Raft Database中了。为了安全起见,现在可以直接将这个文件删掉,因为Swarm中已经有这个密码了。
[root@centos-7 ~]# rm -f mysql-password现在可以查看一下secret列表:
[root@centos-7 ~]# docker secret ls ID NAME DRIVER CREATED UPDATED texcct9ojqcz6n40woe97dd7k mysql-pass 4 minutes ago 4 minutes ago已经存在了。
2、基于命令行创建
[root@centos-7 ~]# echo “root” | docker secret create mysql-pass2 – hrtmn5yr3r3k66o39ba91r2e4 [root@centos-7 ~]# docker secret ls ID NAME DRIVER CREATED UPDATED texcct9ojqcz6n40woe97dd7k mysql-pass 6 minutes ago 6 minutes ago hrtmn5yr3r3k66o39ba91r2e4 mysql-pass2 5 seconds ago 5 seconds ago这种方式还是很简单的就创建成功了
(二)其它操作
那么secret还有什么其它操作吗?
[root@centos-7 ~]# docker secret –help Usage: docker secret COMMAND Manage Docker secrets Commands: create Create a secret from a file or STDIN as content inspect Display detailed information on one or more secrets ls List secrets rm Remove one or more secrets Run docker secret COMMAND –help for more information on a command.可以看到除了create命令外,还有inspect、ls、以及rm命令。
1、inspect
[root@centos-7 ~]# docker secret inspect mysql-pass2 [ { “ID”: “hrtmn5yr3r3k66o39ba91r2e4”, “Version”: { “Index”: 4061 }, “CreatedAt”: “2020-02-07T08:39:25.630341396Z”, “UpdatedAt”: “2020-02-07T08:39:25.630341396Z”, “Spec”: { “Name”: “mysql-pass2”, “Labels”: {} } } ]展示secret的一些详情信息
2、rm
[root@centos-7 ~]# docker secret rm mysql-pass2 mysql-pass2 [root@centos-7 ~]# docker secret ls ID NAME DRIVER CREATED UPDATED texcct9ojqcz6n40woe97dd7k mysql-pass 12 minutes ago 12 minutes ago删除一个secret
(三)Secret在单容器中的使用
1、容器中查看secret
我们创建了一个secret,如何在启动一个服务后,将其授权给特定的服务然后它才可以看到呢?先看看创建服务的命令中是否有类似的命令或者参数:
[root@centos-7 ~]# docker service create –help Usage: docker service create [OPTIONS] IMAGE [COMMAND] [ARG…] Create a new service Options: –config config Specify configurations to expose to the service … –secret secret Specify secrets to expose to the service … …确实是有这样的命令,在创建服务时可以给服务暴露出secret。
2、创建服务
[root@centos-7 ~]# docker service create –name demo –secret mysql-pass busybox sh -c “while true; do sleep 3600; done” zwgk5w0rpf17hn77axz6cn8di overall progress: 1 out of 1 tasks 1/1: running verify: Service converged查看这个服务运行在那个节点上:
[root@centos-7 ~]# docker service ls ID NAME MODE REPLICAS IMAGE PORTS zwgk5w0rpf17 demo replicated 1/1 busybox:latest [root@centos-7 ~]# docker service ps demo ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS yvr9lwvg8oca demo.1 busybox:latest localhost.localdomain Running Running 51 seconds ago可以看到这个服务运行在localhost.localdomain主机的节点上,我们去这个节点上进入到容器内部,看是否能查看secret:
[root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 36573adf21f6 busybox:latest “sh -c while true; …”4 minutes ago Up 4 minutes demo.1.yvr9lwvg8ocatym20hdfublhd [root@localhost ~]# docker exec -it 36573adf21f6 /bin/sh / # ls bin dev etc home proc root run sys tmp usr var / # cd /run/secrets /run/secrets # ls mysql-pass /run/secrets # cat mysql-pass root /run/secrets #可以看到确实是可行的。
2、mysql服务
关于mysql镜像,详情查看https://hub.docker.com/_/mysql其中有关于secret的描述:
作为通过环境变量传递敏感信息的替代方法,_FILE可以将其附加到先前列出的环境变量中,从而使初始化脚本从容器中存在的文件中加载那些变量的值。特别是,这可用于从/run/secrets/<secret_name>文件中存储的Docker Secret加载密码。例如:
$ docker run –name some-mysql -e MYSQL_ROOT_PASSWORD_FILE=/run/secrets/mysql-root -d mysql:tag目前,这仅支持MYSQL_ROOT_PASSWORD,MYSQL_ROOT_HOST,MYSQL_DATABASE,MYSQL_USER,和MYSQL_PASSWORD。
所以我们需要先创建一个文件secret用于存储数据库的敏感信息,因为之前已经创建过,这里无需再创建:
[root@centos-7 ~]# docker secret ls ID NAME DRIVER CREATED UPDATED texcct9ojqcz6n40woe97dd7k mysql-pass 4 hours ago 4 hours ago启动mysql服务:
[root@centos-7 ~]# docker service create –name db –secret mysql-pass -e MYSQL_ROOT_PASSWORD_FILE=/run/secrets/mysql-pass mysql sbpagzqvpwt8ifymavf8o5xmi overall progress: 1 out of 1 tasks 1/1: running verify: Service converged查看mysql服务在那个节点上:
[root@centos-7 ~]# docker service ls ID NAME MODE REPLICAS IMAGE PORTS sbpagzqvpwt8 db replicated 0/1 mysql:latest [root@centos-7 ~]# docker service ps db ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS qlmfm6u7lg8u db.1 mysql:latest localhost.localdomain Running Starting 2 seconds ago在worker节点中进入该服务的容器中查看secret:
[root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2ac2a810e931 mysql:latest “docker-entrypoint.s…” 3 minutes ago Up 2 minutes 3306/tcp, 33060/tcp db.1.qlmfm6u7lg8u8i1v2m2c3ls3r [root@localhost ~]# docker exec -it 2ac2a810e931 /bin/sh # cd /run/secrets/ # ls mysql-pass # cat mysql-pass root这样知道了密码就可以进入到mysql数据库中了。
# mysql -uroot -p Enter password: Welcome to the MySQL monitor. Commands end with ; or g. Your MySQL connection id is 9 Server version: 8.0.19 MySQL Community Server – GPL Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type help; or h for help. Type c to clear the current input statement. mysql>(四)Secret在Stack中的使用
Stack利用的就是docker-compose.yml文件来部署stack,那么如何在docker-compose.yml中来定义secret呢?
version: 3 services: web: image: wordpress ports: – 8080:80 secrets: – my-pw environment: WORDPRESS_DB_HOST: mysql WORDPRESS_DB_PASSWORD_FILE: /run/secrets/wordpress-pass networks: – my-network depends_on: – mysql deploy: mode: replicated replicas: 3 restart_policy: condition: on-failure delay: 5s max_attempts: 3 update_config: parallelism: 1 delay: 10s mysql: image: mysql secrets: – my-pw environment: MYSQL_ROOT_PASSWORD_FILE: /run/secrets/mysql-pass MYSQL_DATABASE: wordpress volumes: – mysql-data:/var/lib/mysql networks: – my-network deploy: mode: global placement: constraints: – node.role == manager volumes: mysql-data: networks: my-network: driver: overlay上面通过在environment中定义WORDPRESS_DB_PASSWORD_FILE以及MYSQL_ROOT_PASSWORD_FILE来制定secret,显然我们在运行这个docker-compose.yml文件之前必须先要进行对应的secret文件的创建。然后就可以通过docker stack deploy命令来部署这个stack了。
暂无评论内容