Docker Secret的管理和使用詳解
一、什麼是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瞭。
到此這篇關於Docker Secret的管理和使用詳解的文章就介紹到這瞭,更多相關Docker Secret內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Docker Compose搭建WordPress服務實現詳解
- 雲原生Docker創建並進入mysql容器的全過程
- Docker compose部署SpringBoot項目連接MySQL及遇到的坑
- kubernetes之statefulset搭建MySQL集群
- Docker部署mysql一主一從的操作方法