概述
当下Docker容器化的架构备受欢迎,越来越多的企业开始利用容器来构建自己的基础架构。通常是自己建立了Docker注册表,部署在服务器上安装Docker,安装Jenkins通过Docker插件Jenkins CI管道管理Docker容器。更大一点规模的则会使用K8S或者Swarm编排集群。对一个企业而言有开始尝试使用容器到逐渐深入,扩大规模要经历一系列的问题和踩坑的过程,那么如何规范化、安全的实施容器化,如何尽量避免踩坑呢?本文虫虫给列出企业尝试容器化架构需要考虑的各方各面问题,希望可以对大家有所帮助。
镜像问题
容器注册表
Docker服务都需要一个注册表(可不是我们常说的windows注册表),Docker注册表是Docker镜像的存储和在线(Web)版本仓库(类似于代码的github仓库)。有很多公有云自有容器注册表服务,比如Docker官方的Docker Hub,很多公有云都提供自己Docker注册表服务:
除了这些公开的注册表,基于安全、网络访问速度、规范化等考虑企业维护一个自建的Docker注册表(Docker私服)也是必须的。构建Docker私服可以使用Docker官方的Distribution,它是Docker官方推出的Docker Registry 2开源产品,使用Golang开发,极大提高了安全和性能。
知名的Git服务器端Gitlab也提供了Gitlab 容器注册表,部署Gitlab企业可以直接考虑使用这个组件,实现统一管理和集成。当然除了开源的,也可以使用商用的产品的比如Vmware开源的Harbor:
企业选择容器注册表需要考虑以下问题:
- 注册表是否能集成到企业内部的身份统一系统(比如LDAP,Kerberos等)?
- 是否支持基于角色的访问控制(RBAC)?
- 统一身份认证和授权对企业来说是一个大问题。虽然快速便宜的开放的注册解决方案可以足够开发环境的构建。但是对企业线上环境,必须要考虑安全性、RBAC标准等。
- 是否有加速镜像的方法?
- 镜像是要有区别对待的。有些是快速、功能全,但是可能杂乱的的开发环境镜像,他们不需要首要考虑正确性;而线上的镜像则是要注重安全和性能和正确防护。企业要对这些镜像分类,并且在注册表中通过实例管理流程或用标签强制执行。
- 是否与其他Artefact包管理架构保持良好的一致性?
企业可能已经有包文件库,内部的Artefact存储等(比如maven,npm,Gitlab等)。在理想的架构中,容器注册表应该是它的一个功能。如果架构上是分开的,那么久要考虑两者的集成和管理开销。
镜像扫描
这是很重要的部分。当镜像上传到自建容器注册表时,需要检查它们是否符合标准。例如,检查诸如此类的问题:
- bash版本是否存在破壳漏洞?
- ssl库是不是过时了?
- 该镜像是否基于一个不安全或不可接受的基本镜像(Base Image)?
- 是否存在有漏洞的或者过时库(Strus 2)和工具?
- 等等
可以通过静态镜像分析来检查这些问题。我们需要注意的是,这些扫描可能不是十全十美的,可能会错过一些非常明显漏洞,所以它也不是解决一切安全问题的灵丹妙药,而是一种必要的手段,特别非常适合用解决:
- 防止恶意攻击者注入木马?
- 在企业范围了,统一规范标准?
- 快速发现和修补已知的和标准CVE漏洞?
这些问题是组成了镜像扫描评估的基础,当然也需要考虑集成的成本。常见的镜像扫描工具有Clair,Anchore,OpenSCAP,Dockerscan等。
镜像构建
如何构建镜像?企业要支持哪些构建方法?如何将这些方组合在一起?
Dockerfiles最常用标准的方法之一,也可以使用S2I,Docker +Chef/Puppet/Ansible,甚至是手工方法构建。
使用那种CM(配置管理,如果已经使用的话)工具管理。
是否可以重复使用标准治理流程来和配置管理交互?
任何人都可以构建镜像吗?
业界的经验表明Dockerfile方法是一个使用广泛而且通用的方法,而且具有大量的社区文档和问题反馈支持。尝试更复杂的CM工具用来符合VM的公司标准的则通常有一定实施门槛。通过S2I或Chef/Puppet/Ansible方法则更加便捷,也能很好的实现代码(playbook)重用。
镜像完整
需要确保系统上运行的镜像在从构建到运行之间没有被篡改过。
是否可以使用安全密钥来对镜像进行签名?
是否有可以重复使用的密钥库?
密钥库可以与选择的工具集成吗?
即使Docker流行了很多年,镜像的完整性仍然是一个新兴领域。很多的供应商的对此还持观望态度。 Docker 公司在这方面做了一些有益的工作,比如Notary(Docker开源签名解决方案,已经转到CNCF基金会下)在Docker企业数据中心产品之外部署。
第三方镜像
如果希望使用一键部署,那么供应商的镜像则可以直接使用。
是否拥有验证供应商镜像的管理流程?
我们不光需要知道镜像是否安全,还需要知道谁可以在必要时更新镜像?
这些镜像可被其他镜像重用么?
这里有潜在的许可问题。是否有办法阻止其他项目/团队重用镜像?
是否强制要求运行于特定的环境(例如DMZ)?
Docker是否可以在这些环境中使用?
例如许多网络级应用程序运行在网络设备类似环境,并且需要认证,所以,它必须与其他容器或项目工作环境隔离。是否有可能在这些环境中运行镜像,需要考虑。
SDLC
如果企业已经实施了软件开发生命周期(SDLC)流程,那么就要考虑Docker和它适应的问题:
- 如何处理补丁?
- 如何识别哪些镜像需要更新?
- 如何更新它们?
- 如何通知团队更新?
- 如果他们不及时更新,如何强制他们更新?
该问题与上面已经提到的镜像扫描方案密切相关。可能需要在某些时候考虑将其与现有SDLC流程集成。
密码管理
在实施中数据库密码等信息需要传递到容器中。可以通过构建时(不建议)或运行时来完成该项工作。
如何在容器内管理密码?
是否对密码信息的使用进行了审核/跟踪并确保安全?
和镜像签名一样,密码管理也是一个仍在快速变化的新兴领域。业界有OpenShift/Origin与Hashicorp Vault等现有集成解决方案。Docker Swarm等核心组件中也有对密码管理的支持,Kubernetes 1.7加强了其密码安全功能。
基础镜像
如果在企业中运行Docker,则可能需要在公司范围内强制使用基础镜像:
- 该基本镜像应该包含哪些内容?
- 应该使用哪种标准工具?
- 谁负责管理集成镜像?
- 需要提前准备好很多关于基本镜像的问题。另外开发人员非常注重镜像的精简。
安全和审计
root权限
默认情况下,访问docker命令(特别是访问Docker UNIX套接字)需要机器root权限。对于生产环境中的来说,这是不可能接受的。需要回答以下问题:
- 谁(组)有权能够运行docker命令?
- 怎么管理这些有运行权限的人员?
- 如何控制可运行的内容?
这些都有解决方案,但它们相对较新,通常是其他更大解决方案的一部分。
例如,OpenShift具有强大的RBAC控制功能,但需要购买整个平台。Twistlock和Aquasec这样的容器安全工具提供了一种管理这些工具的方法,可以考虑集成他们。
运行时监控
企业可能希望能够确定线上容器运行情况。
如何知道线上运行了哪些容器?
这些运行中的容器,怎样容器注册表?怎么关联的,怎么在容器注册表中管理的?
启动以后,容器都更改过哪些关键性的文件?
同样,这还有其他一些问题,这些构成Docker基础运行策略。在这方面另一个经常被供应商提起的功能是异常检测。安全解决方案提供了诸如花哨的机器学习的解决方案,声称可以通过学习容器该做什么,并对可能的异常活动发出告警。例如连接到与应用程序无关的外部应用程序的端口。虽然听起来不错,但是需要考虑一下如何运维他们。一般来说可能会有大量的误报,需要大量调整和回归验证的,是否有人力和资金来维持运维,是问题的关键。
审计
当发生问题后,我们需要知道发生了什么。在物理和虚拟机的架构体系中,有很多安全措施来协助故障调查。而Docker容器的体系下,有可能是一个没有"黑匣子记录"的。
能马上查询出谁在运行容器吗?
能马上查询出谁构建了了容器吗?
要删除容器时,能快速确定该容器的作用吗?
要删除容器时,能确定改容器可能做了什么吗?
在这个问题上,我们可能希望强制使用特定的日志系统解决方案,以确保有关系统活动的信息在容器实例中保持不变。Sysdig的Falco(目前已经转到CNCF基金会下)是容器安全监控和审计领域一个有趣,很有前途的工具。
运维
日志
应用程序日志记录是企业关注的问题之一:
- 容器是否记录了操作所需的内容?
- 日志是否遵循企业日志标准?
- 日志记录在什么地方?
容器的日志可能与传统机器部署有着非常不同的模式。日志存储空间可能要支持横向扩展,可能需要增加存储等。
容器编排
为了让容器可以迅速随着业务扩展和变更迭代,就需要编排系统来统一管理。
选择的编排架构是否和Docker基础架构的其他部分可以很好的适应?
是想使用一个与主流架构相悖的编排架构,还是追随主流呢?
Kubernetes目前看来是赢得编排系统的市场。选择非Kubenetes的架构可能需要找出充分的理由。
操作系统
企业线上操作系统远落后于最新的版本和最通用的版本。
线上的标准操作系统是否能够支持Docker所有最新功能?
例如,一些编排系统和Docker本身需要的内核版本或软件包可能比所能支持的新很多,这可能是一个非常棘手的问题。
系统软件包管理默认支持的Docker版本是多少?
Docker版本之间可能会存在明显差异(比如,1.10是一个很大的差异),我们需要关注这些差异的细节。发行版提供的Docker(或者说'Moby'版本)之间也存在差异,这个影响很大。比如,RedHat的二进制docker包请求的顺序RedHat的注册表排在Docker Hub之前。
开发
开发环境
开发人员往往会要求系统管理权限。如何控制他们权限?
一个比较好的做法是可以为开发人员提供一个VM,让他们在本地进行Docker构建,或者只运行docker客户端,而将Docker服务端运行在统一服务器上。
他们的客户端是否与部署环境保持一致?
如果他们的桌面上使用的是docker-compose,他们可能会很反感在UAT和生产中切换到Kubernetes pod。
CI/CD
Jenkins是最受欢迎的CI工具,但是还有其他流行的替代方案,例如TeamCity,Gitlab CI等
Docker引入很多开发人员渴望使用的插件。其中很多都没有考虑到安全性,甚至可能与其他插件存在兼容性的问题。
你CI/CD插件的策略是什么?
你准备好开启一大堆新良莠不齐的插件了吗?
CI流程是否适合短暂Jenkins实例以及持久的,受支持的实例?
基础设施
共享存储
Docker的核心是使用独立于运行容器的卷,其中存储持久数据。
共享存储容易配置吗?
NFS服务有其局限性,但已经成熟,并且在大型组织中通常得到很好的支持。
共享存储支持是否可以满足业务增加的需求?
是否需要跨部署位置提供共享存储?
你可能拥有多个数据中心和/或云提供商。所有这些地点是否可以互相交互?他们需要交互吗?
网络
企业通常拥有自己喜欢的软件定义网络(SDN)解决方案,如Nuage,或新的方案比如Calico。
你是否有规定的SDN解决方案?
它如何与你选择的解决方案相互作用?
SDN交互是否可能会导致出现问题?
aPaaS
拥有像OpenShift或Tutum Cloud这样的aPaaS可以通过集中化支持Docker运行的上下文来解决上述许多问题。
你是否考虑过使用aPaaS?
云供应商
如果你使用的是亚马逊或谷歌,阿里云等云提供商:
如何在云供应商上提供镜像和运行容器?
是否希望将Docker解决方案与云供应商的产品联系起来,或者让他们与云供应商无关?
解决方案选择时要注意的事项
有两种方法可以选择。一种方法是使用单个供应商的整体统一架构。还有一种方法是使用多个供应商的各个优势产品,然后拼凑集成为一个企业方案。
方法一的,好处是:
- 统一管理,统一认证。
- 减少集成工作量和开销。
- 交付更快。
- 可以享受来自供应商的更大承诺和关注。
- 可能对产品方向的影响
- 更易于管理。
单一供应商解决方案通常要求按照节点付款,可能导致成本费用很高,而且后续更换需要承受巨大损失,也会限制内部的架构。
拼凑集成方案的好处有:
- 可以更具企业需求,用不同的速率提供更灵活的解决方案
- 集众家之长,可以让你少踩坑,少犯错误,有问题可以随时调整更换工具。
- 从从长远来看更加批恩一便宜,而且不会被 "锁定"到某家供应商上,不仰人鼻息,被人敲诈,吊死在一棵树上。
结论
企业Docker架构和部署复杂而多变。制定一个统一的,具有成本效益,安全,完整,灵活的,可以快速交付且无需锁定的战略是当下企业容器化临的挑战之一。本文列出了企业Docker实施各个方面需要注意的问题总结,供大家参考。