优雅地实现安全的容器编排 - Docker Secrets

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 安全无小事,微服务架构的应用对容器集群中安全地管理和分发秘密提出了更大的挑战。通过Docker Secret和Docker编排可以非常简洁、优雅地解决这个问题,帮助您打造安全的云原生应用执行环境。

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端口暴露为服务的访问端口。我们可以打开浏览器,输入 http://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

相关实践学习
巧用云服务器ECS制作节日贺卡
本场景带您体验如何在一台CentOS 7操作系统的ECS实例上,通过搭建web服务器,上传源码到web容器,制作节日贺卡网页。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
相关文章
|
2天前
|
数据库 Docker 容器
docker容器为啥会开机自启动
通过配置适当的重启策略,Docker容器可以在主机系统重启后自动启动。这对于保持关键服务的高可用性和自动恢复能力非常有用。选择适合的重启策略(如 `always`或 `unless-stopped`),可以确保应用程序在各种情况下保持运行。理解并配置这些策略是确保Docker容器化应用可靠性的关键。
139 93
|
5天前
|
Ubuntu NoSQL Linux
《docker基础篇:3.Docker常用命令》包括帮助启动类命令、镜像命令、有镜像才能创建容器,这是根本前提(下载一个CentOS或者ubuntu镜像演示)、容器命令、小总结
《docker基础篇:3.Docker常用命令》包括帮助启动类命令、镜像命令、有镜像才能创建容器,这是根本前提(下载一个CentOS或者ubuntu镜像演示)、容器命令、小总结
52 6
《docker基础篇:3.Docker常用命令》包括帮助启动类命令、镜像命令、有镜像才能创建容器,这是根本前提(下载一个CentOS或者ubuntu镜像演示)、容器命令、小总结
|
16天前
|
搜索推荐 安全 数据安全/隐私保护
7 个最能提高生产力的 Docker 容器
7 个最能提高生产力的 Docker 容器
93 35
|
3天前
|
数据库 Docker 容器
docker容器为啥会开机自启动
通过配置适当的重启策略,Docker容器可以在主机系统重启后自动启动。这对于保持关键服务的高可用性和自动恢复能力非常有用。选择适合的重启策略(如 `always`或 `unless-stopped`),可以确保应用程序在各种情况下保持运行。理解并配置这些策略是确保Docker容器化应用可靠性的关键。
29 17
|
15天前
|
Ubuntu Linux 开发工具
docker 是什么?docker初认识之如何部署docker-优雅草后续将会把产品发布部署至docker容器中-因此会出相关系列文章-优雅草央千澈
Docker 是一个开源的容器化平台,允许开发者将应用程序及其依赖项打包成标准化单元(容器),确保在任何支持 Docker 的操作系统上一致运行。容器共享主机内核,提供轻量级、高效的执行环境。本文介绍如何在 Ubuntu 上安装 Docker,并通过简单步骤验证安装成功。后续文章将探讨使用 Docker 部署开源项目。优雅草央千澈 源、安装 Docker 包、验证安装 - 适用场景:开发、测试、生产环境 通过以上步骤,您可以在 Ubuntu 系统上成功安装并运行 Docker,为后续的应用部署打下基础。
docker 是什么?docker初认识之如何部署docker-优雅草后续将会把产品发布部署至docker容器中-因此会出相关系列文章-优雅草央千澈
|
4天前
|
运维 Java 虚拟化
《docker基础篇:1.Docker简介》,包括Docker是什么、容器与虚拟机比较、能干嘛、去哪下
《docker基础篇:1.Docker简介》,包括Docker是什么、容器与虚拟机比较、能干嘛、去哪下
54 12
|
21天前
|
存储 Kubernetes 开发者
容器化时代的领航者:Docker 和 Kubernetes 云原生时代的黄金搭档
Docker 是一种开源的应用容器引擎,允许开发者将应用程序及其依赖打包成可移植的镜像,并在任何支持 Docker 的平台上运行。其核心概念包括镜像、容器和仓库。镜像是只读的文件系统,容器是镜像的运行实例,仓库用于存储和分发镜像。Kubernetes(k8s)则是容器集群管理系统,提供自动化部署、扩展和维护等功能,支持服务发现、负载均衡、自动伸缩等特性。两者结合使用,可以实现高效的容器化应用管理和运维。Docker 主要用于单主机上的容器管理,而 Kubernetes 则专注于跨多主机的容器编排与调度。尽管 k8s 逐渐减少了对 Docker 作为容器运行时的支持,但 Doc
108 5
容器化时代的领航者:Docker 和 Kubernetes 云原生时代的黄金搭档
|
5天前
|
Kubernetes Linux 虚拟化
入门级容器技术解析:Docker和K8s的区别与关系
本文介绍了容器技术的发展历程及其重要组成部分Docker和Kubernetes。从传统物理机到虚拟机,再到容器化,每一步都旨在更高效地利用服务器资源并简化应用部署。容器技术通过隔离环境、减少依赖冲突和提高可移植性,解决了传统部署方式中的诸多问题。Docker作为容器化平台,专注于创建和管理容器;而Kubernetes则是一个强大的容器编排系统,用于自动化部署、扩展和管理容器化应用。两者相辅相成,共同推动了现代云原生应用的快速发展。
44 10
|
18天前
|
存储 Kubernetes Docker
Kubernetes(k8s)和Docker Compose本质区别
理解它们的区别和各自的优势,有助于选择合适的工具来满足特定的项目需求。
93 19
|
27天前
|
关系型数据库 应用服务中间件 PHP
实战~如何组织一个多容器项目docker-compose
本文介绍了如何使用Docker搭建Nginx、PHP和MySQL的环境。首先启动Nginx容器并查看IP地址,接着启动Alpine容器并安装curl测试连通性。通过`--link`方式或`docker-compose`配置文件实现服务间的通信。最后展示了Nginx配置文件和PHP代码示例,验证了各服务的正常运行。
50 3
实战~如何组织一个多容器项目docker-compose

相关产品

  • 容器服务Kubernetes版