内容简介:本节会介绍由Docker平台提供的主要的安全技术。Swarm模式是Docker未来的趋势。Swarm模式支持用户集群化管理多个Docker主机,同时还能通过声明式的方式部署应用。每个Swarm都由管理者和工作者节点构成,节点可以是Linux或者Windows。管理者节点构成了集群中的控制层,并负责集群配置以及工作负载的分配。工作者节点就是运行应用代码的容器。正如所预期的,Swarm模式包括很多开箱即用的安全特性,同时还设置了合理的默认值。这些安全特性包括以下几点。
本节会介绍由 Docker 平台提供的主要的安全技术。
1.Swarm模式
Swarm模式是Docker未来的趋势。Swarm模式支持用户集群化管理多个Docker主机,同时还能通过声明式的方式部署应用。每个Swarm都由管理者和工作者节点构成,节点可以是 Linux 或者Windows。管理者节点构成了集群中的控制层,并负责集群配置以及工作负载的分配。工作者节点就是运行应用代码的容器。
正如所预期的,Swarm模式包括很多开箱即用的安全特性,同时还设置了合理的默认值。这些安全特性包括以下几点。
- 加密节点ID。
- 基于TLS的认证机制。
- 安全准入令牌。
- 支持周期性证书自动更新的CA配置。
- 加密集群存储(配置DB)。
- 加密网络。
接下来将详细介绍如何构建安全的Swarm,以及如何进行安全相关的配置。
为了完成下面的内容,读者需要至少3个Docker主机,每个都运行1.13或者更高版本的Docker。示例中3个Docker主机分别叫作“mgr1”“mgr2”“wrk1”。每台主机上都安装Ubuntu 16.04,其上运行了Docker 18.01.0-ce。同时还有一个网络负责联通3台主机,并且主机之间可以通过名称互相ping通。安装完成后如图15.6所示。
图15.6 3个Docker主机
(1)配置安全的Swarm集群
读者可以在其Swarm集群管理者节点上运行下面的命令。在本例中,命令运行于“mgr1”节点之上。
$ docker swarm init Swarm initialized: current node (7xam...662z) is now a manager. To add a worker to this swarm, run the following command: docker swarm join --token \ SWMTKN-1-1dmtwu...r17stb-ehp8g...hw738q 172.31.5.251:2377 To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
上面的命令就是配置安全Swarm集群所要做的全部工作!
“mgr1”被配置为Swarm集群中的第一个管理节点,也是根CA节点。Swarm集群已经被赋予了加密Swarm ID,同时“mgr1”节点为自己发布了一个客户端认证信息,标明自己是Swarm集群管理者。证书的更新周期默认设置为90天,集群配置数据库也已经配置完成并且处于加密状态。安全令牌也已经成功创建,允许新的管理者和工作者节点加入到Swarm集群中。以上全部内容都只需要 一条命令
!
实验环境如图15.7所示。
图15.7实验环境
现在将“mgr2”节点加入到集群中,作为额外的管理者节点。
将新的管理者节点加入到Swarm需要两步。第一步,需要提取加入管理者到集群中所需的令牌;第二步,在“mgr2”节点上执行 docker swarm join
命令。只要将管理者准入令牌作为 docker swarm join
命令的一部分,“mgr2”就作为管理者节点加入Swarm。
在“mgr1”上运行下面的命令获取管理者准入令牌。
$ docker swarm join-token manager To add a manager to this swarm, run the following command: docker swarm join --token \ SWMTKN-1-1dmtwu...r17stb-2axi5...8p7glz \ 172.31.5.251:2377
命令输出内容给出了管理者加入Swarm所需运行的准确命令。准入令牌和IP地址在读者自己的实验环境中是不一样的。
复制该命令并在“mgr2”节点上运行。
$ docker swarm join --token SWMTKN-1-1dmtwu...r17stb-2axi5...8p7glz \ > 172.31.5.251:2377 This node joined a swarm as a manager.
“mgr2”现在已经作为另一个管理者加入Swarm。
注:
join命令的格式是 docker swarm join --token <manager-join-token>
<ip-of-existing-manager>:<swarm-port>
。
可以通过在任意管理者节点上运行 docker node ls
命令来确认上述操作。
$ docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS 7xamk...ge662z mgr1 Ready Active Leader i0ue4...zcjm7f * mgr2 Ready Active Reachable
上述输出内容中显示“mgr1”和“mgr2”都加入了Swarm,并且都是Swarm管理者。最新的配置如图15.8所示。
图15.8 “mgr1”和“mgr2”都加入了Swarm
两个管理者这个数量,大概是最糟糕的一种情况了。但是这只是一个实验环境,而不是什么核心业务生产环境,所以糟糕点也无所谓。
向Swarm中加入工作者也只需两步。第一步需要获取新工作者的准入令牌,第二步是在工作者节点上运行 docker swarm join
命令。
在任意管理者节点上运行下面的命令,获取工作者准入令牌。
$ docker swarm join-token worker To add a worker to this swarm, run the following command: docker swarm join --token \ SWMTKN-1-1dmtw...17stb-ehp8g...w738q \ 172.31.5.251:2377
读者可以在指定工作者的节点上运行该命令。准入令牌和IP地址会有所不同。
复制如下所示命令到“wrk1”上并且运行。
$ docker swarm join --token SWMTKN-1-1dmtw...17stb-ehp8g...w738q \ > 172.31.5.251:2377 This node joined a swarm as a worker.
在任意Swarm管理者上运行 docker node ls
命令。
$ docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS 7xamk...ge662z * mgr1 Ready Active Leader ailrd...ofzv1u wrk1 Ready Active i0ue4...zcjm7f mgr2 Ready Active Reachable
目前读者已经拥有包含两个管理者和一个工作者的Swarm集群。管理者配置为高可用(HA),并且复用集群存储。最新的配置如图15.9所示。
图15.9将管理者配置为高可用(HA)
(2)了解Swarm安全背后的原理
到目前为止,读者已经成功搭建了安全的Swarm集群。接下来一起花费几分钟了解一下这背后涉及的安全技术。
1)Swarm准入令牌
向某个现存的Swarm中加入管理者和工作者所需的唯一凭证就是准入令牌。因此,保证准入令牌的安全十分关键!不要将其发布到公开的Github仓库中。
每个Swarm都包含两种不同准入令牌。
- 管理者所需准入令牌。
- 工作者所需准入令牌。
有必要理解Swarm准入令牌的格式。每个准入令牌都由4个不同的字段构成,中间采用虚线(-)连接。
PREFIX-VERSION-SWARM ID-TOKEN
PREFIX永远是“SWMTKN”,这样允许读者通过表达式匹配到该令牌,以避免意外将其发布到公共环境当中;VERSION这一列则展示了Swarm的版本信息;SWARM ID列是Swarm认证信息的一个哈希值;TOKEN这一列的内容决定了该令牌是管理者还是工作者的准入令牌。
如下所示,对于指定Swarm的管理者和工作者准入令牌,除了最后TOKEN字段的内容之外没有任何区别。
- 管理者:SWMTKN-1-1dmtwusdc...r17stb- 2axi53zjbs45lqxykaw8p7glz
。
- 工作者:SWMTKN-1-1dmtwusdc...r17stb- ehp8gltji64jbl45zl6hw738q
。
如果用户认为当前准入令牌存在风险,仅用一条命令就可以取消该准入令牌授权,同时发布新的准入令牌。在下面的示例中,取消了已经授权的管理者准入令牌,之后又发布了新的令牌。
$ docker swarm join-token --rotate manager Successfully rotated manager join token. To add a manager to this swarm, run the following command: docker swarm join --token \ SWMTKN-1-1dmtwu...r17stb-1i7txlh6k3hb921z3yjtcjrc7 \ 172.31.5.251:2377
需要注意的是,新旧令牌只有最后字段存在区别。SWARM ID还是相同的。
准入令牌保存在集群配置的数据库中,默认是加密的。
2)TLS和双向认证
每个加入Swarm的管理者和工作者节点,都需要发布自己的客户端证书。这个证书用于双向认证。证书中定义了节点相关信息,包括从属的Swarm集群以及该节点在集群中的身份(管理者还是工作者)。
在Linux主机上,读者可以指定使用下面的命令查看指定节点的客户端证书。
$ sudo openssl x509 \ -in /var/lib/docker/swarm/certificates/swarm-node.crt \ -text Certificate: Data: Version: 3 (0x2) Serial Number: 80:2c:a7:b1:28...a8:af:89:a1:2a:51:89 Signature Algorithm: ecdsa-with-SHA256 Issuer: CN=swarm-ca Validity Not Before: Jul 19 07:56:00 2017 GMT Not After : Oct 17 08:56:00 2017 GMT Subject: O=mfbkgjm2tlametbnfqt2zid8x, OU=swarm-manager, CN=7xamk8w3hz9q5kgr7xyge662z Subject Public Key Info: <snip>
上述输出中, Subject
中用到了 O
、 OU
以及 CN
字段分别表示Swarm ID、节点角色以及节点ID信息。
O OU CN
如图15.10所示。
图15.10 Subject
中使用的字段
在 Validity
中,还可以直接看到证书的更新周期。
上述信息可以在 docker system info
命令的输出中得到验证。
$ docker system info
3)配置一些CA信息
通过 docker swarm update
命令可以配置Swarm证书的更新周期。下面的示例中,将Swarm的证书更新周期修改为30天。
$ docker swarm update--cert-expiry720h
Swarm允许节点在证书过期前重新创建证书,这样可以保证Swarm中全部节点不会在同一时间尝试更新自己的证书信息。
读者可以在创建Swarm的时候,通过在 docker swarm init
命令中增加 --external-ca
参数来指定外部的CA。
docker swarm ca
命令可以用于管理CA相关配置。可以在运行该命令时指定 --help
来查看命令功能。
$ docker swarm ca --help Usage: docker swarm ca [OPTIONS] Manage root CA Options: --ca-cert pem-file Path to the PEM-formatted root CA certificate to use for the new cluster Path --ca-key pem-file to the PEM-formatted root CA key to use for the new cluster --cert-expiry duration Validity period for node certificates (ns|us|ms|s|m|h) (default 2160h0m0s) -d, --detach Exit immediately instead of waiting for the root rotation to converge Specifications of --external-ca external-ca one or more certificate signing endpoints Print usage --help Suppress progress output -q, --quiet Rotate the swarm CA - if no certificate --rotate or key are provided, new ones will be gene\
4)集群存储
集群存储是Swarm的大脑,保存了集群配置和状态数据。
存储目前是基于 etcd
的某种实现,并且会在Swarm内所有管理者之间自动复制。存储默认也是加密的。
集群存储正逐渐成为很多Docker平台的关键技术。例如,Docker网络和Docker密钥都用到了集群存储。Docker平台的很多部分都已经用到了集群存储,未来对集群存储的利用会更多,而这也是Swarm模式在Docker规划中占据重要地位的原因之一。这还意味着,如果不使用Swarm模式运行Docker,很多Docker特性就无法使用。
集群存储的日常维护由Docker自动完成。但是,在生产环境中,需要为集群存储提供完整的备份和恢复方案。
Swarm模式安全部分的内容到此为止。
2.Docker安全扫描
快速发现代码缺陷的能力至关重要。Docker安全扫描功能使得对Docker镜像中已知缺陷的检测工作变得简单。
注:
在本书编写之时,Docker安全扫描已经可以用于Docker Hub上私有仓库的镜像了。同时该技术还可以作为Docker可信服务本地化部署解决方案的一部分。最后,所有官方Docker镜像都经过了安全扫描,扫描报告在其仓库中可以查阅。
Docker安全扫描对Docker镜像进行二进制代码级别的扫描,对其中的软件根据已知缺陷数据库(CVE数据库)进行检查。在扫描执行完成后,会生成一份详细报告。
打开浏览器访问Docker Hub,并搜索Alpine仓库。图15.11展示了官方Alpine仓库的Tags标签页。
图15.11官方Alpine仓库的Tags标签页
Alpine仓库是官方仓库,这意味着该仓库会自动扫描并生成对应报告。可以看到,镜像标签为 edge
、 latest
以及 3.6
的镜像都通过了已知缺陷的检查。但是 alpine:3.5
镜像存在已知缺陷(标红)。
如果打开 alpine:3.5
镜像,可以发现如图15.12所示的详细信息。
图15.12 alpine:3.5
镜像的详细信息
这是发现自己软件中已知缺陷详情的一种简单方式。
Docker可信镜像仓库服务(Docker Trusted Registry, DTR),属于Docker企业版中本地化镜像仓库服务的一部分内容,提供了相同的Capability,同时还允许用户自行控制其镜像扫描时机以及扫描方式。例如,DTR允许用户选择镜像是在推送时自动触发扫描,还是只能手工触发。同时DTR还允许用户手动更新CVE数据库,这对于DTL无法进行联网来自动更新CVE数据的场景来说,是一种理想的解决方案。
这就是Docker安全扫描,一种深入检测Docker镜像是否存在已知安全缺陷的好方式。当然,能力越大责任越大,当用户发现缺陷后,就需要承担解决相应缺陷的责任了。
3.Docker内容信任
Dockr内容信任(Docker Content Trust,DCT)使得用户很容易就能确认所下载镜像的完整性以及其发布者。在不可信任的网络环境中下载镜像时,这一点很重要。
从更高层面来看,DCT允许开发者对发布到Docker Hub或者Docker可信服务的镜像进行签名。当这些镜像被拉取的时候,会自动确认签名状态。图15.13展示了这一过程。
DCT还可以提供关键上下文,如镜像是否已被签名从而可用于生产环境,镜像是否被新版本取代而过时等。
在本书编写之际,DTC提供的上下文还在初期,配置起来相当复杂。
在Docker主机上启用DCT功能,所要做的只是在环境中将 DOCKER_CONTENT_TRUST
变量设置为1。
$export DOCKER_CONTENT_TRUST=1
图15.13镜像被拉取时自动确认签名状态
在实际环境中,用户可能希望在系统中默认开启该特性。
如果使用Docker统一配置层(Docker企业版的一部分),需要勾选图中15.14所示 Run Only Signed Images
复选项。这样会强制所有在UCP集群中的节点只运行已签名镜像。
图15.14 勾选 Only run signed images
复选项
由图15.14中可知,UCP在DCT的基础上进行进一步封装,提供了已签名镜像的安全首选项信息。例如,用户可能有这样的需求:在生产环境中只能使用由 secops
签名的镜像。
一旦DCT功能开启,就不能获取并使用未签名镜像了。图15.15展示了开启DCT之后,如果再次尝试通过Docker CLI或者UCP Web UI界面拉取未签名镜像时所报的错误(两个示例都尝试拉取标签为“unsigned”的镜像)。
图15.15拉取未签名镜像时报错
图15.16展示了DCT是如何阻止Docker客户端拉取一个被篡改的镜像的。图15.17展示了DCT如何阻止客户端拉取旧镜像。
图15.16拉取被篡改的镜像
图15.17拉取旧镜像
Docker内容信任是一种很重要的技术,能帮助用户检查从Docker服务中拉取的镜像。该技术的基础模式配置起来非常简单,但是类似上下文等一些高级特性,现阶段配置起来还是非常复杂的。
4.Docker密钥
很多应用都需要密钥。比如密码、TLS证书、SSH key等。
在Docker1.13版本之前,没有一种标准且安全的方式能让密钥在应用间实现共享。常见的方式是开发人员将密钥以文本的方式写入环境变量(我们都这么做过)。这与理想状态差距甚远。
Docker1.13引入了Docker密钥,将密钥变成Docker生态系统中的一等公民。例如,增加了一个新的子命令 docker secret
来管理密钥。在Docker的UCP界面中,也有专门的地方来创建和管理密钥。在后台,密钥在创建后以及传输中都是加密的,使用时被挂载到内存文件系统,并且只对那些已经被授权了的服务开放访问。这确实是一种综合性的端到端解决方案。
图15.18展示了其总体流程。
下面依次介绍图15.18中所示工作流的每一步。
(1)密钥被创建,并且发送到Swarm。
(2)密钥存放在集群存储当中,并且是加密的(每个管理者节点都能访问集群存储)。
(3)B服务被创建,并且使用了该密钥。
(4)密钥传输到B服务的任务节点(容器)的过程是加密的。
(5)B服务的容器将密钥解密并挂载到路径 /run/secrets
下。这是一个临时的内存文件系统(在Windows Docker中该步骤有所不同,因为Windows中没有内存文件系统这个概念)。
(6)一旦容器(服务任务)完成,内存文件系统关闭,密钥也随之删除。
(7)A服务中的容器不能访问该密钥。
图15.18引入Docker密钥
用户可以通过 docker secret
子命令来管理密钥,可以通过在运行 docker service create
命令时附加 --secret
,从而为某个服务指定密钥。
小结
Docker可以通过配置变得特别安全。Docker支持全部的Linux主流安全技术,包括Namespace、Control Group、Capability、MAC以及Seccomp。Docker为这些安全技术设定了合理的默认值,但是用户也可以自行修改配置,或者禁用这些安全技术。
在通用的Linux安全技术之上,Docker平台还引入了大量自有安全技术。Swarm模式基于TLS构建,并且配置上极其简单灵活。安全扫描对镜像进行二进制源码级别扫描,并提供已知缺陷的详细报告。Docker内容信任允许用户对内容进行签名和认证,密钥目前也是Docker中的一等公民。
最终结论就是,无论用户希望Docker环境有多安全,Docker都可以实现。这一切都取决于用户如何配置Docker。
本文摘自正在热销的技术书 《深入浅出Docker》
Nigel,Poulton(奈吉尔·波尔顿) 著,李瑞丰,刘康
- Docker技术入门与实践指南教程
- 容器与容器云解析,帮助您快速建立Docker技术知识体系
- Docker认证工程师实用指南
《深入浅出Docker》由Docker概览和Docker技术两部分组成,遵循简介—详解—命令的章节布局,全面系统地剖析Docker的基本原理与实践应用。清晰详细的操作步骤结合大量的实际代码,为读者切实入门Docker保驾护航。
延伸阅读:干货 | Docker中用到的主要Linux安全技术有哪些?
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 英特尔扩充FPGA加速平台产品组合,可为数据中心开发人员提供强大的平台
- core_framework 0.4 发布,提供 windows 平台支持
- 创新中关村报道称 Cocos 开发者沙龙为开发者、技术提供者等提供了交流合作平台
- AWS为开源平台提供的服务超过数据库公司MongoDB
- Qeexo发布嵌入式机器学习平台,为边缘设备提供AI
- 为移动平台提供持续集成和交付方案,Bitrise获2000万美元B轮融资
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
XML、JSON 在线转换
在线XML、JSON转换工具
正则表达式在线测试
正则表达式在线测试