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_PASSWORDMYSQL_ROOT_HOSTMYSQL_DATABASEMYSQL_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了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM