管理密鑰
在動態的、大規模的分布式集群上,管理和分發 密碼
、證書
等敏感信息是極其重要的工作。傳統的密鑰分發方式(如密鑰放入鏡像中,設置環境變量,volume 動態掛載等)都存在着潛在的巨大的安全風險。
Docker 目前已經提供了 secrets
管理功能,用戶可以在 Swarm 集群中安全地管理密碼、密鑰證書等敏感數據,並允許在多個 Docker 容器實例之間共享訪問指定的敏感數據。
我們可以用 docker secret
命令來管理敏感信息。接下來我們在上面章節中創建好的 Swarm 集群中介紹該命令的使用。
這里我們以在 Swarm 集群中部署 mysql
和 wordpress
服務為例。
創建密鑰
我們使用 docker secret create
命令以管道符的形式創建 secret
[root@node1 /opt/mycontainer/wordpress]# openssl rand -base64 20 | docker secret create mysql_password -
q59vqmmatae02sve9p5jrnjvr
[root@node1 /opt/mycontainer/wordpress]# openssl rand -base64 20 | docker secret create mysql_root_password -
jmei7gfyzhndxd3byeexfi2m8
查看密鑰
使用 docker secret ls
命令來查看 secret
[root@node1 /opt/mycontainer/wordpress]# docker secret ls
ID NAME DRIVER CREATED UPDATED
q59vqmmatae02sve9p5jrnjvr mysql_password 16 seconds ago 16 seconds ago
jmei7gfyzhndxd3byeexfi2m8 mysql_root_password 7 seconds ago 7 seconds ago
如何使用密鑰
我們在啟動服務時指定密鑰位置,secret
默認通過 tmpfs
文件系統掛載到容器的 /run/secrets
目錄中。
為這次的服務創建屬於自己的網絡接口(overlay類型):
[root@node1 /opt/mycontainer/wordpress]# docker network create -d overlay mqsql_worldpress
sp7k7aiuhk7glj87cj7xujfov
創建mysql服務:
[root@node1 /opt/mycontainer/wordpress]# docker service create \
--name mysql \
--replicas 1 \
--network mysql_worldpress \
--mount type=volume,source=mydata,target=/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" \
-e MYSQL_PASSWORD_FILE="/run/secrets/mysql_password" \
-e MYSQL_USER="wordpress" \
-e MYSQL_DATABASE="wordpress" \
mysql:latest
wxqgnjh5ykmlh7xnc5xmgrcq4
overall progress: 1 out of 1 tasks
1/1: running [==================================================>]
verify: Service converged
創建worldpress服務:
# 這里請耐性等待一會兒,稍微有點兒慢...
[root@node1 /opt/mycontainer/wordpress]# docker service create \
--name wordpress \
--replicas 1 \
--network mysql_worldpress \
--publish 80 \
--mount type=volume,source=wpdata,target=/var/www/html \
--secret source=mysql_password,target=wp_db_password,mode=0400 \
-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
cf7a60orb2a51r18qa1gto3om
overall progress: 1 out of 1 tasks
1/1: running [==================================================>]
verify: Service converged
服務驗證
現在瀏覽器訪問 IP:8081
,即可開始 WordPress 的安裝與使用。
通過以上方法,我們沒有像以前通過設置環境變量來設置 MySQL 密碼, 而是采用 docker secret
來設置密碼,防范了密碼泄露的風險。
[root@node1 /opt/mycontainer/wordpress]# docker service ls
ID NAME MODE REPLICAS IMAGE
wxqgnjh5ykml mysql replicated 1/1 mysql:latest
cf7a60orb2a5 wordpress replicated 1/1 wordpress:latest
管理配置信息
在動態的、大規模的分布式集群上,管理和分發配置文件也是很重要的工作。
傳統的配置文件分發方式(如配置文件放入鏡像中,設置環境變量,volume 動態掛載等)都降低了鏡像的通用性。
在 Docker 17.06 以上版本中,Docker 新增了 docker config
子命令來管理集群中的配置信息,以后你無需將配置文件放入鏡像或掛載到容器中就可實現對服務的配置。
注意:
config
僅能在 Swarm 集群中使用。
下面以官方的例子為例來來進行展示:
創建配置文件
首先我們先創建一個redis的配置文件:
~]# cat redis.conf
port 6380
然后我們根據該文件內容來創建docker 管理的配置文件
[root@node1 /opt/mycontainer/redis]# docker config create redis.conf redis.conf
ho5m631aiz4hw3tmj2hoz6mnq
[root@node1 /opt/mycontainer/redis]# docker config ls
ID NAME CREATED UPDATED
ho5m631aiz4hw3tmj2hoz6mnq redis.conf 6 seconds ago 6 seconds ago
創建redis服務
[root@node1 /opt/mycontainer/redis]# $ docker service create \
--name redis \
# --config source=redis.conf,target=/etc/redis.conf \
--config redis.conf \
-p 6379:6380 \
redis:latest \
redis-server /redis.conf
如果你沒有在 target
中顯式的指定路徑時,默認的 redis.conf
以 tmpfs
文件系統掛載到容器的 /config.conf
。
以前我們通過監聽主機目錄來配置 Redis,就需要在集群的每個節點放置該文件,如果采用
docker config
來管理服務的配置信息,我們只需在集群中的管理節點創建config
,當部署服務時,集群會自動的將配置文件分發到運行服務的各個節點中,大大降低了配置信息的管理和分發難度。
[root@node1 /opt/mycontainer/redis]# redis-cli -h 127.0.0.1 -p 6379
127.0.0.1:6379> set docker "k8s"
OK
127.0.0.1:6379> get docker
"k8s"
滾動升級
我們通過swarm創建的服務,那么該怎么升級?
錯誤做法❌:先停止原來的服務,再使用新鏡像部署一個服務,就完成服務的 “升級” 。
我們先構建一個低版本的nginx服務:
[root@node1 /opt/mycontainer/redis]# docker service create --name nginx --replicas 3 -p 80:80 nginx:1.13.7-alpine
pofnib1a1c5ybefck3sbuxxnw
overall progress: 3 out of 3 tasks
1/3: running [==================================================>]
2/3: running [==================================================>]
3/3: running [==================================================>]
verify: Service converged
我們嘗試升級:
[root@node1 /opt/mycontainer/redis]# docker service update nginx --image nginx:1.13.12-alpine
nginx
overall progress: 3 out of 3 tasks
1/3: running [==================================================>]
2/3: running [==================================================>]
3/3: running [==================================================>]
verify: Service converged
[root@node1 /opt/mycontainer/redis]# docker service ps nginx
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
ujh469k4ta37 nginx.1 nginx:1.13.12-alpine node2 Running Running 2 minutes ago
3iodal770wzd \_ nginx.1 nginx:1.13.7-alpine node2 Shutdown Shutdown 2 minutes ago
2dzwc981805l nginx.2 nginx:1.13.12-alpine node1 Running Running 48 seconds ago
cyc3sudi4w8f \_ nginx.2 nginx:1.13.7-alpine node1 Shutdown Shutdown about a minute ago
4dzp1irwv0dh nginx.3 nginx:1.13.12-alpine node2 Running Running about a minute ago
t3l9vn1uspsg \_ nginx.3 nginx:1.13.7-alpine node2 Shutdown Shutdown about a minute ago
通過--image
選項更新了服務的鏡像。通過docker service ps nginx
可以看到版本更新成功了。
回滾
現在假設我們發現 nginx
服務的鏡像升級到 nginx:1.13.12-alpine
出現了一些問題,我們可以使用命令一鍵回退。
[root@node1 /opt/mycontainer/redis]# docker service rollback nginx
nginx
rollback: manually requested rollback
overall progress: rolling back update: 3 out of 3 tasks
1/3: running [> ]
2/3: running [> ]
3/3: running [> ]
verify: Service converged
[root@node1 /opt/mycontainer/redis]# docker service ps nginx
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
zjm1b7je4530 nginx.1 nginx:1.13.7-alpine node2 Running Running 50 seconds ago
ujh469k4ta37 \_ nginx.1 nginx:1.13.12-alpine node2 Shutdown Shutdown 50 seconds ago
3iodal770wzd \_ nginx.1 nginx:1.13.7-alpine node2 Shutdown Shutdown 4 minutes ago
1fqs48zdo3b7 nginx.2 nginx:1.13.7-alpine node1 Running Running 18 seconds ago
2dzwc981805l \_ nginx.2 nginx:1.13.12-alpine node1 Shutdown Shutdown 19 seconds ago
cyc3sudi4w8f \_ nginx.2 nginx:1.13.7-alpine node1 Shutdown Shutdown 3 minutes ago
o20xcgwmyjis nginx.3 nginx:1.13.7-alpine node2 Running Running 46 seconds ago
4dzp1irwv0dh \_ nginx.3 nginx:1.13.12-alpine node2 Shutdown Shutdown 46 seconds ago
t3l9vn1uspsg \_ nginx.3 nginx:1.13.7-alpine node2 Shutdown Shutdown 3 minutes ago
通過docker service ps
我們能看到版本變化的詳細信息。