閱讀844 返回首頁    go 阿裏雲 go 技術社區[雲棲]


優雅地實現安全的容器編排 - Docker Secrets

14960555198872

在微服務架構應用中,眾多組件在集群中動態地創建、伸縮、更新。在如此動態和大規模的分布式係統上,管理和分發密碼、證書等敏感信息將會是非常具有挑戰性的工作。對於容器應用,傳統的秘密分發方式,如將秘鑰存放在容器鏡像中,或是利用環境變量,volume動態掛載方式動態傳入都存在著潛在的安全風險。

為了應對這個問題,在Docker 1.13及更高版本中,Docker推出了Secrets管理,可以在Swarm mode集群中安全地管理密碼、密鑰證書等敏感信息,並允許在多個Docker容器實例之間共享訪問指定的秘密信息。

Docker secret 基本功能與典型場景

Docker命令行工具提供了docker secret命令來管理敏感信息,

注: docker secret 隻能從Docker Swarm模式的manager節點調用,如果你在本機進行試驗,請先執行 docker swarm init 命令

$ docker secret --help

Usage:  docker secret COMMAND

Manage Docker secrets

Options:
      --help   Print usage

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.

其中 docker secret create 支持從標準輸入讀取信息,並且存入指定的secret:

首先我們創建兩個 secrets

$ echo "Password4DB" | docker secret create db_password -
$ echo "Password4Root" | docker secret create root_password -

然後我們創建一個“db”服務並引用所創建的secret作為,數據庫密碼和root密碼

$  docker service create --name db \
    -d \
    --secret db_password \
    --secret root_password \
    -e MYSQL_USER=dbtest \
    -e MYSQL_DATABASE=dbtest \
    -e MYSQL_PASSWORD_FILE=/run/secrets/db_password \
    -e MYSQL_ROOT_PASSWORD_FILE=/run/secrets/root_password \
    mariadb

創建完畢之後,我們可以檢查服務的狀態

$ docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
ouq2xbuu3jrp        db                  replicated          1/1                 mariadb:latest

$ docker service logs --tail 100 db
...
db.1.zjmymi0goca0@moby    | 2017-05-28 23:35:25 140451437311936 [Warning] 'proxies_priv' entry '@% root@32ab97f50413' ignored in --skip-name-resolve mode.
db.1.zjmymi0goca0@moby    | 2017-05-28 23:35:25 140451437311936 [Note] mysqld: ready for connections.
db.1.zjmymi0goca0@moby    | Version: '10.1.23-MariaDB-1~jessie'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  mariadb.org binary distribution

我們可以通過 docker exec 命令來進入容器內部,查看掛載到/run/secrets/目錄下的秘密文件

$ docker exec -ti 32ab97f50413 bash
root@32ab97f50413:/# cat /run/secrets/db_password
Password4DB
root@32ab97f50413:/# cat /run/secrets/root_password
Password4Root

容器編排中使用 docker secret

從 Docker Compose V3.1開始,支持在容器編排文件中使用 secret,這可以方便地在不同容器中分享所需的敏感信息。下麵我們將使用 Compose 模板來構建一個Wordpress應用,通過 secret 實現 “wordpress”服務容器和“db”服務容器中共享數據庫密碼。

docker-compose.yml 文件如下

version: "3.1"
services:
  wordpress:
    image: wordpress:latest
    secrets:
      - wp_db_password
    ports:
      - 8080:80
    environment:
      - WORDPRESS_DB_USER=wordpress
      - WORDPRESS_DB_NAME=wordpress
      - WORDPRESS_DB_PASSWORD_FILE=/run/secrets/wp_db_password
      - WORDPRESS_DB_HOST=mariadb
    deploy:
      replicas: 3
      update_config:
        parallelism: 2
        delay: 10s
      restart_policy:
        condition: on-failure
  mariadb:
    image: mariadb
    secrets:
      - wp_db_password
      - root_db_password
    environment:
      - MYSQL_USER=wordpress
      - MYSQL_DATABASE=wordpress
      - MYSQL_PASSWORD_FILE=/run/secrets/wp_db_password
      - MYSQL_ROOT_PASSWORD_FILE=/run/secrets/root_db_password
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
secrets:
  wp_db_password:
    external: true
  root_db_password:
    external: true

通過模板中的 secrets 部分,我們創建和引用 Docker Secrtes,而且在Service 定義中可以非常方便地引用這些秘密信息,實現安全的容器編排。

首先,我們利用命令行創建秘密

$ echo "Password4DB" | docker secret create wp_db_password -
$ echo "Password4Root" | docker secret create root_db_password -

然後利用命令行部署compose模板

$ docker stack deploy -c docker-compose.yml wordpress
Creating network wordpress_default
Creating service wordpress_wordpress
Creating service wordpress_mariadb

由於我們為 “wordpress” 服務定義了 routing mesh 的端口映射,將8080端口暴露為服務的訪問端口。我們可以打開瀏覽器,輸入 https://127.0.0.1:8080 之後,就可以看到 WordPress 著名的配置頁麵了。

14960190435587

關於更多關於 Docker 編排能力的說明,請參見Docker 1.13 編排能力進化

阿裏雲容器服務中使用 Docker Secrets

首先,我們需要創建一個Docker Swarm Mode集群。注意在集群模式中選擇 Docker Swarm Mode。目前它還在 Beta 公測階段,在華東2、美西1等地域開放。

14960209581679

創建集群之後,它會自動構成一個 Docker Swarm集群。

選擇集群,點擊 “管理” >> “秘鑰管理” >> “創建”,來創建新的secret

14960407317919

然後退回容器服務控製台,創建Docker Compose V3模板。
選擇 “鏡像與方案” >> “編排模板” >> “創建”,使用如下內容創建模板 “wordpressv3-secret”

version: "3.1"
services:
  wordpress:
    image: wordpress:latest
    secrets:
      - wp_db_password
    environment:
      - WORDPRESS_DB_USER=wordpress
      - WORDPRESS_DB_NAME=wordpress
      - WORDPRESS_DB_PASSWORD_FILE=/run/secrets/wp_db_password
      - WORDPRESS_DB_HOST=mariadb
    labels:
      aliyun.routing.port_80: wordpress
    deploy:
      replicas: 3
      update_config:
        parallelism: 2
        delay: 10s
      restart_policy:
        condition: on-failure
  mariadb:
    image: mariadb
    secrets:
      - wp_db_password
      - root_db_password
    environment:
      - MYSQL_USER=wordpress
      - MYSQL_DATABASE=wordpress
      - MYSQL_PASSWORD_FILE=/run/secrets/wp_db_password
      - MYSQL_ROOT_PASSWORD_FILE=/run/secrets/root_db_password
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
secrets:
  wp_db_password:
    external: true
  root_db_password:
    external: true

和上麵示例模板一致,它會使用集群中的 secret “wp_db_password” 和 “root_db_password” 來配置數據庫密碼和root密碼。

與之前示例唯一不同的地方在於,在本模板中使用 aliyun.routing.port_80: wordpress 標簽來指明:將虛擬域名 “wordpress” 的請求路由到容器的 80 端口進行處理。這樣無需在集群上暴露額外的端口,就可以直接通過7層負載均衡來訪問應用了。容器服務內置了7層負載均衡和路由能力。

選擇“創建應用”,輸入應用名稱和部署集群,點擊“下一步”

14960415444887

在“應用配置”頁麵,選擇“創建並部署”,

14960416029034

創建完畢,在應用頁麵就可以看見新的容器應用,在其部署就緒之後,我們可以點擊應用名稱進入應用管理界麵,查看服務和容器信息。

14960417218022

在路由列表,我們可以發現應用注冊過的路由地址,

14960417793667

點擊之後,可以進入“WordPress”的配置頁麵了,是不是很方便呢:-)

image

關於更多關於阿裏雲容器服務支持Swarm Mode的信息,請閱讀相應文章。

Docker secret 實現原理

Docker 在Swarm mode集群設計中采用了係統化的安全設計。 用戶創建的 Secrets,會以加密的方式存儲在集群中 Manager節點的 Raft Store中。在創建服務時,Secrets 會下發到服務任務所處的 Worker 節點,並以 tmpfs 的形式掛載在容器內部。從而保證了秘鑰等敏感信息可以安全地在分布式集群上分發。通過這樣的措施,即使集群中一台Worker節點被攻破,沒有容器訪問權限的人是無法獲取相應秘密信息的。

14960161411631

在其他容器編排技術中,如Kubernetes也有類似的 Secrets 機製,然而在安全性上還存在較多的問題,期待在未來能夠解決。

總結

安全無小事,微服務架構的應用對容器集群中安全地管理和分發秘密提出了更大的挑戰。通過Docker Secret和Docker編排可以非常簡潔、優雅地解決這個問題,幫助您打造安全的雲原生應用執行環境。

容器服務的Swarm mode還在公測之中,陸續會有更多更酷的功能發布出來,也歡迎大家多提寶貴意見。

了解更多阿裏雲容器服務內容,請訪問 https://www.aliyun.com/product/containerservice

最後更新:2017-05-29 20:32:16

  上一篇:go  容器化混合雲解決方案實踐
  下一篇:go  阿裏雲開源容器技術Cabernets在阿裏雲上的最佳實踐